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

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

Moved DeleteCollectionPrompt and ExportCollectionPrompt out of "collection" into "gui".

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