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

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

Now aborts the open collection dialog if something went wrong downloading the collection configurations (remote Greenstone).

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