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

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

(West Yorkshire) Now checks if the collection configurations have been downloaded when File -> Open is chosen, and downloads them if not.

  • Property svn:keywords set to Author Date Id Revision
File size: 31.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.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 RemoteGreenstoneServer.downloadCollectionConfigurations();
655 }
656
657 // We first try the simple open collection dialog
658 SimpleOpenCollectionDialog dialog = new SimpleOpenCollectionDialog();
659 int user_choice = dialog.display();
660
661 // Used simple collection list
662 if (user_choice == SimpleOpenCollectionDialog.OK_OPTION) {
663 return dialog.getFileName();
664 }
665
666 // Chosen to use the advanced 'browse' dialog
667 if (user_choice == SimpleOpenCollectionDialog.BROWSE_OPTION) {
668 if (Gatherer.GS3) {
669 collect_directory = new File(Utility.getSitesDir(Configuration.gsdl3_path));
670 }
671 else {
672 collect_directory = new File(Gatherer.getCollectDirectoryPath());
673 }
674 OpenCollectionDialog chooser = new OpenCollectionDialog(collect_directory);
675 return chooser.getFileName();
676 }
677
678 // User must have cancelled the action
679 return null;
680 }
681
682
683 /** When called this method causes the MetadataAuditTable to display a nice dialog box which contains all the metadata assigned in the collection.
684 */
685 public void showMetaAuditBox() {
686 wait(true);
687 meta_audit.display();
688 wait(false);
689 }
690 /** This method is used to open the new collection box on the screen.
691 */
692 private void showNewCollectionPrompt() {
693 NewCollectionMetadataPrompt ncm_prompt = null;
694 // Create the collection details prompt from new collection prompt
695 NewCollectionDetailsPrompt ncd_prompt = new NewCollectionDetailsPrompt();
696 // If no previous collection was indicated as a model design, then show the metadata selection prompt from new collection prompt
697 if(!ncd_prompt.isCancelled() && (ncd_prompt.getBase() == null)) {
698 ncm_prompt = new NewCollectionMetadataPrompt();
699 }
700 // Create the new collection (if not cancelled) in a new thread.
701 if (!ncd_prompt.isCancelled() && (ncm_prompt == null || !ncm_prompt.isCancelled())) {
702 // If there is already a collection open, save and close it.
703 if (Gatherer.c_man.ready()) {
704 saveThenCloseCurrentCollection();
705 }
706
707 // Create new collection.
708 NewCollectionTask new_collection_task = new NewCollectionTask(ncd_prompt, ncm_prompt);
709 new_collection_task.start();
710 }
711 // Done
712 ncd_prompt = null;
713 ncm_prompt = null;
714 }
715
716
717 private class NewCollectionTask
718 extends Thread
719 {
720 private NewCollectionDetailsPrompt ncd_prompt = null;
721 private NewCollectionMetadataPrompt ncm_prompt = null;
722
723 public NewCollectionTask(NewCollectionDetailsPrompt ncd_prompt, NewCollectionMetadataPrompt ncm_prompt)
724 {
725 this.ncd_prompt = ncd_prompt;
726 this.ncm_prompt = ncm_prompt;
727 }
728
729 public void run()
730 {
731 if (ncm_prompt == null) {
732 Gatherer.c_man.createCollection(ncd_prompt.getDescription(), Configuration.getEmail(), ncd_prompt.getName(), ncd_prompt.getTitle(), ncd_prompt.getBase(), null);
733 }
734 else {
735 Gatherer.c_man.createCollection(ncd_prompt.getDescription(), Configuration.getEmail(), ncd_prompt.getName(), ncd_prompt.getTitle(), null, ncm_prompt.getSets());
736 ncm_prompt.dispose();
737 ncm_prompt = null;
738 }
739
740 ncd_prompt.dispose();
741 ncd_prompt = null;
742
743 // Return to some initial pane (Gather)
744 returnToInitialPane();
745
746 // Refresh the workspace tree to allow for the new collection
747 refreshWorkspaceTree(WorkspaceTree.LIBRARY_CONTENTS_CHANGED);
748
749 // Refresh the rest of the GLI
750 Gatherer.refresh(Gatherer.COLLECTION_OPENED);
751 }
752 }
753
754
755 /** 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.
756 * @param event A ChangeEvent containing information about the event that fired this call.
757 */
758 public void stateChanged(ChangeEvent event)
759 {
760 // Tell the previous pane that it has lost focus
761 if (previous_pane != null) {
762 if (previous_pane == enrich_pane) {
763 enrich_pane.loseFocus();
764 }
765 else if (previous_pane == design_pane) {
766 design_pane.loseFocus();
767 }
768 else if (previous_pane == create_pane) {
769 create_pane.loseFocus();
770 }
771 }
772
773 menu_bar.tabSelected(tab_pane.getSelectedIndex());
774 int selected_index = tab_pane.getSelectedIndex();
775 if (selected_index == tab_pane.indexOfComponent(download_pane)) {
776 download_pane.gainFocus();
777 }
778 else if (selected_index == tab_pane.indexOfComponent(gather_pane)) {
779 gather_pane.gainFocus();
780 }
781 else if (selected_index == tab_pane.indexOfComponent(enrich_pane)) {
782 enrich_pane.gainFocus();
783 }
784 else if (selected_index == tab_pane.indexOfComponent(design_pane)) {
785 design_pane.gainFocus();
786 }
787 else if (selected_index == tab_pane.indexOfComponent(create_pane)) {
788 create_pane.gainFocus();
789 }
790
791 previous_pane = (JPanel) tab_pane.getSelectedComponent();
792 }
793
794
795 private MouseListener mouse_blocker_listener = new MouseAdapter() {};
796
797 public void updateUI()
798 {
799 JPanel pane = (JPanel) getContentPane();
800 pane.updateUI();
801 // Also update all of the tabs according to workflow.
802 workflowUpdate("Download", Configuration.get("workflow.download", false));
803 workflowUpdate("Gather", Configuration.get("workflow.gather", false));
804 workflowUpdate("Enrich", Configuration.get("workflow.enrich", false));
805 workflowUpdate("Design", Configuration.get("workflow.design", false));
806 workflowUpdate("Create", Configuration.get("workflow.create", false));
807 }
808
809 public void wait(boolean waiting) {
810 Component glass_pane = getGlassPane();
811 if(waiting) {
812 // Show wait cursor.
813 glass_pane.addMouseListener(mouse_blocker_listener);
814 glass_pane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
815 glass_pane.setVisible(true);
816 }
817 else {
818 // Hide wait cursor.
819 glass_pane.setVisible(false);
820 glass_pane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
821 glass_pane.removeMouseListener(mouse_blocker_listener);
822 }
823 glass_pane = null;
824 }
825
826 public void workflowUpdate(String raw, boolean state) {
827 WorkflowUpdater task = new WorkflowUpdater(raw, state);
828 SwingUtilities.invokeLater(task);
829 task = null;
830 }
831
832
833 /**Overridden from JFrame so we can exit safely when window is closed (or destroyed).
834 * @param event A <strong>WindowEvent</strong> containing information about the event that fired this call.
835 */
836 protected void processWindowEvent(WindowEvent event) {
837 if(event.getID() == WindowEvent.WINDOW_CLOSING) {
838 exit();
839 }
840 }
841
842
843 /** 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.
844 */
845 private class MenuListenerImpl
846 implements MenuListener {
847 /** Called whenever a popup menu is hidden, but we don't care.
848 * @param e Some <strong>MenuEvent</strong> that we could care less about.
849 */
850 public void menuCanceled(MenuEvent e) {
851 }
852 /** Called whenever a menu header (ie button) becomes unselected, but we don't care.
853 * @param e Some <strong>MenuEvent</strong> that we could care less about.
854 */
855 public void menuDeselected(MenuEvent e) {
856 }
857 /** 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.
858 * @param e The <strong>MenuEvent</strong> whose source is checked.
859 */
860 public void menuSelected(MenuEvent e) {
861 if(e.getSource() == menu_bar.help) {
862 if(menu_bar.help.isSelected()) {
863 menu_bar.help.doClick(10);
864 }
865 }
866 }
867 }
868
869 private class TabUpdater
870 implements Runnable {
871 private boolean ready = false;
872 private int download_pos = -1;
873 private int enrich_pos = -1;
874 private int design_pos = -1;
875 private int create_pos = -1;
876 private int export_pos = -1;
877 private JTabbedPane tab_pane = null;
878
879 public TabUpdater(JTabbedPane tab_pane, boolean ready) {
880 this.ready = ready;
881 this.tab_pane = tab_pane;
882 download_pos = tab_pane.indexOfComponent(download_pane);
883 enrich_pos = tab_pane.indexOfComponent(enrich_pane);
884 design_pos = tab_pane.indexOfComponent(design_pane);
885 create_pos = tab_pane.indexOfComponent(create_pane);
886 }
887
888 public void run()
889 {
890 if (download_pos != -1) {
891 if (ready) {
892 tab_pane.setEnabledAt(download_pos, Configuration.get("workflow.download", false));
893 }
894 else {
895 tab_pane.setEnabledAt(download_pos, Configuration.get("workflow.download", true));
896 }
897 }
898 if (enrich_pos != -1) {
899 tab_pane.setEnabledAt(enrich_pos, ready && Configuration.get("workflow.enrich", false));
900 }
901 if (design_pos != -1) {
902 tab_pane.setEnabledAt(design_pos, ready && Configuration.get("workflow.design", false) && Configuration.getMode() > Configuration.ASSISTANT_MODE);
903 }
904 if (create_pos != -1) {
905 tab_pane.setEnabledAt(create_pos, ready && Configuration.get("workflow.create", false));
906 }
907 }
908
909 public void setReady(boolean ready) {
910 this.ready = ready;
911 }
912 }
913
914 private class WorkflowUpdater
915 implements Runnable {
916 private boolean state;
917 private String raw;
918 public WorkflowUpdater(String raw, boolean state) {
919 this.raw = raw;
920 this.state = state;
921 }
922 public void run() {
923 setTabEnabled(raw, state);
924 }
925 }
926}
Note: See TracBrowser for help on using the repository browser.