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