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

Last change on this file since 29036 was 29036, checked in by ak19, 10 years ago

JOptionPane yes, no, cancel, ok buttons need to be translatable

  • Property svn:keywords set to Author Date Id Revision
File size: 42.3 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.FilenameEncoding;
62import org.greenstone.gatherer.metadata.MetadataSet;
63import org.greenstone.gatherer.metadata.MetadataXMLFileManager;
64import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
65import org.greenstone.gatherer.util.JarTools;
66import org.greenstone.gatherer.util.StaticStrings;
67import org.greenstone.gatherer.util.Utility;
68
69/** 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. */
70public class GUIManager
71 extends JFrame
72 implements ActionListener, ChangeListener, WindowFocusListener{
73 /** The download pane contains controls for downloading internet sites. */
74 public DownloadPane download_pane = null;
75 /** The gather pane is more like a file manager where you drag files from one tree to another. */
76 public GatherPane gather_pane = null;
77 /** The enrich pane is used to assign, edit and remove metadata from files within the collection. */
78 public EnrichPane enrich_pane = null;
79 /** The design pane allows you to edit the design of the library in terms of the collection configuration file. - the stuff that requires rebuilding */
80 public DesignPane design_pane = null;
81 /** The create pane contains scripting options for importing and building collections into libraries. */
82 public CreatePane create_pane = null;
83 /** 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 */
84 public FormatPane format_pane = null;
85
86 public FileOpenActionListener foa_listener = new FileOpenActionListener();
87
88
89 /** A reference to the currently instantiated help window, if any. */
90 private HelpFrame help = null;
91 /** The menu bar. */
92 public MenuBar menu_bar = null;
93 public MetaAuditFrame meta_audit;
94 /** Are certain panes currently locked? */
95 private boolean locked = false;
96 /** The size of the Gatherer window. */
97 private Dimension size = null;
98 /** The panel within the window that other components are placed on. */
99 private JPanel content_pane = null;
100 /** The last view pane selected. */
101 private JPanel previous_pane;
102 /** The main tab pane containing the different views, available here to trap view change events. */
103 private JTabbedPane tab_pane = null;
104 /** A threaded tab changer to try and avoid NPE on exit. */
105 private TabUpdater tab_updater = null;
106
107 final static String newline = "\n";
108 final static String space = " ";
109
110
111 /**Constructor. Enable window events and arranges all other components.
112 * @param size The intial <strong>Dimension</strong> of the screen.
113 */
114 public GUIManager(Dimension size) {
115 super();
116 this.setComponentOrientation(Dictionary.getOrientation());
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 // JOptionPane options
137 // http://www.java2s.com/Tutorial/Java/0240__Swing/SettingJOptionPanebuttonlabelstoFrench.htm
138 UIManager.put("OptionPane.cancelButtonText", Dictionary.get("General.Cancel"));
139 UIManager.put("OptionPane.noButtonText", Dictionary.get("General.No"));
140 UIManager.put("OptionPane.okButtonText", Dictionary.get("General.OK"));
141 UIManager.put("OptionPane.yesButtonText", Dictionary.get("General.Yes"));
142 }
143
144
145 public void windowGainedFocus(WindowEvent e)
146 {
147 }
148
149
150 public void windowLostFocus(WindowEvent e)
151 {
152 // Save the loaded collection
153 if (Gatherer.c_man != null && Gatherer.c_man.ready() && Gatherer.c_man.getCollection().cdm != null) {
154 Gatherer.c_man.saveCollection();
155 }
156 }
157
158
159 private class GLIGUIFocusListener
160 extends FocusAdapter {
161 public void focusGained(FocusEvent e) {
162 if (ModalDialog.current_modal != null) {
163 ModalDialog.current_modal.makeVisible();
164 ModalDialog.current_modal.toFront();
165 }
166 }
167 }
168
169 /** 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.
170 * @param event An <strong>ActionEvent</strong> containing information about the action that has occured.
171 */
172 public void actionPerformed(ActionEvent event) {
173 Object esrc = event.getSource();
174 // *************
175 // File Options.
176 // *************
177 if (esrc == menu_bar.file_associations) {
178 Gatherer.assoc_man.edit();
179 }
180 else if (esrc == menu_bar.file_close) {
181 saveThenCloseCurrentCollection();
182 }
183 else if (esrc == menu_bar.file_delete) {
184 new DeleteCollectionTask().start();
185 }
186 else if (esrc == menu_bar.file_cdimage) {
187 WriteCDImagePrompt wcdip = new WriteCDImagePrompt();
188 wcdip.display();
189 wcdip.destroy();
190 wcdip = null;
191 }
192 else if (esrc == menu_bar.file_exportas) {
193 ExportAsPrompt eap = new ExportAsPrompt();
194 eap.display();
195 eap.destroy();
196 eap = null;
197 }
198 else if (esrc == menu_bar.file_exit) {
199 exit();
200 }
201 else if (esrc == menu_bar.file_new) {
202 new NewCollectionTask().start();
203 }
204 else if (esrc == menu_bar.file_open) {
205 new OpenCollectionTask().start();
206 }
207 else if (esrc == menu_bar.file_options) {
208 new Preferences();
209 }
210 else if (esrc == menu_bar.file_save) {
211 // Very important: make sure metadata values are saved too
212 enrich_pane.stopEditingAndRebuild();
213 // Make sure all the metadata has been saved to file
214 MetadataXMLFileManager.saveMetadataXMLFiles();
215
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("themirrorview");
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 closeCurrentCollection()
302 {
303 tab_pane.setSelectedComponent(gather_pane);
304 Gatherer.c_man.closeCollection();
305 FilenameEncoding.closeCollection(); // clear filename-to-encodings map
306 }
307
308
309 public void saveThenCloseCurrentCollection()
310 {
311 Gatherer.c_man.saveCollection();
312 closeCurrentCollection();
313 }
314
315
316 /** This is called when we're absolutely finished with the GLI. It is *not* called when the applet is suspended.
317 */
318 public void destroy()
319 {
320 // Destroying create pane ensures the latest log has been closed
321 if (create_pane != null) {
322 create_pane.destroy();
323 }
324
325 // Deal to help
326 if (help != null) {
327 help.destroy();
328 help = null;
329 }
330 }
331
332
333 /** Enabled events on the window to be trapped, creates all the visual components, then builds the tab and other layouts.
334 */
335 public void display() {
336 content_pane = (JPanel) this.getContentPane();
337 content_pane.setComponentOrientation(Dictionary.getOrientation());
338
339 // Enable window-type events to be fired.
340 enableEvents(AWTEvent.WINDOW_EVENT_MASK);
341 // Initialise and layout sub-components, plus other window dressing.
342 try {
343 this.setSize(size);
344
345 // Set the title
346 String collection_title = null;
347 String collection_name = null;
348 if (Gatherer.c_man.ready()) {
349 Collection collection = Gatherer.c_man.getCollection();
350 collection_title = collection.getTitle();
351 collection_name = collection.getGroupQualifiedName(true);
352 collection = null;
353 }
354 setTitle(collection_title, collection_name);
355 collection_title = null;
356 collection_name = null;
357
358 // Pretty corner icon
359 String gsmall_image = "gatherer.png";
360 if (Configuration.fedora_info.isActive()) {
361 gsmall_image = "fli-" + gsmall_image;
362 }
363 if(Gatherer.isGsdlRemote) {
364 gsmall_image = "client-" + gsmall_image;
365 }
366 this.setIconImage(JarTools.getImage(gsmall_image).getImage());
367 // BorderLayout for the main screen. I'll try my best to avoid these in subcomponents as they're space greedy.
368 content_pane.setLayout(new BorderLayout());
369 // Create the menu-bar and stick it up the top.
370 menu_bar = new MenuBar(new MenuListenerImpl());
371 menu_bar.setComponentOrientation(Dictionary.getOrientation());
372
373 //feedback changes
374 //content_pane.add(menu_bar, BorderLayout.NORTH);
375 this.setJMenuBar(menu_bar);
376 // end feedback changes
377
378 // Create the tabbed pane and plop it in the center where it will
379 // expand to consume all available space like any good gas would.
380 tab_pane = new JTabbedPane();
381 tab_pane.setComponentOrientation(Dictionary.getOrientation());
382 tab_pane.addChangeListener(this);
383 tab_pane.setFont(Configuration.getFont("general.font", false));
384
385 if (Configuration.get("workflow.download", true) && Gatherer.isDownloadEnabled) {
386 download_pane = new DownloadPane();
387 // "GUI.Download_Tooltip" is used automatically
388 tab_pane.addTab(Dictionary.get("GUI.Download"), JarTools.getImage("download.gif"), download_pane, Dictionary.get("GUI.Download_Tooltip"));
389 tab_pane.setEnabledAt(tab_pane.indexOfComponent(download_pane), Configuration.get("workflow.download", false));
390 }
391
392 gather_pane = new GatherPane();
393 gather_pane.display();
394 if (Configuration.get("workflow.gather", true)) {
395 // "GUI.Gather_Tooltip" is used automatically
396 tab_pane.addTab(Dictionary.get("GUI.Gather"), JarTools.getImage("gather.gif"), gather_pane, Dictionary.get("GUI.Gather_Tooltip"));
397 tab_pane.setEnabledAt(tab_pane.indexOfComponent(gather_pane), Configuration.get("workflow.gather", false));
398 }
399
400 enrich_pane = new EnrichPane();
401 enrich_pane.display();
402 if (Configuration.get("workflow.enrich", true)) {
403 // "GUI.Enrich_Tooltip" is used automatically
404 tab_pane.addTab(Dictionary.get("GUI.Enrich"), JarTools.getImage("enrich.gif"), enrich_pane, Dictionary.get("GUI.Enrich_Tooltip"));
405 tab_pane.setEnabledAt(tab_pane.indexOfComponent(enrich_pane), false);
406 }
407
408 design_pane = new DesignPane();
409 design_pane.display();
410 if (Configuration.get("workflow.design", true)) {
411 // "GUI.Design_Tooltip" is used automatically
412 if (Configuration.fedora_info.isActive()) {
413 tab_pane.addTab("Plugins", JarTools.getImage("design.gif"), design_pane, Dictionary.get("GUI.Design_Tooltip"));
414 }
415 else {
416 tab_pane.addTab(Dictionary.get("GUI.Design"), JarTools.getImage("design.gif"), design_pane, Dictionary.get("GUI.Design_Tooltip"));
417 }
418
419 tab_pane.setEnabledAt(tab_pane.indexOfComponent(design_pane), false);
420 }
421
422 create_pane = new CreatePane();
423 create_pane.setComponentOrientation(Dictionary.getOrientation());
424 create_pane.display();
425 if (Configuration.get("workflow.create", true)) {
426 // "GUI.Create_Tooltip" is used automatically
427 tab_pane.addTab(Dictionary.get("GUI.Create"), JarTools.getImage("create.gif"), create_pane, Dictionary.get("GUI.Create_Tooltip"));
428 tab_pane.setEnabledAt(tab_pane.indexOfComponent(create_pane), false);
429 }
430
431 format_pane = new FormatPane();
432 format_pane.setComponentOrientation(Dictionary.getOrientation());
433 format_pane.display();
434 if (Configuration.get("workflow.format", true)) {
435 tab_pane.addTab(Dictionary.get("GUI.Format"), JarTools.getImage("format.gif"), format_pane, Dictionary.get("GUI.Format_Tooltip"));
436 tab_pane.setEnabledAt(tab_pane.indexOfComponent(format_pane), false);
437 }
438
439 // The MetaAuditFrame must be created after the gather/enrich panes but before they get focus
440 meta_audit = new MetaAuditFrame();
441 meta_audit.setComponentOrientation(Dictionary.getOrientation());
442 // Select the collect pane if it is available
443 if (tab_pane.indexOfComponent(gather_pane) != -1) {
444 tab_pane.setSelectedComponent(gather_pane);
445 }
446 // Otherwise find the first tab that is enabled and select that.
447 else {
448 for (int i = 0; i < tab_pane.getTabCount(); i++) {
449 if (tab_pane.isEnabledAt(i)) {
450 tab_pane.setSelectedIndex(i);
451 break;
452 }
453 }
454 }
455
456 content_pane.add(tab_pane, BorderLayout.CENTER);
457
458 // Add an extra progress bar at the bottom of every screen when using a remote Greenstone server
459 if (Gatherer.isGsdlRemote) {
460 JPanel remote_greenstone_server_progress_panel = new JPanel();
461 //remote_greenstone_server_progress_panel.setComponentOrientation(Dictionary.getOrientation());
462 JLabel remote_greenstone_server_progress_label = new JLabel(Dictionary.get("RemoteGreenstoneServer.Progress"));
463 //remote_greenstone_server_progress_label.setComponentOrientation(Dictionary.getOrientation());
464 remote_greenstone_server_progress_panel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
465 remote_greenstone_server_progress_panel.setLayout(new BorderLayout());
466 remote_greenstone_server_progress_panel.add(remote_greenstone_server_progress_label, BorderLayout.LINE_START);
467 remote_greenstone_server_progress_panel.add(Gatherer.remoteGreenstoneServer.getProgressBar(), BorderLayout.CENTER);
468 content_pane.add(remote_greenstone_server_progress_panel, BorderLayout.SOUTH);
469 }
470
471 // Call refresh to update all controls to reflect current collection status.
472 refresh(-1, Gatherer.c_man.ready());
473 }
474 catch (Exception e) {
475 DebugStream.printStackTrace(e);
476 // The GUI failing to build is an app killer
477 e.printStackTrace();
478 System.exit(1);
479 }
480 }
481
482 public void exit()
483 {
484 exit(0);
485 }
486
487 // some cases we have already saved the collection, but don't want to
488 // override the general.open_collection value here
489 public void exitNoCollectionSave(int exit_status) {
490 // Store the current position and size of the GLI for next time
491 Configuration.setBounds("general.bounds", true, getBounds());
492
493 // Save configuration
494 Configuration.save();
495
496 // Hide the main window
497 setVisible(false);
498
499 // If we're running as an applet we don't quit here (we quit when the browser calls GathererApplet.destroy())
500 if (!Gatherer.isApplet) {
501 Gatherer.exit(exit_status);
502 }
503
504 }
505 /** This method ensures that all the things needing saving are saved before Gatherer.exit() is called.
506 */
507 public void exit(int exit_status)
508 {
509 boolean collection_open = false;
510 // If we have a collection open remember it for next time, then save it and close it
511 if (Gatherer.c_man.ready()) {
512 // but we no longer remember open collections for remote GLI, as this causes problems
513 // in applets when other users on a machine want to use an applet and GLI wants to load
514 // a collection left open from a previous session and *requires* the old user to authenticate
515 if(Gatherer.isGsdlRemote) {
516 Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(),
517 true, "");
518 } else {
519 Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(),
520 true, CollectionManager.getLoadedCollectionColFilePath());
521 }
522 saveThenCloseCurrentCollection();
523 collection_open = true;
524 }
525 else {
526 // if there was no open collection, then write out the collect dir path for next time
527 // IF this is not the default collect directory and not a remote GLI/applet
528 if(Gatherer.isGsdlRemote || Gatherer.getCollectDirectoryPath().equals(
529 Gatherer.getDefaultGSCollectDirectoryPath(true))) {
530 Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(),
531 true, "");
532 } else {
533 Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(),
534 true, Gatherer.getCollectDirectoryPath());
535 }
536 }
537
538
539 // Basically, if GLI coldir != gsdlsite_colhome, we ask them if they want to save GLI coldir as gsdlsite_colhome
540 // If gsdlsite_colhome = "" (meaning default GS coldir) and GLI is also set to defaultGScoldir, no saving necessary.
541 // We ONLY do this for the local included apache web server, since the issue revolves around gsdlsite.cfg containing
542 // the global collecthome when using the apache web server. This is not an issue for remote GS or server.exe (the latter
543 // has separate config files specifying collecthome for when GLI is running whereas when just the server.exe is running).
544 if(!Gatherer.isGsdlRemote && !Gatherer.isPersistentServer()) {
545
546 String defaultColDir = Gatherer.getDefaultGSCollectDirectoryPath(false); // no filesep at end
547 String gliColDir = Gatherer.getCollectDirectoryPath();
548 String serverColDir = Gatherer.gsdlsite_collecthome;
549
550 boolean showSettingsDlg = true;
551 // if collectdir was changed during GLI session (to something different from what's in gsdlsite), need to ask what to store
552 String gsdlsiteColdir = Gatherer.gsdlsite_collecthome.replace("\"", "");
553 if(gliColDir.equals(gsdlsiteColdir+File.separator)) {
554 showSettingsDlg = false;
555 } else if(gsdlsiteColdir.equals("") // both set to default coldir
556 && gliColDir.equals(defaultColDir+File.separator)) {
557 showSettingsDlg = false;
558 }
559 if(showSettingsDlg) {
560
561 // else we will be showing the Collect Directory Settings Dialog
562 if(gliColDir.endsWith(File.separator)) {
563 gliColDir = gliColDir.substring(0, gliColDir.length()-1);
564 }
565
566 if(serverColDir.equals("")) {
567 serverColDir = defaultColDir;
568 }
569 collectDirSettingsDialog(defaultColDir, serverColDir, gliColDir, collection_open);
570 }
571 }
572
573 // Store the current position and size of the GLI for next time
574 Configuration.setBounds("general.bounds", true, getBounds());
575
576 // Save configuration
577 Configuration.save();
578
579 // Hide the main window
580 setVisible(false);
581
582 // If we're running as an applet we don't quit here (we quit when the browser calls GathererApplet.destroy())
583 if (!Gatherer.isApplet) {
584 Gatherer.exit(exit_status);
585 }
586 }
587
588 public void collectDirSettingsDialog(final String defaultColDir,
589 final String from, final String to, final boolean collection_open)
590 {
591 final JDialog colHomeDialog
592 = new JDialog(this, Dictionary.get("GUI.CollectHome.title"), true); // this = Gatherer.g_man
593 colHomeDialog.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
594
595
596 JRadioButton gliYes = new JRadioButton(Dictionary.get("General.Yes"), true);
597 // the default selection for GLI, collecthome=to
598 JRadioButton serverYes = new JRadioButton(Dictionary.get("General.Yes")); // not selected for the server
599 JRadioButton gliNo = null;
600 JRadioButton gliThirdOption = null;
601 JRadioButton serverNo = null;
602 JRadioButton serverThirdOption = null;
603
604 if(from.equals(defaultColDir)) {
605 gliNo = new JRadioButton(Dictionary.get("GUI.CollectHome.resetToDefault"));
606 serverNo = new JRadioButton(Dictionary.get("GUI.CollectHome.leaveAtDefault"), true);
607 // default selection for server, collecthome=from
608 } else {
609 gliNo = new JRadioButton(Dictionary.get("General.No"));
610 serverNo = new JRadioButton(Dictionary.get("General.No"), true); // default selection for server
611 if(!to.equals(defaultColDir)) { // neither from nor to is the default GS collect dir, so give them that as the third option
612 gliThirdOption = new JRadioButton(Dictionary.get("GUI.CollectHome.reset"));
613 serverThirdOption = new JRadioButton(Dictionary.get("GUI.CollectHome.reset"));
614 }
615 }
616
617 JPanel gliPanel = new JPanel(); // flowlayout by default
618 ButtonGroup gliGroup = new ButtonGroup();
619 JPanel serverPanel = new JPanel(); // flowlayout by default
620 ButtonGroup serverGroup = new ButtonGroup();
621
622 gliGroup.add(gliYes);
623 gliPanel.add(gliYes);
624 serverGroup.add(serverYes);
625 serverPanel.add(serverYes);
626
627 gliGroup.add(gliNo);
628 gliPanel.add(gliNo);
629 serverGroup.add(serverNo);
630 serverPanel.add(serverNo);
631
632 if(gliThirdOption != null) {
633 gliThirdOption = new JRadioButton("Reset to default");
634 serverThirdOption = new JRadioButton("Reset to default");
635
636 gliGroup.add(gliThirdOption);
637 gliPanel.add(gliThirdOption);
638 serverGroup.add(serverThirdOption);
639 serverPanel.add(serverThirdOption);
640 }
641
642 // vars need to be final to use them in the actionlistener below
643 final JRadioButton gli_yes = gliYes;
644 final JRadioButton gli_no = gliNo;
645 final JRadioButton gli_optional = gliThirdOption;
646 final JRadioButton server_yes = serverYes;
647 final JRadioButton server_no = serverNo;
648 final JRadioButton server_optional = serverThirdOption;
649
650 JButton okButton = new JButton(Dictionary.get("General.OK"));
651 okButton.addActionListener(new ActionListener() {
652 public void actionPerformed(ActionEvent e) {
653 // store the option chosen for GLI
654 String gliColDir = to;
655 if(gli_optional != null && gli_optional.isSelected()) {
656 // defaultColDir
657 gliColDir = "";
658 } else if(gli_yes.isSelected()) {
659 gliColDir = to;
660 } else if (gli_no.isSelected()) {
661 gliColDir = from;
662 }
663 if(defaultColDir.equals(gliColDir)) {
664 gliColDir = "";
665 }
666 if(!(collection_open && gli_yes.isSelected())) { // don't overwrite open collections
667 Configuration.setString(
668 "general.open_collection"+Configuration.gliPropertyNameSuffix(),
669 true, gliColDir);
670 }
671
672 // store the option chosen for the server's settings
673 String serverColDir = from;
674 if(server_optional != null && server_optional.isSelected()) {
675 // defaultColDir
676 serverColDir = null;
677 } else if(server_yes.isSelected()) {
678 serverColDir = to;
679 } else if (server_no.isSelected()) {
680 serverColDir = from;
681 }
682 if(serverColDir != null && defaultColDir.equals(serverColDir)) {
683 serverColDir = null;
684 }
685
686 if(serverColDir != null) {
687 serverColDir = serverColDir.replace("\"","");
688 serverColDir = "\""+serverColDir+"\"";
689 }
690
691 Gatherer.gsdlsite_collecthome = Utility.updatePropertyConfigFile(
692 Gatherer.getGsdlSiteConfigFile(), "collecthome", serverColDir);
693
694 colHomeDialog.dispose();
695 }
696 });
697
698 //String[] dirs = {from, to};
699 //JLabel message = new JLabel(Dictionary.get("GUI.CollectHome.message", dirs));
700 JLabel message = new JLabel(Dictionary.get("GUI.CollectHome.message"));
701 JLabel fromDirLine = new JLabel(Dictionary.get("GUI.CollectHome.dir", from));
702 fromDirLine.setBorder(BorderFactory.createEmptyBorder(0,25,0,0)); // padding
703 JLabel toLine = new JLabel(Dictionary.get("GUI.CollectHome.to"));
704 JLabel toDirLine = new JLabel(Dictionary.get("GUI.CollectHome.dir", to));
705 toDirLine.setBorder(BorderFactory.createEmptyBorder(0,25,0,0)); // padding
706 JLabel gliOption = new JLabel(Dictionary.get("GUI.CollectHome.gli"));
707 JLabel serverOption = new JLabel(Dictionary.get("GUI.CollectHome.server"));
708
709 JPanel mainPanel = new JPanel();
710 mainPanel.setLayout(new GridLayout(9, 1));
711 mainPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); // padding
712 mainPanel.add(message);
713 mainPanel.add(fromDirLine);
714 mainPanel.add(toLine);
715 mainPanel.add(toDirLine);
716 mainPanel.add(gliOption);
717 mainPanel.add(gliPanel);
718 mainPanel.add(serverOption);
719 mainPanel.add(serverPanel);
720 mainPanel.add(okButton);
721 Container c = colHomeDialog.getContentPane();
722 c.setLayout(new BorderLayout());
723 c.add(mainPanel, BorderLayout.CENTER);
724 colHomeDialog.getRootPane().setDefaultButton(okButton);
725
726 colHomeDialog.pack();
727 colHomeDialog.setVisible(true);
728 }
729
730
731 /** 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.
732 */
733 public void lockCollection(boolean import_stage, boolean lock)
734 {
735 locked = lock;
736
737 if (import_stage) {
738 int gather_pos = tab_pane.indexOfComponent(gather_pane);
739 if (gather_pos != -1) {
740 tab_pane.setEnabledAt(gather_pos, !lock);
741 }
742 int enrich_pos = tab_pane.indexOfComponent(enrich_pane);
743 if (enrich_pos != -1) {
744 tab_pane.setEnabledAt(enrich_pos, !lock);
745 }
746 }
747
748 int design_pos = tab_pane.indexOfComponent(design_pane);
749 if (design_pos != -1) {
750 tab_pane.setEnabledAt(design_pos, !lock);
751 }
752 }
753
754
755 public void modeChanged(int mode) {
756 // Set the title
757 String collection_title = null;
758 String collection_name = null;
759 if (Gatherer.c_man.ready()) {
760 Collection collection = Gatherer.c_man.getCollection();
761 collection_title = collection.getTitle();
762 collection_name = collection.getGroupQualifiedName(true);
763 collection = null;
764 }
765 setTitle(collection_title, collection_name);
766 collection_title = null;
767 collection_name = null;
768 // Now pass on the message to anyone who cares
769 if (download_pane != null) {
770 download_pane.modeChanged(mode);
771 }
772 if (gather_pane != null) {
773 gather_pane.modeChanged(mode);
774 }
775 if (enrich_pane != null) {
776 enrich_pane.modeChanged(mode);
777 }
778 if (design_pane != null) {
779 design_pane.modeChanged(mode);
780 }
781 if (create_pane != null) {
782 create_pane.modeChanged(mode);
783 }
784 if (format_pane != null) {
785 format_pane.modeChanged(mode);
786 }
787 }
788
789
790 public void refresh(int refresh_reason, boolean collection_loaded)
791 {
792 // Set the collection information in the title bar
793 if (collection_loaded) {
794 Collection collection = Gatherer.c_man.getCollection();
795 setTitle(collection.getTitle(), collection.getGroupQualifiedName(true));
796 }
797 else {
798 setTitle(null, null);
799 }
800
801 // Update the menu bar
802 menu_bar.refresh(refresh_reason, collection_loaded);
803
804 // Update the loaded panes
805 if (download_pane != null) {
806 download_pane.refresh(refresh_reason, collection_loaded);
807 }
808 if (gather_pane != null) {
809 gather_pane.refresh(refresh_reason, collection_loaded);
810 }
811 if (enrich_pane != null) {
812 enrich_pane.refresh(refresh_reason, collection_loaded);
813 }
814 if (design_pane != null) {
815 design_pane.refresh(refresh_reason, collection_loaded);
816 }
817 if (create_pane != null) {
818 create_pane.refresh(refresh_reason, collection_loaded);
819 }
820 if (format_pane != null) {
821 format_pane.refresh(refresh_reason, collection_loaded);
822 }
823
824 // Now enable tabs as necessary. Do this on event queue to prevent crazy NPEs
825 if (!locked) {
826 if (tab_updater == null) {
827 tab_updater = new TabUpdater(tab_pane, collection_loaded);
828 }
829 else {
830 tab_updater.setReady(collection_loaded);
831 }
832 SwingUtilities.invokeLater(tab_updater);
833 }
834 }
835
836
837 public void refreshCollectionTree(int refresh_reason)
838 {
839 if (gather_pane != null) {
840 gather_pane.refreshCollectionTree(refresh_reason);
841 }
842 }
843
844
845 public void refreshWorkspaceTree(int refresh_reason)
846 {
847 if (gather_pane != null) {
848 gather_pane.refreshWorkspaceTree(refresh_reason);
849 }
850 }
851
852 public void refreshWorkspaceTreeGreenstoneCollections()
853 {
854 refreshWorkspaceTree(WorkspaceTree.LIBRARY_CONTENTS_CHANGED);
855 }
856
857 /** Specifies whether a certain tab is enabled or not. */
858 private void setTabEnabled(String rawname, boolean state) {
859 // Retrieve the dictionary based name.
860 String name = Dictionary.get("GUI." + rawname);
861 int index = tab_pane.indexOfTab(name);
862 // Of course we may not have this tab available.
863 if(index != -1) {
864 // Some tabs are also dependant on if a collection is ready
865 Component component = tab_pane.getComponentAt(index);
866 if(component == enrich_pane || component == design_pane || component == create_pane || component == format_pane) {
867 tab_pane.setEnabledAt(index, state && Gatherer.c_man != null && Gatherer.c_man.ready());
868 }
869 else {
870 tab_pane.setEnabledAt(index, state);
871 }
872 // If this was the currently selected tab and it is now disabled, change the view to the first enabled tab.
873 if(tab_pane.getSelectedIndex() == index && !state) {
874 boolean found = false;
875 for(int i = 0; !found && i < tab_pane.getTabCount(); i++) {
876 if(tab_pane.isEnabledAt(i)) {
877 tab_pane.setSelectedIndex(i);
878 found = true;
879 }
880 }
881 // If there are no tabs enabled, which should be impossible, then select the first tab
882 if(!found) {
883 tab_pane.setSelectedIndex(0);
884 }
885 }
886 }
887 }
888
889 /** 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.
890 * @param title
891 * @param name
892 */
893 public void setTitle(String title, String name) {
894
895 // Finally display the collection name in the title bar.
896 StringBuffer title_buffer = new StringBuffer(Configuration.getApplicationTitle());
897 title_buffer.append(StaticStrings.SPACE_CHARACTER);
898 title_buffer.append(Gatherer.PROGRAM_VERSION);
899 title_buffer.append(StaticStrings.SPACE_CHARACTER);
900 title_buffer.append(StaticStrings.SPACE_CHARACTER);
901 // Server version information
902 title_buffer.append(Gatherer.getServerVersionAsString());
903 title_buffer.append(StaticStrings.SPACE_CHARACTER);
904 title_buffer.append(StaticStrings.SPACE_CHARACTER);
905 // Describe the current user mode
906 title_buffer.append(StaticStrings.MODE_STR);
907 title_buffer.append(Configuration.getModeAsString());
908 title_buffer.append(StaticStrings.SPACE_CHARACTER);
909 title_buffer.append(StaticStrings.SPACE_CHARACTER);
910 // Now for the current collection
911 title_buffer.append(StaticStrings.COLLECTION_STR);
912 if (title != null && name != null) {
913 title_buffer.append(title);
914 title_buffer.append(StaticStrings.SPACE_CHARACTER);
915 title_buffer.append(StaticStrings.OPEN_PARENTHESIS_CHARACTER);
916 title_buffer.append(name);
917 title_buffer.append(StaticStrings.CLOSE_PARENTHESIS_CHARACTER);
918 }
919 else {
920 title_buffer.append(Dictionary.get("Collection.No_Collection"));
921 }
922 this.setTitle(title_buffer.toString());
923 title_buffer = null;
924 }
925
926
927 private class OpenCollectionTask
928 extends Thread
929 {
930 public void run()
931 {
932 String collection_file_path = showOpenCollectionDialog();
933
934 // User has selected a collection to open
935 if (collection_file_path != null) {
936 // If there is already a collection open, save and close it
937 if (Gatherer.c_man.ready()) {
938 saveThenCloseCurrentCollection();
939 }
940
941 // Open the selected collection
942 Gatherer.c_man.loadCollection(collection_file_path);
943 }
944 }
945 }
946
947
948 /** When the load collection option is chosen this method is called to produce the modal file load prompt.
949 */
950 private String showOpenCollectionDialog()
951 {
952 OpenCollectionDialog dialog = new OpenCollectionDialog();
953 dialog.setComponentOrientation(Dictionary.getOrientation());
954 if (dialog.display() == OpenCollectionDialog.OK_OPTION) {
955 return dialog.getFileName();
956 }
957
958 // User must have cancelled the action
959 return null;
960 }
961
962
963 /** When called this method causes the MetadataAuditTable to display a nice dialog box which contains all the metadata assigned in the collection.
964 */
965 public void showMetaAuditBox() {
966 wait(true);
967 meta_audit.display();
968 wait(false);
969 }
970
971
972 private class NewCollectionTask
973 extends Thread
974 {
975 public void run()
976 {
977 // Create the collection details prompt from new collection prompt
978 NewCollectionDetailsPrompt ncd_prompt = new NewCollectionDetailsPrompt();
979
980 // Create the new collection (if not cancelled) in a new thread.
981 if (!ncd_prompt.isCancelled()) {
982 // If there is already a collection open, save and close it.
983 if (Gatherer.c_man.ready()) {
984 saveThenCloseCurrentCollection();
985 }
986
987 // Create new collection.
988 Gatherer.c_man.createCollection(ncd_prompt.getDescription(), Configuration.getEmail(), ncd_prompt.getName(), ncd_prompt.getTitle(), ncd_prompt.getBase(), new ArrayList());
989 ncd_prompt.dispose();
990 }
991
992 // Done
993 ncd_prompt = null;
994 }
995 }
996
997
998 private class DeleteCollectionTask
999 extends Thread
1000 {
1001 public void run()
1002 {
1003 // The rest is handled by the DeleteCollectionPrompt
1004 DeleteCollectionPrompt dc_prompt = new DeleteCollectionPrompt();
1005 if (dc_prompt.display()) {
1006 //closeCurrentCollection();
1007 }
1008 dc_prompt.destroy();
1009 dc_prompt = null;
1010 }
1011 }
1012
1013
1014 /** 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.
1015 * @param event A ChangeEvent containing information about the event that fired this call.
1016 */
1017 public void stateChanged(ChangeEvent event)
1018 {
1019 if (previous_pane != null) {
1020 if (previous_pane == gather_pane) {
1021 gather_pane.loseFocus();
1022 }
1023 else if (previous_pane == enrich_pane) {
1024 enrich_pane.loseFocus();
1025 }
1026 else if (previous_pane == design_pane) {
1027 design_pane.loseFocus();
1028 }
1029 else if (previous_pane == create_pane) {
1030 create_pane.loseFocus();
1031 }
1032 else if (previous_pane == format_pane) {
1033 format_pane.loseFocus();
1034 }
1035 }
1036
1037 menu_bar.tabSelected(tab_pane.getSelectedIndex());
1038 int selected_index = tab_pane.getSelectedIndex();
1039 if (selected_index == tab_pane.indexOfComponent(download_pane)) {
1040 download_pane.gainFocus();
1041 }
1042 else if (selected_index == tab_pane.indexOfComponent(gather_pane)) {
1043 gather_pane.gainFocus();
1044 }
1045 else if (selected_index == tab_pane.indexOfComponent(enrich_pane)) {
1046 enrich_pane.gainFocus();
1047 }
1048 else if (selected_index == tab_pane.indexOfComponent(design_pane)) {
1049 design_pane.gainFocus();
1050 }
1051 else if (selected_index == tab_pane.indexOfComponent(create_pane)) {
1052 create_pane.gainFocus();
1053 }
1054 else if (selected_index == tab_pane.indexOfComponent(format_pane)) {
1055 format_pane.gainFocus();
1056 }
1057
1058 previous_pane = (JPanel) tab_pane.getSelectedComponent();
1059
1060 }
1061
1062
1063 private MouseListener mouse_blocker_listener = new MouseAdapter() {};
1064
1065 public void updateUI()
1066 {
1067 JPanel pane = (JPanel) getContentPane();
1068 pane.updateUI();
1069 // Also update all of the tabs according to workflow.
1070 workflowUpdate("Download", Configuration.get("workflow.download", false));
1071 workflowUpdate("Gather", Configuration.get("workflow.gather", false));
1072 workflowUpdate("Enrich", Configuration.get("workflow.enrich", false));
1073 workflowUpdate("Design", Configuration.get("workflow.design", false));
1074 workflowUpdate("Create", Configuration.get("workflow.create", false));
1075 workflowUpdate("Format", Configuration.get("workflow.format", false));
1076 }
1077
1078 public void wait(boolean waiting) {
1079 Component glass_pane = getGlassPane();
1080 if(waiting) {
1081 // Show wait cursor.
1082 glass_pane.addMouseListener(mouse_blocker_listener);
1083 glass_pane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1084 glass_pane.setVisible(true);
1085 }
1086 else {
1087 // Hide wait cursor.
1088 glass_pane.setVisible(false);
1089 glass_pane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1090 glass_pane.removeMouseListener(mouse_blocker_listener);
1091 }
1092 glass_pane = null;
1093 }
1094
1095 public void workflowUpdate(String raw, boolean state) {
1096 WorkflowUpdater task = new WorkflowUpdater(raw, state);
1097 SwingUtilities.invokeLater(task);
1098 task = null;
1099 }
1100
1101
1102 /**Overridden from JFrame so we can exit safely when window is closed (or destroyed).
1103 * @param event A <strong>WindowEvent</strong> containing information about the event that fired this call.
1104 */
1105 protected void processWindowEvent(WindowEvent event) {
1106 if(event.getID() == WindowEvent.WINDOW_CLOSING) {
1107 exit();
1108 }
1109 }
1110
1111
1112 /** 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.
1113 */
1114 private class MenuListenerImpl
1115 implements MenuListener {
1116 /** Called whenever a popup menu is hidden, but we don't care.
1117 * @param e Some <strong>MenuEvent</strong> that we could care less about.
1118 */
1119 public void menuCanceled(MenuEvent e) {
1120 }
1121 /** Called whenever a menu header (ie button) becomes unselected, but we don't care.
1122 * @param e Some <strong>MenuEvent</strong> that we could care less about.
1123 */
1124 public void menuDeselected(MenuEvent e) {
1125 }
1126 /** 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.
1127 * @param e The <strong>MenuEvent</strong> whose source is checked.
1128 */
1129 public void menuSelected(MenuEvent e) {
1130 if(e.getSource() == menu_bar.help) {
1131 if(menu_bar.help.isSelected()) {
1132 menu_bar.help.doClick(10);
1133 }
1134 }
1135 }
1136 }
1137
1138 private class TabUpdater
1139 implements Runnable {
1140 private boolean ready = false;
1141 private int download_pos = -1;
1142 private int enrich_pos = -1;
1143 private int design_pos = -1;
1144 private int create_pos = -1;
1145 private int format_pos = -1;
1146 private int export_pos = -1;
1147 private JTabbedPane tab_pane = null;
1148
1149 public TabUpdater(JTabbedPane tab_pane, boolean ready) {
1150 this.ready = ready;
1151 this.tab_pane = tab_pane;
1152 download_pos = tab_pane.indexOfComponent(download_pane);
1153 enrich_pos = tab_pane.indexOfComponent(enrich_pane);
1154 design_pos = tab_pane.indexOfComponent(design_pane);
1155 create_pos = tab_pane.indexOfComponent(create_pane);
1156 format_pos = tab_pane.indexOfComponent(format_pane);
1157 }
1158
1159 public void run()
1160 {
1161 if (download_pos != -1) {
1162 if (ready) {
1163 tab_pane.setEnabledAt(download_pos, Configuration.get("workflow.download", false));
1164 }
1165 else {
1166 tab_pane.setEnabledAt(download_pos, Configuration.get("workflow.download", true));
1167 }
1168 }
1169 if (enrich_pos != -1) {
1170 tab_pane.setEnabledAt(enrich_pos, ready && Configuration.get("workflow.enrich", false));
1171 }
1172 if (design_pos != -1) {
1173 tab_pane.setEnabledAt(design_pos, ready && Configuration.get("workflow.design", false) && Configuration.getMode() > Configuration.ASSISTANT_MODE);
1174 }
1175 if (create_pos != -1) {
1176 tab_pane.setEnabledAt(create_pos, ready && Configuration.get("workflow.create", false));
1177 }
1178 if (format_pos != -1) {
1179 tab_pane.setEnabledAt(format_pos, ready && Configuration.get("workflow.format", false) && Configuration.getMode() > Configuration.ASSISTANT_MODE);
1180 }
1181 }
1182
1183 public void setReady(boolean ready) {
1184 this.ready = ready;
1185 }
1186 }
1187
1188 private class WorkflowUpdater
1189 implements Runnable {
1190 private boolean state;
1191 private String raw;
1192 public WorkflowUpdater(String raw, boolean state) {
1193 this.raw = raw;
1194 this.state = state;
1195 }
1196 public void run() {
1197 setTabEnabled(raw, state);
1198 }
1199 }
1200}
Note: See TracBrowser for help on using the repository browser.