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

Last change on this file since 12119 was 12117, checked in by kjdon, 18 years ago

Changed text handling to use Dictionary.get rather than Dictionary.setText or Dictionary.registerBoth etc. removed the Dictionary.register(tab_pane) bit and set the text and tooltips in the addTab method. also removed mnemonics cos they suck for other languages

  • Property svn:keywords set to Author Date Id Revision
File size: 33.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.remote.RemoteGreenstoneServer;
62import org.greenstone.gatherer.util.JarTools;
63import org.greenstone.gatherer.util.StaticStrings;
64import org.greenstone.gatherer.util.Utility;
65
66/** The GUIManager is in charge of creating the Gatherer window frame then filling it with the goodness of the view panes. GUIManager not only creates these panes, but allows some messaging between them. Furthermore GUIManager includes functionality from menu driven choices, simply as it was easier to put it here once and have it accessible from all pane children. */
67public class GUIManager
68 extends JFrame
69 implements ActionListener, ChangeListener, WindowFocusListener{
70 /** The download pane contains controls for downloading internet sites. */
71 public DownloadPane download_pane = null;
72 /** The gather pane is more like a file manager where you drag files from one tree to another. */
73 public GatherPane gather_pane = null;
74 /** The enrich pane is used to assign, edit and remove metadata from files within the collection. */
75 public EnrichPane enrich_pane = null;
76 /** The design pane allows you to edit the design of the library in terms of the collection configuration file. - the stuff that requires rebuilding */
77 public DesignPane design_pane = null;
78 /** The create pane contains scripting options for importing and building collections into libraries. */
79 public CreatePane create_pane = null;
80 /** 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 */
81 public FormatPane format_pane = null;
82
83 public FileOpenActionListener foa_listener = new FileOpenActionListener();
84
85
86 /** A reference to the currently instantiated help window, if any. */
87 private HelpFrame help = null;
88 /** The menu bar. */
89 public MenuBar menu_bar = null;
90 public MetaAuditFrame meta_audit;
91 /** Are certain panes currently locked? */
92 private boolean locked = false;
93 /** The size of the Gatherer window. */
94 private Dimension size = null;
95 /** The panel within the window that other components are placed on. */
96 private JPanel content_pane = null;
97 /** The last view pane selected. */
98 private JPanel previous_pane;
99 /** The main tab pane containing the different views, available here to trap view change events. */
100 private JTabbedPane tab_pane = null;
101 /** A threaded tab changer to try and avoid NPE on exit. */
102 private TabUpdater tab_updater = null;
103
104
105
106
107
108 final static String newline = "\n";
109 final static String space = " ";
110
111
112 /**Constructor. Enable window events and arranges all other components.
113 * @param size The intial <strong>Dimension</strong> of the screen.
114 */
115 public GUIManager(Dimension size) {
116 super();
117 // Initialization
118 this.help = new HelpFrame();
119 this.size = size;
120
121 this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
122
123 // 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.
124 this.addFocusListener(new GLIGUIFocusListener());
125
126 this.addWindowFocusListener(this);
127
128 // Make the Tool tip hang around for a rediculous amount of time.
129 ToolTipManager.sharedInstance().setDismissDelay(10000);
130
131 // Set up some other UI stuff. (fonts handled in Gatherer.main())
132 UIManager.put("FileChooser.lookInLabelText", Dictionary.get("SaveCollectionBox.Look_In"));
133 UIManager.put("FileChooser.filesOfTypeLabelText", Dictionary.get("SaveCollectionBox.Files_Of_Type"));
134 UIManager.put("FileChooser.fileNameLabelText", Dictionary.get("SaveCollectionBox.File_Name"));
135 }
136
137
138
139 public void windowGainedFocus(WindowEvent e) {
140 //System.out.println("JPanel windowGainedFocus.");
141 }
142
143 public void windowLostFocus(WindowEvent e) {
144 //System.out.println("JPanel windowLostFocus.");
145
146 if (Gatherer.c_man != null && Gatherer.c_man.ready() && Gatherer.c_man.getCollection().cdm != null) {
147 Gatherer.c_man.getCollection().cdm.save();
148 }
149 //Gatherer.g_man.design_pane.saveConfiguration();
150
151 }
152
153
154 private class GLIGUIFocusListener
155 extends FocusAdapter {
156 public void focusGained(FocusEvent e) {
157 if (ModalDialog.current_modal != null) {
158 ModalDialog.current_modal.makeVisible();
159 ModalDialog.current_modal.toFront();
160 }
161 }
162 }
163
164 /** 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.
165 * @param event An <strong>ActionEvent</strong> containing information about the action that has occured.
166 */
167 public void actionPerformed(ActionEvent event) {
168 Object esrc = event.getSource();
169 // *************
170 // File Options.
171 // *************
172 if (esrc == menu_bar.file_associations) {
173 Gatherer.assoc_man.edit();
174 }
175 else if (esrc == menu_bar.file_close) {
176 saveThenCloseCurrentCollection();
177 }
178 else if (esrc == menu_bar.file_delete) {
179 DeleteCollectionPrompt dcp = new DeleteCollectionPrompt();
180 if (dcp.display()) {
181 saveThenCloseCurrentCollection();
182 }
183 dcp.destroy();
184 dcp = null;
185 System.gc();
186 }
187 else if (esrc == menu_bar.file_cdimage) {
188 WriteCDImagePrompt wcdip = new WriteCDImagePrompt();
189 wcdip.display();
190 wcdip.destroy();
191 wcdip = null;
192 }
193 else if (esrc == menu_bar.file_exportas) {
194 ExportAsPrompt eap = new ExportAsPrompt();
195 eap.display();
196 eap.destroy();
197 eap = null;
198 }
199 else if (esrc == menu_bar.file_exit) {
200 exit();
201 }
202 else if (esrc == menu_bar.file_new) {
203 new NewCollectionTask().start();
204 }
205 else if (esrc == menu_bar.file_open) {
206 new OpenCollectionTask().start();
207 }
208 else if (esrc == menu_bar.file_options) {
209 // Just incase the user has edited the GeneralSettings of a collection without losing focus afterwards. Well I'm forever losing foc... ooh shiney.
210 design_pane.loseFocus();
211 // And spawn a new preferences.
212 new Preferences();
213 }
214 else if (esrc == menu_bar.file_save) {
215 Gatherer.c_man.saveCollection();
216 }
217
218 // *************
219 // Edit Options.
220 // *************
221 else if(esrc == menu_bar.edit_copy) {
222 try {
223 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
224 // Get the component with selected text as a JTextComponent
225 JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner();//getFocusOwner();
226 text.copy();
227 }
228 catch (Exception cce) {
229 // If the component is not a text component ignore the copy command
230 DebugStream.println(cce.toString());
231 }
232 }
233 else if(esrc == menu_bar.edit_cut) {
234 try {
235 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
236 // Get the component with selected text as a JTextComponent
237 JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner();
238 // Cut the text to the clipboard
239 text.cut();
240 }
241 catch (ClassCastException cce) {
242 // If the component is not a text component ignore the cut command
243 DebugStream.println(cce.toString());
244 }
245 }
246 else if(esrc == menu_bar.edit_paste) {
247 try {
248 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
249 // Get the component with selected text as a JTextComponent
250 JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner();
251 // Cut the text to the clipboard
252 text.paste();
253 }
254 catch (ClassCastException cce) {
255 // If the component is not a text component ignore the paste command
256 DebugStream.println(cce.toString());
257 }
258 }
259
260 // *************
261 // Help Options.
262 // *************
263 else if (esrc == menu_bar.help_general) {
264 HelpFrame.setView("introduction");
265 }
266 else if (esrc == menu_bar.help_download) {
267 HelpFrame.setView("downloadingfiles");
268 }
269 else if (esrc == menu_bar.help_gather) {
270 HelpFrame.setView("collectingfiles");
271 }
272 else if (esrc == menu_bar.help_enrich) {
273 HelpFrame.setView("enrichingacollection");
274 }
275 else if (esrc == menu_bar.help_design) {
276 HelpFrame.setView("designingacollection");
277 }
278 else if (esrc == menu_bar.help_create) {
279 HelpFrame.setView("producingthecollection");
280 }
281 else if (esrc == menu_bar.help_format) {
282 HelpFrame.setView("formattingacollection");
283 }
284 else if (esrc == menu_bar.help_about) {
285 new AboutDialog(this);
286 }
287 }
288
289
290 /** 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.
291 */
292 public void afterDisplay() {
293 if (download_pane != null) {
294 download_pane.afterDisplay();
295 }
296 enrich_pane.afterDisplay();
297 }
298
299
300 public void saveThenCloseCurrentCollection()
301 {
302 tab_pane.setSelectedComponent(gather_pane);
303 Gatherer.c_man.saveCollection();
304 Gatherer.c_man.closeCollection();
305 }
306
307
308 /** This is called when we're absolutely finished with the GLI. It is *not* called when the applet is suspended.
309 */
310 public void destroy()
311 {
312 // Destroying create pane ensures the latest log has been closed
313 if (create_pane != null) {
314 create_pane.destroy();
315 }
316
317 // Deal to help
318 if (help != null) {
319 help.destroy();
320 help = null;
321 }
322 }
323
324
325 /** Enabled events on the window to be trapped, creates all the visual components, then builds the tab and other layouts.
326 */
327 public void display() {
328 content_pane = (JPanel) this.getContentPane();
329 // Enable window-type events to be fired.
330 enableEvents(AWTEvent.WINDOW_EVENT_MASK);
331 // Initialise and layout sub-components, plus other window dressing.
332 try {
333 this.setSize(size);
334
335 // Set the title
336 String collection_title = null;
337 String collection_name = null;
338 if (Gatherer.c_man.ready()) {
339 Collection collection = Gatherer.c_man.getCollection();
340 collection_title = collection.getTitle();
341 collection_name = collection.getName();
342 collection = null;
343 }
344 setTitle(collection_title, collection_name);
345 collection_title = null;
346 collection_name = null;
347
348 // Pretty corner icon
349 this.setIconImage(JarTools.getImage("gatherer_small.gif").getImage());
350 // BorderLayout for the main screen. I'll try my best to avoid these in subcomponents as they're space greedy.
351 content_pane.setLayout(new BorderLayout());
352 // Create the menu-bar and stick it up the top.
353 menu_bar = new MenuBar(new MenuListenerImpl());
354
355 //feedback changes
356 //content_pane.add(menu_bar, BorderLayout.NORTH);
357 this.setJMenuBar(menu_bar);
358 // end feedback changes
359
360 // Create the tabbed pane and plop it in the center where it will
361 // expand to consume all available space like any good gas would.
362 tab_pane = new JTabbedPane();
363 tab_pane.addChangeListener(this);
364 tab_pane.setFont(Configuration.getFont("general.font", false));
365
366 if (Configuration.get("workflow.download", true)) {
367 download_pane = new DownloadPane();
368 // "GUI.Download_Tooltip" is used automatically
369 tab_pane.addTab(Dictionary.get("GUI.Download"), JarTools.getImage("download.gif"), download_pane, Dictionary.get("GUI.Download_Tooltip"));
370 tab_pane.setEnabledAt(tab_pane.indexOfComponent(download_pane), Configuration.get("workflow.download", false));
371 }
372
373 gather_pane = new GatherPane();
374 gather_pane.display();
375 if (Configuration.get("workflow.gather", true)) {
376 // "GUI.Gather_Tooltip" is used automatically
377 tab_pane.addTab(Dictionary.get("GUI.Gather"), JarTools.getImage("gather.gif"), gather_pane, Dictionary.get("GUI.Gather_Tooltip"));
378 tab_pane.setEnabledAt(tab_pane.indexOfComponent(gather_pane), Configuration.get("workflow.gather", false));
379 }
380
381 enrich_pane = new EnrichPane();
382 enrich_pane.display();
383 if (Configuration.get("workflow.enrich", true)) {
384 // "GUI.Enrich_Tooltip" is used automatically
385 tab_pane.addTab(Dictionary.get("GUI.Enrich"), JarTools.getImage("enrich.gif"), enrich_pane, Dictionary.get("GUI.Enrich_Tooltip"));
386 tab_pane.setEnabledAt(tab_pane.indexOfComponent(enrich_pane), false);
387 }
388
389 design_pane = new DesignPane();
390 design_pane.display();
391 if (Configuration.get("workflow.design", true)) {
392 // "GUI.Design_Tooltip" is used automatically
393 tab_pane.addTab(Dictionary.get("GUI.Design"), JarTools.getImage("design.gif"), design_pane, Dictionary.get("GUI.Design_Tooltip"));
394 tab_pane.setEnabledAt(tab_pane.indexOfComponent(design_pane), false);
395 }
396
397 create_pane = new CreatePane();
398 create_pane.display();
399 if (Configuration.get("workflow.create", true)) {
400 // "GUI.Create_Tooltip" is used automatically
401 tab_pane.addTab(Dictionary.get("GUI.Create"), JarTools.getImage("create.gif"), create_pane, Dictionary.get("GUI.Create_Tooltip"));
402 tab_pane.setEnabledAt(tab_pane.indexOfComponent(create_pane), false);
403 }
404
405 format_pane = new FormatPane();
406 format_pane.display();
407 if (Configuration.get("workflow.format", true)) {
408 tab_pane.addTab(Dictionary.get("GUI.Format"), JarTools.getImage("format.gif"), format_pane, Dictionary.get("GUI.Format_Tooltip"));
409 tab_pane.setEnabledAt(tab_pane.indexOfComponent(format_pane), false);
410 }
411
412 // The MetaAuditFrame must be created after the gather/enrich panes but before they get focus
413 meta_audit = new MetaAuditFrame();
414
415 // Select the collect pane if it is available
416 if (tab_pane.indexOfComponent(gather_pane) != -1) {
417 tab_pane.setSelectedComponent(gather_pane);
418 }
419 // Otherwise find the first tab that is enabled and select that.
420 else {
421 for (int i = 0; i < tab_pane.getTabCount(); i++) {
422 if (tab_pane.isEnabledAt(i)) {
423 tab_pane.setSelectedIndex(i);
424 break;
425 }
426 }
427 }
428
429 content_pane.add(tab_pane, BorderLayout.CENTER);
430
431 // Add an extra progress bar at the bottom of every screen when using a remote Greenstone server
432 if (Gatherer.isGsdlRemote) {
433 JPanel remote_greenstone_server_progress_panel = new JPanel();
434 JLabel remote_greenstone_server_progress_label = new JLabel(Dictionary.get("RemoteGreenstoneServer.Progress"));
435 remote_greenstone_server_progress_panel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
436 remote_greenstone_server_progress_panel.setLayout(new BorderLayout());
437 remote_greenstone_server_progress_panel.add(remote_greenstone_server_progress_label, BorderLayout.WEST);
438 remote_greenstone_server_progress_panel.add(RemoteGreenstoneServer.getProgressBar(), BorderLayout.CENTER);
439 content_pane.add(remote_greenstone_server_progress_panel, BorderLayout.SOUTH);
440 }
441
442 // Call refresh to update all controls to reflect current collection status.
443 refresh(-1, Gatherer.c_man.ready());
444 }
445 catch (Exception e) {
446 DebugStream.printStackTrace(e);
447 // The GUI failing to build is an app killer
448 e.printStackTrace();
449 System.exit(1);
450 }
451 }
452
453
454 /** This method ensures that all the things needing saving are saved before Gatherer.exit() is called.
455 */
456 public void exit()
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, Gatherer.c_man.getCollectionFilePath());
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();
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 /** Returns to some "initial" pane (when no collection is loaded) */
606 public void returnToInitialPane()
607 {
608 if (gather_pane != null) {
609 tab_pane.setSelectedComponent(gather_pane);
610 }
611 }
612
613
614 /** Specifies whether a certain tab is enabled or not. */
615 private void setTabEnabled(String rawname, boolean state) {
616 // Retrieve the dictionary based name.
617 String name = Dictionary.get("GUI." + rawname);
618 int index = tab_pane.indexOfTab(name);
619 // Of course we may not have this tab available.
620 if(index != -1) {
621 // Some tabs are also dependant on if a collection is ready
622 Component component = tab_pane.getComponentAt(index);
623 if(component == enrich_pane || component == design_pane || component == create_pane || component == format_pane) {
624 tab_pane.setEnabledAt(index, state && Gatherer.c_man != null && Gatherer.c_man.ready());
625 }
626 else {
627 tab_pane.setEnabledAt(index, state);
628 }
629 // If this was the currently selected tab and it is now disabled, change the view to the first enabled tab.
630 if(tab_pane.getSelectedIndex() == index && !state) {
631 boolean found = false;
632 for(int i = 0; !found && i < tab_pane.getTabCount(); i++) {
633 if(tab_pane.isEnabledAt(i)) {
634 tab_pane.setSelectedIndex(i);
635 found = true;
636 }
637 }
638 // If there are no tabs enabled, which should be impossible, then select the first tab
639 if(!found) {
640 tab_pane.setSelectedIndex(0);
641 }
642 }
643 }
644 }
645
646 /** 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.
647 * @param title
648 * @param name
649 */
650 public void setTitle(String title, String name) {
651 // Finally display the collection name in the title bar.
652 StringBuffer title_buffer = new StringBuffer(Gatherer.PROGRAM_NAME);
653 title_buffer.append(StaticStrings.SPACE_CHARACTER);
654 title_buffer.append(StaticStrings.SPACE_CHARACTER);
655 // Describe the current user mode
656 title_buffer.append(StaticStrings.MODE_STR);
657 title_buffer.append(Configuration.getModeAsString());
658 title_buffer.append(StaticStrings.SPACE_CHARACTER);
659 title_buffer.append(StaticStrings.SPACE_CHARACTER);
660 // Now for the current collection
661 title_buffer.append(StaticStrings.COLLECTION_STR);
662 if (title != null && name != null) {
663 title_buffer.append(title);
664 title_buffer.append(StaticStrings.SPACE_CHARACTER);
665 title_buffer.append(StaticStrings.OPEN_PARENTHESIS_CHARACTER);
666 title_buffer.append(name);
667 title_buffer.append(StaticStrings.CLOSE_PARENTHESIS_CHARACTER);
668 }
669 else {
670 title_buffer.append(Dictionary.get("Collection.No_Collection"));
671 }
672 this.setTitle(title_buffer.toString());
673 title_buffer = null;
674 }
675
676
677 private class OpenCollectionTask
678 extends Thread
679 {
680 public void run()
681 {
682 // If using a remote Greenstone check if the collection configurations have been downloaded; do so if not
683 if (Gatherer.isGsdlRemote && !CollectionManager.downloaded_collection_configurations) {
684 if (RemoteGreenstoneServer.downloadCollectionConfigurations().equals("")) {
685 // Something went wrong downloading the collection configurations
686 return;
687 }
688
689 CollectionManager.downloaded_collection_configurations = true;
690 }
691
692 String collection_file_path = showOpenCollectionDialog();
693
694 // User has selected a collection to open
695 if (collection_file_path != null) {
696 // If there is already a collection open, save and close it
697 if (Gatherer.c_man.ready()) {
698 saveThenCloseCurrentCollection();
699 }
700
701 // Open the selected collection
702 Gatherer.c_man.loadCollection(collection_file_path);
703 }
704 }
705 }
706
707
708 /** When the load collection option is chosen this method is called to produce the modal file load prompt.
709 */
710 private String showOpenCollectionDialog()
711 {
712 // We first try the simple open collection dialog
713 SimpleOpenCollectionDialog dialog = new SimpleOpenCollectionDialog();
714 int user_choice = dialog.display();
715
716 // Used simple collection list
717 if (user_choice == SimpleOpenCollectionDialog.OK_OPTION) {
718 return dialog.getFileName();
719 }
720
721 // Chosen to use the advanced 'browse' dialog
722 File collect_directory = null;
723 if (user_choice == SimpleOpenCollectionDialog.BROWSE_OPTION) {
724 if (Gatherer.GS3) {
725 collect_directory = new File(Utility.getSitesDir(Configuration.gsdl3_path));
726 }
727 else {
728 collect_directory = new File(Gatherer.getCollectDirectoryPath());
729 }
730 OpenCollectionDialog chooser = new OpenCollectionDialog(collect_directory);
731 return chooser.getFileName();
732 }
733
734 // User must have cancelled the action
735 return null;
736 }
737
738
739 /** When called this method causes the MetadataAuditTable to display a nice dialog box which contains all the metadata assigned in the collection.
740 */
741 public void showMetaAuditBox() {
742 wait(true);
743 meta_audit.display();
744 wait(false);
745 }
746
747
748 private class NewCollectionTask
749 extends Thread
750 {
751 public void run()
752 {
753 // If using a remote Greenstone check if the collection configurations have been downloaded; do so if not
754 if (Gatherer.isGsdlRemote && !CollectionManager.downloaded_collection_configurations) {
755 if (RemoteGreenstoneServer.downloadCollectionConfigurations().equals("")) {
756 // Something went wrong downloading the collection configurations
757 return;
758 }
759
760 CollectionManager.downloaded_collection_configurations = true;
761 }
762
763 // Create the collection details prompt from new collection prompt
764 NewCollectionMetadataPrompt ncm_prompt = null;
765 NewCollectionDetailsPrompt ncd_prompt = new NewCollectionDetailsPrompt();
766 // If no previous collection was indicated as a model design, then show the metadata selection prompt from new collection prompt
767 if(!ncd_prompt.isCancelled() && (ncd_prompt.getBase() == null)) {
768 ncm_prompt = new NewCollectionMetadataPrompt();
769 }
770 // Create the new collection (if not cancelled) in a new thread.
771 if (!ncd_prompt.isCancelled() && (ncm_prompt == null || !ncm_prompt.isCancelled())) {
772 // If there is already a collection open, save and close it.
773 if (Gatherer.c_man.ready()) {
774 saveThenCloseCurrentCollection();
775 }
776
777 // Create new collection.
778 if (ncm_prompt == null) {
779 Gatherer.c_man.createCollection(ncd_prompt.getDescription(), Configuration.getEmail(), ncd_prompt.getName(), ncd_prompt.getTitle(), ncd_prompt.getBase(), null);
780 }
781 else {
782 Gatherer.c_man.createCollection(ncd_prompt.getDescription(), Configuration.getEmail(), ncd_prompt.getName(), ncd_prompt.getTitle(), null, ncm_prompt.getSets());
783 ncm_prompt.dispose();
784 }
785
786 ncd_prompt.dispose();
787
788 // Return to some initial pane (Gather)
789 returnToInitialPane();
790
791 // Refresh the workspace tree to allow for the new collection
792 refreshWorkspaceTree(WorkspaceTree.LIBRARY_CONTENTS_CHANGED);
793
794 // Refresh the rest of the GLI
795 Gatherer.refresh(Gatherer.COLLECTION_OPENED);
796 }
797
798 // Done
799 ncd_prompt = null;
800 ncm_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.