Subversion Repositories wimsdev

Rev

Rev 7246 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

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