1   /*
2    *  Copyright (c) 1998-2005, The University of Sheffield.
3    *
4    *  This file is part of GATE (see http://gate.ac.uk/), and is free
5    *  software, licenced under the GNU Library General Public License,
6    *  Version 2, June 1991 (in the distribution as file licence.html,
7    *  and also available at http://gate.ac.uk/gate/licence.html).
8    *
9    *  Valentin Tablan 22/01/2001
10   *
11   *  $Id: MainFrame.java,v 1.212 2005/12/21 16:14:04 valyt Exp $
12   *
13   */
14  
15  package gate.gui;
16  
17  import java.awt.*;
18  import java.awt.event.*;
19  import java.beans.PropertyChangeEvent;
20  import java.beans.PropertyChangeListener;
21  import java.io.File;
22  import java.io.IOException;
23  import java.net.MalformedURLException;
24  import java.net.URL;
25  import java.text.NumberFormat;
26  import java.util.*;
27  import java.util.List;
28  import java.lang.reflect.Proxy;
29  import java.lang.reflect.Method;
30  import java.lang.reflect.InvocationHandler;
31  
32  import javax.swing.*;
33  import javax.swing.event.*;
34  import javax.swing.tree.*;
35  
36  import junit.framework.Assert;
37  
38  import com.ontotext.gate.vr.Gaze;
39  import com.ontotext.gate.vr.OntologyEditorImpl;
40  
41  import gate.*;
42  import gate.creole.*;
43  import gate.event.*;
44  import gate.persist.PersistenceException;
45  import gate.security.*;
46  import gate.swing.*;
47  import gate.util.*;
48  
49  /**
50   * The main Gate GUI frame.
51   */
52  public class MainFrame extends JFrame
53                      implements ProgressListener, StatusListener, CreoleListener{
54  
55    protected JMenuBar menuBar;
56    protected JSplitPane mainSplit;
57    protected JSplitPane leftSplit;
58    protected JLabel statusBar;
59    protected JProgressBar progressBar;
60    protected XJTabbedPane mainTabbedPane;
61    protected JScrollPane projectTreeScroll;
62    protected JScrollPane lowerScroll;
63  
64    /**
65     * Popup used for right click actions on the Applications node.
66     */
67    protected JPopupMenu appsPopup;
68    /**
69     * Popup used for right click actions on the Datastores node.
70     */
71    protected JPopupMenu dssPopup;
72  
73    /**
74     * Popup used for right click actions on the LRs node.
75     */
76    protected JPopupMenu lrsPopup;
77  
78    /**
79     * Popup used for right click actions on the PRs node.
80     */
81    protected JPopupMenu prsPopup;
82  
83    protected JCheckBoxMenuItem verboseModeItem;
84  
85    protected JTree resourcesTree;
86    protected JScrollPane resourcesTreeScroll;
87    protected DefaultTreeModel resourcesTreeModel;
88    protected DefaultMutableTreeNode resourcesTreeRoot;
89    protected DefaultMutableTreeNode applicationsRoot;
90    protected DefaultMutableTreeNode languageResourcesRoot;
91    protected DefaultMutableTreeNode processingResourcesRoot;
92    protected DefaultMutableTreeNode datastoresRoot;
93  
94  
95  
96  
97    protected Splash splash;
98    protected PluginManagerUI pluginManager;
99    protected LogArea logArea;
100   protected JScrollPane logScroll;
101   protected JToolBar toolbar;
102   static JFileChooser fileChooser;
103 
104   protected AppearanceDialog appearanceDialog;
105   protected OptionsDialog optionsDialog;
106   protected CartoonMinder animator;
107   protected TabHighlighter logHighlighter;
108   protected NewResourceDialog newResourceDialog;
109   protected WaitDialog waitDialog;
110 
111 
112   /**
113    * Holds all the icons used in the Gate GUI indexed by filename.
114    * This is needed so we do not need to decode the icon everytime
115    * we need it as that would use unecessary CPU time and memory.
116    * Access to this data is avaialable through the {@link #getIcon(String)}
117    * method.
118    */
119   protected static Map iconByName = new HashMap();
120 
121   /**
122    * A Map which holds listeners that are singletons (e.g. the status listener
123    * that updates the status bar on the main frame or the progress listener that
124    * updates the progress bar on the main frame).
125    * The keys used are the class names of the listener interface and the values
126    * are the actual listeners (e.g "gate.event.StatusListener" -> this).
127    */
128   private static java.util.Map listeners = new HashMap();
129   
130   protected static java.util.Collection guiRoots = new ArrayList();
131 
132   private static JDialog guiLock = null;
133 
134   static public Icon getIcon(String filename){
135     Icon result = (Icon)iconByName.get(filename);
136     if(result == null){
137       result = new ImageIcon(MainFrame.class.
138               getResource(Files.getResourcePath() + "/img/" + filename));
139       iconByName.put(filename, result);
140     }
141     return result;
142   }
143 
144 
145 /*
146   static public MainFrame getInstance(){
147     if(instance == null) instance = new MainFrame();
148     return instance;
149   }
150 */
151 
152   static public JFileChooser getFileChooser(){
153     return fileChooser;
154   }
155 
156 
157   /**
158    * Selects a resource if loaded in the system and not invisible.
159    * @param res the resource to be selected.
160    */
161   public void select(Resource res){
162     //first find the handle for the resource
163     Handle handle = null;
164     //go through all the nodes
165     Enumeration nodesEnum = resourcesTreeRoot.breadthFirstEnumeration();
166     while(nodesEnum.hasMoreElements() && handle == null){
167       Object node = nodesEnum.nextElement();
168       if(node instanceof DefaultMutableTreeNode){
169         DefaultMutableTreeNode dmtNode = (DefaultMutableTreeNode)node;
170         if(dmtNode.getUserObject() instanceof Handle){
171           if(((Handle)dmtNode.getUserObject()).getTarget() == res){
172             handle = (Handle)dmtNode.getUserObject();
173           }
174         }
175       }
176     }
177 
178     //now select the handle if found
179     if(handle != null) select(handle);
180   }
181 
182   protected void select(Handle handle){
183     if(handle.viewsBuilt() &&
184        mainTabbedPane.indexOfComponent(handle.getLargeView()) != -1) {
185       //select
186       JComponent largeView = handle.getLargeView();
187       if(largeView != null) {
188         mainTabbedPane.setSelectedComponent(largeView);
189       }
190     } else {
191       //show
192       JComponent largeView = handle.getLargeView();
193       if(largeView != null) {
194         mainTabbedPane.addTab(handle.getTitle(), handle.getIcon(),
195                               largeView, handle.getTooltipText());
196         mainTabbedPane.setSelectedComponent(handle.getLargeView());
197       }
198     }
199     //show the small view
200     JComponent smallView = handle.getSmallView();
201     if(smallView != null) {
202       lowerScroll.getViewport().setView(smallView);
203     } else {
204       lowerScroll.getViewport().setView(null);
205     }
206   }//protected void select(ResourceHandle handle)
207 
208   public MainFrame() {
209     this(false);
210   } // MainFrame
211 
212   /**Construct the frame*/
213   public MainFrame(boolean isShellSlacGIU) {
214     guiRoots.add(this);
215     if(fileChooser == null){
216       fileChooser = new JFileChooser();
217       fileChooser.setMultiSelectionEnabled(false);
218       String lastUsedDir = Gate.getUserConfig()
219           .getString(GateConstants.LAST_FILECHOOSER_LOCATION);
220       if(lastUsedDir != null && lastUsedDir.length() > 0) {
221         File lastDir = new File(lastUsedDir);
222         if(lastDir.exists() && lastDir.isDirectory())
223           fileChooser.setCurrentDirectory(new File(lastUsedDir));
224       }
225       guiRoots.add(fileChooser);
226 
227       //the JFileChooser seems to size itself better once it's been added to a
228       //top level container such as a dialog.
229       JDialog dialog = new JDialog(this, "", true);
230       java.awt.Container contentPane = dialog.getContentPane();
231       contentPane.setLayout(new BorderLayout());
232       contentPane.add(fileChooser, BorderLayout.CENTER);
233       dialog.pack();
234       dialog.getContentPane().removeAll();
235       dialog.dispose();
236       dialog = null;
237     }
238     enableEvents(AWTEvent.WINDOW_EVENT_MASK);
239     initLocalData(isShellSlacGIU);
240     initGuiComponents(isShellSlacGIU);
241     initListeners(isShellSlacGIU);
242   } // MainFrame(boolean simple)
243 
244   protected void initLocalData(boolean isShellSlacGIU){
245     resourcesTreeRoot = new DefaultMutableTreeNode("GATE", true);
246     applicationsRoot = new DefaultMutableTreeNode("Applications", true);
247     if(isShellSlacGIU) {
248       languageResourcesRoot = new DefaultMutableTreeNode("Documents",
249                                                        true);
250     } else {
251       languageResourcesRoot = new DefaultMutableTreeNode("Language Resources",
252                                                        true);
253     } // if
254     processingResourcesRoot = new DefaultMutableTreeNode("Processing Resources",
255                                                          true);
256     datastoresRoot = new DefaultMutableTreeNode("Data stores", true);
257     resourcesTreeRoot.add(applicationsRoot);
258     resourcesTreeRoot.add(languageResourcesRoot);
259     resourcesTreeRoot.add(processingResourcesRoot);
260     resourcesTreeRoot.add(datastoresRoot);
261 
262     resourcesTreeModel = new ResourcesTreeModel(resourcesTreeRoot, true);
263   }
264 
265   protected void initGuiComponents(boolean isShellSlacGUI){
266     this.getContentPane().setLayout(new BorderLayout());
267 
268     Integer width =Gate.getUserConfig().getInt(GateConstants.MAIN_FRAME_WIDTH);
269     Integer height =Gate.getUserConfig().getInt(GateConstants.MAIN_FRAME_HEIGHT);
270     this.setSize(new Dimension(width == null ? 800 : width.intValue(),
271                                height == null ? 600 : height.intValue()));
272 
273     this.setIconImage(Toolkit.getDefaultToolkit().getImage(
274           MainFrame.class.getResource(Files.getResourcePath() +
275                   "/img/gateIcon.gif")));
276     resourcesTree = new JTree(resourcesTreeModel){
277       public void updateUI(){
278         super.updateUI();
279         setRowHeight(0);
280       }
281     };
282 
283     resourcesTree.setEditable(true);
284     ResourcesTreeCellRenderer treeCellRenderer =
285                               new ResourcesTreeCellRenderer();
286     resourcesTree.setCellRenderer(treeCellRenderer);
287     resourcesTree.setCellEditor(new ResourcesTreeCellEditor(resourcesTree,
288                                                           treeCellRenderer));
289 
290     resourcesTree.setRowHeight(0);
291     //expand all nodes
292     resourcesTree.expandRow(0);
293     resourcesTree.expandRow(1);
294     resourcesTree.expandRow(2);
295     resourcesTree.expandRow(3);
296     resourcesTree.expandRow(4);
297     resourcesTree.getSelectionModel().
298                   setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION
299                                    );
300     resourcesTree.setEnabled(true);
301     ToolTipManager.sharedInstance().registerComponent(resourcesTree);
302     resourcesTreeScroll = new JScrollPane(resourcesTree);
303 
304     lowerScroll = new JScrollPane();
305     JPanel lowerPane = new JPanel();
306     lowerPane.setLayout(new OverlayLayout(lowerPane));
307 
308     JPanel animationPane = new JPanel();
309     animationPane.setOpaque(false);
310     animationPane.setLayout(new BoxLayout(animationPane, BoxLayout.X_AXIS));
311 
312     JPanel vBox = new JPanel();
313     vBox.setLayout(new BoxLayout(vBox, BoxLayout.Y_AXIS));
314     vBox.setOpaque(false);
315 
316     JPanel hBox = new JPanel();
317     hBox.setLayout(new BoxLayout(hBox, BoxLayout.X_AXIS));
318     hBox.setOpaque(false);
319 
320     vBox.add(Box.createVerticalGlue());
321     vBox.add(animationPane);
322 
323     hBox.add(vBox);
324     hBox.add(Box.createHorizontalGlue());
325 
326     lowerPane.add(hBox);
327     lowerPane.add(lowerScroll);
328 
329     animator = new CartoonMinder(animationPane);
330     Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
331                                animator,
332                                "MainFrame1");
333     thread.setPriority(Thread.MIN_PRIORITY);
334     thread.start();
335 
336     leftSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
337                                resourcesTreeScroll, lowerPane);
338 
339     leftSplit.setResizeWeight((double)0.7);
340 
341     // Create a new logArea and redirect the Out and Err output to it.
342     logArea = new LogArea();
343     logScroll = new JScrollPane(logArea);
344     // Out has been redirected to the logArea
345 
346     Out.prln("GATE " + Main.version + " build " + Main.build + " started at: " +
347             new Date().toString());
348     mainTabbedPane = new XJTabbedPane(JTabbedPane.TOP);
349     mainTabbedPane.insertTab("Messages",null, logScroll, "GATE log", 0);
350 
351     logHighlighter = new TabHighlighter(mainTabbedPane, logScroll, Color.red);
352 
353 
354     mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
355                                leftSplit, mainTabbedPane);
356 
357     mainSplit.setDividerLocation(leftSplit.getPreferredSize().width + 10);
358     this.getContentPane().add(mainSplit, BorderLayout.CENTER);
359 
360     //status and progress bars
361     statusBar = new JLabel(" ");
362     statusBar.setPreferredSize(new Dimension(200,
363                                              statusBar.getPreferredSize().
364                                              height));
365 
366     UIManager.put("ProgressBar.cellSpacing", new Integer(0));
367     progressBar = new JProgressBar(JProgressBar.HORIZONTAL);
368 //    progressBar.setBorder(BorderFactory.createEmptyBorder());
369     progressBar.setForeground(new Color(150, 75, 150));
370 //    progressBar.setBorderPainted(false);
371     progressBar.setStringPainted(false);
372     progressBar.setOrientation(JProgressBar.HORIZONTAL);
373 
374     JPanel southBox = new JPanel();
375     southBox.setLayout(new GridLayout(1,2));
376     southBox.setBorder(null);
377 
378     Box tempHBox = Box.createHorizontalBox();
379     tempHBox.add(Box.createHorizontalStrut(5));
380     tempHBox.add(statusBar);
381     southBox.add(tempHBox);
382     tempHBox = Box.createHorizontalBox();
383     tempHBox.add(progressBar);
384     tempHBox.add(Box.createHorizontalStrut(5));
385     southBox.add(tempHBox);
386 
387     this.getContentPane().add(southBox, BorderLayout.SOUTH);
388     progressBar.setVisible(false);
389 
390 
391     //extra stuff
392     newResourceDialog = new NewResourceDialog(
393       this, "Resource parameters", true
394     );
395     waitDialog = new WaitDialog(this, "");
396     
397     
398     //build the Help->About dialog
399     JPanel splashBox = new JPanel();
400     splashBox.setBackground(Color.WHITE);
401     
402     splashBox.setLayout(new GridBagLayout());
403     GridBagConstraints constraints = new GridBagConstraints();
404     constraints.weightx = 0;
405     constraints.weighty = 0;
406     constraints.insets = new Insets(2, 2, 2, 2);
407     constraints.fill = GridBagConstraints.NONE;
408     constraints.anchor = GridBagConstraints.CENTER;
409 
410     constraints.gridy = 0;
411     constraints.gridwidth = 2;
412     constraints.fill = GridBagConstraints.NONE;
413     JLabel gifLbl = new JLabel(getIcon("gateHeader.gif"));
414     splashBox.add(gifLbl, constraints);
415 
416     constraints.gridy = 1;
417     constraints.fill = GridBagConstraints.NONE;
418     constraints.gridx = GridBagConstraints.RELATIVE;
419     constraints.gridwidth = 1;
420     constraints.gridheight = 1;
421     
422     gifLbl = new JLabel(getIcon("gateSplash.gif"));
423     splashBox.add(gifLbl, constraints);
424     
425     gifLbl = new JLabel(getIcon("sponsors.gif"));
426     splashBox.add(gifLbl, constraints);
427     constraints.gridy = 2;
428     constraints.gridwidth = 2;
429     constraints.anchor = GridBagConstraints.CENTER;
430     constraints.fill = GridBagConstraints.HORIZONTAL;
431     JLabel htmlLbl = new JLabel(
432             "<HTML><CENTER>" +
433             "<B>Hamish Cunningham, Valentin Tablan, Kalina Bontcheva, Diana Maynard,</B>" +
434             "<BR>Niraj Aswani, Mike Dowman, Marin Dimitrov, Bobby Popov, Yaoyong Li, Akshay Java," +
435             "<BR>Wim Peters, Ian Roberts, Mark Greenwood, Angus Roberts, Andrey Shafirin," +
436             "<BR>Horacio Saggion, Cristian Ursu, Atanas Kiryakov, Angel Kirilov, Damyan Ognyanoff," +
437             "<BR>Dimitar Manov, Milena Yankova, Oana Hamza, Robert Gaizauskas, Mark Hepple," +
438             "<BR>Mark Leisher, Fang Huang, Kevin Humphreys, Yorick Wilks." +            
439             "</CENTER></HTML>");
440     htmlLbl.setHorizontalAlignment(SwingConstants.CENTER);
441     splashBox.add(htmlLbl, constraints);
442     
443     constraints.gridy = 3;
444     htmlLbl = new JLabel(
445             "<HTML><FONT color=\"blue\">Version <B>"
446             + Main.version + "</B></FONT>" +
447             ", <FONT color=\"red\">build <B>" + Main.build + "</B></FONT>" +
448             "<P><B>JVM version</B>: " + System.getProperty("java.version") +
449             " from " + System.getProperty("java.vendor") +
450             "</HTML>"
451           );
452     constraints.fill = GridBagConstraints.HORIZONTAL;
453     splashBox.add(htmlLbl, constraints);
454 
455     
456     constraints.gridy = 4;
457     constraints.gridwidth = 2;
458     constraints.fill = GridBagConstraints.NONE;
459     JButton okBtn = new JButton("OK");
460     okBtn.addActionListener(new ActionListener() {
461       public void actionPerformed(ActionEvent e) {
462         splash.setVisible(false);
463       }
464     });
465     okBtn.setBackground(Color.white);
466     splashBox.add(okBtn, constraints);
467     splash = new Splash(this, splashBox);
468 
469 
470     //MENUS
471     menuBar = new JMenuBar();
472 
473 
474     JMenu fileMenu = new XJMenu("File");
475 
476     LiveMenu newAPPMenu = new LiveMenu(LiveMenu.APP);
477     newAPPMenu.setText("New application");
478     newAPPMenu.setIcon(getIcon("applications.gif"));
479     fileMenu.add(newAPPMenu);
480 
481     LiveMenu newLRMenu = new LiveMenu(LiveMenu.LR);
482     newLRMenu.setText("New language resource");
483     newLRMenu.setIcon(getIcon("lrs.gif"));
484     fileMenu.add(newLRMenu);
485 
486     LiveMenu newPRMenu = new LiveMenu(LiveMenu.PR);
487     newPRMenu.setText("New processing resource");
488     newPRMenu.setIcon(getIcon("prs.gif"));
489     fileMenu.add(newPRMenu);
490 
491     JMenu dsMenu = new JMenu("Datastores");
492     dsMenu.setIcon(getIcon("dss.gif"));
493     dsMenu.add(new XJMenuItem(new NewDSAction(), this));
494     dsMenu.add(new XJMenuItem(new OpenDSAction(), this));
495     fileMenu.add(dsMenu);
496 
497     fileMenu.addSeparator();
498     fileMenu.add(new XJMenuItem(new LoadResourceFromFileAction(), this));
499 
500     fileMenu.addSeparator();
501     JMenu loadANNIEMenu = new JMenu("Load ANNIE system");
502     loadANNIEMenu.setIcon(getIcon("application.gif"));
503     loadANNIEMenu.add(new XJMenuItem(new LoadANNIEWithDefaultsAction(), this));
504     loadANNIEMenu.add(new XJMenuItem(new LoadANNIEWithoutDefaultsAction(), this));
505     fileMenu.add(loadANNIEMenu);
506 
507 //    fileMenu.add(new XJMenuItem(new LoadCreoleRepositoryAction(), this));
508 
509     fileMenu.add(new XJMenuItem(new ManagePluginsAction(), this));
510     fileMenu.addSeparator();
511 
512     fileMenu.add(new XJMenuItem(new ExitGateAction(), this));
513     menuBar.add(fileMenu);
514 
515 
516 
517     JMenu optionsMenu = new JMenu("Options");
518 
519     optionsDialog = new OptionsDialog(MainFrame.this);
520     optionsMenu.add(new XJMenuItem(new AbstractAction("Configuration"){
521       {
522         putValue(SHORT_DESCRIPTION, "Edit gate options");
523       }
524       public void actionPerformed(ActionEvent evt){
525         optionsDialog.show();
526       }
527     }, this));
528 
529 
530     JMenu imMenu = null;
531     List installedLocales = new ArrayList();
532     try{
533       //if this fails guk is not present
534       Class.forName("guk.im.GateIMDescriptor");
535       //add the Gate input methods
536       installedLocales.addAll(Arrays.asList(new guk.im.GateIMDescriptor().
537                                             getAvailableLocales()));
538     }catch(Exception e){
539       //something happened; most probably guk not present.
540       //just drop it, is not vital.
541     }
542     try{
543       //add the MPI IMs
544       //if this fails mpi IM is not present
545       Class.forName("mpi.alt.java.awt.im.spi.lookup.LookupDescriptor");
546 
547       installedLocales.addAll(Arrays.asList(
548             new mpi.alt.java.awt.im.spi.lookup.LookupDescriptor().
549             getAvailableLocales()));
550     }catch(Exception e){
551       //something happened; most probably MPI not present.
552       //just drop it, is not vital.
553     }
554 
555     Collections.sort(installedLocales, new Comparator(){
556       public int compare(Object o1, Object o2){
557         return ((Locale)o1).getDisplayName().compareTo(((Locale)o2).getDisplayName());
558       }
559     });
560     JMenuItem item;
561     if(!installedLocales.isEmpty()){
562       imMenu = new XJMenu("Input methods");
563       ButtonGroup bg = new ButtonGroup();
564       item = new LocaleSelectorMenuItem();
565       imMenu.add(item);
566       item.setSelected(true);
567       imMenu.addSeparator();
568       bg.add(item);
569       for(int i = 0; i < installedLocales.size(); i++){
570         Locale locale = (Locale)installedLocales.get(i);
571         item = new LocaleSelectorMenuItem(locale);
572         imMenu.add(item);
573         bg.add(item);
574       }
575     }
576     if(imMenu != null) optionsMenu.add(imMenu);
577 
578     menuBar.add(optionsMenu);
579 
580     JMenu toolsMenu = new XJMenu("Tools");
581     toolsMenu.add(new NewAnnotDiffAction());
582 //    toolsMenu.add(newCorpusAnnotDiffAction);
583     toolsMenu.add(new NewBootStrapAction());
584     //temporarily disabled till the evaluation tools are made to run within
585     //the GUI
586     JMenu corpusEvalMenu = new JMenu("Corpus Benchmark Tools");
587     corpusEvalMenu.setIcon(getIcon("annDiff.gif"));
588     toolsMenu.add(corpusEvalMenu);
589     corpusEvalMenu.add(new NewCorpusEvalAction());
590     corpusEvalMenu.addSeparator();
591     corpusEvalMenu.add(new GenerateStoredCorpusEvalAction());
592     corpusEvalMenu.addSeparator();
593     corpusEvalMenu.add(new StoredMarkedCorpusEvalAction());
594     corpusEvalMenu.add(new CleanMarkedCorpusEvalAction());
595     corpusEvalMenu.addSeparator();
596     verboseModeItem =
597       new JCheckBoxMenuItem(new VerboseModeCorpusEvalToolAction());
598     corpusEvalMenu.add(verboseModeItem);
599 //    JCheckBoxMenuItem datastoreModeItem =
600 //      new JCheckBoxMenuItem(datastoreModeCorpusEvalToolAction);
601 //    corpusEvalMenu.add(datastoreModeItem);
602     toolsMenu.add(
603       new AbstractAction("Unicode editor", getIcon("unicode.gif")){
604       public void actionPerformed(ActionEvent evt){
605         new guk.Editor();
606       }
607     });
608 
609     /*add the ontology editor to the tools menu
610     ontotext.bp */
611     //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
612     //Removed as it is now obsolete.
613 //    toolsMenu.add(new NewOntologyEditorAction());
614 
615     if(Gate.isEnableJapeDebug()) {
616       // by Shafirin Andrey start
617       toolsMenu.add(
618           new AbstractAction("JAPE Debugger", getIcon("application.gif")) {
619         public void actionPerformed(ActionEvent evt) {
620           System.out.println("Creating Jape Debugger");
621           new debugger.JapeDebugger();
622         }
623       });
624       // by Shafirin Andrey end
625     }
626 
627     menuBar.add(toolsMenu);
628 
629     JMenu helpMenu = new JMenu("Help");
630 //    helpMenu.add(new HelpUserGuideAction());
631     helpMenu.add(new HelpAboutAction());
632     menuBar.add(helpMenu);
633 
634     this.setJMenuBar(menuBar);
635 
636     //popups
637     appsPopup = new XJPopupMenu();
638     LiveMenu appsMenu = new LiveMenu(LiveMenu.APP);
639     appsMenu.setText("New");
640     appsPopup.add(appsMenu);
641     appsPopup.addSeparator();
642     appsPopup.add(new XJMenuItem(new LoadResourceFromFileAction(), this));
643     guiRoots.add(appsMenu);
644     guiRoots.add(appsPopup);
645 
646     lrsPopup = new XJPopupMenu();
647     LiveMenu lrsMenu = new LiveMenu(LiveMenu.LR);
648     lrsMenu.setText("New");
649     lrsPopup.add(lrsMenu);
650     guiRoots.add(lrsPopup);
651     guiRoots.add(lrsMenu);
652 
653     prsPopup = new XJPopupMenu();
654     LiveMenu prsMenu = new LiveMenu(LiveMenu.PR);
655     prsMenu.setText("New");
656     prsPopup.add(prsMenu);
657     guiRoots.add(prsMenu);
658     guiRoots.add(prsPopup);
659 
660     dssPopup = new XJPopupMenu();
661     dssPopup.add(new NewDSAction());
662     dssPopup.add(new OpenDSAction());
663     guiRoots.add(dssPopup);
664 
665     //TOOLBAR
666     toolbar = new JToolBar(JToolBar.HORIZONTAL);
667     toolbar.setFloatable(false);
668     toolbar.add(new LoadResourceFromFileAction());
669     JMenuBar smallMenuBar = new JMenuBar();
670     smallMenuBar.setBorderPainted(false);
671     smallMenuBar.setAlignmentY(JComponent.CENTER_ALIGNMENT);
672     JMenu annieMenu = new JMenu();
673     annieMenu.setIcon(getIcon("application.gif"));
674     annieMenu.setToolTipText("Load ANNIE System");
675     annieMenu.add(new LoadANNIEWithDefaultsAction());
676     annieMenu.add(new LoadANNIEWithoutDefaultsAction());
677     smallMenuBar.add(annieMenu);
678     toolbar.add(smallMenuBar);
679     toolbar.addSeparator();
680     smallMenuBar = new JMenuBar();
681     smallMenuBar.setBorderPainted(false);
682     smallMenuBar.setAlignmentY(JComponent.CENTER_ALIGNMENT);
683     LiveMenu tbNewLRMenu = new LiveMenu(LiveMenu.LR);
684     tbNewLRMenu.setToolTipText("New Language Resource");
685     tbNewLRMenu.setIcon(getIcon("lrs.gif"));
686     smallMenuBar.add(tbNewLRMenu);
687     toolbar.add(smallMenuBar);
688 
689     smallMenuBar = new JMenuBar();
690     smallMenuBar.setBorderPainted(false);
691     smallMenuBar.setAlignmentY(JComponent.CENTER_ALIGNMENT);
692     LiveMenu tbNewPRMenu = new LiveMenu(LiveMenu.PR);
693     tbNewPRMenu.setToolTipText("New Processing Resource");
694     tbNewPRMenu.setIcon(getIcon("prs.gif"));
695     smallMenuBar.add(tbNewPRMenu);
696     toolbar.add(smallMenuBar);
697 
698     smallMenuBar = new JMenuBar();
699     smallMenuBar.setBorderPainted(false);
700     smallMenuBar.setAlignmentY(JComponent.CENTER_ALIGNMENT);
701     LiveMenu tbNewAppMenu = new LiveMenu(LiveMenu.APP);
702     tbNewAppMenu.setToolTipText("New Application");
703     tbNewAppMenu.setIcon(getIcon("applications.gif"));
704     smallMenuBar.add(tbNewAppMenu);
705     toolbar.add(smallMenuBar);
706 
707     smallMenuBar = new JMenuBar();
708     smallMenuBar.setBorderPainted(false);
709     smallMenuBar.setAlignmentY(JComponent.CENTER_ALIGNMENT);
710     JMenu tbDsMenu = new JMenu();
711     tbDsMenu.setToolTipText("Datastores");
712     tbDsMenu.setIcon(getIcon("dss.gif"));
713     tbDsMenu.add(new NewDSAction());
714     tbDsMenu.add(new OpenDSAction());
715     smallMenuBar.add(tbDsMenu);
716     toolbar.add(smallMenuBar);
717 
718     toolbar.addSeparator();
719     toolbar.add(new ManagePluginsAction());
720     toolbar.addSeparator();
721     toolbar.add(new NewAnnotDiffAction());
722 
723     toolbar.add(Box.createGlue());
724     this.getContentPane().add(toolbar, BorderLayout.NORTH);
725   }
726 
727   protected void initListeners(boolean isShellSlacGIU){
728     Gate.getCreoleRegister().addCreoleListener(this);
729 
730     resourcesTree.addMouseListener(new MouseAdapter() {
731       public void mouseClicked(MouseEvent e) {
732         //where inside the tree?
733         int x = e.getX();
734         int y = e.getY();
735         TreePath path = resourcesTree.getPathForLocation(x, y);
736         JPopupMenu popup = null;
737         Handle handle = null;
738         if(path != null){
739           Object value = path.getLastPathComponent();
740           if(value == resourcesTreeRoot){
741           } else if(value == applicationsRoot){
742             popup = appsPopup;
743           } else if(value == languageResourcesRoot){
744             popup = lrsPopup;
745           } else if(value == processingResourcesRoot){
746             popup = prsPopup;
747           } else if(value == datastoresRoot){
748             popup = dssPopup;
749           }else{
750             value = ((DefaultMutableTreeNode)value).getUserObject();
751             if(value instanceof Handle){
752               handle = (Handle)value;
753               popup = handle.getPopup();
754             }
755           }
756         }
757         if (SwingUtilities.isRightMouseButton(e)) {
758           if(resourcesTree.getSelectionCount() > 1){
759             //multiple selection in tree-> show a popup for delete all
760             popup = new XJPopupMenu();
761             popup.add(new XJMenuItem(new CloseSelectedResourcesAction(),
762                       MainFrame.this));
763             popup.show(resourcesTree, e.getX(), e.getY());
764           }else if(popup != null){
765             if(handle != null){
766 //              // Create a CloseViewAction and a menu item based on it
767 //              CloseViewAction cva = new CloseViewAction(handle);
768 //              XJMenuItem menuItem = new XJMenuItem(cva, MainFrame.this);
769 //              popup.insert(menuItem, 1);
770 
771               //add a rename action
772               popup.insert(new JPopupMenu.Separator(), 2);
773               popup.insert(new XJMenuItem(new RenameResourceAction(path),
774                                           MainFrame.this), 3);
775 
776               // Put the action command in the component's action map
777 //              if (handle.getLargeView() != null){
778 //                handle.getLargeView().getActionMap().
779 //                                      put("Hide current view",cva);
780 //              }
781             }
782 
783 
784             popup.show(resourcesTree, e.getX(), e.getY());
785           }
786         } else if(SwingUtilities.isLeftMouseButton(e)) {
787           if(e.getClickCount() == 2 && handle != null) {
788             //double click - show the resource
789             select(handle);
790           }
791         }
792       }
793 
794       public void mousePressed(MouseEvent e) {
795       }
796 
797       public void mouseReleased(MouseEvent e) {
798       }
799 
800       public void mouseEntered(MouseEvent e) {
801       }
802 
803       public void mouseExited(MouseEvent e) {
804       }
805     });
806 
807     // Add the keyboard listeners for CTRL+F4 and ALT+F4
808     this.addKeyListener(new KeyAdapter() {
809       public void keyTyped(KeyEvent e) {
810       }
811 
812       public void keyPressed(KeyEvent e) {
813         // If Ctrl+F4 was pressed then close the active resource
814         if (e.isControlDown() && e.getKeyCode()==KeyEvent.VK_F4){
815           JComponent resource = (JComponent)
816                                         mainTabbedPane.getSelectedComponent();
817           if (resource != null){
818             Action act = resource.getActionMap().get("Close resource");
819             if (act != null)
820               act.actionPerformed(null);
821           }// End if
822         }// End if
823         // If CTRL+H was pressed then hide the active view.
824         if (e.isControlDown() && e.getKeyCode()==KeyEvent.VK_H){
825           JComponent resource = (JComponent)
826                                         mainTabbedPane.getSelectedComponent();
827           if (resource != null){
828             Action act = resource.getActionMap().get("Hide current view");
829             if (act != null)
830               act.actionPerformed(null);
831           }// End if
832         }// End if
833         // If CTRL+X was pressed then save as XML
834         if (e.isControlDown() && e.getKeyCode()==KeyEvent.VK_X){
835           JComponent resource = (JComponent)
836                                         mainTabbedPane.getSelectedComponent();
837           if (resource != null){
838             Action act = resource.getActionMap().get("Save As XML");
839             if (act != null)
840               act.actionPerformed(null);
841           }// End if
842         }// End if
843       }// End keyPressed();
844 
845       public void keyReleased(KeyEvent e) {
846       }
847     });
848 
849     mainTabbedPane.getModel().addChangeListener(new ChangeListener() {
850       public void stateChanged(ChangeEvent e) {
851         //use this to synchronise the selection in the tabbed pane with the one
852         //in the resources tree
853         JComponent largeView = (JComponent)mainTabbedPane.getSelectedComponent();
854         Enumeration nodesEnum = resourcesTreeRoot.preorderEnumeration();
855         boolean done = false;
856         DefaultMutableTreeNode node = resourcesTreeRoot;
857         while(!done && nodesEnum.hasMoreElements()){
858           node = (DefaultMutableTreeNode)nodesEnum.nextElement();
859           done = node.getUserObject() instanceof Handle &&
860                  ((Handle)node.getUserObject()).viewsBuilt() &&
861                  ((Handle)node.getUserObject()).getLargeView() == largeView;
862         }
863         if(done){
864           Handle handle = (Handle)node.getUserObject();
865           TreePath nodePath = new TreePath(node.getPath());
866           resourcesTree.setSelectionPath(nodePath);
867           resourcesTree.scrollPathToVisible(nodePath);
868           lowerScroll.getViewport().setView(handle.getSmallView());
869         }else{
870           //the selected item is not a resource (maybe the log area?)
871           lowerScroll.getViewport().setView(null);
872         }
873       }
874     });
875 
876     mainTabbedPane.addMouseListener(new MouseAdapter() {
877       public void mouseClicked(MouseEvent e) {
878         if(SwingUtilities.isRightMouseButton(e)){
879           int index = mainTabbedPane.getIndexAt(e.getPoint());
880           if(index != -1){
881             JComponent view = (JComponent)mainTabbedPane.getComponentAt(index);
882             Enumeration nodesEnum = resourcesTreeRoot.preorderEnumeration();
883             boolean done = false;
884             DefaultMutableTreeNode node = resourcesTreeRoot;
885             while(!done && nodesEnum.hasMoreElements()){
886               node = (DefaultMutableTreeNode)nodesEnum.nextElement();
887               done = node.getUserObject() instanceof Handle &&
888                      ((Handle)node.getUserObject()).viewsBuilt() &&
889                      ((Handle)node.getUserObject()).getLargeView() == view;
890             }
891             if(done){
892               Handle handle = (Handle)node.getUserObject();
893               JPopupMenu popup = handle.getPopup();
894               // Create a CloseViewAction and a menu item based on it
895               CloseViewAction cva = new CloseViewAction(handle);
896               XJMenuItem menuItem = new XJMenuItem(cva, MainFrame.this);
897               popup.insert(menuItem, 1);
898               popup.insert(new JPopupMenu.Separator(), 2);
899               
900               popup.show(mainTabbedPane, e.getX(), e.getY());
901             }
902           }
903         }
904       }
905 
906       public void mousePressed(MouseEvent e) {
907       }
908 
909       public void mouseReleased(MouseEvent e) {
910       }
911 
912       public void mouseEntered(MouseEvent e) {
913       }
914 
915       public void mouseExited(MouseEvent e) {
916       }
917     });
918 
919     addComponentListener(new ComponentAdapter() {
920       public void componentHidden(ComponentEvent e) {
921 
922       }
923 
924       public void componentMoved(ComponentEvent e) {
925       }
926 
927       public void componentResized(ComponentEvent e) {
928       }
929 
930       public void componentShown(ComponentEvent e) {
931         leftSplit.setDividerLocation((double)0.7);
932       }
933     });
934 
935     if(isShellSlacGIU) {
936       mainSplit.setDividerSize(0);
937       mainSplit.getTopComponent().setVisible(false);
938       mainSplit.getTopComponent().addComponentListener(new ComponentAdapter() {
939         public void componentHidden(ComponentEvent e) {
940         }
941         public void componentMoved(ComponentEvent e) {
942           mainSplit.setDividerLocation(0);
943         }
944         public void componentResized(ComponentEvent e) {
945           mainSplit.setDividerLocation(0);
946         }
947         public void componentShown(ComponentEvent e) {
948           mainSplit.setDividerLocation(0);
949         }
950       });
951     } // if
952 
953     //blink the messages tab when new information is displayed
954     logArea.getDocument().addDocumentListener(new javax.swing.event.DocumentListener(){
955       public void insertUpdate(javax.swing.event.DocumentEvent e){
956         changeOccured();
957       }
958       public void removeUpdate(javax.swing.event.DocumentEvent e){
959         changeOccured();
960       }
961       public void changedUpdate(javax.swing.event.DocumentEvent e){
962         changeOccured();
963       }
964       protected void changeOccured(){
965         logHighlighter.highlight();
966       }
967     });
968 
969     logArea.addPropertyChangeListener("document", new PropertyChangeListener(){
970       public void propertyChange(PropertyChangeEvent evt){
971         //add the document listener
972         logArea.getDocument().addDocumentListener(new javax.swing.event.DocumentListener(){
973           public void insertUpdate(javax.swing.event.DocumentEvent e){
974             changeOccured();
975           }
976           public void removeUpdate(javax.swing.event.DocumentEvent e){
977             changeOccured();
978           }
979           public void changedUpdate(javax.swing.event.DocumentEvent e){
980             changeOccured();
981           }
982           protected void changeOccured(){
983             logHighlighter.highlight();
984           }
985         });
986       }
987     });
988 
989 
990    listeners.put("gate.event.StatusListener", MainFrame.this);
991    listeners.put("gate.event.ProgressListener", MainFrame.this);
992    if(System.getProperty("mrj.version") != null) {
993      // mac-specific initialisation
994      initMacListeners();
995    }
996   }//protected void initListeners()
997 
998   /**
999    * Set up the handlers to support the Macintosh Application menu.  This makes
1000   * the About, Quit and Preferences menu items map to their equivalents in
1001   * GATE.  If an exception occurs during this process we print a warning.
1002   */
1003  protected void initMacListeners() {
1004    // What this method effectively does is:
1005    // 
1006    // com.apple.eawt.Application app = Application.getApplication();
1007    // app.addApplicationListener(new ApplicationAdapter() {
1008    //   public void handleAbout(ApplicationEvent e) {
1009    //     e.setHandled(true);
1010    //     new HelpAboutAction().actionPerformed(null);
1011    //   }
1012    //   public void handleQuit(ApplicationEvent e) {
1013    //     e.setHandled(false);
1014    //     new ExitGateAction().actionPerformed(null);
1015    //   }
1016    //   public void handlePreferences(ApplicationEvent e) {
1017    //     e.setHandled(true);
1018    //     optionsDialog.show();
1019    //   }
1020    // });
1021    // 
1022    // app.setEnabledPreferencesMenu(true);
1023    //
1024    // except that it does it all by reflection so as not to compile-time
1025    // depend on Apple classes.
1026    try {
1027      // load the Apple classes
1028      final Class eawtApplicationClass =
1029        Gate.getClassLoader().loadClass("com.apple.eawt.Application");
1030      final Class eawtApplicationListenerInterface =
1031        Gate.getClassLoader().loadClass("com.apple.eawt.ApplicationListener");
1032      final Class eawtApplicationEventClass =
1033        Gate.getClassLoader().loadClass("com.apple.eawt.ApplicationEvent");
1034
1035      // method used in the InvocationHandler
1036      final Method appEventSetHandledMethod =
1037        eawtApplicationEventClass.getMethod("setHandled",
1038                                            new Class[] {boolean.class});
1039
1040      // Invocation handler used to process Apple application events
1041      InvocationHandler handler = new InvocationHandler() {
1042        private Action aboutAction = new HelpAboutAction();
1043        private Action exitAction = new ExitGateAction();
1044
1045        public Object invoke(Object proxy, Method method,
1046                             Object[] args) throws Throwable {
1047          Object appEvent = args[0];
1048          if("handleAbout".equals(method.getName())) {
1049            appEventSetHandledMethod.invoke(appEvent,
1050                                            new Object[] {Boolean.TRUE});
1051            aboutAction.actionPerformed(null);
1052          }
1053          else if("handleQuit".equals(method.getName())) {
1054            appEventSetHandledMethod.invoke(appEvent,
1055                                            new Object[] {Boolean.FALSE});
1056            exitAction.actionPerformed(null);
1057          }
1058          else if("handlePreferences".equals(method.getName())) {
1059            appEventSetHandledMethod.invoke(appEvent,
1060                                            new Object[] {Boolean.TRUE});
1061            optionsDialog.show();
1062          }
1063
1064          return null;
1065        }
1066      };
1067
1068      // Create an ApplicationListener proxy instance
1069      Object applicationListenerObject = Proxy.newProxyInstance(
1070        Gate.getClassLoader(), new Class[] {eawtApplicationListenerInterface},
1071        handler);
1072
1073      // get hold of the Application object
1074      Method getApplicationMethod = eawtApplicationClass.getMethod(
1075        "getApplication", new Class[0]);
1076      Object applicationObject =
1077        getApplicationMethod.invoke(null, new Object[0]);
1078
1079      // enable the preferences menu item
1080      Method setEnabledPreferencesMenuMethod = eawtApplicationClass.getMethod(
1081        "setEnabledPreferencesMenu", new Class[] {boolean.class});
1082      setEnabledPreferencesMenuMethod.invoke(applicationObject,
1083        new Object[] {Boolean.TRUE});
1084
1085      // Register our proxy instance as an ApplicationListener
1086      Method addApplicationListenerMethod = eawtApplicationClass.getMethod(
1087        "addApplicationListener",
1088        new Class[] {eawtApplicationListenerInterface});
1089      addApplicationListenerMethod.invoke(applicationObject,
1090        new Object[] {applicationListenerObject});
1091    }
1092    catch(Throwable t) {
1093      // oh well, we tried
1094      System.out.println("Warning: there was a problem setting up the Mac "
1095        + "application\nmenu.  Your options/session will not be saved if "
1096        + "you exit\nwith command-Q, use \"File/Exit GATE\" instead");
1097    }
1098  }
1099
1100  public void progressChanged(int i) {
1101    //progressBar.setStringPainted(true);
1102    int oldValue = progressBar.getValue();
1103//    if((!stopAction.isEnabled()) &&
1104//       (Gate.getExecutable() != null)){
1105//      stopAction.setEnabled(true);
1106//      SwingUtilities.invokeLater(new Runnable(){
1107//        public void run(){
1108//          southBox.add(stopBtn, 0);
1109//        }
1110//      });
1111//    }
1112    if(!animator.isActive()) animator.activate();
1113    if(oldValue != i){
1114      SwingUtilities.invokeLater(new ProgressBarUpdater(i));
1115    }
1116  }
1117
1118  /**
1119   * Called when the process is finished.
1120   *
1121   */
1122  public void processFinished() {
1123    //progressBar.setStringPainted(false);
1124//    if(stopAction.isEnabled()){
1125//      stopAction.setEnabled(false);
1126//      SwingUtilities.invokeLater(new Runnable(){
1127//        public void run(){
1128//          southBox.remove(stopBtn);
1129//        }
1130//      });
1131//    }
1132    SwingUtilities.invokeLater(new ProgressBarUpdater(0));
1133    animator.deactivate();
1134  }
1135
1136  public void statusChanged(String text) {
1137    SwingUtilities.invokeLater(new StatusBarUpdater(text));
1138  }
1139
1140  public void resourceLoaded(CreoleEvent e) {
1141    Resource res = e.getResource();
1142    if(Gate.getHiddenAttribute(res.getFeatures()) ||
1143            res instanceof VisualResource) return;
1144    NameBearerHandle handle = new NameBearerHandle(res, MainFrame.this);
1145    DefaultMutableTreeNode node = new DefaultMutableTreeNode(handle, false);
1146    if(res instanceof ProcessingResource){
1147      resourcesTreeModel.insertNodeInto(node, processingResourcesRoot, 0);
1148    }else if(res instanceof LanguageResource){
1149      resourcesTreeModel.insertNodeInto(node, languageResourcesRoot, 0);
1150    }else if(res instanceof Controller){
1151      resourcesTreeModel.insertNodeInto(node, applicationsRoot, 0);
1152    }
1153
1154    handle.addProgressListener(MainFrame.this);
1155    handle.addStatusListener(MainFrame.this);
1156
1157//    JPopupMenu popup = handle.getPopup();
1158//
1159//    // Create a CloseViewAction and a menu item based on it
1160//    CloseViewAction cva = new CloseViewAction(handle);
1161//    XJMenuItem menuItem = new XJMenuItem(cva, this);
1162//    // Add an accelerator ATL+F4 for this action
1163//    menuItem.setAccelerator(KeyStroke.getKeyStroke(
1164//                                      KeyEvent.VK_H, ActionEvent.CTRL_MASK));
1165//    popup.insert(menuItem, 1);
1166//    popup.insert(new JPopupMenu.Separator(), 2);
1167//
1168//    popup.insert(new XJMenuItem(
1169//                  new RenameResourceAction(
1170//                      new TreePath(resourcesTreeModel.getPathToRoot(node))),
1171//                  MainFrame.this) , 3);
1172//
1173//    // Put the action command in the component's action map
1174//    if (handle.getLargeView() != null)
1175//      handle.getLargeView().getActionMap().put("Hide current view",cva);
1176//
1177  }// resourceLoaded();
1178
1179
1180  public void resourceUnloaded(CreoleEvent e) {
1181    final Resource res = e.getResource();
1182    if(Gate.getHiddenAttribute(res.getFeatures())) return;
1183    Runnable runner = new Runnable(){
1184      public void run(){
1185        DefaultMutableTreeNode node;
1186        DefaultMutableTreeNode parent = null;
1187        if(res instanceof ProcessingResource){
1188          parent = processingResourcesRoot;
1189        }else if(res instanceof LanguageResource){
1190          parent = languageResourcesRoot;
1191        }else if(res instanceof Controller){
1192          parent = applicationsRoot;
1193        }
1194        if(parent != null){
1195          Enumeration children = parent.children();
1196          while(children.hasMoreElements()){
1197            node = (DefaultMutableTreeNode)children.nextElement();
1198            if(((NameBearerHandle)node.getUserObject()).getTarget() == res){
1199              resourcesTreeModel.removeNodeFromParent(node);
1200              Handle handle = (Handle)node.getUserObject();
1201              if(handle.viewsBuilt()){
1202                if(mainTabbedPane.indexOfComponent(handle.getLargeView()) != -1)
1203                  mainTabbedPane.remove(handle.getLargeView());
1204                if(lowerScroll.getViewport().getView() == handle.getSmallView())
1205                  lowerScroll.getViewport().setView(null);
1206              }
1207              handle.cleanup();
1208              return;
1209            }
1210          }
1211        }
1212      }
1213    };
1214    SwingUtilities.invokeLater(runner);
1215  }
1216
1217  /**Called when a {@link gate.DataStore} has been opened*/
1218  public void datastoreOpened(CreoleEvent e){
1219    DataStore ds = e.getDatastore();
1220
1221    ds.setName(ds.getStorageUrl());
1222
1223    NameBearerHandle handle = new NameBearerHandle(ds, MainFrame.this);
1224    DefaultMutableTreeNode node = new DefaultMutableTreeNode(handle, false);
1225    resourcesTreeModel.insertNodeInto(node, datastoresRoot, 0);
1226    handle.addProgressListener(MainFrame.this);
1227    handle.addStatusListener(MainFrame.this);
1228
1229//    JPopupMenu popup = handle.getPopup();
1230//    popup.addSeparator();
1231//    // Create a CloseViewAction and a menu item based on it
1232//    CloseViewAction cva = new CloseViewAction(handle);
1233//    XJMenuItem menuItem = new XJMenuItem(cva, this);
1234//    // Add an accelerator ATL+F4 for this action
1235//    menuItem.setAccelerator(KeyStroke.getKeyStroke(
1236//                                      KeyEvent.VK_H, ActionEvent.CTRL_MASK));
1237//    popup.add(menuItem);
1238//    // Put the action command in the component's action map
1239//    if (handle.getLargeView() != null)
1240//      handle.getLargeView().getActionMap().put("Hide current view",cva);
1241  }// datastoreOpened();
1242
1243  /**Called when a {@link gate.DataStore} has been created*/
1244  public void datastoreCreated(CreoleEvent e){
1245    datastoreOpened(e);
1246  }
1247
1248  /**Called when a {@link gate.DataStore} has been closed*/
1249  public void datastoreClosed(CreoleEvent e){
1250    DataStore ds = e.getDatastore();
1251    DefaultMutableTreeNode node;
1252    DefaultMutableTreeNode parent = datastoresRoot;
1253    if(parent != null){
1254      Enumeration children = parent.children();
1255      while(children.hasMoreElements()){
1256        node = (DefaultMutableTreeNode)children.nextElement();
1257        if(((NameBearerHandle)node.getUserObject()).
1258            getTarget() == ds){
1259          resourcesTreeModel.removeNodeFromParent(node);
1260          NameBearerHandle handle = (NameBearerHandle)
1261                                          node.getUserObject();
1262          
1263          if(handle.viewsBuilt() && 
1264             mainTabbedPane.indexOfComponent(handle.getLargeView()) != -1){
1265            mainTabbedPane.remove(handle.getLargeView());
1266          }
1267          if(lowerScroll.getViewport().getView() == handle.getSmallView()){
1268            lowerScroll.getViewport().setView(null);
1269          }
1270          return;
1271        }
1272      }
1273    }
1274  }
1275
1276  public void resourceRenamed(Resource resource, String oldName,
1277                              String newName){
1278    for(int i = 0; i < mainTabbedPane.getTabCount(); i++){
1279      if(mainTabbedPane.getTitleAt(i).equals(oldName)){
1280        mainTabbedPane.setTitleAt(i, newName);
1281
1282        return;
1283      }
1284    }
1285  }
1286
1287  /**
1288   * Overridden so we can exit when window is closed
1289   */
1290  protected void processWindowEvent(WindowEvent e) {
1291    if (e.getID() == WindowEvent.WINDOW_CLOSING) {
1292      new ExitGateAction().actionPerformed(null);
1293    }
1294    super.processWindowEvent(e);
1295  }// processWindowEvent(WindowEvent e)
1296
1297  /**
1298   * Returns the listeners map, a map that holds all the listeners that are
1299   * singletons (e.g. the status listener that updates the status bar on the
1300   * main frame or the progress listener that updates the progress bar on the
1301   * main frame).
1302   * The keys used are the class names of the listener interface and the values
1303   * are the actual listeners (e.g "gate.event.StatusListener" -> this).
1304   * The returned map is the actual data member used to store the listeners so
1305   * any changes in this map will be visible to everyone.
1306   */
1307  public static java.util.Map getListeners() {
1308    return listeners;
1309  }
1310
1311  public static java.util.Collection getGuiRoots() {
1312    return guiRoots;
1313  }
1314
1315  /**
1316   * This method will lock all input to the gui by means of a modal dialog.
1317   * If Gate is not currently running in GUI mode this call will be ignored.
1318   * A call to this method while the GUI is locked will cause the GUI to be
1319   * unlocked and then locked again with the new message.
1320   * If a message is provided it will show in the dialog.
1321   * @param message the message to be displayed while the GUI is locked
1322   */
1323  public synchronized static void lockGUI(final String message){
1324    //check whether GUI is up
1325    if(getGuiRoots() == null || getGuiRoots().isEmpty()) return;
1326    //if the GUI is locked unlock it so we can show the new message
1327    unlockGUI();
1328
1329    //build the dialog contents
1330    Object[] options = new Object[]{new JButton(new StopAction())};
1331    JOptionPane pane = new JOptionPane(message, JOptionPane.WARNING_MESSAGE,
1332                                       JOptionPane.DEFAULT_OPTION,
1333                                       null, options, null);
1334
1335    //build the dialog
1336    Component parentComp = (Component)((ArrayList)getGuiRoots()).get(0);
1337    JDialog dialog;
1338    Window parentWindow;
1339    if(parentComp instanceof Window) parentWindow = (Window)parentComp;
1340    else parentWindow = SwingUtilities.getWindowAncestor(parentComp);
1341    if(parentWindow instanceof Frame){
1342      dialog = new JDialog((Frame)parentWindow, "Please wait", true){
1343        protected void processWindowEvent(WindowEvent e) {
1344          if (e.getID() == WindowEvent.WINDOW_CLOSING) {
1345            getToolkit().beep();
1346          }
1347        }
1348      };
1349    }else if(parentWindow instanceof Dialog){
1350      dialog = new JDialog((Dialog)parentWindow, "Please wait", true){
1351        protected void processWindowEvent(WindowEvent e) {
1352          if (e.getID() == WindowEvent.WINDOW_CLOSING) {
1353            getToolkit().beep();
1354          }
1355        }
1356      };
1357    }else{
1358      dialog = new JDialog(JOptionPane.getRootFrame(), "Please wait", true){
1359        protected void processWindowEvent(WindowEvent e) {
1360          if (e.getID() == WindowEvent.WINDOW_CLOSING) {
1361            getToolkit().beep();
1362          }
1363        }
1364      };
1365    }
1366    dialog.getContentPane().setLayout(new BorderLayout());
1367    dialog.getContentPane().add(pane, BorderLayout.CENTER);
1368    dialog.pack();
1369    dialog.setLocationRelativeTo(parentComp);
1370    dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
1371    guiLock = dialog;
1372
1373    //this call needs to return so we'll show the dialog from a different thread
1374    //the Swing thread sounds good for that
1375    SwingUtilities.invokeLater(new Runnable(){
1376      public void run(){
1377        guiLock.setVisible(true);
1378      }
1379    });
1380
1381    //this call should not return until the dialog is up to ensure proper
1382    //sequentiality for lock - unlock calls
1383    while(!guiLock.isShowing()){
1384      try{
1385        Thread.sleep(100);
1386      }catch(InterruptedException ie){}
1387    }
1388  }
1389
1390  public synchronized static void unlockGUI(){
1391    //check whether GUI is up
1392    if(getGuiRoots() == null || getGuiRoots().isEmpty()) return;
1393
1394    if(guiLock != null){
1395      guiLock.setVisible(false);
1396      //completely dispose the dialog (causes it to dissapear even if
1397      //displayed on a non-visible virtual display on Linux)
1398      //fix for bug 1369096 
1399      //(http://sourceforge.net/tracker/index.php?func=detail&aid=1369096&group_id=143829&atid=756796)
1400      guiLock.dispose();
1401    }
1402    guiLock = null;
1403  }
1404
1405  /** Flag to protect Frame title to be changed */
1406  private boolean titleChangable = false;
1407
1408  public void setTitleChangable(boolean isChangable) {
1409    titleChangable = isChangable;
1410  } // setTitleChangable(boolean isChangable)
1411
1412  /** Override to avoid Protege to change Frame title */
1413  public synchronized void setTitle(String title) {
1414    if(titleChangable) {
1415      super.setTitle(title);
1416    } // if
1417  } // setTitle(String title)
1418
1419
1420
1421  /** Method is used in NewDSAction */
1422  protected DataStore createSerialDataStore() {
1423    DataStore ds = null;
1424
1425    //get the URL (a file in this case)
1426    fileChooser.setDialogTitle("Please create a new empty directory");
1427    fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
1428    if(fileChooser.showOpenDialog(MainFrame.this) ==
1429                                          JFileChooser.APPROVE_OPTION){
1430      try {
1431        URL dsURL = fileChooser.getSelectedFile().toURL();
1432        ds = Factory.createDataStore("gate.persist.SerialDataStore",
1433                                               dsURL.toExternalForm());
1434      } catch(MalformedURLException mue) {
1435        JOptionPane.showMessageDialog(
1436            MainFrame.this, "Invalid location for the datastore\n " +
1437                              mue.toString(),
1438                              "GATE", JOptionPane.ERROR_MESSAGE);
1439      } catch(PersistenceException pe) {
1440        JOptionPane.showMessageDialog(
1441            MainFrame.this, "Datastore creation error!\n " +
1442                              pe.toString(),
1443                              "GATE", JOptionPane.ERROR_MESSAGE);
1444      } // catch
1445    } // if
1446
1447    return ds;
1448  } // createSerialDataStore()
1449
1450  /** Method is used in OpenDSAction */
1451  protected DataStore openSerialDataStore() {
1452    DataStore ds = null;
1453
1454    //get the URL (a file in this case)
1455    fileChooser.setDialogTitle("Select the datastore directory");
1456    fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
1457    if (fileChooser.showOpenDialog(MainFrame.this) ==
1458                                          JFileChooser.APPROVE_OPTION){
1459      try {
1460        URL dsURL = fileChooser.getSelectedFile().toURL();
1461        ds = Factory.openDataStore("gate.persist.SerialDataStore",
1462                                             dsURL.toExternalForm());
1463      } catch(MalformedURLException mue) {
1464        JOptionPane.showMessageDialog(
1465            MainFrame.this, "Invalid location for the datastore\n " +
1466                              mue.toString(),
1467                              "GATE", JOptionPane.ERROR_MESSAGE);
1468      } catch(PersistenceException pe) {
1469        JOptionPane.showMessageDialog(
1470            MainFrame.this, "Datastore opening error!\n " +
1471                              pe.toString(),
1472                              "GATE", JOptionPane.ERROR_MESSAGE);
1473      } // catch
1474    } // if
1475
1476    return ds;
1477  } // openSerialDataStore()
1478
1479
1480/*
1481  synchronized void showWaitDialog() {
1482    Point location = getLocationOnScreen();
1483    location.translate(10,
1484              getHeight() - waitDialog.getHeight() - southBox.getHeight() - 10);
1485    waitDialog.setLocation(location);
1486    waitDialog.showDialog(new Component[]{});
1487  }
1488
1489  synchronized void  hideWaitDialog() {
1490    waitDialog.goAway();
1491  }
1492*/
1493
1494/*
1495  class NewProjectAction extends AbstractAction {
1496    public NewProjectAction(){
1497      super("New Project", new ImageIcon(MainFrame.class.getResource(
1498                                        "/gate/resources/img/newProject.gif")));
1499      putValue(SHORT_DESCRIPTION,"Create a new project");
1500    }
1501    public void actionPerformed(ActionEvent e){
1502      fileChooser.setDialogTitle("Select new project file");
1503      fileChooser.setFileSelectionMode(fileChooser.FILES_ONLY);
1504      if(fileChooser.showOpenDialog(parentFrame) == fileChooser.APPROVE_OPTION){
1505        ProjectData pData = new ProjectData(fileChooser.getSelectedFile(),
1506                                                                  parentFrame);
1507        addProject(pData);
1508      }
1509    }
1510  }
1511*/
1512
1513  /** This class represent an action which brings up the Annot Diff tool*/
1514  class NewAnnotDiffAction extends AbstractAction {
1515    public NewAnnotDiffAction() {
1516      super("Annotation Diff", getIcon("annDiff.gif"));
1517      putValue(SHORT_DESCRIPTION,"Open a new Annotation Diff window");
1518    }// NewAnnotDiffAction
1519    public void actionPerformed(ActionEvent e) {
1520//      AnnotDiffDialog annotDiffDialog = new AnnotDiffDialog(MainFrame.this);
1521//      annotDiffDialog.setTitle("Annotation Diff Tool");
1522//      annotDiffDialog.setVisible(true);
1523      AnnotationDiffGUI frame = new AnnotationDiffGUI("Annotation Diff Tool");
1524      frame.pack();
1525      frame.setIconImage(((ImageIcon)getIcon("annDiff.gif")).getImage());
1526      frame.setLocationRelativeTo(MainFrame.this);
1527      frame.setVisible(true);
1528    }// actionPerformed();
1529  }//class NewAnnotDiffAction
1530
1531  /** This class represent an action which brings up the Corpus Annot Diff tool*/
1532  class NewCorpusAnnotDiffAction extends AbstractAction {
1533    public NewCorpusAnnotDiffAction() {
1534      super("Corpus Annotation Diff", getIcon("annDiff.gif"));
1535      putValue(SHORT_DESCRIPTION,"Create a new Corpus Annotation Diff Tool");
1536    }// NewCorpusAnnotDiffAction
1537    public void actionPerformed(ActionEvent e) {
1538      CorpusAnnotDiffDialog annotDiffDialog =
1539        new CorpusAnnotDiffDialog(MainFrame.this);
1540      annotDiffDialog.setTitle("Corpus Annotation Diff Tool");
1541      annotDiffDialog.setVisible(true);
1542    }// actionPerformed();
1543  }//class NewCorpusAnnotDiffAction
1544
1545  /** This class represent an action which brings up the corpus evaluation tool*/
1546  class NewCorpusEvalAction extends AbstractAction {
1547    public NewCorpusEvalAction() {
1548      super("Default mode");
1549      putValue(SHORT_DESCRIPTION,"Run the Benchmark Tool in its default mode");
1550    }// newCorpusEvalAction
1551
1552    public void actionPerformed(ActionEvent e) {
1553      Runnable runnable = new Runnable(){
1554        public void run(){
1555          JFileChooser chooser = MainFrame.getFileChooser();
1556          chooser.setDialogTitle("Please select a directory which contains " +
1557                                 "the documents to be evaluated");
1558          chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
1559          chooser.setMultiSelectionEnabled(false);
1560          int state = chooser.showOpenDialog(MainFrame.this);
1561          File startDir = chooser.getSelectedFile();
1562          if (state == JFileChooser.CANCEL_OPTION || startDir == null)
1563            return;
1564
1565          chooser.setDialogTitle("Please select the application that you want to run");
1566          chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
1567          state = chooser.showOpenDialog(MainFrame.this);
1568          File testApp = chooser.getSelectedFile();
1569          if (state == JFileChooser.CANCEL_OPTION || startDir == null)
1570            return;
1571
1572          //first create the tool and set its parameters
1573          CorpusBenchmarkTool theTool = new CorpusBenchmarkTool();
1574          theTool.setStartDirectory(startDir);
1575          theTool.setApplicationFile(testApp);
1576          theTool.setVerboseMode(verboseModeItem.isSelected());
1577
1578          Out.prln("Please wait while GATE tools are initialised.");
1579          //initialise the tool
1580          theTool.init();
1581          //and execute it
1582          theTool.execute();
1583          theTool.printStatistics();
1584
1585          Out.prln("<BR>Overall average precision: " + theTool.getPrecisionAverage());
1586          Out.prln("<BR>Overall average recall: " + theTool.getRecallAverage());
1587          Out.prln("<BR>Overall average fMeasure : "+theTool.getFMeasureAverage());
1588          Out.prln("<BR>Finished!");
1589          theTool.unloadPRs();
1590        }
1591      };
1592      Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
1593                                 runnable, "Eval thread");
1594      thread.setPriority(Thread.MIN_PRIORITY);
1595      thread.start();
1596    }// actionPerformed();
1597  }//class NewCorpusEvalAction
1598
1599  /** This class represent an action which brings up the corpus evaluation tool*/
1600  class StoredMarkedCorpusEvalAction extends AbstractAction {
1601    public StoredMarkedCorpusEvalAction() {
1602      super("Human marked against stored processing results");
1603      putValue(SHORT_DESCRIPTION,"Run the Benchmark Tool -stored_clean");
1604    }// newCorpusEvalAction
1605
1606    public void actionPerformed(ActionEvent e) {
1607      Runnable runnable = new Runnable(){
1608        public void run(){
1609          JFileChooser chooser = MainFrame.getFileChooser();
1610          chooser.setDialogTitle("Please select a directory which contains " +
1611                                 "the documents to be evaluated");
1612          chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
1613          chooser.setMultiSelectionEnabled(false);
1614          int state = chooser.showOpenDialog(MainFrame.this);
1615          File startDir = chooser.getSelectedFile();
1616          if (state == JFileChooser.CANCEL_OPTION || startDir == null)
1617            return;
1618
1619          //first create the tool and set its parameters
1620          CorpusBenchmarkTool theTool = new CorpusBenchmarkTool();
1621          theTool.setStartDirectory(startDir);
1622          theTool.setMarkedStored(true);
1623          theTool.setVerboseMode(verboseModeItem.isSelected());
1624//          theTool.setMarkedDS(
1625//            MainFrame.this.datastoreModeCorpusEvalToolAction.isDatastoreMode());
1626
1627
1628          Out.prln("Evaluating human-marked documents against pre-stored results.");
1629          //initialise the tool
1630          theTool.init();
1631          //and execute it
1632          theTool.execute();
1633          theTool.printStatistics();
1634
1635          Out.prln("<BR>Overall average precision: " + theTool.getPrecisionAverage());
1636          Out.prln("<BR>Overall average recall: " + theTool.getRecallAverage());
1637          Out.prln("<BR>Overall average fMeasure : "+theTool.getFMeasureAverage());
1638          Out.prln("<BR>Finished!");
1639          theTool.unloadPRs();
1640        }
1641      };
1642      Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
1643                                 runnable, "Eval thread");
1644      thread.setPriority(Thread.MIN_PRIORITY);
1645      thread.start();
1646    }// actionPerformed();
1647  }//class StoredMarkedCorpusEvalActionpusEvalAction
1648
1649  /** This class represent an action which brings up the corpus evaluation tool*/
1650  class CleanMarkedCorpusEvalAction extends AbstractAction {
1651    public CleanMarkedCorpusEvalAction() {
1652      super("Human marked against current processing results");
1653      putValue(SHORT_DESCRIPTION,"Run the Benchmark Tool -marked_clean");
1654    }// newCorpusEvalAction
1655
1656    public void actionPerformed(ActionEvent e) {
1657      Runnable runnable = new Runnable(){
1658        public void run(){
1659          JFileChooser chooser = MainFrame.getFileChooser();
1660          chooser.setDialogTitle("Please select a directory which contains " +
1661                                 "the documents to be evaluated");
1662          chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
1663          chooser.setMultiSelectionEnabled(false);
1664          int state = chooser.showOpenDialog(MainFrame.this);
1665          File startDir = chooser.getSelectedFile();
1666          if (state == JFileChooser.CANCEL_OPTION || startDir == null)
1667            return;
1668
1669          chooser.setDialogTitle("Please select the application that you want to run");
1670          chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
1671          state = chooser.showOpenDialog(MainFrame.this);
1672          File testApp = chooser.getSelectedFile();
1673          if (state == JFileChooser.CANCEL_OPTION || startDir == null)
1674            return;
1675
1676          //first create the tool and set its parameters
1677          CorpusBenchmarkTool theTool = new CorpusBenchmarkTool();
1678          theTool.setStartDirectory(startDir);
1679          theTool.setApplicationFile(testApp);
1680          theTool.setMarkedClean(true);
1681          theTool.setVerboseMode(verboseModeItem.isSelected());
1682
1683          Out.prln("Evaluating human-marked documents against current processing results.");
1684          //initialise the tool
1685          theTool.init();
1686          //and execute it
1687          theTool.execute();
1688          theTool.printStatistics();
1689
1690          Out.prln("Overall average precision: " + theTool.getPrecisionAverage());
1691          Out.prln("Overall average recall: " + theTool.getRecallAverage());
1692          Out.prln("Overall average fMeasure : "+theTool.getFMeasureAverage());
1693          Out.prln("Finished!");
1694          theTool.unloadPRs();
1695        }
1696      };
1697      Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
1698                                 runnable, "Eval thread");
1699      thread.setPriority(Thread.MIN_PRIORITY);
1700      thread.start();
1701    }// actionPerformed();
1702  }//class CleanMarkedCorpusEvalActionpusEvalAction
1703
1704
1705  /** This class represent an action which brings up the corpus evaluation tool*/
1706  class GenerateStoredCorpusEvalAction extends AbstractAction {
1707    public GenerateStoredCorpusEvalAction() {
1708      super("Store corpus for future evaluation");
1709      putValue(SHORT_DESCRIPTION,"Run the Benchmark Tool -generate");
1710    }// newCorpusEvalAction
1711
1712    public void actionPerformed(ActionEvent e) {
1713      Runnable runnable = new Runnable(){
1714        public void run(){
1715          JFileChooser chooser = MainFrame.getFileChooser();
1716          chooser.setDialogTitle("Please select a directory which contains " +
1717                                 "the documents to be evaluated");
1718          chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
1719          chooser.setMultiSelectionEnabled(false);
1720          int state = chooser.showOpenDialog(MainFrame.this);
1721          File startDir = chooser.getSelectedFile();
1722          if (state == JFileChooser.CANCEL_OPTION || startDir == null)
1723            return;
1724
1725          chooser.setDialogTitle("Please select the application that you want to run");
1726          chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
1727          state = chooser.showOpenDialog(MainFrame.this);
1728          File testApp = chooser.getSelectedFile();
1729          if (state == JFileChooser.CANCEL_OPTION || startDir == null)
1730            return;
1731
1732          //first create the tool and set its parameters
1733          CorpusBenchmarkTool theTool = new CorpusBenchmarkTool();
1734          theTool.setStartDirectory(startDir);
1735          theTool.setApplicationFile(testApp);
1736          theTool.setGenerateMode(true);
1737
1738          Out.prln("Processing and storing documents for future evaluation.");
1739          //initialise the tool
1740          theTool.init();
1741          //and execute it
1742          theTool.execute();
1743          theTool.unloadPRs();
1744          Out.prln("Finished!");
1745        }
1746      };
1747      Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
1748                                 runnable, "Eval thread");
1749      thread.setPriority(Thread.MIN_PRIORITY);
1750      thread.start();
1751    }// actionPerformed();
1752  }//class GenerateStoredCorpusEvalAction
1753
1754  /** This class represent an action which brings up the corpus evaluation tool*/
1755  class VerboseModeCorpusEvalToolAction extends AbstractAction  {
1756    public VerboseModeCorpusEvalToolAction() {
1757      super("Verbose mode");
1758      putValue(SHORT_DESCRIPTION,"Run the Benchmark Tool in verbose mode");
1759    }// VerboseModeCorpusEvalToolAction
1760
1761    public boolean isVerboseMode() {return verboseMode;}
1762
1763    public void actionPerformed(ActionEvent e) {
1764      if (! (e.getSource() instanceof JCheckBoxMenuItem))
1765        return;
1766      verboseMode = ((JCheckBoxMenuItem)e.getSource()).getState();
1767    }// actionPerformed();
1768    protected boolean verboseMode = false;
1769  }//class f
1770
1771  /** This class represent an action which brings up the corpus evaluation tool*/
1772/*
1773  class DatastoreModeCorpusEvalToolAction extends AbstractAction  {
1774    public DatastoreModeCorpusEvalToolAction() {
1775      super("Use a datastore for human annotated texts");
1776      putValue(SHORT_DESCRIPTION,"Use a datastore for the human annotated texts");
1777    }// DatastoreModeCorpusEvalToolAction
1778
1779    public boolean isDatastoreMode() {return datastoreMode;}
1780
1781    public void actionPerformed(ActionEvent e) {
1782      if (! (e.getSource() instanceof JCheckBoxMenuItem))
1783        return;
1784      datastoreMode = ((JCheckBoxMenuItem)e.getSource()).getState();
1785    }// actionPerformed();
1786    protected boolean datastoreMode = false;
1787  }//class DatastoreModeCorpusEvalToolListener
1788*/
1789
1790  /** This class represent an action which loads ANNIE with default params*/
1791  class LoadANNIEWithDefaultsAction extends AbstractAction
1792                                    implements ANNIEConstants{
1793    public LoadANNIEWithDefaultsAction() {
1794      super("With defaults");
1795      putValue(SHORT_DESCRIPTION, "Load ANNIE system using defaults");
1796      putValue(SMALL_ICON, getIcon("application.gif"));
1797    }// NewAnnotDiffAction
1798    public void actionPerformed(ActionEvent e) {
1799      // Loads ANNIE with defaults
1800      Runnable runnable = new Runnable(){
1801        public void run(){
1802          long startTime = System.currentTimeMillis();
1803          FeatureMap params = Factory.newFeatureMap();
1804          try{
1805            //lock the gui
1806            lockGUI("ANNIE is being loaded...");
1807            // Create a serial analyser
1808            SerialAnalyserController sac = (SerialAnalyserController)
1809                Factory.createResource("gate.creole.SerialAnalyserController",
1810                                       Factory.newFeatureMap(),
1811                                       Factory.newFeatureMap(),
1812                                       "ANNIE_" + Gate.genSym());
1813            // Load each PR as defined in gate.creole.ANNIEConstants.PR_NAMES
1814            for(int i = 0; i < PR_NAMES.length; i++){
1815            ProcessingResource pr = (ProcessingResource)
1816                Factory.createResource(PR_NAMES[i], params);
1817              // Add the PR to the sac
1818              sac.add(pr);
1819            }// End for
1820
1821            long endTime = System.currentTimeMillis();
1822            statusChanged("ANNIE loaded in " +
1823                NumberFormat.getInstance().format(
1824                (double)(endTime - startTime) / 1000) + " seconds");
1825          }catch(gate.creole.ResourceInstantiationException ex){
1826            ex.printStackTrace(Err.getPrintWriter());
1827          }finally{
1828            unlockGUI();
1829          }
1830        }// run()
1831      };// End Runnable
1832      Thread thread = new Thread(runnable, "");
1833      thread.setPriority(Thread.MIN_PRIORITY);
1834      thread.start();
1835    }// actionPerformed();
1836  }//class LoadANNIEWithDefaultsAction
1837
1838  /** This class represent an action which loads ANNIE with default params*/
1839  class LoadANNIEWithoutDefaultsAction extends AbstractAction
1840                                    implements ANNIEConstants{
1841    public LoadANNIEWithoutDefaultsAction() {
1842      super("Without defaults");
1843      putValue(SHORT_DESCRIPTION, "Load ANNIE system without defaults");
1844      putValue(SMALL_ICON, getIcon("application.gif"));
1845    }// NewAnnotDiffAction
1846    public void actionPerformed(ActionEvent e) {
1847      // Loads ANNIE with defaults
1848      Runnable runnable = new Runnable(){
1849        public void run(){
1850          FeatureMap params = Factory.newFeatureMap();
1851          try{
1852            // Create a serial analyser
1853            SerialAnalyserController sac = (SerialAnalyserController)
1854                Factory.createResource("gate.creole.SerialAnalyserController",
1855                                       Factory.newFeatureMap(),
1856                                       Factory.newFeatureMap(),
1857                                       "ANNIE_" + Gate.genSym());
1858//            NewResourceDialog resourceDialog = new NewResourceDialog(
1859//                                  MainFrame.this, "Resource parameters", true );
1860            // Load each PR as defined in gate.creole.ANNIEConstants.PR_NAMES
1861            for(int i = 0; i < PR_NAMES.length; i++){
1862              //get the params for the Current PR
1863              ResourceData resData = (ResourceData)Gate.getCreoleRegister().
1864                                      get(PR_NAMES[i]);
1865              if(newResourceDialog.show(resData,
1866                                     "Parameters for the new " +
1867                                     resData.getName())){
1868                sac.add((ProcessingResource)Factory.createResource(
1869                          PR_NAMES[i],
1870                          newResourceDialog.getSelectedParameters()));
1871              }else{
1872                //the user got bored and aborted the operation
1873                statusChanged("Loading cancelled! Removing traces...");
1874                Iterator loadedPRsIter = new ArrayList(sac.getPRs()).iterator();
1875                while(loadedPRsIter.hasNext()){
1876                  Factory.deleteResource((ProcessingResource)
1877                                         loadedPRsIter.next());
1878                }
1879                Factory.deleteResource(sac);
1880                statusChanged("Loading cancelled!");
1881                return;
1882              }
1883            }// End for
1884            statusChanged("ANNIE loaded!");
1885          }catch(gate.creole.ResourceInstantiationException ex){
1886            ex.printStackTrace(Err.getPrintWriter());
1887          }// End try
1888        }// run()
1889      };// End Runnable
1890      SwingUtilities.invokeLater(runnable);
1891//      Thread thread = new Thread(runnable, "");
1892//      thread.setPriority(Thread.MIN_PRIORITY);
1893//      thread.start();
1894    }// actionPerformed();
1895  }//class LoadANNIEWithoutDefaultsAction
1896
1897  /** This class represent an action which loads ANNIE without default param*/
1898  class LoadANNIEWithoutDefaultsAction1 extends AbstractAction
1899                                       implements ANNIEConstants {
1900    public LoadANNIEWithoutDefaultsAction1() {
1901      super("Without defaults");
1902    }// NewAnnotDiffAction
1903    public void actionPerformed(ActionEvent e) {
1904      //Load ANNIE without defaults
1905      CreoleRegister reg = Gate.getCreoleRegister();
1906      // Load each PR as defined in gate.creole.ANNIEConstants.PR_NAMES
1907      for(int i = 0; i < PR_NAMES.length; i++){
1908        ResourceData resData = (ResourceData)reg.get(PR_NAMES[i]);
1909        if (resData != null){
1910          NewResourceDialog resourceDialog = new NewResourceDialog(
1911              MainFrame.this, "Resource parameters", true );
1912          resourceDialog.setTitle(
1913                            "Parameters for the new " + resData.getName());
1914          resourceDialog.show(resData);
1915        }else{
1916          Err.prln(PR_NAMES[i] + " not found in Creole register");
1917        }// End if
1918      }// End for
1919      try{
1920        // Create an application at the end.
1921        Factory.createResource("gate.creole.SerialAnalyserController",
1922                               Factory.newFeatureMap(), Factory.newFeatureMap(),
1923                               "ANNIE_" + Gate.genSym());
1924      }catch(gate.creole.ResourceInstantiationException ex){
1925        ex.printStackTrace(Err.getPrintWriter());
1926      }// End try
1927    }// actionPerformed();
1928  }//class LoadANNIEWithoutDefaultsAction
1929
1930  class NewBootStrapAction extends AbstractAction {
1931    public NewBootStrapAction() {
1932      super("BootStrap Wizard", getIcon("application.gif"));
1933    }// NewBootStrapAction
1934    public void actionPerformed(ActionEvent e) {
1935      BootStrapDialog bootStrapDialog = new BootStrapDialog(MainFrame.this);
1936      bootStrapDialog.setVisible(true);
1937    }// actionPerformed();
1938  }//class NewBootStrapAction
1939
1940
1941  class ManagePluginsAction extends AbstractAction {
1942    public ManagePluginsAction(){
1943      super("Manage CREOLE plugins");
1944      putValue(SHORT_DESCRIPTION,"Manage CREOLE plugins");
1945      putValue(SMALL_ICON, getIcon("param.gif"));
1946    }
1947
1948    public void actionPerformed(ActionEvent e) {
1949      if(pluginManager == null){
1950        pluginManager = new PluginManagerUI(MainFrame.this);
1951//        pluginManager.setLocationRelativeTo(MainFrame.this);
1952        pluginManager.setModal(true);
1953        getGuiRoots().add(pluginManager);
1954        pluginManager.pack();
1955        //size the window so that it doesn't go off-screen
1956        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
1957        Dimension dialogSize = pluginManager.getPreferredSize();
1958        int width = dialogSize.width > screenSize.width ?
1959                screenSize.width * 3 /4 :
1960                dialogSize.width;
1961        int height = dialogSize.height > screenSize.height ?
1962                screenSize.height * 3 /4 :
1963                dialogSize.height;
1964        pluginManager.setSize(width, height);
1965        pluginManager.validate();
1966        //center the window on screen
1967        int x = (screenSize.width - width)/2;
1968        int y = (screenSize.height - height)/2;
1969        pluginManager.setLocation(x, y);
1970      }
1971      pluginManager.setVisible(true);
1972    }
1973  }
1974
1975
1976  class LoadCreoleRepositoryAction extends AbstractAction {
1977    public LoadCreoleRepositoryAction(){
1978      super("Load a CREOLE repository");
1979      putValue(SHORT_DESCRIPTION,"Load a CREOLE repository");
1980    }
1981
1982    public void actionPerformed(ActionEvent e) {
1983      Box messageBox = Box.createHorizontalBox();
1984      Box leftBox = Box.createVerticalBox();
1985      JTextField urlTextField = new JTextField(20);
1986      leftBox.add(new JLabel("Type an URL"));
1987      leftBox.add(urlTextField);
1988      messageBox.add(leftBox);
1989
1990      messageBox.add(Box.createHorizontalStrut(10));
1991      messageBox.add(new JLabel("or"));
1992      messageBox.add(Box.createHorizontalStrut(10));
1993
1994      class URLfromFileAction extends AbstractAction{
1995        URLfromFileAction(JTextField textField){
1996          super(null, getIcon("loadFile.gif"));
1997          putValue(SHORT_DESCRIPTION,"Click to select a directory");
1998          this.textField = textField;
1999        }
2000
2001        public void actionPerformed(ActionEvent e){
2002          fileChooser.setMultiSelectionEnabled(false);
2003          fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
2004          fileChooser.setFileFilter(fileChooser.getAcceptAllFileFilter());
2005          int result = fileChooser.showOpenDialog(MainFrame.this);
2006          if(result == JFileChooser.APPROVE_OPTION){
2007            try{
2008              textField.setText(fileChooser.getSelectedFile().
2009                                            toURL().toExternalForm());
2010            }catch(MalformedURLException mue){
2011              throw new GateRuntimeException(mue.toString());
2012            }
2013          }
2014        }
2015        JTextField textField;
2016      };//class URLfromFileAction extends AbstractAction
2017
2018      Box rightBox = Box.createVerticalBox();
2019      rightBox.add(new JLabel("Select a directory"));
2020      JButton fileBtn = new JButton(new URLfromFileAction(urlTextField));
2021      rightBox.add(fileBtn);
2022      messageBox.add(rightBox);
2023
2024
2025//JOptionPane.showInputDialog(
2026//                            MainFrame.this,
2027//                            "Select type of Datastore",
2028//                            "Gate", JOptionPane.QUESTION_MESSAGE,
2029//                            null, names,
2030//                            names[0]);
2031
2032      int res = JOptionPane.showConfirmDialog(
2033                            MainFrame.this, messageBox,
2034                            "Enter an URL to the directory containig the " +
2035                            "\"creole.xml\" file", JOptionPane.OK_CANCEL_OPTION,
2036                            JOptionPane.QUESTION_MESSAGE, null);
2037      if(res == JOptionPane.OK_OPTION){
2038        try{
2039          URL creoleURL = new URL(urlTextField.getText());
2040          Gate.getCreoleRegister().registerDirectories(creoleURL);
2041        }catch(Exception ex){
2042          JOptionPane.showMessageDialog(
2043              MainFrame.this,
2044              "There was a problem with your selection:\n" +
2045              ex.toString() ,
2046              "GATE", JOptionPane.ERROR_MESSAGE);
2047          ex.printStackTrace(Err.getPrintWriter());
2048        }
2049      }
2050    }
2051  }//class LoadCreoleRepositoryAction extends AbstractAction
2052
2053
2054  class NewResourceAction extends AbstractAction {
2055    /** Used for creation of resource menu item and creation dialog */
2056    ResourceData rData;
2057
2058    public NewResourceAction(ResourceData rData) {
2059      super(rData.getName());
2060      putValue(SHORT_DESCRIPTION, rData.getComment());
2061      this.rData = rData;
2062    } // NewResourceAction(ResourceData rData)
2063
2064    public void actionPerformed(ActionEvent evt) {
2065      Runnable runnable = new Runnable(){
2066        public void run(){
2067          newResourceDialog.setTitle(
2068                              "Parameters for the new " + rData.getName());
2069          newResourceDialog.show(rData);
2070        }
2071      };
2072      SwingUtilities.invokeLater(runnable);
2073    } // actionPerformed
2074  } // class NewResourceAction extends AbstractAction
2075
2076
2077  static class StopAction extends AbstractAction {
2078    public StopAction(){
2079      super(" Stop! ");
2080      putValue(SHORT_DESCRIPTION,"Stops the current action");
2081    }
2082
2083    public boolean isEnabled(){
2084      return Gate.getExecutable() != null;
2085    }
2086
2087    public void actionPerformed(ActionEvent e) {
2088      Executable ex = Gate.getExecutable();
2089      if(ex != null) ex.interrupt();
2090    }
2091  }
2092
2093
2094  class NewDSAction extends AbstractAction {
2095    public NewDSAction(){
2096      super("Create datastore");
2097      putValue(SHORT_DESCRIPTION,"Create a new Datastore");
2098      putValue(SMALL_ICON, getIcon("ds.gif"));
2099    }
2100
2101    public void actionPerformed(ActionEvent e) {
2102      DataStoreRegister reg = Gate.getDataStoreRegister();
2103      Map dsTypes = DataStoreRegister.getDataStoreClassNames();
2104      HashMap dsTypeByName = new HashMap();
2105      Iterator dsTypesIter = dsTypes.entrySet().iterator();
2106      while(dsTypesIter.hasNext()){
2107        Map.Entry entry = (Map.Entry)dsTypesIter.next();
2108        dsTypeByName.put(entry.getValue(), entry.getKey());
2109      }
2110
2111      if(!dsTypeByName.isEmpty()) {
2112        Object[] names = dsTypeByName.keySet().toArray();
2113        Object answer = JOptionPane.showInputDialog(
2114                            MainFrame.this,
2115                            "Select type of Datastore",
2116                            "GATE", JOptionPane.QUESTION_MESSAGE,
2117                            null, names,
2118                            names[0]);
2119        if(answer != null) {
2120          String className = (String)dsTypeByName.get(answer);
2121          if(className.equals("gate.persist.SerialDataStore")){
2122            createSerialDataStore();
2123          } else if(className.equals("gate.persist.OracleDataStore")) {
2124              JOptionPane.showMessageDialog(
2125                    MainFrame.this, "Oracle datastores can only be created " +
2126                                    "by your Oracle administrator!",
2127                                    "GATE", JOptionPane.ERROR_MESSAGE);
2128          }  else {
2129
2130            throw new UnsupportedOperationException("Unimplemented option!\n"+
2131                                                    "Use a serial datastore");
2132          }
2133        }
2134      } else {
2135        //no ds types
2136        JOptionPane.showMessageDialog(MainFrame.this,
2137                                      "Could not find any registered types " +
2138                                      "of datastores...\n" +
2139                                      "Check your GATE installation!",
2140                                      "GATE", JOptionPane.ERROR_MESSAGE);
2141
2142      }
2143    }
2144  }//class NewDSAction extends AbstractAction
2145
2146  class LoadResourceFromFileAction extends AbstractAction {
2147    public LoadResourceFromFileAction(){
2148      super("Restore application from file");
2149      putValue(SHORT_DESCRIPTION,"Restores a previously saved application");
2150      putValue(SMALL_ICON, getIcon("controller.gif"));
2151    }
2152
2153    public void actionPerformed(ActionEvent e) {
2154      Runnable runnable = new Runnable(){
2155        public void run(){
2156          fileChooser.setDialogTitle("Select a file for this resource");
2157          fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
2158          if (fileChooser.showOpenDialog(MainFrame.this) ==
2159                                                JFileChooser.APPROVE_OPTION){
2160            File file = fileChooser.getSelectedFile();
2161            try{
2162              gate.util.persistence.PersistenceManager.loadObjectFromFile(file);
2163            }catch(ResourceInstantiationException rie){
2164              processFinished();
2165              JOptionPane.showMessageDialog(MainFrame.this,
2166                              "Error!\n"+
2167                               rie.toString(),
2168                               "GATE", JOptionPane.ERROR_MESSAGE);
2169              rie.printStackTrace(Err.getPrintWriter());
2170            }catch(Exception ex){
2171              processFinished();
2172              JOptionPane.showMessageDialog(MainFrame.this,
2173                              "Error!\n"+
2174                               ex.toString(),
2175                               "GATE", JOptionPane.ERROR_MESSAGE);
2176              ex.printStackTrace(Err.getPrintWriter());
2177            }
2178          }
2179        }
2180      };
2181      Thread thread = new Thread(runnable);
2182      thread.setPriority(Thread.MIN_PRIORITY);
2183      thread.start();
2184    }
2185  }
2186
2187  /**
2188   * Closes the view associated to a resource.
2189   * Does not remove the resource from the system, only its view.
2190   */
2191  class CloseViewAction extends AbstractAction {
2192    public CloseViewAction(Handle handle) {
2193      super("Hide this view");
2194      putValue(SHORT_DESCRIPTION, "Hides this view");
2195      this.handle = handle;
2196    }
2197
2198    public void actionPerformed(ActionEvent e) {
2199      mainTabbedPane.remove(handle.getLargeView());
2200      mainTabbedPane.setSelectedIndex(mainTabbedPane.getTabCount() - 1);
2201    }//public void actionPerformed(ActionEvent e)
2202    Handle handle;
2203  }//class CloseViewAction
2204
2205  class RenameResourceAction extends AbstractAction{
2206    RenameResourceAction(TreePath path){
2207      super("Rename");
2208      putValue(SHORT_DESCRIPTION, "Renames the resource");
2209      this.path = path;
2210    }
2211    public void actionPerformed(ActionEvent e) {
2212      resourcesTree.startEditingAtPath(path);
2213    }
2214
2215    TreePath path;
2216  }
2217
2218  class CloseSelectedResourcesAction extends AbstractAction {
2219    public CloseSelectedResourcesAction() {
2220      super("Close all");
2221      putValue(SHORT_DESCRIPTION, "Closes the selected resources");
2222    }
2223
2224    public void actionPerformed(ActionEvent e) {
2225      Runnable runner = new Runnable(){
2226        public void run(){
2227          TreePath[] paths = resourcesTree.getSelectionPaths();
2228          for(int i = 0; i < paths.length; i++){
2229            Object userObject = ((DefaultMutableTreeNode)paths[i].
2230                                getLastPathComponent()).getUserObject();
2231            if(userObject instanceof NameBearerHandle){
2232              ((NameBearerHandle)userObject).getCloseAction().actionPerformed(null);
2233            }
2234          }
2235        }
2236      };
2237      Thread thread = new Thread(runner);
2238      thread.setPriority(Thread.MIN_PRIORITY);
2239      thread.start();
2240    }
2241  }
2242
2243
2244  /**
2245   * Closes the view associated to a resource.
2246   * Does not remove the resource from the system, only its view.
2247   */
2248  class ExitGateAction extends AbstractAction {
2249    public ExitGateAction() {
2250      super("Exit GATE");
2251      putValue(SHORT_DESCRIPTION, "Closes the application");
2252      putValue(SMALL_ICON, getIcon("exit.gif"));
2253    }
2254
2255    public void actionPerformed(ActionEvent e) {
2256      Runnable runnable = new Runnable(){
2257        public void run(){
2258          //save the options
2259          OptionsMap userConfig = Gate.getUserConfig();
2260          if(userConfig.getBoolean(GateConstants.SAVE_OPTIONS_ON_EXIT).
2261             booleanValue()){
2262            //save the window size
2263            Integer width = new Integer(MainFrame.this.getWidth());
2264            Integer height = new Integer(MainFrame.this.getHeight());
2265            userConfig.put(GateConstants.MAIN_FRAME_WIDTH, width);
2266            userConfig.put(GateConstants.MAIN_FRAME_HEIGHT, height);
2267            try {
2268              File lastCurrentDirectory = fileChooser.getCurrentDirectory();
2269              userConfig.put(GateConstants.LAST_FILECHOOSER_LOCATION,
2270                      lastCurrentDirectory == null ? "" : 
2271                      lastCurrentDirectory.getCanonicalPath());
2272            }catch(IOException ioe) {
2273              //ignore
2274            }
2275            try{
2276              Gate.writeUserConfig();
2277            }catch(GateException ge){
2278              logArea.getOriginalErr().println("Failed to save config data:");
2279              ge.printStackTrace(logArea.getOriginalErr());
2280            }
2281          }else{
2282            //don't save options on close
2283            //save the option not to save the options
2284            OptionsMap originalUserConfig = Gate.getOriginalUserConfig();
2285            originalUserConfig.put(GateConstants.SAVE_OPTIONS_ON_EXIT,
2286                                   new Boolean(false));
2287            userConfig.clear();
2288            userConfig.putAll(originalUserConfig);
2289            try{
2290              Gate.writeUserConfig();
2291            }catch(GateException ge){
2292              logArea.getOriginalErr().println("Failed to save config data:");
2293              ge.printStackTrace(logArea.getOriginalErr());
2294            }
2295          }
2296
2297          //save the session;
2298          File sessionFile = new File(Gate.getUserSessionFileName());
2299          if(userConfig.getBoolean(GateConstants.SAVE_SESSION_ON_EXIT).
2300             booleanValue()){
2301            //save all the open applications
2302            try{
2303              ArrayList appList = new ArrayList(Gate.getCreoleRegister().
2304                                  getAllInstances("gate.Controller"));
2305              //remove all hidden instances
2306              Iterator appIter = appList.iterator();
2307              while(appIter.hasNext())
2308                if(Gate.getHiddenAttribute(((Controller)appIter.next()).
2309                   getFeatures())) appIter.remove();
2310
2311
2312              gate.util.persistence.PersistenceManager.
2313                                    saveObjectToFile(appList, sessionFile);
2314            }catch(Exception ex){
2315              logArea.getOriginalErr().println("Failed to save session data:");
2316              ex.printStackTrace(logArea.getOriginalErr());
2317            }
2318          }else{
2319            //we don't want to save the session
2320            if(sessionFile.exists()) sessionFile.delete();
2321          }
2322          setVisible(false);
2323          dispose();
2324          System.exit(0);
2325        }//run
2326      };//Runnable
2327      Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
2328                                 runnable, "Session loader");
2329      thread.setPriority(Thread.MIN_PRIORITY);
2330      thread.start();
2331    }
2332  }
2333
2334
2335  class OpenDSAction extends AbstractAction {
2336    public OpenDSAction() {
2337      super("Open datastore");
2338      putValue(SHORT_DESCRIPTION,"Open a datastore");
2339      putValue(SMALL_ICON, getIcon("ds.gif"));
2340    }
2341
2342    public void actionPerformed(ActionEvent e) {
2343      DataStoreRegister reg = Gate.getDataStoreRegister();
2344      Map dsTypes = DataStoreRegister.getDataStoreClassNames();
2345      HashMap dsTypeByName = new HashMap();
2346      Iterator dsTypesIter = dsTypes.entrySet().iterator();
2347      while(dsTypesIter.hasNext()){
2348        Map.Entry entry = (Map.Entry)dsTypesIter.next();
2349        dsTypeByName.put(entry.getValue(), entry.getKey());
2350      }
2351
2352      if(!dsTypeByName.isEmpty()) {
2353        Object[] names = dsTypeByName.keySet().toArray();
2354        Object answer = JOptionPane.showInputDialog(
2355                            MainFrame.this,
2356                            "Select type of Datastore",
2357                            "GATE", JOptionPane.QUESTION_MESSAGE,
2358                            null, names,
2359                            names[0]);
2360        if(answer != null) {
2361          String className = (String)dsTypeByName.get(answer);
2362          if(className.indexOf("SerialDataStore") != -1){
2363            openSerialDataStore();
2364          } else if(className.equals("gate.persist.OracleDataStore") ||
2365                    className.equals("gate.persist.PostgresDataStore")
2366                   ) {
2367              List dbPaths = new ArrayList();
2368              Iterator keyIter = DataStoreRegister.getConfigData().keySet().iterator();
2369              while (keyIter.hasNext()) {
2370                String keyName = (String) keyIter.next();
2371                if (keyName.startsWith("url"))
2372                  dbPaths.add(DataStoreRegister.getConfigData().get(keyName));
2373              }
2374              if (dbPaths.isEmpty())
2375                throw new
2376                  GateRuntimeException("JDBC URL not configured in gate.xml");
2377              //by default make it the first
2378              String storageURL = (String)dbPaths.get(0);
2379              if (dbPaths.size() > 1) {
2380                Object[] paths = dbPaths.toArray();
2381                answer = JOptionPane.showInputDialog(
2382                                    MainFrame.this,
2383                                    "Select a database",
2384                                    "GATE", JOptionPane.QUESTION_MESSAGE,
2385                                    null, paths,
2386                                    paths[0]);
2387                if (answer != null)
2388                  storageURL = (String) answer;
2389                else
2390                  return;
2391              }
2392              DataStore ds = null;
2393              AccessController ac = null;
2394              try {
2395                //1. login the user
2396//                ac = new AccessControllerImpl(storageURL);
2397                ac = Factory.createAccessController(storageURL);
2398                Assert.assertNotNull(ac);
2399                ac.open();
2400
2401                Session mySession = null;
2402                User usr = null;
2403                Group grp = null;
2404                try {
2405                  String userName = "";
2406                  String userPass = "";
2407                  String group = "";
2408
2409                  JPanel listPanel = new JPanel();
2410                  listPanel.setLayout(new BoxLayout(listPanel,BoxLayout.X_AXIS));
2411
2412                  JPanel panel1 = new JPanel();
2413                  panel1.setLayout(new BoxLayout(panel1,BoxLayout.Y_AXIS));
2414                  panel1.add(new JLabel("User name: "));
2415                  panel1.add(new JLabel("Password: "));
2416                  panel1.add(new JLabel("Group: "));
2417
2418                  JPanel panel2 = new JPanel();
2419                  panel2.setLayout(new BoxLayout(panel2,BoxLayout.Y_AXIS));
2420                  JTextField usrField = new JTextField(30);
2421                  panel2.add(usrField);
2422                  JPasswordField pwdField = new JPasswordField(30);
2423                  panel2.add(pwdField);
2424                  JComboBox grpField = new JComboBox(ac.listGroups().toArray());
2425                  grpField.setSelectedIndex(0);
2426                  panel2.add(grpField);
2427
2428                  listPanel.add(panel1);
2429                  listPanel.add(Box.createHorizontalStrut(20));
2430                  listPanel.add(panel2);
2431
2432                  if(OkCancelDialog.showDialog(MainFrame.this.getContentPane(),
2433                                                listPanel,
2434                                                "Please enter login details")){
2435
2436                    userName = usrField.getText();
2437                    userPass = new String(pwdField.getPassword());
2438                    group = (String) grpField.getSelectedItem();
2439
2440                    if(userName.equals("") || userPass.equals("") || group.equals("")) {
2441                      JOptionPane.showMessageDialog(
2442                        MainFrame.this,
2443                        "You must provide non-empty user name, password and group!",
2444                        "Login error",
2445                        JOptionPane.ERROR_MESSAGE
2446                        );
2447                      return;
2448                    }
2449                  }
2450                  else if(OkCancelDialog.userHasPressedCancel) {
2451                      return;
2452                  }
2453
2454                  grp = ac.findGroup(group);
2455                  usr = ac.findUser(userName);
2456                  mySession = ac.login(userName, userPass, grp.getID());
2457
2458                  //save here the user name, pass and group in local gate.xml
2459
2460                } catch (gate.security.SecurityException ex) {
2461                    JOptionPane.showMessageDialog(
2462                      MainFrame.this,
2463                      ex.getMessage(),
2464                      "Login error",
2465                      JOptionPane.ERROR_MESSAGE
2466                      );
2467                  ac.close();
2468                  return;
2469                }
2470
2471                if (! ac.isValidSession(mySession)){
2472                  JOptionPane.showMessageDialog(
2473                    MainFrame.this,
2474                    "Incorrect session obtained. "
2475                      + "Probably there is a problem with the database!",
2476                    "Login error",
2477                    JOptionPane.ERROR_MESSAGE
2478                    );
2479                  ac.close();
2480                  return;
2481                }
2482
2483                //2. open the oracle datastore
2484                ds = Factory.openDataStore(className, storageURL);
2485                //set the session, so all get/adopt/etc work
2486                ds.setSession(mySession);
2487
2488                //3. add the security data for this datastore
2489                //this saves the user and group information, so it can
2490                //be used later when resources are created with certain rights
2491                FeatureMap securityData = Factory.newFeatureMap();
2492                securityData.put("user", usr);
2493                securityData.put("group", grp);
2494                DataStoreRegister.addSecurityData(ds, securityData);
2495              } catch(PersistenceException pe) {
2496                JOptionPane.showMessageDialog(
2497                    MainFrame.this, "Datastore open error!\n " +
2498                                      pe.toString(),
2499                                      "GATE", JOptionPane.ERROR_MESSAGE);
2500              } catch(gate.security.SecurityException se) {
2501                JOptionPane.showMessageDialog(
2502                    MainFrame.this, "User identification error!\n " +
2503                                      se.toString(),
2504                                      "GATE", JOptionPane.ERROR_MESSAGE);
2505                try {
2506                  if (ac != null)
2507                    ac.close();
2508                  if (ds != null)
2509                    ds.close();
2510                } catch (gate.persist.PersistenceException ex) {
2511                  JOptionPane.showMessageDialog(
2512                      MainFrame.this, "Persistence error!\n " +
2513                                        ex.toString(),
2514                                        "GATE", JOptionPane.ERROR_MESSAGE);
2515                }
2516              }
2517
2518          }else{
2519            JOptionPane.showMessageDialog(
2520                MainFrame.this,
2521                "Support for this type of datastores is not implemenented!\n",
2522                "GATE", JOptionPane.ERROR_MESSAGE);
2523          }
2524        }
2525      } else {
2526        //no ds types
2527        JOptionPane.showMessageDialog(MainFrame.this,
2528                                      "Could not find any registered types " +
2529                                      "of datastores...\n" +
2530                                      "Check your GATE installation!",
2531                                      "GATE", JOptionPane.ERROR_MESSAGE);
2532
2533      }
2534    }
2535  }//class OpenDSAction extends AbstractAction
2536
2537  /**
2538   * A menu that self populates based on CREOLE register data before being
2539   * shown. Used for creating new resources of all possible types.
2540   */
2541  class LiveMenu extends XJMenu{
2542    public LiveMenu(int type){
2543      super();
2544      this.type = type;
2545      init();
2546    }
2547
2548
2549    protected void init(){
2550      addMenuListener(new MenuListener(){
2551        public void menuCanceled(MenuEvent e) {
2552        }
2553        public void menuDeselected(MenuEvent e) {
2554        }
2555        public void menuSelected(MenuEvent e) {
2556          removeAll();
2557          //find out the available types of LRs and repopulate the menu
2558          CreoleRegister reg = Gate.getCreoleRegister();
2559          List resTypes;
2560          switch (type){
2561            case LR:
2562              resTypes = reg.getPublicLrTypes();
2563              break;
2564            case PR:
2565              resTypes = reg.getPublicPrTypes();
2566              break;
2567            case APP:
2568              resTypes = reg.getPublicControllerTypes();
2569              break;
2570            default:
2571              throw new GateRuntimeException("Unknown LiveMenu type: " + type);
2572          }
2573
2574          if(resTypes != null && !resTypes.isEmpty()){
2575            HashMap resourcesByName = new HashMap();
2576            Iterator resIter = resTypes.iterator();
2577            while(resIter.hasNext()){
2578              ResourceData rData = (ResourceData)reg.get(resIter.next());
2579              resourcesByName.put(rData.getName(), rData);
2580            }
2581            List resNames = new ArrayList(resourcesByName.keySet());
2582            Collections.sort(resNames);
2583            resIter = resNames.iterator();
2584            while(resIter.hasNext()){
2585              ResourceData rData = (ResourceData)resourcesByName.
2586                                   get(resIter.next());
2587              add(new XJMenuItem(new NewResourceAction(rData),
2588                                           MainFrame.this));
2589            }
2590          }
2591        }
2592      });
2593    }
2594
2595    protected int type;
2596    /**
2597     * Switch for using LR data.
2598     */
2599    public static final int LR = 1;
2600
2601    /**
2602     * Switch for using PR data.
2603     */
2604    public static final int PR = 2;
2605
2606    /**
2607     * Switch for using Controller data.
2608     */
2609    public static final int APP = 3;
2610  }
2611
2612
2613  class HelpAboutAction extends AbstractAction {
2614    public HelpAboutAction(){
2615      super("About");
2616    }
2617
2618    public void actionPerformed(ActionEvent e) {
2619      splash.showSplash();
2620    }
2621  }
2622
2623  class HelpUserGuideAction extends AbstractAction {
2624    public HelpUserGuideAction(){
2625      super("User Guide");
2626      putValue(SHORT_DESCRIPTION, "This option needs an internet connection");
2627    }
2628
2629    public void actionPerformed(ActionEvent e) {
2630
2631      Runnable runnable = new Runnable(){
2632        public void run(){
2633          try{
2634            HelpFrame helpFrame = new HelpFrame();
2635            helpFrame.setPage(new URL("http://www.gate.ac.uk/sale/tao/index.html"));
2636            helpFrame.setSize(800, 600);
2637            //center on screen
2638            Dimension frameSize = helpFrame.getSize();
2639            Dimension ownerSize = Toolkit.getDefaultToolkit().getScreenSize();
2640            Point ownerLocation = new Point(0, 0);
2641            helpFrame.setLocation(
2642                      ownerLocation.x + (ownerSize.width - frameSize.width) / 2,
2643                      ownerLocation.y + (ownerSize.height - frameSize.height) / 2);
2644
2645            helpFrame.setVisible(true);
2646          }catch(IOException ioe){
2647            ioe.printStackTrace(Err.getPrintWriter());
2648          }
2649        }
2650      };
2651      Thread thread = new Thread(runnable);
2652      thread.start();
2653    }
2654  }
2655
2656  protected class ResourcesTreeCellRenderer extends DefaultTreeCellRenderer {
2657    public ResourcesTreeCellRenderer() {
2658      setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
2659    }
2660    public Component getTreeCellRendererComponent(JTree tree,
2661                                              Object value,
2662                                              boolean sel,
2663                                              boolean expanded,
2664                                              boolean leaf,
2665                                              int row,
2666                                              boolean hasFocus){
2667      super.getTreeCellRendererComponent(tree, value, sel, expanded,
2668                                         leaf, row, hasFocus);
2669      if(value == resourcesTreeRoot) {
2670        setIcon(MainFrame.getIcon("project.gif"));
2671        setToolTipText("GATE");
2672      } else if(value == applicationsRoot) {
2673        setIcon(MainFrame.getIcon("applications.gif"));
2674        setToolTipText("GATE applications");
2675      } else if(value == languageResourcesRoot) {
2676        setIcon(MainFrame.getIcon("lrs.gif"));
2677        setToolTipText("Language Resources");
2678      } else if(value == processingResourcesRoot) {
2679        setIcon(MainFrame.getIcon("prs.gif"));
2680        setToolTipText("Processing Resources");
2681      } else if(value == datastoresRoot) {
2682        setIcon(MainFrame.getIcon("dss.gif"));
2683        setToolTipText("GATE Datastores");
2684      }else{
2685        //not one of the default root nodes
2686        value = ((DefaultMutableTreeNode)value).getUserObject();
2687        if(value instanceof Handle) {
2688          setIcon(((Handle)value).getIcon());
2689          setText(((Handle)value).getTitle());
2690          setToolTipText(((Handle)value).getTooltipText());
2691        }
2692      }
2693      return this;
2694    }
2695
2696    public Component getTreeCellRendererComponent1(JTree tree,
2697                                              Object value,
2698                                              boolean sel,
2699                                              boolean expanded,
2700                                              boolean leaf,
2701                                              int row,
2702                                              boolean hasFocus) {
2703      super.getTreeCellRendererComponent(tree, value, selected, expanded,
2704                                         leaf, row, hasFocus);
2705      Object handle = ((DefaultMutableTreeNode)value).getUserObject();
2706      if(handle != null && handle instanceof Handle){
2707        setIcon(((Handle)handle).getIcon());
2708        setText(((Handle)handle).getTitle());
2709        setToolTipText(((Handle)handle).getTooltipText());
2710      }
2711      return this;
2712    }
2713  }
2714
2715  protected class ResourcesTreeCellEditor extends DefaultTreeCellEditor {
2716    ResourcesTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer){
2717      super(tree, renderer);
2718    }
2719
2720    /**
2721     * This is the original implementation from the super class with some
2722     * changes (i.e. shorter timer: 500 ms instead of 1200)
2723     */
2724    protected void startEditingTimer() {
2725      if(timer == null) {
2726        timer = new javax.swing.Timer(500, this);
2727        timer.setRepeats(false);
2728      }
2729      timer.start();
2730    }
2731
2732    /**
2733     * This is the original implementation from the super class with some
2734     * changes (i.e. correct discovery of icon)
2735     */
2736    public Component getTreeCellEditorComponent(JTree tree, Object value,
2737                                                boolean isSelected,
2738                                                boolean expanded,
2739                                                boolean leaf, int row) {
2740      Component retValue = super.getTreeCellEditorComponent(tree, value,
2741                                                            isSelected,
2742                                                            expanded,
2743                                                            leaf, row);
2744      //lets find the actual icon
2745      if(renderer != null) {
2746        renderer.getTreeCellRendererComponent(tree, value, isSelected, expanded,
2747                                              leaf, row, false);
2748        editingIcon = renderer.getIcon();
2749      }
2750      return retValue;
2751    }
2752  }//protected class ResourcesTreeCellEditor extends DefaultTreeCellEditor {
2753
2754  protected class ResourcesTreeModel extends DefaultTreeModel {
2755    ResourcesTreeModel(TreeNode root, boolean asksAllowChildren){
2756      super(root, asksAllowChildren);
2757    }
2758
2759    public void valueForPathChanged(TreePath path, Object newValue){
2760      DefaultMutableTreeNode   aNode = (DefaultMutableTreeNode)
2761                                       path.getLastPathComponent();
2762      Object userObject = aNode.getUserObject();
2763      if(userObject instanceof Handle){
2764        Object target = ((Handle)userObject).getTarget();
2765        if(target instanceof Resource){
2766          Gate.getCreoleRegister().setResourceName((Resource)target,
2767                                                   (String)newValue);
2768        }
2769      }
2770      nodeChanged(aNode);
2771    }
2772  }
2773
2774
2775
2776  class ProgressBarUpdater implements Runnable{
2777    ProgressBarUpdater(int newValue){
2778      value = newValue;
2779    }
2780
2781    public void run(){
2782      if(value == 0) progressBar.setVisible(false);
2783      else progressBar.setVisible(true);
2784      progressBar.setValue(value);
2785    }
2786
2787    int value;
2788  }
2789
2790  class StatusBarUpdater implements Runnable {
2791    StatusBarUpdater(String text){
2792      this.text = text;
2793    }
2794    public void run(){
2795      statusBar.setText(text);
2796    }
2797    String text;
2798  }
2799
2800  /**
2801   * During longer operations it is nice to keep the user entertained so
2802   * (s)he doesn't fall asleep looking at a progress bar that seems have
2803   * stopped. Also there are some operations that do not support progress
2804   * reporting so the progress bar would not work at all so we need a way
2805   * to let the user know that things are happening. We chose for purpose
2806   * to show the user a small cartoon in the form of an animated gif.
2807   * This class handles the diplaying and updating of those cartoons.
2808   */
2809  class CartoonMinder implements Runnable{
2810
2811    CartoonMinder(JPanel targetPanel){
2812      active = false;
2813      dying = false;
2814      this.targetPanel = targetPanel;
2815      imageLabel = new JLabel(getIcon("working.gif"));
2816      imageLabel.setOpaque(false);
2817      imageLabel.setBorder(BorderFactory.createEmptyBorder(3,3,3,3));
2818    }
2819
2820    public boolean isActive(){
2821      boolean res;
2822      synchronized(lock){
2823        res = active;
2824      }
2825      return res;
2826    }
2827
2828    public void activate(){
2829      //add the label in the panel
2830      SwingUtilities.invokeLater(new Runnable(){
2831        public void run(){
2832          targetPanel.add(imageLabel);
2833        }
2834      });
2835      //wake the dorment thread
2836      synchronized(lock){
2837        active = true;
2838      }
2839    }
2840
2841    public void deactivate(){
2842      //send the thread to sleep
2843      synchronized(lock){
2844        active = false;
2845      }
2846      //clear the panel
2847      SwingUtilities.invokeLater(new Runnable(){
2848        public void run(){
2849          targetPanel.removeAll();
2850          targetPanel.repaint();
2851        }
2852      });
2853    }
2854
2855    public void dispose(){
2856      synchronized(lock){
2857        dying = true;
2858      }
2859    }
2860
2861    public void run(){
2862      boolean isDying;
2863      synchronized(lock){
2864        isDying = dying;
2865      }
2866      while(!isDying){
2867        boolean isActive;
2868        synchronized(lock){
2869          isActive = active;
2870        }
2871        if(isActive && targetPanel.isVisible()){
2872          SwingUtilities.invokeLater(new Runnable(){
2873            public void run(){
2874//              targetPanel.getParent().validate();
2875//              targetPanel.getParent().repaint();
2876//              ((JComponent)targetPanel.getParent()).paintImmediately(((JComponent)targetPanel.getParent()).getBounds());
2877//              targetPanel.doLayout();
2878
2879//              targetPanel.requestFocus();
2880              targetPanel.getParent().getParent().invalidate();
2881              targetPanel.getParent().getParent().repaint();
2882//              targetPanel.paintImmediately(targetPanel.getBounds());
2883            }
2884          });
2885        }
2886        //sleep
2887        try{
2888          Thread.sleep(300);
2889        }catch(InterruptedException ie){}
2890
2891        synchronized(lock){
2892          isDying = dying;
2893        }
2894      }//while(!isDying)
2895    }
2896
2897    boolean dying;
2898    boolean active;
2899    String lock = "lock";
2900    JPanel targetPanel;
2901    JLabel imageLabel;
2902  }
2903
2904/*
2905  class JGateMenuItem extends JMenuItem {
2906    JGateMenuItem(javax.swing.Action a){
2907      super(a);
2908      this.addMouseListener(new MouseAdapter() {
2909        public void mouseEntered(MouseEvent e) {
2910          oldText = statusBar.getText();
2911          statusChanged((String)getAction().
2912                        getValue(javax.swing.Action.SHORT_DESCRIPTION));
2913        }
2914
2915        public void mouseExited(MouseEvent e) {
2916          statusChanged(oldText);
2917        }
2918      });
2919    }
2920    String oldText;
2921  }
2922
2923  class JGateButton extends JButton {
2924    JGateButton(javax.swing.Action a){
2925      super(a);
2926      this.addMouseListener(new MouseAdapter() {
2927        public void mouseEntered(MouseEvent e) {
2928          oldText = statusBar.getText();
2929          statusChanged((String)getAction().
2930                        getValue(javax.swing.Action.SHORT_DESCRIPTION));
2931        }
2932
2933        public void mouseExited(MouseEvent e) {
2934          statusChanged(oldText);
2935        }
2936      });
2937    }
2938    String oldText;
2939  }
2940*/
2941  class LocaleSelectorMenuItem extends JRadioButtonMenuItem {
2942    public LocaleSelectorMenuItem(Locale locale) {
2943      super(locale.getDisplayName());
2944      me = this;
2945      myLocale = locale;
2946      this.addActionListener(new ActionListener()  {
2947        public void actionPerformed(ActionEvent e) {
2948          Iterator rootIter = MainFrame.getGuiRoots().iterator();
2949          while(rootIter.hasNext()){
2950            Object aRoot = rootIter.next();
2951            if(aRoot instanceof Window){
2952              me.setSelected(((Window)aRoot).getInputContext().
2953                              selectInputMethod(myLocale));
2954            }
2955          }
2956        }
2957      });
2958    }
2959
2960    public LocaleSelectorMenuItem() {
2961      super("System default  >>" +
2962            Locale.getDefault().getDisplayName() + "<<");
2963      me = this;
2964      myLocale = Locale.getDefault();
2965      this.addActionListener(new ActionListener()  {
2966        public void actionPerformed(ActionEvent e) {
2967          Iterator rootIter = MainFrame.getGuiRoots().iterator();
2968          while(rootIter.hasNext()){
2969            Object aRoot = rootIter.next();
2970            if(aRoot instanceof Window){
2971              me.setSelected(((Window)aRoot).getInputContext().
2972                              selectInputMethod(myLocale));
2973            }
2974          }
2975        }
2976      });
2977    }
2978
2979    Locale myLocale;
2980    JRadioButtonMenuItem me;
2981  }////class LocaleSelectorMenuItem extends JRadioButtonMenuItem
2982
2983  /**ontotext.bp
2984   * This class represent an action which brings up the Ontology Editor tool*/
2985  class NewOntologyEditorAction extends AbstractAction {
2986    public NewOntologyEditorAction(){
2987      super("Ontology Editor", getIcon("controller.gif"));
2988      putValue(SHORT_DESCRIPTION,"Start the Ontology Editor");
2989    }// NewAnnotDiffAction
2990
2991    public void actionPerformed(ActionEvent e) {
2992      OntologyEditorImpl editor = new OntologyEditorImpl();
2993      try {
2994        JFrame frame = new JFrame();
2995        editor.init();
2996        frame.setTitle("Ontology Editor");
2997        frame.getContentPane().add(editor);
2998        /*
2999          SET ONTOLOGY LIST AND ONTOLOGY
3000        */
3001        Set ontologies = new HashSet(Gate.getCreoleRegister().getLrInstances(
3002          "gate.creole.ontology.Ontology"));
3003
3004        editor.setOntologyList(new Vector(ontologies));
3005
3006        frame.setSize(OntologyEditorImpl.SIZE_X,OntologyEditorImpl.SIZE_Y);
3007        frame.setLocation(OntologyEditorImpl.POSITION_X,OntologyEditorImpl.POSITION_Y);
3008        frame.setVisible(true);
3009        editor.visualize();
3010      } catch ( ResourceInstantiationException ex ) {
3011        ex.printStackTrace(Err.getPrintWriter());
3012      }
3013    }// actionPerformed();
3014  }//class NewOntologyEditorAction
3015
3016  /** This class represent an action which brings up the Gazetteer Editor tool*/
3017  class NewGazetteerEditorAction extends AbstractAction {
3018    public NewGazetteerEditorAction(){
3019      super("Gazetteer Editor", getIcon("controller.gif"));
3020      putValue(SHORT_DESCRIPTION,"Start the Gazetteer Editor");
3021    }
3022
3023    public void actionPerformed(ActionEvent e) {
3024      com.ontotext.gate.vr.Gaze editor = new com.ontotext.gate.vr.Gaze();
3025      try {
3026        JFrame frame = new JFrame();
3027        editor.init();
3028        frame.setTitle("Gazetteer Editor");
3029        frame.getContentPane().add(editor);
3030
3031        Set gazetteers = new HashSet(Gate.getCreoleRegister().getLrInstances(
3032          "gate.creole.gazetteer.DefaultGazetteer"));
3033        if (gazetteers == null || gazetteers.isEmpty())
3034          return;
3035        Iterator iter = gazetteers.iterator();
3036        while (iter.hasNext()) {
3037          gate.creole.gazetteer.Gazetteer gaz =
3038            (gate.creole.gazetteer.Gazetteer) iter.next();
3039          if (gaz.getListsURL().toString().endsWith(System.getProperty("gate.slug.gazetteer")))
3040           editor.setTarget(gaz);
3041        }
3042
3043        frame.setSize(Gaze.SIZE_X,Gaze.SIZE_Y);
3044        frame.setLocation(Gaze.POSITION_X,Gaze.POSITION_Y);
3045        frame.setVisible(true);
3046        editor.setVisible(true);
3047      } catch ( ResourceInstantiationException ex ) {
3048        ex.printStackTrace(Err.getPrintWriter());
3049      }
3050    }// actionPerformed();
3051  }//class NewOntologyEditorAction
3052
3053} // class MainFrame
3054