source: trunk/gli/src/org/greenstone/gatherer/gui/GUIManager.java@ 10379

Last change on this file since 10379 was 10379, checked in by mdewsnip, 19 years ago

Now downloads the collection configurations (when using a remote Greenstone server) when the GLI starts up, rather than when File -> Open is selected.

  • Property svn:keywords set to Author Date Id Revision
File size: 30.7 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * <BR><BR>
9 *
10 * Author: John Thompson, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37package org.greenstone.gatherer.gui;
38
39import java.awt.*;
40import java.awt.datatransfer.*;
41import java.awt.event.*;
42import java.io.File;
43import java.lang.*;
44import java.net.*;
45import java.util.*;
46import javax.swing.*;
47import javax.swing.event.*;
48import javax.swing.filechooser.*;
49import javax.swing.plaf.*;
50import javax.swing.text.*;
51import org.greenstone.gatherer.Configuration;
52import org.greenstone.gatherer.DebugStream;
53import org.greenstone.gatherer.Dictionary;
54import org.greenstone.gatherer.Gatherer;
55import org.greenstone.gatherer.collection.Collection;
56import org.greenstone.gatherer.file.FileOpenActionListener;
57import org.greenstone.gatherer.file.WorkspaceTree;
58import org.greenstone.gatherer.gui.metaaudit.MetaAuditFrame;
59import org.greenstone.gatherer.gui.tree.DragTree;
60import org.greenstone.gatherer.util.JarTools;
61import org.greenstone.gatherer.util.StaticStrings;
62import org.greenstone.gatherer.util.TreeSynchronizer;
63import org.greenstone.gatherer.util.Utility;
64
65/** The GUIManager is in charge of creating the Gatherer window frame then filling it with the goodness of the view panes. GUIManager not only creates these panes, but allows some messaging between them. Furthermore GUIManager includes functionality from menu driven choices, simply as it was easier to put it here once and have it accessible from all pane children. */
66public class GUIManager
67 extends JFrame
68 implements ActionListener, ChangeListener {
69 /** The download pane contains controls for downloading internet sites. */
70 public DownloadPane download_pane = null;
71 /** The gather pane is more like a file manager where you drag files from one tree to another. */
72 private GatherPane gather_pane = null;
73 /** The enrich pane is used to assign, edit and remove metadata from files within the collection. */
74 public EnrichPane enrich_pane = null;
75 /** The design pane allows you to edit the design of the library in terms of the collection configuration file. */
76 public DesignPane design_pane = null;
77 /** The create pane contains scripting options for importing and building collections into libraries. */
78 public CreatePane create_pane = null;
79
80 public FileOpenActionListener foa_listener = new FileOpenActionListener();
81
82 /** A reference to the currently instantiated help window, if any. */
83 private HelpFrame help = null;
84 /** The menu bar. */
85 public MenuBar menu_bar = null;
86 public MetaAuditFrame meta_audit;
87 /** Are certain panes currently locked? */
88 private boolean locked = false;
89 /** The size of the Gatherer window. */
90 private Dimension size = null;
91 /** The filters used to dynamically filter the trees at user request. */
92 private HashMap filters = new HashMap();
93 /** The panel within the window that other components are placed on. */
94 private JPanel content_pane = null;
95 /** The last view pane selected. */
96 private JPanel previous_pane;
97 /** The main tab pane containing the different views, available here to trap view change events. */
98 private JTabbedPane tab_pane = null;
99 /** A threaded tab changer to try and avoid NPE on exit. */
100 private TabUpdater tab_updater = null;
101 /** Ensures that expansion events between like collection trees are synchronized. */
102 private TreeSynchronizer collection_tree_sync = null;
103
104
105 /**Constructor. Enable window events and arranges all other components.
106 * @param size The intial <strong>Dimension</strong> of the screen.
107 */
108 public GUIManager(Dimension size) {
109 super();
110 // Initialization
111 this.help = new HelpFrame();
112 this.size = size;
113 this.collection_tree_sync = new TreeSynchronizer();
114 this.meta_audit = new MetaAuditFrame(collection_tree_sync, null);
115
116 this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
117
118 // Add a focus listener to ourselves. Thus if we gain focus when a Modal Dialog should instead have it, we can try to bring the modal dialog to the fore.
119 this.addFocusListener(new GLIGUIFocusListener());
120
121 // Make the Tool tip hang around for a rediculous amount of time.
122 ToolTipManager.sharedInstance().setDismissDelay(10000);
123
124 // Set up some other UI stuff. (fonts handled in Gatherer.main())
125 UIManager.put("FileChooser.lookInLabelText", Dictionary.get("SaveCollectionBox.Look_In"));
126 UIManager.put("FileChooser.filesOfTypeLabelText", Dictionary.get("SaveCollectionBox.Files_Of_Type"));
127 UIManager.put("FileChooser.fileNameLabelText", Dictionary.get("SaveCollectionBox.File_Name"));
128 }
129
130 private class GLIGUIFocusListener
131 extends FocusAdapter {
132 public void focusGained(FocusEvent e) {
133 if (ModalDialog.current_modal != null) {
134 ModalDialog.current_modal.makeVisible();
135 ModalDialog.current_modal.toFront();
136 }
137 }
138 }
139
140 /** Any implementation of <i>ActionListener</i> must include this method so that we can be informed when an action has occured. In this case we are listening to actions from the menu-bar, and should react appropriately.
141 * @param event An <strong>ActionEvent</strong> containing information about the action that has occured.
142 */
143 public void actionPerformed(ActionEvent event) {
144 Object esrc = event.getSource();
145 // *************
146 // File Options.
147 // *************
148 if (esrc == menu_bar.file_associations) {
149 Gatherer.assoc_man.edit();
150 }
151 else if (esrc == menu_bar.file_close) {
152 tab_pane.setSelectedComponent(gather_pane); // Must be done before closing the collection
153 Gatherer.c_man.saveCollection();
154 Gatherer.c_man.closeCollection();
155 }
156 else if (esrc == menu_bar.file_delete) {
157 DeleteCollectionPrompt dcp = new DeleteCollectionPrompt();
158 if (dcp.display()) {
159 Gatherer.c_man.closeCollection();
160 }
161 dcp.destroy();
162 dcp = null;
163 System.gc();
164 }
165 else if (esrc == menu_bar.file_cdimage) {
166 WriteCDImagePrompt wcdip = new WriteCDImagePrompt();
167 wcdip.display();
168 wcdip.destroy();
169 wcdip = null;
170 }
171 else if (esrc == menu_bar.file_exportas) {
172 ExportAsPrompt eap = new ExportAsPrompt();
173 eap.display();
174 eap.destroy();
175 eap = null;
176 }
177 else if (esrc == menu_bar.file_exit) {
178 exit();
179 }
180 else if (esrc == menu_bar.file_new) {
181 showNewCollectionPrompt();
182 }
183 else if (esrc == menu_bar.file_open) {
184 String collection_file_path = showOpenCollectionDialog();
185
186 // User has selected a collection to open
187 if (collection_file_path != null) {
188 // If there is already a collection open, save and close it
189 if (Gatherer.c_man.ready()) {
190 tab_pane.setSelectedComponent(gather_pane); // Must be done before closing the collection
191 Gatherer.c_man.saveCollection();
192 Gatherer.c_man.closeCollection();
193 }
194
195 // Open the selected collection
196 Gatherer.c_man.loadCollection(collection_file_path);
197 }
198 }
199 else if (esrc == menu_bar.file_options) {
200 // Just incase the user has edited the GeneralSettings of a collection without losing focus afterwards. Well I'm forever losing foc... ooh shiney.
201 design_pane.loseFocus();
202 // And spawn a new preferences.
203 new Preferences();
204 }
205 else if (esrc == menu_bar.file_save) {
206 Gatherer.c_man.saveCollection();
207 }
208
209 // *************
210 // Edit Options.
211 // *************
212 else if(esrc == menu_bar.edit_copy) {
213 try {
214 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
215 // Get the component with selected text as a JTextComponent
216 JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner();//getFocusOwner();
217 text.copy();
218 }
219 catch (Exception cce) {
220 // If the component is not a text component ignore the copy command
221 DebugStream.println(cce.toString());
222 }
223 }
224 else if(esrc == menu_bar.edit_cut) {
225 try {
226 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
227 // Get the component with selected text as a JTextComponent
228 JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner();
229 // Cut the text to the clipboard
230 text.cut();
231 }
232 catch (ClassCastException cce) {
233 // If the component is not a text component ignore the cut command
234 DebugStream.println(cce.toString());
235 }
236 }
237 else if(esrc == menu_bar.edit_paste) {
238 try {
239 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
240 // Get the component with selected text as a JTextComponent
241 JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner();
242 // Cut the text to the clipboard
243 text.paste();
244 }
245 catch (ClassCastException cce) {
246 // If the component is not a text component ignore the paste command
247 DebugStream.println(cce.toString());
248 }
249 }
250
251 // *************
252 // Help Options.
253 // *************
254 else if (esrc == menu_bar.help_general) {
255 HelpFrame.setView("introduction");
256 }
257 else if (esrc == menu_bar.help_download) {
258 HelpFrame.setView("downloadingfiles");
259 }
260 else if (esrc == menu_bar.help_gather) {
261 HelpFrame.setView("collectingfiles");
262 }
263 else if (esrc == menu_bar.help_enrich) {
264 HelpFrame.setView("enrichingacollection");
265 }
266 else if (esrc == menu_bar.help_design) {
267 HelpFrame.setView("designingacollection");
268 }
269 else if (esrc == menu_bar.help_create) {
270 HelpFrame.setView("producingthecollection");
271 }
272 else if (esrc == menu_bar.help_about) {
273 new AboutDialog(this);
274 }
275 }
276
277
278 /** Any actions that should happen after the display of the Gatherer window can be called here. Currently only updates the browser pane if it is active to work around bug in Mozilla renderer implementation.
279 */
280 public void afterDisplay() {
281 if (download_pane != null) {
282 download_pane.afterDisplay();
283 }
284 enrich_pane.afterDisplay();
285 }
286
287
288 public void closeCurrentCollection() {
289 Gatherer.c_man.saveCollection();
290 Gatherer.c_man.closeCollection();
291 tab_pane.setSelectedComponent(gather_pane);
292 }
293
294
295 public void destroy() {
296 // Destroying create pane ensures the latest log has been closed
297 if (create_pane != null) {
298 create_pane.destroy();
299 }
300 }
301
302
303 /** Enabled events on the window to be trapped, creates all the visual components, then builds the tab and other layouts.
304 */
305 public void display() {
306 content_pane = (JPanel) this.getContentPane();
307 // Enable window-type events to be fired.
308 enableEvents(AWTEvent.WINDOW_EVENT_MASK);
309 // Initialise and layout sub-components, plus other window dressing.
310 try {
311 this.setSize(size);
312
313 // Set the title
314 String collection_title = null;
315 String collection_name = null;
316 if (Gatherer.c_man.ready()) {
317 Collection collection = Gatherer.c_man.getCollection();
318 collection_title = collection.getTitle();
319 collection_name = collection.getName();
320 collection = null;
321 }
322 setTitle(collection_title, collection_name);
323 collection_title = null;
324 collection_name = null;
325
326 // Pretty corner icon
327 this.setIconImage(JarTools.getImage("gatherer_small.gif").getImage());
328 // BorderLayout for the main screen. I'll try my best to avoid these in subcomponents as they're space greedy.
329 content_pane.setLayout(new BorderLayout());
330 // Create the menu-bar and stick it up the top.
331 menu_bar = new MenuBar(new MenuListenerImpl());
332
333 //feedback changes
334 //content_pane.add(menu_bar, BorderLayout.NORTH);
335 this.setJMenuBar(menu_bar);
336 // end feedback changes
337
338 // Create the tabbed pane and plop it in the center where it will
339 // expand to consume all available space like any good gas would.
340 tab_pane = new JTabbedPane();
341 tab_pane.addChangeListener(this);
342 tab_pane.setFont(Configuration.getFont("general.font", false));
343
344 if (Configuration.get("workflow.download", true)) {
345 download_pane = new DownloadPane();
346 // "GUI.Download_Tooltip" is used automatically
347 tab_pane.addTab("GUI.Download", JarTools.getImage("download.gif"), download_pane);
348 tab_pane.setEnabledAt(tab_pane.indexOfComponent(download_pane), Configuration.get("workflow.download", false));
349 }
350
351 gather_pane = new GatherPane(collection_tree_sync);
352 gather_pane.display();
353 if (Configuration.get("workflow.gather", true)) {
354 // "GUI.Gather_Tooltip" is used automatically
355 tab_pane.addTab("GUI.Gather", JarTools.getImage("gather.gif"), gather_pane);
356 tab_pane.setEnabledAt(tab_pane.indexOfComponent(gather_pane), Configuration.get("workflow.gather", false));
357 }
358
359 enrich_pane = new EnrichPane(collection_tree_sync);
360 enrich_pane.display();
361 if (Configuration.get("workflow.enrich", true)) {
362 // "GUI.Enrich_Tooltip" is used automatically
363 tab_pane.addTab("GUI.Enrich", JarTools.getImage("enrich.gif"), enrich_pane);
364 tab_pane.setEnabledAt(tab_pane.indexOfComponent(enrich_pane), false);
365 }
366
367 design_pane = new DesignPane();
368 design_pane.display();
369 if (Configuration.get("workflow.design", true)) {
370 // "GUI.Design_Tooltip" is used automatically
371 tab_pane.addTab("GUI.Design", JarTools.getImage("design.gif"), design_pane);
372 tab_pane.setEnabledAt(tab_pane.indexOfComponent(design_pane), false);
373 }
374
375 create_pane = new CreatePane();
376 create_pane.display();
377 if (Configuration.get("workflow.create", true)) {
378 // "GUI.Create_Tooltip" is used automatically
379 tab_pane.addTab("GUI.Create", JarTools.getImage("create.gif"), create_pane);
380 tab_pane.setEnabledAt(tab_pane.indexOfComponent(create_pane), false);
381 }
382
383 // Select the collect pane if it is available
384 if (tab_pane.indexOfComponent(gather_pane) != -1) {
385 tab_pane.setSelectedComponent(gather_pane);
386 }
387 // Otherwise find the first tab that is enabled and select that.
388 else {
389 for (int i = 0; i < tab_pane.getTabCount(); i++) {
390 if (tab_pane.isEnabledAt(i)) {
391 tab_pane.setSelectedIndex(i);
392 break;
393 }
394 }
395 }
396
397 Dictionary.register(tab_pane);
398 content_pane.add(tab_pane, BorderLayout.CENTER);
399 // Call refresh to update all controls to reflect current collection status.
400 refresh(-1, Gatherer.c_man.ready());
401 }
402 catch (Exception e) {
403 DebugStream.printStackTrace(e);
404 // The GUI failing to build is an app killer
405 e.printStackTrace();
406 System.exit(1);
407 }
408 }
409
410
411 /** This method ensures that all the things needing saving are saved before Gatherer.exit() is called.
412 */
413 public void exit() {
414 // Tell everyone who cares that they are losing focus
415 DebugStream.println("**** GUIManager exit called!");
416
417 if (!Gatherer.c_man.ready() || design_pane.canSave()) {
418 // If we're running as an applet we don't actually quit, just hide the main GLI window
419 if (Gatherer.isApplet) {
420 // consider saving???
421 setVisible(false);
422 }
423 else {
424 if (Gatherer.c_man.ready() && !Gatherer.c_man.saved()) {
425 Gatherer.c_man.saveCollection();
426 }
427
428 // Deal to help
429 if (help != null) {
430 help.destroy();
431 help = null;
432 }
433 DebugStream.println("**** Calling Gatherer.self.exit");
434 Gatherer.self.exit();
435 }
436 }
437 }
438
439
440 /** Retrieve the filter, or if one already exists, spawn a linked copy. */
441 public Filter getFilter(DragTree tree) {
442 Filter filter = (Filter) filters.get(tree.getModel());
443 if (filter == null) {
444 filter = new Filter(tree, null);
445 filters.put(tree.getModel(), filter);
446 return filter;
447 }
448 return filter.spawn(tree);
449 }
450
451
452 /** This method is called when the collection is being built, and is used to disable all controls in all pane which could change the state of the collection.
453 */
454 public void lockCollection(boolean import_stage, boolean lock)
455 {
456 locked = lock;
457
458 if (import_stage) {
459 int gather_pos = tab_pane.indexOfComponent(gather_pane);
460 if (gather_pos != -1) {
461 tab_pane.setEnabledAt(gather_pos, !lock);
462 }
463 int enrich_pos = tab_pane.indexOfComponent(enrich_pane);
464 if (enrich_pos != -1) {
465 tab_pane.setEnabledAt(enrich_pos, !lock);
466 }
467 }
468
469 int design_pos = tab_pane.indexOfComponent(design_pane);
470 if (design_pos != -1) {
471 tab_pane.setEnabledAt(design_pos, !lock);
472 }
473 }
474
475
476 public void modeChanged(int mode) {
477 // Set the title
478 String collection_title = null;
479 String collection_name = null;
480 if (Gatherer.c_man.ready()) {
481 Collection collection = Gatherer.c_man.getCollection();
482 collection_title = collection.getTitle();
483 collection_name = collection.getName();
484 collection = null;
485 }
486 setTitle(collection_title, collection_name);
487 collection_title = null;
488 collection_name = null;
489 // Now pass on the message to anyone who cares
490 if (download_pane != null) {
491 download_pane.modeChanged(mode);
492 }
493 if (gather_pane != null) {
494 gather_pane.modeChanged(mode);
495 }
496 if (enrich_pane != null) {
497 enrich_pane.modeChanged(mode);
498 }
499 if (design_pane != null) {
500 design_pane.modeChanged(mode);
501 }
502 if (create_pane != null) {
503 create_pane.modeChanged(mode);
504 }
505 }
506
507
508 public void refresh(int refresh_reason, boolean collection_loaded)
509 {
510 // Set the collection information in the title bar
511 if (collection_loaded) {
512 Collection collection = Gatherer.c_man.getCollection();
513 setTitle(collection.getTitle(), collection.getName());
514 }
515 else {
516 setTitle(null, null);
517 }
518
519 // Update the menu bar
520 menu_bar.refresh(refresh_reason, collection_loaded);
521
522 // Update the loaded panes
523 if (download_pane != null) {
524 download_pane.refresh(refresh_reason, collection_loaded);
525 }
526 if (gather_pane != null) {
527 gather_pane.refresh(refresh_reason, collection_loaded);
528 }
529 if (enrich_pane != null) {
530 enrich_pane.refresh(refresh_reason, collection_loaded);
531 }
532 if (design_pane != null) {
533 design_pane.refresh(refresh_reason, collection_loaded);
534 }
535 if (create_pane != null) {
536 create_pane.refresh(refresh_reason, collection_loaded);
537 }
538
539 // Now enable tabs as necessary. Do this on event queue to prevent crazy NPEs
540 if (!locked) {
541 if (tab_updater == null) {
542 tab_updater = new TabUpdater(tab_pane, collection_loaded);
543 }
544 else {
545 tab_updater.setReady(collection_loaded);
546 }
547 SwingUtilities.invokeLater(tab_updater);
548 }
549 }
550
551
552 public void refreshCollectionTree(int refresh_reason)
553 {
554 if (gather_pane != null) {
555 gather_pane.refreshCollectionTree(refresh_reason);
556 }
557 }
558
559
560 public void refreshWorkspaceTree(int refresh_reason)
561 {
562 if (gather_pane != null) {
563 gather_pane.refreshWorkspaceTree(refresh_reason);
564 }
565 }
566
567
568 /** Returns to some "initial" pane (when no collection is loaded) */
569 public void returnToInitialPane()
570 {
571 if (gather_pane != null) {
572 tab_pane.setSelectedComponent(gather_pane);
573 }
574 }
575
576
577 /** Specifies whether a certain tab is enabled or not. */
578 private void setTabEnabled(String rawname, boolean state) {
579 // Retrieve the dictionary based name.
580 String name = Dictionary.get("GUI." + rawname);
581 int index = tab_pane.indexOfTab(name);
582 // Of course we may not have this tab available.
583 if(index != -1) {
584 // Some tabs are also dependant on if a collection is ready
585 Component component = tab_pane.getComponentAt(index);
586 if(component == enrich_pane || component == design_pane || component == create_pane) {
587 tab_pane.setEnabledAt(index, state && Gatherer.c_man != null && Gatherer.c_man.ready());
588 }
589 else {
590 tab_pane.setEnabledAt(index, state);
591 }
592 // If this was the currently selected tab and it is now disabled, change the view to the first enabled tab.
593 if(tab_pane.getSelectedIndex() == index && !state) {
594 boolean found = false;
595 for(int i = 0; !found && i < tab_pane.getTabCount(); i++) {
596 if(tab_pane.isEnabledAt(i)) {
597 tab_pane.setSelectedIndex(i);
598 found = true;
599 }
600 }
601 // If there are no tabs enabled, which should be impossible, then select the first tab
602 if(!found) {
603 tab_pane.setSelectedIndex(0);
604 }
605 }
606 }
607 }
608
609 /** Change the string shown in the title bar of the main gui frame. If either value is null, the 'No Collection' string is shown instead.
610 * @param title
611 * @param name
612 */
613 public void setTitle(String title, String name) {
614 // Finally display the collection name in the title bar.
615 StringBuffer title_buffer = new StringBuffer(Utility.PROGRAM_NAME);
616 title_buffer.append(StaticStrings.SPACE_CHARACTER);
617 title_buffer.append(StaticStrings.SPACE_CHARACTER);
618 // Describe the current user mode
619 title_buffer.append(StaticStrings.MODE_STR);
620 title_buffer.append(Configuration.getModeAsString());
621 title_buffer.append(StaticStrings.SPACE_CHARACTER);
622 title_buffer.append(StaticStrings.SPACE_CHARACTER);
623 // Now for the current collection
624 title_buffer.append(StaticStrings.COLLECTION_STR);
625 if (title != null && name != null) {
626 title_buffer.append(title);
627 title_buffer.append(StaticStrings.SPACE_CHARACTER);
628 title_buffer.append(StaticStrings.OPEN_PARENTHESIS_CHARACTER);
629 title_buffer.append(name);
630 title_buffer.append(StaticStrings.CLOSE_PARENTHESIS_CHARACTER);
631 }
632 else {
633 title_buffer.append(Dictionary.get("Collection.No_Collection"));
634 }
635 this.setTitle(title_buffer.toString());
636 title_buffer = null;
637 }
638
639
640 /** When the load collection option is choosen this method is called to produce the modal file load prompt.
641 */
642 private String showOpenCollectionDialog()
643 {
644 // We first try the simple open collection dialog
645 SimpleOpenCollectionDialog dialog = new SimpleOpenCollectionDialog();
646 int user_choice = dialog.display();
647
648 // Used simple collection list
649 if (user_choice == SimpleOpenCollectionDialog.OK_OPTION) {
650 return dialog.getFileName();
651 }
652
653 // Chosen to use the advanced 'browse' dialog
654 if (user_choice == SimpleOpenCollectionDialog.BROWSE_OPTION) {
655 File collect_directory;
656 if (Gatherer.GS3) {
657 collect_directory = new File(Utility.getSitesDir(Configuration.gsdl3_path));
658 }
659 else {
660 collect_directory = new File(Gatherer.getCollectDirectoryPath());
661 }
662 OpenCollectionDialog chooser = new OpenCollectionDialog(collect_directory);
663 return chooser.getFileName();
664 }
665
666 // User must have cancelled the action
667 return null;
668 }
669
670
671 /** When called this method causes the MetadataAuditTable to display a nice dialog box which contains all the metadata assigned in the collection.
672 */
673 public void showMetaAuditBox() {
674 wait(true);
675 meta_audit.display();
676 wait(false);
677 }
678 /** This method is used to open the new collection box on the screen.
679 */
680 private void showNewCollectionPrompt() {
681 NewCollectionMetadataPrompt ncm_prompt = null;
682 // Create the collection details prompt from new collection prompt
683 NewCollectionDetailsPrompt ncd_prompt = new NewCollectionDetailsPrompt();
684 // If no previous collection was indicated as a model design, then show the metadata selection prompt from new collection prompt
685 if(!ncd_prompt.isCancelled() && (ncd_prompt.getBase() == null)) {
686 ncm_prompt = new NewCollectionMetadataPrompt();
687 }
688 // Create the new collection (if not cancelled) in a new thread.
689 if (!ncd_prompt.isCancelled() && (ncm_prompt == null || !ncm_prompt.isCancelled())) {
690 // If there is already a collection open, save and close it.
691 if (Gatherer.c_man.ready()) {
692 Gatherer.c_man.saveCollection();
693 Gatherer.c_man.closeCollection();
694 }
695
696 // Create new collection.
697 NewCollectionTask new_collection_task = new NewCollectionTask(ncd_prompt, ncm_prompt);
698 new_collection_task.start();
699 }
700 // Done
701 ncd_prompt = null;
702 ncm_prompt = null;
703 }
704
705
706 private class NewCollectionTask
707 extends Thread
708 {
709 private NewCollectionDetailsPrompt ncd_prompt = null;
710 private NewCollectionMetadataPrompt ncm_prompt = null;
711
712 public NewCollectionTask(NewCollectionDetailsPrompt ncd_prompt, NewCollectionMetadataPrompt ncm_prompt)
713 {
714 this.ncd_prompt = ncd_prompt;
715 this.ncm_prompt = ncm_prompt;
716 }
717
718 public void run()
719 {
720 if (ncm_prompt == null) {
721 Gatherer.c_man.createCollection(ncd_prompt.getDescription(), Configuration.getEmail(), ncd_prompt.getName(), ncd_prompt.getTitle(), ncd_prompt.getBase(), null);
722 }
723 else {
724 Gatherer.c_man.createCollection(ncd_prompt.getDescription(), Configuration.getEmail(), ncd_prompt.getName(), ncd_prompt.getTitle(), null, ncm_prompt.getSets());
725 ncm_prompt.dispose();
726 ncm_prompt = null;
727 }
728
729 ncd_prompt.dispose();
730 ncd_prompt = null;
731
732 // Return to some initial pane (Gather)
733 returnToInitialPane();
734
735 // Refresh the workspace tree to allow for the new collection
736 refreshWorkspaceTree(WorkspaceTree.LIBRARY_CONTENTS_CHANGED);
737
738 // Refresh the rest of the GLI
739 Gatherer.refresh(Gatherer.COLLECTION_OPENED);
740 }
741 }
742
743
744 /** Any implementation of ChangeListener must include this method so we can be informed when the state of one of the registered objects changes. In this case we are listening to view changes within the tabbed pane.
745 * @param event A ChangeEvent containing information about the event that fired this call.
746 */
747 public void stateChanged(ChangeEvent event) {
748 if(previous_pane != null) {
749 if(previous_pane == create_pane) {
750 create_pane.loseFocus();
751 }
752 else if(previous_pane == design_pane) {
753 design_pane.loseFocus();
754 }
755 }
756
757 menu_bar.tabSelected(tab_pane.getSelectedIndex());
758 int selected_index = tab_pane.getSelectedIndex();
759 if (selected_index == tab_pane.indexOfComponent(download_pane)) {
760 download_pane.gainFocus();
761 }
762 else if (selected_index == tab_pane.indexOfComponent(gather_pane)) {
763 gather_pane.gainFocus();
764 }
765 else if (selected_index == tab_pane.indexOfComponent(enrich_pane)) {
766 enrich_pane.gainFocus();
767 }
768 else if (selected_index == tab_pane.indexOfComponent(design_pane)) {
769 design_pane.gainFocus();
770 }
771 else if (selected_index == tab_pane.indexOfComponent(create_pane)) {
772 create_pane.gainFocus();
773 }
774
775 previous_pane = (JPanel) tab_pane.getSelectedComponent();
776 }
777
778
779 private MouseListener mouse_blocker_listener = new MouseAdapter() {};
780
781 public void updateUI()
782 {
783 JPanel pane = (JPanel) getContentPane();
784 pane.updateUI();
785 // Also update all of the tabs according to workflow.
786 workflowUpdate("Download", Configuration.get("workflow.download", false));
787 workflowUpdate("Gather", Configuration.get("workflow.gather", false));
788 workflowUpdate("Enrich", Configuration.get("workflow.enrich", false));
789 workflowUpdate("Design", Configuration.get("workflow.design", false));
790 workflowUpdate("Create", Configuration.get("workflow.create", false));
791 }
792
793 public void wait(boolean waiting) {
794 Component glass_pane = getGlassPane();
795 if(waiting) {
796 // Show wait cursor.
797 glass_pane.addMouseListener(mouse_blocker_listener);
798 glass_pane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
799 glass_pane.setVisible(true);
800 }
801 else {
802 // Hide wait cursor.
803 glass_pane.setVisible(false);
804 glass_pane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
805 glass_pane.removeMouseListener(mouse_blocker_listener);
806 }
807 glass_pane = null;
808 }
809
810 public void workflowUpdate(String raw, boolean state) {
811 WorkflowUpdater task = new WorkflowUpdater(raw, state);
812 SwingUtilities.invokeLater(task);
813 task = null;
814 }
815
816
817 /**Overridden from JFrame so we can exit safely when window is closed (or destroyed).
818 * @param event A <strong>WindowEvent</strong> containing information about the event that fired this call.
819 */
820 protected void processWindowEvent(WindowEvent event) {
821 if(event.getID() == WindowEvent.WINDOW_CLOSING) {
822 exit();
823 }
824 }
825
826
827 /** Listens to actions upon the menu bar, and if it detects a click over the help menu brings the help window to the front if it has become hidden.
828 */
829 private class MenuListenerImpl
830 implements MenuListener {
831 /** Called whenever a popup menu is hidden, but we don't care.
832 * @param e Some <strong>MenuEvent</strong> that we could care less about.
833 */
834 public void menuCanceled(MenuEvent e) {
835 }
836 /** Called whenever a menu header (ie button) becomes unselected, but we don't care.
837 * @param e Some <strong>MenuEvent</strong> that we could care less about.
838 */
839 public void menuDeselected(MenuEvent e) {
840 }
841 /** This method, when a menu is first opened, is the only one we respond to by bringing the help window to the front if possible, but only if there is a help window and the help menu is the one opening.
842 * @param e The <strong>MenuEvent</strong> whose source is checked.
843 */
844 public void menuSelected(MenuEvent e) {
845 if(e.getSource() == menu_bar.help) {
846 if(menu_bar.help.isSelected()) {
847 menu_bar.help.doClick(10);
848 }
849 }
850 }
851 }
852
853 private class TabUpdater
854 implements Runnable {
855 private boolean ready = false;
856 private int download_pos = -1;
857 private int enrich_pos = -1;
858 private int design_pos = -1;
859 private int create_pos = -1;
860 private int export_pos = -1;
861 private JTabbedPane tab_pane = null;
862
863 public TabUpdater(JTabbedPane tab_pane, boolean ready) {
864 this.ready = ready;
865 this.tab_pane = tab_pane;
866 download_pos = tab_pane.indexOfComponent(download_pane);
867 enrich_pos = tab_pane.indexOfComponent(enrich_pane);
868 design_pos = tab_pane.indexOfComponent(design_pane);
869 create_pos = tab_pane.indexOfComponent(create_pane);
870 }
871
872 public void run()
873 {
874 if (download_pos != -1) {
875 if (ready) {
876 tab_pane.setEnabledAt(download_pos, Configuration.get("workflow.download", false));
877 }
878 else {
879 tab_pane.setEnabledAt(download_pos, Configuration.get("workflow.download", true));
880 }
881 }
882 if (enrich_pos != -1) {
883 tab_pane.setEnabledAt(enrich_pos, ready && Configuration.get("workflow.enrich", false));
884 }
885 if (design_pos != -1) {
886 tab_pane.setEnabledAt(design_pos, ready && Configuration.get("workflow.design", false) && Configuration.getMode() > Configuration.ASSISTANT_MODE);
887 }
888 if (create_pos != -1) {
889 tab_pane.setEnabledAt(create_pos, ready && Configuration.get("workflow.create", false));
890 }
891 }
892
893 public void setReady(boolean ready) {
894 this.ready = ready;
895 }
896 }
897
898 private class WorkflowUpdater
899 implements Runnable {
900 private boolean state;
901 private String raw;
902 public WorkflowUpdater(String raw, boolean state) {
903 this.raw = raw;
904 this.state = state;
905 }
906 public void run() {
907 setTabEnabled(raw, state);
908 }
909 }
910}
Note: See TracBrowser for help on using the repository browser.