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

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

Changed "Mirror" pane to "Download".

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