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

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

Tidied up all the CollectionManager functions for getting loaded collection paths, and made them static, as part of making CollectionManager fully static.

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