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

Last change on this file since 13399 was 13399, checked in by mdewsnip, 17 years ago

Tidied up default metadata sets and added a "addRequiredMetadataSets" function so the extracted metadata set is always loaded when creating or loading a collection.

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