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

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

Now downloads the collection configuration files when File -> Open is selected, if using a remote Greenstone server.

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