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