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

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

Moved some GUI stuff out of CollectionManager and into GUIManager.

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