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

Last change on this file since 11662 was 11629, checked in by mdewsnip, 18 years ago

Kissed the horrible TreeSynchronizer goodbye.

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