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

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

Tidied up opening collections, and showLoadCollectionBox (now showOpenCollectionDialog) in particular. Now switches back to the Gather pane correctly before closing an open collection, as it needs to do to prevent nasty problems.

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