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

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

added in the format pane

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