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

Last change on this file since 12730 was 12609, checked in by kjdon, 18 years ago

exit now takes an int exit_status argument, which is passed to Gatherer.exit

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