Subversion Repositories wimsdev

Rev

Rev 7246 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
7246 schaersvoo 1
/*    Sketch Elements: Chemistry molecular diagram drawing tool.
3662 schaersvoo 2
 
3
    (c) 2007 Dr. Alex M. Clark
4
 
5
    Released as GNUware, under the Gnu Public License (GPL)
6
 
7
    See www.gnu.org for details.
8
*/
9
 
10
package WIMSchem;
11
 
12
import WIMSchem.ds.*;
13
 
14
import java.io.*;
15
import java.awt.*;
16
import java.util.*;
17
import java.awt.image.*;
18
import java.awt.event.*;
19
import java.awt.datatransfer.*;
20
import javax.swing.*;
21
 
22
/*
23
    Encapsulates the editing panel, provides menus and toolbars, and responds to various types
24
    of events.
25
 
26
    few other miscellaneous useful tasks. Is generally intended for using in conjunction with various computational or presentation
27
    packages which do not themselves necessarily have a good editor for molecular connection graphs.
28
*/
29
 
7246 schaersvoo 30
 
3662 schaersvoo 31
public class MainPanel extends JPanel implements ActionListener, MouseListener, WindowListener, KeyListener, ClipboardOwner,
32
                                                  TemplSelectListener, MolSelectListener
33
{
7246 schaersvoo 34
    public static final String LICENSE= // (encoded in a string so that it appears in the final .jar file)
3662 schaersvoo 35
        "This program is free software; you can redistribute it and/or modify\n"+
36
        "it under the terms of the GNU General Public License as published by\n"+
37
        "the Free Software Foundation; either version 2 of the License, or\n"+
38
        "(at your option) any later version.\n\n"+
39
        "This program is distributed in the hope that it will be useful,\n"+
40
        "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"+
41
        "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"+
42
        "GNU General Public License for more details.\n\n"+
43
        "You should have received a copy of the GNU General Public License\n"+
44
        "along with this program; if not, write to the Free Software\n"+
45
        "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n\n"+
46
        "or see http://www.gnu.org for details.";
47
 
7246 schaersvoo 48
    public static final String VERSION="SketchEl 1.21 WIMSversion 0.2 SVG export";
49
    private JFrame frameParent;
50
    public ImageIcon mainIcon=null,mainLogo=null;
51
    private static final int TOOL_CURSOR=0;
52
    private static final int TOOL_ROTATOR=1;
53
    private static final int TOOL_ERASOR=2;
54
    private static final int TOOL_DIALOG=3;
55
    private static final int TOOL_EDIT=4;
56
    private static final int TOOL_SETATOM=5;
57
    private static final int TOOL_SINGLE=6;
58
    private static final int TOOL_DOUBLE=7;
59
    private static final int TOOL_TRIPLE=8;
60
    private static final int TOOL_ZERO=9;
61
    private static final int TOOL_INCLINED=10;
62
    private static final int TOOL_DECLINED=11;
63
    private static final int TOOL_UNKNOWN=12;
64
    private static final int TOOL_CHARGE=13;
65
    private static final int TOOL_UNDO=14;
66
    private static final int TOOL_REDO=15;
67
    private static final int TOOL_TEMPLATE=16;
68
    private static final int TOOL_CUT=17;
69
    private static final int TOOL_COPY=18;
70
    private static final int TOOL_PASTE=19;
71
    private static final int TOOL_SELECT=20;
72
    private static final int TOOL_UNSELECT=21;
73
    public static int        TOOL_COUNT=22;
74
    public String myAtoms[];
75
    public boolean ATOM_BUTTONS = false;
76
    private Properties translation;
77
    public int MENU_COUNT=8;
78
    private static final String[] IMAGE_TOOL={"Cursor","Rotator","Erasor","EDialog","AEdit",
79
    "ASelect","BSingle","BDouble","BTriple","BZero",
80
    "BInclined","BDeclined","BUnknown","ACharge","Undo",
81
    "Redo","Template","ECut","ECopy","EPaste","Select","UnSelect","BUnknown","BUnknown"};
82
    public static boolean[] TOOL_SELECTION={true,true,true,false,true,true,true,true,true,true,
83
                                        true,true,true,true,false,false,true,false,false,false,false,false};
84
    public static boolean[] MENU_SELECTION={true,true,true,true,true,true,true,true};
85
    private AbstractButton[] atomlistButtons;
86
    private ButtonGroup atomlistGroup;
87
    private AbstractButton[] toolButtons;
88
    private ButtonGroup toolGroup;
89
    private ImageIcon[] toolIcons;
90
    public EditorPane editor;
91
    private Templates templ;
92
    private JCheckBoxMenuItem chkShowHydr,chkShowSter;
93
    private DraggableMolecule dragMol=null;
94
    private boolean firstResize=true;
95
    private String filename=null;
96
    private String lastElement=null,typedElement="";
97
    private Molecule lastTemplate=null;
98
    private int templateIdx=-1;
3662 schaersvoo 99
    public static boolean appletMode=false;
7246 schaersvoo 100
    private boolean streamMode=false,slaveMode=false;
101
    private boolean useLocalClipboard=false;
102
    private String appletClipboard="";
103
    private SaveListener saver=null;
104
    public final static int MODE_NORMAL=0; // usual invocation, with a frame, and a current file
105
    public final static int MODE_STREAM=1; // molecule flow-through editing, from stdin to stdout
106
    public final static int MODE_APPLET=2; // embedded applet version, with no frame
107
    public final static int MODE_SLAVE=3; // non-file version, editing a transient datastructure
3662 schaersvoo 108
 
7246 schaersvoo 109
    public MainPanel(String LoadFN,int Mode,JFrame FrameParent)
110
    {
111
        streamMode=Mode==MODE_STREAM;
112
        appletMode=Mode==MODE_APPLET;
113
        slaveMode=Mode==MODE_SLAVE;
114
        frameParent=FrameParent;
3662 schaersvoo 115
        if(appletMode){
7246 schaersvoo 116
         translation = loadProperties((MainApplet.language).toString());
117
         TOOL_SELECTION = MainApplet.TOOL_SELECTION;
118
         TOOL_COUNT = TOOL_SELECTION.length;
119
         MENU_SELECTION = MainApplet.MENU_SELECTION;
120
         MENU_COUNT = MENU_SELECTION.length;
121
         myAtoms = MainApplet.myAtoms;
122
         ATOM_BUTTONS = MainApplet.ATOM_BUTTONS;
123
         mainIcon=new ImageIcon(getClass().getResource("/images/wims_icon.gif"));
124
         mainLogo=new ImageIcon(getClass().getResource("/images/wims_logo.gif"));
3662 schaersvoo 125
        }
126
        else
7246 schaersvoo 127
        {
128
            for(int i = 0 ;i < TOOL_COUNT ; i++){ TOOL_SELECTION[i] = true; }
3662 schaersvoo 129
            mainIcon=new ImageIcon(getClass().getResource("/images/MainIcon.png"));
130
            mainLogo=new ImageIcon(getClass().getResource("/images/MainLogo.png"));
7246 schaersvoo 131
            translation = loadProperties("en");
3662 schaersvoo 132
        }
7246 schaersvoo 133
        if(myAtoms == null ){ myAtoms = new String[] {"C","N","O","H","F","Cl","Br","I","S","P","Na","K","Mg","Ca","Fe","Si"}; }
134
        useLocalClipboard=appletMode; // applet mode always uses "local clipboard"; if the applet is signed, this will need to switch
135
                                      // to false if permission has been granted to use the system clipboard
136
 
137
 
138
 
139
 
3662 schaersvoo 140
        templ=new Templates(getClass());
7246 schaersvoo 141
 
142
        /* list of atoms in row , like ketcher */
143
        int num_atoms = myAtoms.length;
144
        JToolBar atomlist = new JToolBar(JToolBar.HORIZONTAL);
145
        atomlist.setFloatable(true);
146
        atomlistButtons = new AbstractButton[num_atoms];
147
        atomlistGroup = new ButtonGroup();
148
        Font f = new Font("Dialog", Font.PLAIN, 24);
149
        atomlist.setFont(f);
3662 schaersvoo 150
 
7246 schaersvoo 151
        /* show a button bar with atoms if the main tool was activated via params*/
152
        if( ATOM_BUTTONS && appletMode && TOOL_SELECTION[TOOL_SETATOM] ){
153
            for(int n=0 ; n < num_atoms ;n++ ){
154
                atomlistButtons[n]=new JButton(myAtoms[n]);
155
                atomlistGroup.add(atomlistButtons[n]);
156
                atomlist.add(atomlistButtons[n]);
157
                atomlistButtons[n].addActionListener(this);
158
                atomlistButtons[n].setToolTipText("element"+myAtoms[n]);    
159
                atomlistButtons[n].setBorderPainted(false);
160
            }
161
        }
162
 
163
 
3662 schaersvoo 164
        // toolbar
7246 schaersvoo 165
 
166
        JToolBar tools = new JToolBar(JToolBar.VERTICAL);
167
        tools.setFloatable(true);
3662 schaersvoo 168
        toolButtons=new AbstractButton[TOOL_COUNT];
169
        toolIcons=new ImageIcon[TOOL_COUNT];
170
        toolGroup=new ButtonGroup();
7246 schaersvoo 171
        for (int n=0;n<TOOL_COUNT;n++){
172
          if(TOOL_SELECTION[n]){
173
           toolIcons[n]=new ImageIcon(getClass().getResource("/images/"+IMAGE_TOOL[n]+".png"));
174
           toolButtons[n]=new ToolButton(toolIcons[n]);
175
           toolGroup.add(toolButtons[n]);
176
           tools.add(toolButtons[n]);
177
           toolButtons[n].addActionListener(this);
178
           toolButtons[n].setToolTipText(getToolTips(n));
179
         }
3662 schaersvoo 180
        }
7246 schaersvoo 181
        if( TOOL_SELECTION[TOOL_CURSOR] ){ toolGroup.setSelected(toolButtons[TOOL_CURSOR].getModel(),true);}
182
        if( TOOL_SELECTION[TOOL_SETATOM] ){ toolButtons[TOOL_SETATOM].addMouseListener(this);toolButtons[TOOL_SETATOM].addKeyListener(this);selectElement("C");}
183
        if( TOOL_SELECTION[TOOL_TEMPLATE] ){ toolButtons[TOOL_TEMPLATE].addMouseListener(this);}
184
 
3662 schaersvoo 185
        // menu
186
 
7246 schaersvoo 187
        JMenuBar menubar=appletMode ? menuBarApplet() : menuBarApplication();
3662 schaersvoo 188
 
189
        // molecule
190
 
191
        editor=new EditorPane();
7246 schaersvoo 192
        editor.setMolSelectListener(this);
193
        editor.enableDnD();
3662 schaersvoo 194
        JScrollPane scroll=new JScrollPane(editor);
195
 
196
        // overall layout
197
 
7246 schaersvoo 198
        if (!appletMode)
3662 schaersvoo 199
        {
200
            setLayout(new BorderLayout());
201
            add(scroll,BorderLayout.CENTER);
202
            add(menubar,BorderLayout.NORTH);
203
            add(tools,BorderLayout.WEST);
204
        }
205
        else
206
        {
207
            // (!! add a little icon somewhere which does the About box...)
208
 
209
            JPanel p=new JPanel();
210
            p.setLayout(new BorderLayout());
211
            p.add(menubar,BorderLayout.NORTH);
212
 
213
            setLayout(new BorderLayout());
214
            add(tools,BorderLayout.WEST);
7246 schaersvoo 215
            if( ATOM_BUTTONS ){ add(atomlist,BorderLayout.SOUTH); }
216
            add(scroll,BorderLayout.EAST);
3662 schaersvoo 217
            add(p,BorderLayout.CENTER);
7246 schaersvoo 218
            p.add(scroll,BorderLayout.CENTER);
3662 schaersvoo 219
        }
220
 
221
        editor.grabFocus();
222
 
7246 schaersvoo 223
        editor.setToolCursor();
3662 schaersvoo 224
 
225
        if (LoadFN!=null)
226
        {
227
            try
228
            {
229
                FileInputStream istr=new FileInputStream(LoadFN);
7246 schaersvoo 230
                Molecule frag=MoleculeStream.readUnknown(istr);
231
                editor.addArbitraryFragment(frag);
3662 schaersvoo 232
                istr.close();
233
            }
234
            catch (IOException e)
235
            {
236
                JOptionPane.showMessageDialog(null,e.toString(),"Open Failed",JOptionPane.ERROR_MESSAGE);
237
                return;
238
            }
239
 
7246 schaersvoo 240
            setFilename(LoadFN);
241
            editor.notifySaved();
3662 schaersvoo 242
        }
7246 schaersvoo 243
        if (streamMode) readStream();
3662 schaersvoo 244
 
245
        addKeyListener(this);
246
        editor.addKeyListener(this);
7246 schaersvoo 247
        if (frameParent!=null) frameParent.addWindowListener(this);
3662 schaersvoo 248
 
7246 schaersvoo 249
        if (!appletMode)
250
        {      
251
            dragMol=new DraggableMolecule(editor);
252
            menubar.add(dragMol);
253
        }
3662 schaersvoo 254
    }
255
 
7246 schaersvoo 256
    // if specified, this interface will hijack all user efforts to "Save" to the source file
257
    public void setSaveListener(SaveListener saver) {this.saver=saver;}
258
 
3662 schaersvoo 259
    // builds and returns a menu bar suitable for the application-style invocation
7246 schaersvoo 260
    private JMenuBar menuBarApplication()
3662 schaersvoo 261
    {
262
        JMenuBar menubar=new JMenuBar();
7246 schaersvoo 263
 
3662 schaersvoo 264
        JMenu menufile=new JMenu(translation.getProperty("File"));
265
        menufile.setMnemonic(KeyEvent.VK_F);
7246 schaersvoo 266
        menufile.add(menuItem(translation.getProperty("New"),KeyEvent.VK_N,null,KeyStroke.getKeyStroke('N',InputEvent.CTRL_MASK)));
267
        menufile.add(menuItem(translation.getProperty("New_Window"),KeyEvent.VK_W,null,KeyStroke.getKeyStroke('N',InputEvent.CTRL_MASK+InputEvent.SHIFT_MASK)));
3662 schaersvoo 268
        if (DataWindow.ALLOW) // (temporary)
7246 schaersvoo 269
            menufile.add(menuItem(translation.getProperty("New_DataSheet"),KeyEvent.VK_D,null));
270
        menufile.add(menuItem(translation.getProperty("Open"),KeyEvent.VK_O,null,KeyStroke.getKeyStroke('O',InputEvent.CTRL_MASK)));
271
        if (!streamMode) menufile.add(menuItem(translation.getProperty("Save"),KeyEvent.VK_S,null,KeyStroke.getKeyStroke('S',InputEvent.CTRL_MASK)));
272
        menufile.add(menuItem(translation.getProperty("Save_As"),KeyEvent.VK_A));
3662 schaersvoo 273
        JMenu menuexport=new JMenu(translation.getProperty("Export"));
274
        menuexport.setMnemonic(KeyEvent.VK_X);
7246 schaersvoo 275
        menuexport.add(menuItem(translation.getProperty("as_MDL_MOL"),KeyEvent.VK_M,null,KeyStroke.getKeyStroke('M',InputEvent.CTRL_MASK+InputEvent.SHIFT_MASK)));
276
        menuexport.add(menuItem(translation.getProperty("as_CML_XML"),KeyEvent.VK_X,null,KeyStroke.getKeyStroke('X',InputEvent.CTRL_MASK+InputEvent.SHIFT_MASK)));
277
        menuexport.add(menuItem(translation.getProperty("as_SVG"),KeyEvent.VK_S,null,KeyStroke.getKeyStroke('S',InputEvent.CTRL_MASK+InputEvent.SHIFT_MASK)));
3662 schaersvoo 278
        menufile.add(menuexport);
279
 
280
        menufile.addSeparator();
7246 schaersvoo 281
        if (streamMode) menufile.add(menuItem(translation.getProperty("Save_and_Quit"),KeyEvent.VK_Q,null,KeyStroke.getKeyStroke('Q',InputEvent.CTRL_MASK)));
282
        else if (slaveMode) menufile.add(menuItem(translation.getProperty("Close"),KeyEvent.VK_C,null,KeyStroke.getKeyStroke('W',InputEvent.CTRL_MASK)));
283
        else menufile.add(menuItem(translation.getProperty("Quit"),KeyEvent.VK_Q,null,KeyStroke.getKeyStroke('Q',InputEvent.CTRL_MASK)));
3662 schaersvoo 284
 
285
        JMenu menuedit=new JMenu(translation.getProperty("Edit"));
286
        menuedit.setMnemonic(KeyEvent.VK_E);
7246 schaersvoo 287
        menuedit.add(menuItem(translation.getProperty("Editttt"),KeyEvent.VK_E,toolIcons[TOOL_DIALOG],KeyStroke.getKeyStroke(' ',InputEvent.CTRL_MASK)));
288
        menuedit.add(menuItem(translation.getProperty("Undo"),KeyEvent.VK_U,toolIcons[TOOL_UNDO],KeyStroke.getKeyStroke('Z',InputEvent.CTRL_MASK)));
289
        menuedit.add(menuItem(translation.getProperty("Redo"),KeyEvent.VK_R,toolIcons[TOOL_REDO],
290
                                                        KeyStroke.getKeyStroke('Z',InputEvent.CTRL_MASK+InputEvent.SHIFT_MASK)));
291
 
292
 
293
        menuedit.add(menuItem(translation.getProperty("Cut"),KeyEvent.VK_X,toolIcons[TOOL_CUT],KeyStroke.getKeyStroke('X',InputEvent.CTRL_MASK)));
294
        menuedit.add(menuItem(translation.getProperty("Copy"),KeyEvent.VK_C,toolIcons[TOOL_COPY],KeyStroke.getKeyStroke('C',InputEvent.CTRL_MASK)));
295
        menuedit.add(menuItem(translation.getProperty("Copy_SVG"),KeyEvent.VK_V,null,KeyStroke.getKeyStroke('C',InputEvent.CTRL_MASK+InputEvent.SHIFT_MASK)));
296
        menuedit.add(menuItem(translation.getProperty("Paste"),KeyEvent.VK_V,toolIcons[TOOL_PASTE],KeyStroke.getKeyStroke('V',InputEvent.CTRL_MASK)));
3662 schaersvoo 297
        menuedit.addSeparator();
7246 schaersvoo 298
        menuedit.add(menuItem(translation.getProperty("Select_All"),KeyEvent.VK_S,null,KeyStroke.getKeyStroke('A',InputEvent.CTRL_MASK)));
299
        menuedit.add(menuItem(translation.getProperty("Next_Atom"),KeyEvent.VK_N,null,KeyStroke.getKeyStroke('E',InputEvent.CTRL_MASK)));
300
        menuedit.add(menuItem(translation.getProperty("Previous_Atom"),KeyEvent.VK_P,null,KeyStroke.getKeyStroke('E',InputEvent.CTRL_MASK+InputEvent.SHIFT_MASK)));
301
        menuedit.add(menuItem(translation.getProperty("Next_Group"),KeyEvent.VK_G,null,KeyStroke.getKeyStroke('G',InputEvent.CTRL_MASK)));
302
        menuedit.add(menuItem(translation.getProperty("Previous_Group"),KeyEvent.VK_R,null,KeyStroke.getKeyStroke('G',InputEvent.CTRL_MASK+InputEvent.SHIFT_MASK)));
3662 schaersvoo 303
        menuedit.addSeparator();
7246 schaersvoo 304
        menuedit.add(menuItem(translation.getProperty("Flip_Horizontal"),KeyEvent.VK_H,null,null));
305
        menuedit.add(menuItem(translation.getProperty("Flip_Vertical"),KeyEvent.VK_V,null,null));
306
        menuedit.add(menuItem(translation.getProperty("Rotate_P45"),KeyEvent.VK_4,null,null));
307
        menuedit.add(menuItem(translation.getProperty("Rotate_M45"),KeyEvent.VK_5,null,null));
308
        menuedit.add(menuItem(translation.getProperty("Rotate_P90"),KeyEvent.VK_9,null,null));
309
        menuedit.add(menuItem(translation.getProperty("Rotate_M90"),KeyEvent.VK_0,null,null));
3662 schaersvoo 310
        menuedit.addSeparator();
7246 schaersvoo 311
        menuedit.add(menuItem(translation.getProperty("Add_Temporary_Template"),KeyEvent.VK_T,null,null));
312
        menuedit.add(menuItem(translation.getProperty("Normalise_Bond_Lengths"),KeyEvent.VK_N,null,null));
3662 schaersvoo 313
 
314
        JMenu menuview=new JMenu(translation.getProperty("View"));
315
        menuview.setMnemonic(KeyEvent.VK_V);
7246 schaersvoo 316
        menuview.add(menuItem(translation.getProperty("Zoom_Full"),KeyEvent.VK_F,null,KeyStroke.getKeyStroke('0',InputEvent.CTRL_MASK)));
317
        menuview.add(menuItem(translation.getProperty("Zoom_In"),KeyEvent.VK_I,null,KeyStroke.getKeyStroke('=',InputEvent.CTRL_MASK)));
318
        menuview.add(menuItem(translation.getProperty("Zoom_Out"),KeyEvent.VK_O,null,KeyStroke.getKeyStroke('-',InputEvent.CTRL_MASK)));
3662 schaersvoo 319
        menuview.addSeparator();
320
        ButtonGroup showBG=new ButtonGroup();
7246 schaersvoo 321
        menuview.add(radioMenuItem(translation.getProperty("Show_Elements"),KeyEvent.VK_E,true,showBG));
322
        menuview.add(radioMenuItem(translation.getProperty("Show_All_Elements"),KeyEvent.VK_A,false,showBG));
323
        menuview.add(radioMenuItem(translation.getProperty("Show_Indices"),KeyEvent.VK_I,false,showBG));
324
        menuview.add(radioMenuItem(translation.getProperty("Show_Ring_ID"),KeyEvent.VK_R,false,showBG));
325
        menuview.add(radioMenuItem(translation.getProperty("Show_CIP_Priority"),KeyEvent.VK_C,false,showBG));
326
        menuview.add(radioMenuItem(translation.getProperty("Show_Mapping_Number"),KeyEvent.VK_M,false,showBG));
3662 schaersvoo 327
 
328
        JMenu menutool=new JMenu(translation.getProperty("Tool"));
329
        menutool.setMnemonic(KeyEvent.VK_T);
7246 schaersvoo 330
        menutool.add(menuItem(translation.getProperty("Cursor"),KeyEvent.VK_C,toolIcons[TOOL_CURSOR],KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0)));
331
        menutool.add(menuItem(translation.getProperty("Rotator"),KeyEvent.VK_R,toolIcons[TOOL_ROTATOR],KeyStroke.getKeyStroke('R',InputEvent.CTRL_MASK)));
332
        menutool.add(menuItem(translation.getProperty("Erasor"),KeyEvent.VK_E,toolIcons[TOOL_ERASOR],KeyStroke.getKeyStroke('D',InputEvent.CTRL_MASK)));
333
        menutool.add(menuItem(translation.getProperty("Edit_Atom"),KeyEvent.VK_A,toolIcons[TOOL_EDIT],KeyStroke.getKeyStroke(',',InputEvent.CTRL_MASK)));
334
        menutool.add(menuItem(translation.getProperty("Set_Atom"),KeyEvent.VK_S,new ImageIcon(getClass().getResource("/images/ASelMenu.png")),
335
                                                                                KeyStroke.getKeyStroke('.',InputEvent.CTRL_MASK)));
336
        menutool.add(menuItem(translation.getProperty("Single_Bond"),KeyEvent.VK_1,toolIcons[TOOL_SINGLE],KeyStroke.getKeyStroke('1',InputEvent.CTRL_MASK)));
337
        menutool.add(menuItem(translation.getProperty("Double_Bond"),KeyEvent.VK_2,toolIcons[TOOL_DOUBLE],KeyStroke.getKeyStroke('2',InputEvent.CTRL_MASK)));
338
        menutool.add(menuItem(translation.getProperty("Triple_Bond"),KeyEvent.VK_3,toolIcons[TOOL_TRIPLE],KeyStroke.getKeyStroke('3',InputEvent.CTRL_MASK)));
339
        menutool.add(menuItem(translation.getProperty("Zero_Bond"),KeyEvent.VK_0,toolIcons[TOOL_ZERO],KeyStroke.getKeyStroke('0',InputEvent.CTRL_MASK)));
340
        menutool.add(menuItem(translation.getProperty("Inclined_Bond"),KeyEvent.VK_I,toolIcons[TOOL_INCLINED]));
341
        menutool.add(menuItem(translation.getProperty("Declined_Bond"),KeyEvent.VK_D,toolIcons[TOOL_DECLINED]));
342
        menutool.add(menuItem(translation.getProperty("Unknown_Bond"),KeyEvent.VK_U,toolIcons[TOOL_UNKNOWN]));
343
        menutool.add(menuItem(translation.getProperty("Charge"),KeyEvent.VK_H,toolIcons[TOOL_CHARGE],KeyStroke.getKeyStroke('H',InputEvent.CTRL_MASK)));
344
        menutool.add(menuItem(translation.getProperty("Template_Tool"),KeyEvent.VK_T,toolIcons[TOOL_TEMPLATE],KeyStroke.getKeyStroke('T',InputEvent.CTRL_MASK)));
345
        menutool.add(menuItem(translation.getProperty("Select_Template"),KeyEvent.VK_T,toolIcons[TOOL_TEMPLATE],
346
                                                        KeyStroke.getKeyStroke('T',InputEvent.CTRL_MASK+InputEvent.SHIFT_MASK)));
3662 schaersvoo 347
        JMenu menuhydr=new JMenu(translation.getProperty("Hydrogen"));
348
        menuhydr.setMnemonic(KeyEvent.VK_Y);
349
        chkShowHydr=new JCheckBoxMenuItem(translation.getProperty("Show_Hydrogen"));
350
        chkShowHydr.setMnemonic(KeyEvent.VK_Y);
351
        chkShowHydr.setSelected(true);
352
        chkShowHydr.addActionListener(this);
353
        menuhydr.add(chkShowHydr);
7246 schaersvoo 354
        menuhydr.add(menuItem(translation.getProperty("Set_Explicit"),KeyEvent.VK_E));
355
        menuhydr.add(menuItem(translation.getProperty("Clear_Explicit"),KeyEvent.VK_X));
356
        menuhydr.add(menuItem(translation.getProperty("Zero_Explicit"),KeyEvent.VK_Z));
357
        menuhydr.add(menuItem(translation.getProperty("Create_Actual"),KeyEvent.VK_C));
358
        menuhydr.add(menuItem(translation.getProperty("Delete_Actual"),KeyEvent.VK_D));
3662 schaersvoo 359
 
360
        JMenu menuster=new JMenu(translation.getProperty("Stereochemistry"));
361
        menuster.setMnemonic(KeyEvent.VK_S);
362
        chkShowSter=new JCheckBoxMenuItem(translation.getProperty("Show_Stereolabels"));
363
        chkShowSter.setMnemonic(KeyEvent.VK_L);
364
        chkShowSter.setSelected(false);
365
        chkShowSter.addActionListener(this);
366
        menuster.add(chkShowSter);
7246 schaersvoo 367
        menuster.add(menuItem(translation.getProperty("Invert_Stereochemistry"),KeyEvent.VK_I));
368
        menuster.add(menuItem(translation.getProperty("Set_R/Z"),KeyEvent.VK_R));
369
        menuster.add(menuItem(translation.getProperty("Set_S/E"),KeyEvent.VK_S));
370
        menuster.add(menuItem(translation.getProperty("Cycle_Wedges"),KeyEvent.VK_C));
371
        menuster.add(menuItem(translation.getProperty("Remove_Wedges"),KeyEvent.VK_W));
3662 schaersvoo 372
 
373
        JMenu menuhelp=new JMenu(translation.getProperty("Help"));
374
        menuhelp.setMnemonic(KeyEvent.VK_H);
7246 schaersvoo 375
        menuhelp.add(menuItem(translation.getProperty("About"),KeyEvent.VK_A));
3662 schaersvoo 376
 
377
        menubar.add(menufile);
378
        menubar.add(menuedit);
379
        menubar.add(menuview);
380
        menubar.add(menutool);
381
        menubar.add(menuhydr);
382
        menubar.add(menuster);
383
        menubar.add(Box.createHorizontalGlue());
384
        menubar.add(menuhelp);
7246 schaersvoo 385
 
3662 schaersvoo 386
        return menubar;
387
    }    
7246 schaersvoo 388
 
3662 schaersvoo 389
    // builds and returns a menu bar suitable for the applet-style invocation
7246 schaersvoo 390
    private JMenuBar menuBarApplet()
391
    {
3662 schaersvoo 392
        JMenuBar menubar=new JMenuBar();
7246 schaersvoo 393
        AppletMenu menublock=new AppletMenu(translation.getProperty("Block"));
394
        AppletMenu menuselect=new AppletMenu(translation.getProperty("Select"));
395
        AppletMenu menutransform=new AppletMenu(translation.getProperty("Transform"));
396
        AppletMenu menuzoom=new AppletMenu(translation.getProperty("Zoom"));
397
        AppletMenu menushow=new AppletMenu(translation.getProperty("Show"));
398
        AppletMenu menuhydrogen=new AppletMenu(translation.getProperty("Hydrogen"));
399
        AppletMenu menuhelp=new AppletMenu(translation.getProperty("Help"));
400
        if( MENU_SELECTION[0]){
401
         menublock.setMnemonic(KeyEvent.VK_B);
402
         menublock.add(menuItem(translation.getProperty("New"),KeyEvent.VK_N,null,KeyStroke.getKeyStroke('N',InputEvent.CTRL_MASK)));
403
         menublock.add(menuItem(translation.getProperty("Editttt"),KeyEvent.VK_E,null,KeyStroke.getKeyStroke(' ',InputEvent.CTRL_MASK)));
404
         menublock.add(menuItem(translation.getProperty("Undo"),KeyEvent.VK_U,null,KeyStroke.getKeyStroke('Z',InputEvent.CTRL_MASK)));
405
         menublock.add(menuItem(translation.getProperty("Redo"),KeyEvent.VK_R,null,KeyStroke.getKeyStroke('Z',InputEvent.CTRL_MASK+InputEvent.SHIFT_MASK)));
406
         menublock.add(menuItem(translation.getProperty("Cut"),KeyEvent.VK_X,null,KeyStroke.getKeyStroke('X',InputEvent.CTRL_MASK)));
407
         menublock.add(menuItem(translation.getProperty("Copy"),KeyEvent.VK_C,null,KeyStroke.getKeyStroke('C',InputEvent.CTRL_MASK)));
408
         menublock.add(menuItem(translation.getProperty("Paste"),KeyEvent.VK_V,null,KeyStroke.getKeyStroke('V',InputEvent.CTRL_MASK)));
409
        menubar.add(menublock);
3662 schaersvoo 410
        }
7246 schaersvoo 411
        if( MENU_SELECTION[1]){
412
        menuselect.setMnemonic(KeyEvent.VK_S);
413
        menuselect.add(menuItem(translation.getProperty("Select_All"),KeyEvent.VK_S,null,KeyStroke.getKeyStroke('A',InputEvent.CTRL_MASK)));
414
        menuselect.add(menuItem(translation.getProperty("Next_Atom"),KeyEvent.VK_N,null,KeyStroke.getKeyStroke('E',InputEvent.CTRL_MASK)));
415
        menuselect.add(menuItem(translation.getProperty("Previous_Atom"),KeyEvent.VK_P,null,KeyStroke.getKeyStroke('E',InputEvent.CTRL_MASK+InputEvent.SHIFT_MASK)));
416
        menuselect.add(menuItem(translation.getProperty("Next_Group"),KeyEvent.VK_G,null,KeyStroke.getKeyStroke('G',InputEvent.CTRL_MASK)));
417
        menuselect.add(menuItem(translation.getProperty("Previous_Group"),KeyEvent.VK_R,null,KeyStroke.getKeyStroke('G',InputEvent.CTRL_MASK+InputEvent.SHIFT_MASK)));
418
        menubar.add(menuselect);       
3662 schaersvoo 419
        }
7246 schaersvoo 420
 
421
        if( MENU_SELECTION[2]){
422
        menutransform.setMnemonic(KeyEvent.VK_T);
423
        menutransform.add(menuItem(translation.getProperty("Flip_Horizontal"),KeyEvent.VK_H,null,null));
424
        menutransform.add(menuItem(translation.getProperty("Flip_Vertical"),KeyEvent.VK_V,null,null));
425
        menutransform.add(menuItem(translation.getProperty("Rotate_P45"),KeyEvent.VK_4,null,null));
426
        menutransform.add(menuItem(translation.getProperty("Rotate_M45"),KeyEvent.VK_5,null,null));
427
        menutransform.add(menuItem(translation.getProperty("Rotate_P90"),KeyEvent.VK_9,null,null));
428
        menutransform.add(menuItem(translation.getProperty("Rotate_M90"),KeyEvent.VK_0,null,null));
429
        menutransform.addSeparator();
430
        menutransform.add(menuItem(translation.getProperty("Add_Temporary_Template"),KeyEvent.VK_T,null,null));
431
        menutransform.add(menuItem(translation.getProperty("Normalise_Bond_Lengths"),KeyEvent.VK_N,null,null));
3662 schaersvoo 432
        menubar.add(menutransform);
433
        }
434
 
7246 schaersvoo 435
        if( MENU_SELECTION[3]){
436
        menuzoom.setMnemonic(KeyEvent.VK_Z);
437
        menuzoom.add(menuItem(translation.getProperty("Zoom_Full"),KeyEvent.VK_F,null,KeyStroke.getKeyStroke('0',InputEvent.CTRL_MASK)));
438
        menuzoom.add(menuItem(translation.getProperty("Zoom_In"),KeyEvent.VK_I,null,KeyStroke.getKeyStroke('=',InputEvent.CTRL_MASK)));
439
        menuzoom.add(menuItem(translation.getProperty("Zoom_Out"),KeyEvent.VK_O,null,KeyStroke.getKeyStroke('-',InputEvent.CTRL_MASK)));
440
        menubar.add(menuzoom);
3662 schaersvoo 441
        }
442
 
7246 schaersvoo 443
        if( MENU_SELECTION[4]){
444
        menushow.setMnemonic(KeyEvent.VK_O);
445
        ButtonGroup showBG=new ButtonGroup();
446
        menushow.add(radioMenuItem(translation.getProperty("Show_Elements"),KeyEvent.VK_E,true,showBG));
447
        menushow.add(radioMenuItem(translation.getProperty("Show_All_Elements"),KeyEvent.VK_A,false,showBG));
448
        menushow.add(radioMenuItem(translation.getProperty("Show_Indices"),KeyEvent.VK_I,false,showBG));
449
        menushow.add(radioMenuItem(translation.getProperty("Show_Ring_ID"),KeyEvent.VK_R,false,showBG));
450
        menushow.add(radioMenuItem(translation.getProperty("Show_CIP_Priority"),KeyEvent.VK_C,false,showBG));
451
        menushow.add(radioMenuItem(translation.getProperty("Show_Mapping_Number"),KeyEvent.VK_M,false,showBG));
452
        menubar.add(menushow);
3662 schaersvoo 453
        }
454
 
7246 schaersvoo 455
        if( MENU_SELECTION[5]){
456
        menuhydrogen.setMnemonic(KeyEvent.VK_H);
457
        chkShowHydr=new JCheckBoxMenuItem(translation.getProperty("Show_Hydrogen"));
458
        chkShowHydr.setMnemonic(KeyEvent.VK_Y);
459
        chkShowHydr.setSelected(true);
460
        chkShowHydr.addActionListener(this);
461
        menuhydrogen.add(chkShowHydr);
462
        menuhydrogen.add(menuItem(translation.getProperty("Set_Explicit"),KeyEvent.VK_E));
463
        menuhydrogen.add(menuItem(translation.getProperty("Clear_Explicit"),KeyEvent.VK_X));
464
        menuhydrogen.add(menuItem(translation.getProperty("Zero_Explicit"),KeyEvent.VK_Z));
465
        menuhydrogen.add(menuItem(translation.getProperty("Create_Actual"),KeyEvent.VK_C));
466
        menuhydrogen.add(menuItem(translation.getProperty("Delete_Actual"),KeyEvent.VK_D));
467
        menubar.add(menuhydrogen);
3662 schaersvoo 468
        }
7246 schaersvoo 469
 
470
        if( MENU_SELECTION[6]){
471
        AppletMenu menustereo=new AppletMenu(translation.getProperty("Stereo"));
472
        menustereo.setMnemonic(KeyEvent.VK_E);
473
        chkShowSter=new JCheckBoxMenuItem(translation.getProperty("Show_Stereolabels"));
474
        chkShowSter.setMnemonic(KeyEvent.VK_L);
475
        chkShowSter.setSelected(false);
476
        chkShowSter.addActionListener(this);
477
        menustereo.add(chkShowSter);
478
        menustereo.add(menuItem(translation.getProperty("Invert_Stereochemistry"),KeyEvent.VK_I));
479
        menustereo.add(menuItem(translation.getProperty("Set R/Z"),KeyEvent.VK_R));
480
        menustereo.add(menuItem(translation.getProperty("Set_S/E"),KeyEvent.VK_S));
481
        menustereo.add(menuItem(translation.getProperty("Cycle_Wedges"),KeyEvent.VK_C));
482
        menustereo.add(menuItem(translation.getProperty("Remove_Wedges"),KeyEvent.VK_W));
483
        menubar.add(menustereo);
3662 schaersvoo 484
        }
485
 
7246 schaersvoo 486
        if( MENU_SELECTION[7]){
487
        menuhelp.setMnemonic(KeyEvent.VK_P);
488
        menuhelp.add(menuItem(translation.getProperty("About"),KeyEvent.VK_A));
489
        menubar.add(menuhelp); 
3662 schaersvoo 490
        }
491
 
492
        return menubar;
493
    }
494
 
7246 schaersvoo 495
    public Molecule molData() {return editor.molData();} // shallow copy, use with care
496
    public void setMolecule(Molecule Mol)
497
    {
498
        editor.replace(Mol);
499
        editor.RotateMolecule();
500
        editor.scaleToFit();
501
        editor.notifySaved();
3662 schaersvoo 502
    }
7246 schaersvoo 503
    public void addMolecule(Molecule Mol)
504
    {
505
        editor.addArbitraryFragment(Mol);
506
        editor.scaleToFit();
507
        editor.notifySaved();
3662 schaersvoo 508
    }
7246 schaersvoo 509
    public void scaleToFit() {editor.scaleToFit();}
3662 schaersvoo 510
 
7246 schaersvoo 511
    JMenuItem menuItem(String txt,int key) {return menuItem(txt,key,null,null);}
512
    JMenuItem menuItem(String txt,int key,Icon icon) {return menuItem(txt,key,icon,null);}
513
    JMenuItem menuItem(String txt,int key,Icon icon,KeyStroke accel)
3662 schaersvoo 514
    {
515
        JMenuItem mi=new JMenuItem(txt,key);
516
        mi.addActionListener(this);
517
        if (icon!=null) mi.setIcon(icon);
518
        if (accel!=null) mi.setAccelerator(accel);
519
        return mi;
520
    }
7246 schaersvoo 521
    JRadioButtonMenuItem radioMenuItem(String txt,int key,boolean sel,ButtonGroup bg)
3662 schaersvoo 522
    {
523
        JRadioButtonMenuItem mi=new JRadioButtonMenuItem(txt,sel);
524
        mi.addActionListener(this);
525
        mi.setMnemonic(key);
526
        bg.add(mi);
527
        return mi;
528
    }
529
 
7246 schaersvoo 530
    void fileQuit()
3662 schaersvoo 531
    {
532
        if (!streamMode)
533
        {
7246 schaersvoo 534
            if (editor.isDirty())
3662 schaersvoo 535
            {
7246 schaersvoo 536
                if (JOptionPane.showConfirmDialog(null,
537
                    "Current structure has been modified. Exit without saving?","Quit",
538
                    JOptionPane.YES_NO_OPTION)!=JOptionPane.YES_OPTION) return;
3662 schaersvoo 539
            }
540
        }
541
        else
542
        {
7246 schaersvoo 543
            writeStream();
3662 schaersvoo 544
        }
545
 
546
        if (frameParent!=null) frameParent.dispose();
547
 
548
        return;
549
    }
7246 schaersvoo 550
    void fileNew()
3662 schaersvoo 551
    {
7246 schaersvoo 552
        if (editor.molData().numAtoms()>0)
3662 schaersvoo 553
        {
7246 schaersvoo 554
            if (JOptionPane.showConfirmDialog(null,
555
                "Clear current structure and start anew?","New",
556
                JOptionPane.YES_NO_OPTION)!=JOptionPane.YES_OPTION) return;
3662 schaersvoo 557
        }
7246 schaersvoo 558
        editor.clear();
3662 schaersvoo 559
        filename=null;
7246 schaersvoo 560
        if (frameParent!=null && saver==null) frameParent.setTitle("WIMSchem");
561
        editor.notifySaved();
3662 schaersvoo 562
    }
7246 schaersvoo 563
    void fileNewWindow()
3662 schaersvoo 564
    {
7246 schaersvoo 565
        MainWindow mw=new MainWindow(null,false);
3662 schaersvoo 566
        mw.setVisible(true);
567
    }
7246 schaersvoo 568
    void fileNewDataSheet()
3662 schaersvoo 569
    {
570
        DataWindow dw=new DataWindow(null);
571
        dw.setVisible(true);
572
    }
7246 schaersvoo 573
    void fileOpen()
3662 schaersvoo 574
    {
575
        JFileChooser chooser=new JFileChooser(System.getenv().get("PWD"));
576
        chooser.setDragEnabled(false);
577
        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
7246 schaersvoo 578
        chooser.setFileFilter(new FileExtFilter("Molecular Structures",".el;.mol;.sdf;.xml"));
3662 schaersvoo 579
        chooser.setAccessory(new FileMolPreview(chooser));
580
        if (chooser.showOpenDialog(frameParent)!=JFileChooser.APPROVE_OPTION) return;
581
 
7246 schaersvoo 582
        boolean fresh=editor.isEmpty();
3662 schaersvoo 583
        String newfn=chooser.getSelectedFile().getPath();
7246 schaersvoo 584
        boolean anything=editor.molData().numAtoms()>0;
3662 schaersvoo 585
        try
586
        {
587
            FileInputStream istr=new FileInputStream(newfn);
7246 schaersvoo 588
            if (!DataWindow.ALLOW && MoleculeStream.examineIsDatabase(istr))
3662 schaersvoo 589
            {   // !! this section is to be deprecated when DataSheet is fully functional
590
                istr.close();
591
                CatalogWindow cw=new CatalogWindow(newfn);
592
                cw.setVisible(true);
593
            }
7246 schaersvoo 594
            else if (DataSheetStream.examineIsXMLDS(istr) || DataSheetStream.examineIsMDLSDF(istr))
3662 schaersvoo 595
            {
596
                istr.close();
597
                DataWindow dw=new DataWindow(newfn);
598
                dw.setVisible(true);
599
            }
600
            else
601
            {
7246 schaersvoo 602
                Molecule frag=MoleculeStream.readUnknown(istr);
603
                editor.addArbitraryFragment(frag);
3662 schaersvoo 604
                istr.close();
7246 schaersvoo 605
                if (fresh) setFilename(newfn);
606
                if (!anything) editor.notifySaved();
3662 schaersvoo 607
            }
608
        }
609
        catch (IOException e)
610
        {
7246 schaersvoo 611
            JOptionPane.showMessageDialog(null,e.toString(),"Open Failed",JOptionPane.ERROR_MESSAGE);
3662 schaersvoo 612
            //e.printStackTrace();
613
            return;
614
        }
615
    }
616
 
7246 schaersvoo 617
    void fileSave()
3662 schaersvoo 618
    {
7246 schaersvoo 619
        if (filename==null && saver==null) {fileSaveAs(); return;}
620
        saveCurrent();
3662 schaersvoo 621
    }
622
 
7246 schaersvoo 623
    void fileSaveAs()
3662 schaersvoo 624
    {
625
        JFileChooser chooser=new JFileChooser(System.getenv().get("PWD"));
626
        chooser.setDragEnabled(false);
627
        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
7246 schaersvoo 628
        chooser.setFileFilter(new FileExtFilter("WIMSchem Files",".el"));
3662 schaersvoo 629
        chooser.setAccessory(new FileMolPreview(chooser));
630
        if (chooser.showSaveDialog(frameParent)!=JFileChooser.APPROVE_OPTION) return;
631
 
632
        String fn=chooser.getSelectedFile().getPath();
633
        if (chooser.getSelectedFile().getName().indexOf('.')<0) fn=fn+".el";
634
 
635
        File newf=new File(fn);
636
        if (newf.exists())
637
        {
7246 schaersvoo 638
            if (JOptionPane.showConfirmDialog(null,
639
                "Overwrite existing file ["+newf.getName()+"]?","Save As",
640
                JOptionPane.YES_NO_OPTION)!=JOptionPane.YES_OPTION) return;
3662 schaersvoo 641
        }      
642
 
7246 schaersvoo 643
        setFilename(fn);
644
        saveCurrent(true);
3662 schaersvoo 645
    }
646
 
7246 schaersvoo 647
    void fileExportMDLMOL()
648
    {
3662 schaersvoo 649
        JFileChooser chooser=new JFileChooser(System.getenv().get("PWD"));
650
        chooser.setDragEnabled(false);
651
        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
7246 schaersvoo 652
        chooser.setFileFilter(new FileExtFilter("MDL MOL Files",".mol"));
653
        chooser.setAccessory(new FileMolPreview(chooser));
3662 schaersvoo 654
        if (chooser.showSaveDialog(frameParent)!=JFileChooser.APPROVE_OPTION) return;
655
 
656
        String fn=chooser.getSelectedFile().getPath();
7246 schaersvoo 657
        if (chooser.getSelectedFile().getName().indexOf('.')<0) fn=fn+".mol";
3662 schaersvoo 658
 
659
        File newf=new File(fn);
660
        if (newf.exists())
661
        {
7246 schaersvoo 662
            if (JOptionPane.showConfirmDialog(null,
663
                "Overwrite existing file ["+newf.getName()+"]?","Export MDL MOL",
664
                JOptionPane.YES_NO_OPTION)!=JOptionPane.YES_OPTION) return;
3662 schaersvoo 665
        }      
666
 
667
        try
668
        {
669
            FileOutputStream ostr=new FileOutputStream(fn);
7246 schaersvoo 670
            MoleculeStream.writeMDLMOL(ostr,editor.molData());
3662 schaersvoo 671
            ostr.close();
672
        }
673
        catch (IOException e)
674
        {
7246 schaersvoo 675
            JOptionPane.showMessageDialog(null,e.toString(),"Export Failed",JOptionPane.ERROR_MESSAGE);
3662 schaersvoo 676
        }
677
    }
678
 
7246 schaersvoo 679
    void fileExportSVG()
680
    {
3662 schaersvoo 681
        JFileChooser chooser=new JFileChooser(System.getenv().get("PWD"));
682
        chooser.setDragEnabled(false);
683
        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
7246 schaersvoo 684
        chooser.setFileFilter(new FileExtFilter("SVG Files",".svg"));
685
        chooser.setAccessory(new FileMolPreview(chooser));
3662 schaersvoo 686
        if (chooser.showSaveDialog(frameParent)!=JFileChooser.APPROVE_OPTION) return;
687
 
688
        String fn=chooser.getSelectedFile().getPath();
7246 schaersvoo 689
        if (chooser.getSelectedFile().getName().indexOf('.')<0) fn=fn+".svg";
3662 schaersvoo 690
 
691
        File newf=new File(fn);
692
        if (newf.exists())
693
        {
7246 schaersvoo 694
            if (JOptionPane.showConfirmDialog(null,
695
                "Overwrite existing file ["+newf.getName()+"]?","Export SVG",
696
                JOptionPane.YES_NO_OPTION)!=JOptionPane.YES_OPTION) return;
3662 schaersvoo 697
        }      
698
 
699
        try
700
        {
701
            FileOutputStream ostr=new FileOutputStream(fn);
7246 schaersvoo 702
            SVGMolecule svgmol=new SVGMolecule(editor.molData());
703
            svgmol.draw();
704
            svgmol.build(new PrintWriter(ostr));
3662 schaersvoo 705
            ostr.close();
706
        }
707
        catch (IOException e)
708
        {
7246 schaersvoo 709
            JOptionPane.showMessageDialog(null,e.toString(),"Export Failed",JOptionPane.ERROR_MESSAGE);
3662 schaersvoo 710
        }
711
    }
712
 
7246 schaersvoo 713
    void fileExportCMLXML()
714
    {
3662 schaersvoo 715
        JFileChooser chooser=new JFileChooser(System.getenv().get("PWD"));
716
        chooser.setDragEnabled(false);
717
        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
7246 schaersvoo 718
        chooser.setFileFilter(new FileExtFilter("XML Files",".xml"));
3662 schaersvoo 719
        chooser.setAccessory(new FileMolPreview(chooser));
720
        if (chooser.showSaveDialog(frameParent)!=JFileChooser.APPROVE_OPTION) return;
721
 
722
        String fn=chooser.getSelectedFile().getPath();
723
        if (chooser.getSelectedFile().getName().indexOf('.')<0) fn=fn+".xml";
724
 
725
        File newf=new File(fn);
726
        if (newf.exists())
727
        {
7246 schaersvoo 728
            if (JOptionPane.showConfirmDialog(null,
729
                "Overwrite existing file ["+newf.getName()+"]?","Export CML XML",
730
                JOptionPane.YES_NO_OPTION)!=JOptionPane.YES_OPTION) return;
3662 schaersvoo 731
        }      
732
 
733
        try
734
        {
735
            FileOutputStream ostr=new FileOutputStream(fn);
7246 schaersvoo 736
            MoleculeStream.writeCMLXML(ostr,editor.molData());
3662 schaersvoo 737
            ostr.close();
738
        }
739
        catch (IOException e)
740
        {
7246 schaersvoo 741
            JOptionPane.showMessageDialog(null,e.toString(),"Export Failed",JOptionPane.ERROR_MESSAGE);
3662 schaersvoo 742
        }
743
    }
744
 
7246 schaersvoo 745
    void setFilename(String fn)
746
    {
3662 schaersvoo 747
        if (fn.length()==0) {filename=null; return;}
748
        filename=fn;
749
 
750
        if (!streamMode)
751
        {
752
           String chopfn=fn;
753
           int i=chopfn.lastIndexOf("/");
754
           if (i>=0) chopfn=chopfn.substring(i+1);
7246 schaersvoo 755
           if (frameParent!=null && saver==null) frameParent.setTitle(chopfn+" - WIMSchem");
3662 schaersvoo 756
        }
7246 schaersvoo 757
        else {if (frameParent!=null && saver==null) frameParent.setTitle("WIMSchem");}
3662 schaersvoo 758
    }
759
 
7246 schaersvoo 760
    void saveCurrent() {saveCurrent(false);}
761
    void saveCurrent(boolean force)
762
    {
763
        if (saver!=null && !force)
764
        {
765
            saver.saveMolecule(editor.molData().clone());
766
            editor.notifySaved();
767
            return;
768
        }
769
 
3662 schaersvoo 770
        try
771
        {
7246 schaersvoo 772
            boolean fmtNative=true;
773
 
774
            if (filename.toLowerCase().endsWith(".mol"))
775
            {
776
                String msg="The filename to save ends with '.mol', which is the\n"+
777
                           "conventional suffix for MDL MOL-files. Exporting to\n"+
778
                           "this format will cause some information loss. Do you wish\n"+
779
                           "to save in MDL MOL-file format?";
780
                if (JOptionPane.showConfirmDialog(null,msg,"Format",JOptionPane.YES_NO_OPTION)==JOptionPane.YES_OPTION)
781
                    fmtNative=false;
782
            }
783
 
3662 schaersvoo 784
            FileOutputStream ostr=new FileOutputStream(filename);
7246 schaersvoo 785
            if (fmtNative) MoleculeStream.writeNative(ostr,editor.molData());
786
            else MoleculeStream.writeMDLMOL(ostr,editor.molData());
3662 schaersvoo 787
            ostr.close();
7246 schaersvoo 788
            editor.notifySaved();
3662 schaersvoo 789
        }
790
        catch (IOException e)
791
        {
7246 schaersvoo 792
            JOptionPane.showMessageDialog(null,e.toString(),"Save Failed",JOptionPane.ERROR_MESSAGE);
3662 schaersvoo 793
        }
794
    }
795
 
7246 schaersvoo 796
    void readStream()
797
    {
3662 schaersvoo 798
        try
799
        {
7246 schaersvoo 800
            Molecule frag=MoleculeStream.readUnknown(System.in);
801
            editor.addArbitraryFragment(frag);
3662 schaersvoo 802
        }
803
        catch (IOException e)
804
        {
7246 schaersvoo 805
            JOptionPane.showMessageDialog(null,e.toString(),"<stdin> Read Failed",JOptionPane.ERROR_MESSAGE);
3662 schaersvoo 806
            return;
807
        }
808
    }
7246 schaersvoo 809
    void writeStream()
810
    {
811
        Molecule mol=editor.molData();
3662 schaersvoo 812
        try
813
        {
7246 schaersvoo 814
            MoleculeStream.writeMDLMOL(System.out,mol);
815
            MoleculeStream.writeNative(System.out,mol);
3662 schaersvoo 816
        }
817
        catch (IOException e)
818
        {
7246 schaersvoo 819
            JOptionPane.showMessageDialog(null,e.toString(),"<stdout> Write Failed",JOptionPane.ERROR_MESSAGE);
3662 schaersvoo 820
        }
821
    }
822
 
7246 schaersvoo 823
    void testMol()
824
    {
3662 schaersvoo 825
        Molecule mol=new Molecule();
826
 
7246 schaersvoo 827
        mol.addAtom("N",0,0);
828
        mol.addAtom("C",1.2,0);
829
        mol.addAtom("O",2,0.8);
830
        mol.addAtom("H",3,-0.8);
831
        mol.addAtom("H",4,0);
832
        mol.addBond(1,2,1);
833
        mol.addBond(2,3,2);
834
        mol.addBond(3,4,1);
835
        mol.addBond(4,5,0);
3662 schaersvoo 836
 
7246 schaersvoo 837
        editor.replace(mol);
3662 schaersvoo 838
    }
839
 
7246 schaersvoo 840
    void editCut()
841
    {
842
        Molecule frag=editor.selectedSubgraph();
3662 schaersvoo 843
        try
844
        {
845
            StringWriter sw=new StringWriter();
846
            BufferedWriter bw=new BufferedWriter(sw);
7246 schaersvoo 847
            MoleculeStream.writeMDLMOL(bw,frag);
848
            MoleculeStream.writeNative(bw,frag);
3662 schaersvoo 849
            if (useLocalClipboard)
850
            {
851
                appletClipboard=sw.toString();
852
            }
853
            else
854
            {
855
                Clipboard clip=Toolkit.getDefaultToolkit().getSystemClipboard();
856
                clip.setContents(new StringSelection(sw.toString()),this);
857
            }
7246 schaersvoo 858
            editor.deleteSelected(); // (keep this within the exception trap)
3662 schaersvoo 859
        }
860
        catch (IOException e)
861
        {
7246 schaersvoo 862
            JOptionPane.showMessageDialog(null,e.toString(),"Cut Failed",JOptionPane.ERROR_MESSAGE);
3662 schaersvoo 863
        }
864
    }
865
 
7246 schaersvoo 866
    void editCopy()
867
    {
868
        Molecule frag=editor.selectedSubgraph();
3662 schaersvoo 869
        try
870
        {
871
            StringWriter sw=new StringWriter();
872
            BufferedWriter bw=new BufferedWriter(sw);
7246 schaersvoo 873
            MoleculeStream.writeMDLMOL(bw,frag);
874
            MoleculeStream.writeNative(bw,frag);
3662 schaersvoo 875
            if (useLocalClipboard)
876
            {
877
                appletClipboard=sw.toString();
878
            }
879
            else
880
            {
881
                Clipboard clip=Toolkit.getDefaultToolkit().getSystemClipboard();
882
                clip.setContents(new StringSelection(sw.toString()),this);
883
            }
884
        }
885
        catch (IOException e)
886
        {
7246 schaersvoo 887
            JOptionPane.showMessageDialog(null,e.toString(),"Copy Failed",JOptionPane.ERROR_MESSAGE);
3662 schaersvoo 888
        }
889
    }
7246 schaersvoo 890
 
891
    void editCopySVG()
892
    {
893
        StringWriter sw=new StringWriter();
894
        SVGMolecule svgmol=new SVGMolecule(editor.molData());
895
        svgmol.draw();
896
        svgmol.build(new PrintWriter(sw));
897
        if (useLocalClipboard)
898
        {
899
            appletClipboard=sw.toString();
900
        }
901
        else
902
        {
903
            Clipboard clip=Toolkit.getDefaultToolkit().getSystemClipboard();
904
            clip.setContents(new StringSelection(sw.toString()),this);
905
        }
906
    }
3662 schaersvoo 907
 
7246 schaersvoo 908
    void editPaste()
909
    {
3662 schaersvoo 910
        try
911
        {
912
            String cliptext=null;
913
            if (useLocalClipboard) cliptext=appletClipboard;
914
            else
915
            {
916
                Clipboard clip=Toolkit.getDefaultToolkit().getSystemClipboard();
917
                Transferable contents=clip.getContents(null);
918
                if (contents!=null && contents.isDataFlavorSupported(DataFlavor.stringFlavor))
919
                {
920
                    cliptext=(String)contents.getTransferData(DataFlavor.stringFlavor);
921
                }
922
            }
923
 
924
            if (cliptext!=null)
925
            {
7246 schaersvoo 926
                Molecule frag=MoleculeStream.readUnknown(new BufferedReader(new StringReader(cliptext)));
927
                if (frag!=null) editor.addArbitraryFragment(frag);
3662 schaersvoo 928
            }
929
        }
930
        catch (UnsupportedFlavorException e)
931
        {
7246 schaersvoo 932
            JOptionPane.showMessageDialog(null,e.toString(),"Clipboard Read Failed",JOptionPane.ERROR_MESSAGE);
3662 schaersvoo 933
        }
934
        catch (IOException e)
935
        {
7246 schaersvoo 936
            JOptionPane.showMessageDialog(null,e.toString(),"Paste Failed",JOptionPane.ERROR_MESSAGE);
3662 schaersvoo 937
        }
938
    }
939
 
7246 schaersvoo 940
    void selectElement(String El)
941
    {
942
            if (lastElement!=null){
943
                if (lastElement.compareTo(El)==0) return;
944
                toolIcons[TOOL_SETATOM]=new ImageIcon(getClass().getResource("/images/"+IMAGE_TOOL[TOOL_SETATOM]+".png"));
945
            }
946
            int w=toolIcons[TOOL_SETATOM].getImage().getWidth(null),h=toolIcons[TOOL_SETATOM].getImage().getHeight(null);
947
            BufferedImage img=new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
948
            Graphics2D g=(Graphics2D)img.getGraphics();
949
            g.setColor(new Color(0x00000000,true));
950
            g.fillRect(0,0,w,h);
951
            g.drawImage(toolIcons[TOOL_SETATOM].getImage(),0,0,null);
952
            Font font=new Font("SansSerif",Font.PLAIN,El.length()==1 ? 20 : 14);
953
            g.setFont(font);
954
            g.setColor(new Color(0,192,0));
955
            FontMetrics metrics=g.getFontMetrics();
956
            g.drawString(El,(w-metrics.stringWidth(El))/2-3,(h+metrics.getAscent())/2-2);
957
            toolButtons[TOOL_SETATOM].setIcon(new ImageIcon(img));
958
            lastElement=El;
3662 schaersvoo 959
    }
960
 
7246 schaersvoo 961
    void templateTool()
962
    {
963
        if (lastTemplate==null) {templateSelect(); return;}
964
        editor.setToolTemplate(lastTemplate,templateIdx);
3662 schaersvoo 965
    }
966
 
7246 schaersvoo 967
    void templateSelect()
968
    {
3662 schaersvoo 969
        int heightFudge=appletMode ? 30 : 0; // !! unpleasant hack which stands in for being a non-signed applet; correct at some point
970
        TemplateSelector sel=new TemplateSelector(templ,this,heightFudge);
971
        Point pos=toolButtons[TOOL_TEMPLATE].getLocationOnScreen();
972
 
973
        Dimension ssz=Toolkit.getDefaultToolkit().getScreenSize();
974
        GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment();
975
        GraphicsConfiguration gc=ge.getScreenDevices()[0].getConfigurations()[0];
976
        ssz.width-=Toolkit.getDefaultToolkit().getScreenInsets(gc).right;
977
        ssz.height-=Toolkit.getDefaultToolkit().getScreenInsets(gc).bottom;
978
 
979
        if (pos.x+sel.getWidth()>ssz.width) pos.x=ssz.width-sel.getWidth();
980
        if (pos.y+sel.getHeight()>ssz.height) pos.y=ssz.height-sel.getHeight();
981
        sel.setLocation(pos);
982
        sel.setVisible(true);
983
    }
984
 
7246 schaersvoo 985
    void templateAddTo()
986
    {
987
        templ.addTemplate(editor.selectedSubgraph());
3662 schaersvoo 988
    }
989
 
7246 schaersvoo 990
    void editDialog()
991
    {
992
        Molecule newMol=(new DialogEdit(frameParent,editor.molData(),editor.selectedIndices())).exec();
3662 schaersvoo 993
        if (newMol!=null)
994
        {
7246 schaersvoo 995
            editor.cacheUndo();
996
            editor.replace(newMol,false);
3662 schaersvoo 997
        }
998
    }
999
 
7246 schaersvoo 1000
    void helpAbout()
3662 schaersvoo 1001
    {
7246 schaersvoo 1002
        String msg="WIMSchem v"+VERSION+"\n"+
1003
                   "Molecule drawing tool\n"+
1004
                   "© 2005-2008 Dr. Alex M. Clark\n"+
1005
                   "Released under the Gnu Public\n"+
1006
                   "License (GPL), see www.gnu.org\n"+
1007
                   "Home page and documentation:\n"+
1008
                   "http://sketchel.sf.net\n"+
1009
                   "Modified for WIMS\n"+
1010
                   "jm.evers 2009";
1011
        JOptionPane.showMessageDialog(null,msg,"About WIMSchem",JOptionPane.INFORMATION_MESSAGE,mainLogo);
3662 schaersvoo 1012
    }
1013
 
1014
    // ------------------ event functions --------------------
1015
 
1016
    public void actionPerformed(ActionEvent e)
1017
    {
1018
        String cmd=e.getActionCommand();
1019
 
1020
        int setsel=-1;
1021
 
7246 schaersvoo 1022
        if (cmd.equals(translation.getProperty("Quit")) || cmd.equals(translation.getProperty("Close")) || cmd.equals(translation.getProperty("Save_and_Quit"))) fileQuit();
1023
        else if (cmd.equals(translation.getProperty("New"))) fileNew();
1024
        else if (cmd.equals(translation.getProperty("New_Window"))) fileNewWindow();
1025
        else if (cmd.equals(translation.getProperty("New_DataSheet"))) fileNewDataSheet();
1026
        else if (cmd.equals(translation.getProperty("Open"))) fileOpen();
1027
        else if (cmd.equals(translation.getProperty("Save"))) fileSave();
1028
        else if (cmd.equals(translation.getProperty("Save_As"))) fileSaveAs();
1029
        else if (cmd.equals(translation.getProperty("as_MDL_MOL"))) fileExportMDLMOL();
1030
        else if (cmd.equals(translation.getProperty("as_CML_XML"))) fileExportCMLXML();
1031
        else if (cmd.equals(translation.getProperty("as_SVG"))) fileExportSVG();
1032
        else if (cmd.equals(translation.getProperty("Cursor")) || e.getSource()==toolButtons[TOOL_CURSOR]) {editor.setToolCursor(); setsel=TOOL_CURSOR;}
1033
        else if (cmd.equals(translation.getProperty("Rotator")) || e.getSource()==toolButtons[TOOL_ROTATOR]) {editor.setToolRotator(); setsel=TOOL_ROTATOR;}
1034
        else if (cmd.equals(translation.getProperty("Erasor")) || e.getSource()==toolButtons[TOOL_ERASOR]) {editor.setToolErasor(); setsel=TOOL_ERASOR;}
1035
        else if (cmd.equals(translation.getProperty("Editttt")) || e.getSource()==toolButtons[TOOL_DIALOG]) editDialog();
1036
        else if (cmd.equals(translation.getProperty("Select_All"))) editor.selectAll();
1037
        else if (cmd.equals(translation.getProperty("Next_Atom"))) editor.cycleSelection(true,false);
1038
        else if (cmd.equals(translation.getProperty("Previous_Atom"))) editor.cycleSelection(false,false);
1039
        else if (cmd.equals(translation.getProperty("Next_Group"))) editor.cycleSelection(true,true);
1040
        else if (cmd.equals(translation.getProperty("Previous_Group"))) editor.cycleSelection(false,true);
1041
        else if (cmd.equals(translation.getProperty("Edit_Atom")) || e.getSource()==toolButtons[TOOL_EDIT]) {editor.setToolAtom(null); setsel=TOOL_EDIT;}
1042
        else if (cmd.equals(translation.getProperty("Set_Atom")) || e.getSource()==toolButtons[TOOL_SETATOM]) {editor.setToolAtom(lastElement); setsel=TOOL_SETATOM;}
1043
        else if (cmd.equals(translation.getProperty("Single_Bond")) || e.getSource()==toolButtons[TOOL_SINGLE]) {editor.setToolBond(1); setsel=TOOL_SINGLE;}
1044
        else if (cmd.equals(translation.getProperty("Double_Bond")) || e.getSource()==toolButtons[TOOL_DOUBLE]) {editor.setToolBond(2); setsel=TOOL_DOUBLE;}
1045
        else if (cmd.equals(translation.getProperty("Triple_Bond")) || e.getSource()==toolButtons[TOOL_TRIPLE]) {editor.setToolBond(3); setsel=TOOL_TRIPLE;}
1046
        else if (cmd.equals(translation.getProperty("Zero_Bond")) || e.getSource()==toolButtons[TOOL_ZERO]) {editor.setToolBond(0); setsel=TOOL_ZERO;}
1047
        else if (cmd.equals(translation.getProperty("Inclined_Bond")) || e.getSource()==toolButtons[TOOL_INCLINED]) {editor.setToolBond(-1); setsel=TOOL_INCLINED;}
1048
        else if (cmd.equals(translation.getProperty("Declined_Bond")) || e.getSource()==toolButtons[TOOL_DECLINED]) {editor.setToolBond(-2); setsel=TOOL_DECLINED;}
1049
        else if (cmd.equals(translation.getProperty("Unknown_Bond")) || e.getSource()==toolButtons[TOOL_UNKNOWN]) {editor.setToolBond(-3); setsel=TOOL_UNKNOWN;}
1050
        else if (cmd.equals(translation.getProperty("Charge")) || e.getSource()==toolButtons[TOOL_CHARGE]) {editor.setToolCharge(1); setsel=TOOL_CHARGE;}
1051
        else if (cmd.equals(translation.getProperty("Undo")) || e.getSource()==toolButtons[TOOL_UNDO]) editor.undo();
1052
        else if (cmd.equals(translation.getProperty("Redo")) || e.getSource()==toolButtons[TOOL_REDO]) editor.redo();
1053
        else if (cmd.equals(translation.getProperty("Un_select_all")) || e.getSource()==toolButtons[TOOL_UNSELECT]) editor.deSelectAll();
1054
        else if (cmd.equals(translation.getProperty("Select")) || e.getSource()==toolButtons[TOOL_SELECT]) editor.Select();
1055
        else if (cmd.equals(translation.getProperty("Cut"))) editCut();
1056
        else if (cmd.equals(translation.getProperty("Copy"))) editCopy();
1057
        else if (cmd.equals(translation.getProperty("Copy_SVG"))) editCopySVG();
1058
        else if (cmd.equals(translation.getProperty("Paste"))) editPaste();
1059
        else if (cmd.equals(translation.getProperty("Flip_Horizontal"))) editor.flipSelectedAtoms(false);
1060
        else if (cmd.equals(translation.getProperty("Flip_Vertical"))) editor.flipSelectedAtoms(true);
1061
        else if (cmd.equals(translation.getProperty("Rotate_P45"))) editor.rotateSelectedAtoms(45);
1062
        else if (cmd.equals(translation.getProperty("Rotate_M45"))) editor.rotateSelectedAtoms(-45);
1063
        else if (cmd.equals(translation.getProperty("Rotate_P90"))) editor.rotateSelectedAtoms(90);
1064
        else if (cmd.equals(translation.getProperty("Rotate_M90"))) editor.rotateSelectedAtoms(-90);
1065
        else if (cmd.equals(translation.getProperty("Add_Temporary_Template"))) templateAddTo();
1066
        else if (cmd.equals(translation.getProperty("Normalise_Bond_Lengths"))) editor.normaliseBondLengths();
1067
        else if (cmd.equals(translation.getProperty("Template_Tool")) || e.getSource()==toolButtons[TOOL_TEMPLATE]) {templateTool(); setsel=TOOL_TEMPLATE;}
1068
        else if (cmd.equals(translation.getProperty("Select_Template"))) {templateSelect(); setsel=TOOL_TEMPLATE;}
1069
        else if (cmd.equals(translation.getProperty("Zoom_Full"))) editor.zoomFull();
1070
        else if (cmd.equals(translation.getProperty("Zoom_In"))) editor.zoomIn(1.5);
1071
        else if (cmd.equals(translation.getProperty("Zoom_Out"))) editor.zoomOut(1.5);
1072
        else if (cmd.equals(translation.getProperty("Show_Elements"))) editor.setShowMode(ArrangeMolecule.SHOW_ELEMENTS);
1073
        else if (cmd.equals(translation.getProperty("Show_All_Elements"))) editor.setShowMode(ArrangeMolecule.SHOW_ALL_ELEMENTS);
1074
        else if (cmd.equals(translation.getProperty("Show_Indices"))) editor.setShowMode(ArrangeMolecule.SHOW_INDEXES);
1075
        else if (cmd.equals(translation.getProperty("Show_Ring_ID"))) editor.setShowMode(ArrangeMolecule.SHOW_RINGID);
1076
        else if (cmd.equals(translation.getProperty("Show_CIP_Priority"))) editor.setShowMode(ArrangeMolecule.SHOW_PRIORITY);
1077
        else if (cmd.equals(translation.getProperty("Show_Mapping_Number"))) editor.setShowMode(ArrangeMolecule.SHOW_MAPNUM);
1078
        else if (cmd.equals(translation.getProperty("Show_Hydrogen"))) editor.setShowHydrogens(chkShowHydr.isSelected());
1079
        else if (cmd.equals(translation.getProperty("Set_Explicit")))  editor.hydrogenSetExplicit(true);
1080
        else if (cmd.equals(translation.getProperty("Clear_Explicit"))) editor.hydrogenSetExplicit(false);
1081
        else if (cmd.equals(translation.getProperty("Zero_Explicit"))) editor.hydrogenSetExplicit(false,0);
1082
        else if (cmd.equals(translation.getProperty("Create_Actual"))) editor.hydrogenCreateActual();
1083
        else if (cmd.equals(translation.getProperty("Delete_Actual"))) editor.hydrogenDeleteActual();
1084
        else if (cmd.equals(translation.getProperty("Show_Stereolabels"))) editor.setShowStereolabels(chkShowSter.isSelected());
1085
        else if (cmd.equals(translation.getProperty("Invert_Stereochemistry"))) editor.setStereo(Molecule.STEREO_UNKNOWN);
1086
        else if (cmd.equals(translation.getProperty("Set_R/Z"))) editor.setStereo(Molecule.STEREO_POS);
1087
        else if (cmd.equals(translation.getProperty("Set_S/E"))) editor.setStereo(Molecule.STEREO_NEG);
1088
        else if (cmd.equals(translation.getProperty("Cycle_Wedges"))) editor.cycleChiralWedges();
1089
        else if (cmd.equals(translation.getProperty("Remove_Wedges"))) editor.removeChiralWedges();
1090
        else if (cmd.equals(translation.getProperty("About"))) helpAbout();
1091
        else if (TOOL_SELECTION[TOOL_SETATOM] && cmd.length()<=2) {selectElement(cmd); editor.setToolAtom(lastElement);}
3662 schaersvoo 1092
        if (setsel!=-1) toolGroup.setSelected(toolButtons[setsel].getModel(),true);
1093
    }
1094
 
1095
    public void mouseClicked(MouseEvent e) {}
1096
    public void mouseEntered(MouseEvent e) {}
1097
    public void mouseExited(MouseEvent e) {}
7246 schaersvoo 1098
    public void mousePressed(MouseEvent e)
1099
    {
3662 schaersvoo 1100
        if (e.getSource()==toolButtons[TOOL_SETATOM] && e.getButton()==MouseEvent.BUTTON3)
1101
        {
1102
            toolButtons[TOOL_SETATOM].setSelected(true);
1103
            JPopupMenu popup=new JPopupMenu();
7246 schaersvoo 1104
            int max = myAtoms.length;
1105
            for(int i=0 ; i < max ;i++ ){
1106
             popup.add(menuItem( myAtoms[i] ,0));
3662 schaersvoo 1107
            }
1108
            popup.show(toolButtons[TOOL_SETATOM],0,0);
1109
        }
1110
        if (e.getSource()==toolButtons[TOOL_TEMPLATE] && e.getButton()==MouseEvent.BUTTON3)
1111
        {
1112
            toolGroup.setSelected(toolButtons[TOOL_TEMPLATE].getModel(),true);
7246 schaersvoo 1113
            templateSelect();
3662 schaersvoo 1114
        }
1115
    }
1116
    public void mouseReleased(MouseEvent e) {}  
1117
    public void keyPressed(KeyEvent e)
1118
    {
1119
        // keyboard arrow-nudges
1120
        if (!e.isAltDown() && !e.isShiftDown() && !e.isControlDown() && !e.isMetaDown())
1121
        {
7246 schaersvoo 1122
            if (e.getKeyCode()==KeyEvent.VK_UP) {editor.nudgeSelectedAtoms(0,0.05); return;}
1123
            if (e.getKeyCode()==KeyEvent.VK_DOWN) {editor.nudgeSelectedAtoms(0,-0.05); return;}
1124
            if (e.getKeyCode()==KeyEvent.VK_LEFT) {editor.nudgeSelectedAtoms(-0.05,0); return;}
1125
            if (e.getKeyCode()==KeyEvent.VK_RIGHT) {editor.nudgeSelectedAtoms(0.05,0); return;}
3662 schaersvoo 1126
        }
1127
    }
1128
    public void keyReleased(KeyEvent e) {}
1129
    public void keyTyped(KeyEvent e)
1130
    {    
1131
        // user typing in an element...
1132
        char ch=e.getKeyChar();
1133
        if (ch>='A' && ch<='Z') typedElement=""+ch;
1134
        else if (typedElement.length()==1 && ch>='a' && ch<='z') typedElement=typedElement+ch;
1135
        else if (typedElement.compareTo("R")==0 && ch>='0' && ch<='9') typedElement=typedElement+ch;
1136
        else {typedElement=""; return;}
1137
 
1138
        String elset=null;
1139
        if (typedElement.length()>=2 && typedElement.charAt(0)=='R' && typedElement.charAt(1)>='0' && typedElement.charAt(1)<='9')
1140
        {
1141
            elset=typedElement;
1142
        }
1143
        else
1144
        {
1145
            for (int n=1;n<Molecule.ELEMENTS.length;n++) if (typedElement.compareTo(Molecule.ELEMENTS[n])==0) {elset=typedElement;}
1146
        }
1147
        if (elset!=null)
1148
        {
7246 schaersvoo 1149
            selectElement(elset);
3662 schaersvoo 1150
            toolGroup.setSelected(toolButtons[TOOL_SETATOM].getModel(),true);
7246 schaersvoo 1151
            editor.setToolAtom(elset);
3662 schaersvoo 1152
        }
1153
    }
1154
 
7246 schaersvoo 1155
    public void templSelected(Molecule mol,int idx)
3662 schaersvoo 1156
    {
1157
        lastTemplate=mol;
1158
        templateIdx=idx;
7246 schaersvoo 1159
        editor.setToolTemplate(mol,idx);
3662 schaersvoo 1160
    }
7246 schaersvoo 1161
    public void molSelected(EditorPane source,int idx,boolean dblclick)
3662 schaersvoo 1162
    {
1163
        if (dblclick && idx!=0)
1164
        {
1165
            ArrayList<Integer> selidx=new ArrayList<Integer>();
1166
            if (idx>0) selidx.add(idx);
7246 schaersvoo 1167
            else {selidx.add(editor.molData().bondFrom(-idx)); selidx.add(editor.molData().bondTo(-idx));}
1168
            Molecule newMol=(new DialogEdit(frameParent,editor.molData(),selidx)).exec();
1169
            if (newMol!=null) editor.replace(newMol);
3662 schaersvoo 1170
        }
1171
    }
7246 schaersvoo 1172
    public void dirtyChanged(boolean isdirty)
3662 schaersvoo 1173
    {
1174
        String str=frameParent==null ? "WIMSchem" : frameParent.getTitle();
1175
        if (str.charAt(0)=='*') str=str.substring(1);
1176
        if (isdirty) str="*"+str;
7246 schaersvoo 1177
        if (frameParent!=null && saver==null) frameParent.setTitle(str);
3662 schaersvoo 1178
    }
1179
 
1180
    public void lostOwnership(Clipboard clipboard,Transferable contents) {} // don't care
1181
 
1182
    public void windowActivated(WindowEvent e) {}
1183
    public void windowClosed(WindowEvent e) {}
1184
    public void windowClosing(WindowEvent e)
1185
    {
7246 schaersvoo 1186
        fileQuit();
3662 schaersvoo 1187
    }
1188
    public void windowDeactivated(WindowEvent e) {}
1189
    public void windowDeiconified(WindowEvent e) {}
1190
    public void windowIconified(WindowEvent e) {}
1191
    public void windowOpened(WindowEvent e)
1192
    {
1193
        if (firstResize)
1194
        {
7246 schaersvoo 1195
            editor.scaleToFit();
3662 schaersvoo 1196
            editor.repaint();
1197
            firstResize=false;
1198
        }
1199
        editor.requestFocusInWindow();
1200
    }
7246 schaersvoo 1201
 
1202
    public  String getToolTips( int p ){
1203
        switch(p){
1204
         case 0: return translation.getProperty("CURSOR_TIP");
1205
         case 1: return translation.getProperty("ROTATOR_TIP");
1206
         case 2: return translation.getProperty("ERASOR_TIP");
1207
         case 3: return translation.getProperty("EDIT_DIALOG_TIP");
1208
         case 4: return translation.getProperty("EDIT_ELEMENT_TIP");
1209
         case 5: return translation.getProperty("PLACE_ELEMENT_TIP");
1210
         case 6: return translation.getProperty("SINGLE_BOND_TIP");
1211
         case 7: return translation.getProperty("DOUBLE_BOND_TIP");
1212
         case 8: return translation.getProperty("TRIPLE_BOND_TIP");
1213
         case 9: return translation.getProperty("ZERO_BOND_TIP");
1214
         case 10: return translation.getProperty("INCLINED_BOND_TIP");
1215
         case 11: return translation.getProperty("DECLINE_BOND_TIP");
1216
         case 12: return translation.getProperty("SQUIGGLY_BOND_TIP");
1217
         case 13: return translation.getProperty("CHARGE_TIP");
1218
         case 14: return translation.getProperty("UNDO_TIP");
1219
         case 15: return translation.getProperty("REDO_TIP");
1220
         case 16: return translation.getProperty("TEMPLATE_TIP");
1221
         case 17: return translation.getProperty("CUT_TIP");
1222
         case 18: return translation.getProperty("COPY_TIP");
1223
         case 19: return translation.getProperty("PASTE");
7317 schaersvoo 1224
         case 20: return translation.getProperty("SELECT");
1225
         case 21: return translation.getProperty("UNSELECT");
1226
         default : return "NO TIP?";
7246 schaersvoo 1227
        }
1228
    }
1229
    private Properties loadProperties(String lang){
1230
     Properties P=new Properties();
1231
     try{
1232
      InputStream in = getClass().getResourceAsStream("/lang/WIMSchemProperties_"+lang+".properties");
1233
      P.load(in);in.close();
1234
      return P;
1235
     }catch (Exception e){ System.out.println("error reading /lang/WIMSchemProperties_"+lang+".properties\n"+e);}
1236
     return null;
1237
    }
1238
 
1239
 
3662 schaersvoo 1240
}