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 | */
|
---|
37 | package org.greenstone.gatherer.gui;
|
---|
38 |
|
---|
39 | import java.awt.*;
|
---|
40 | import java.awt.datatransfer.*;
|
---|
41 | import java.awt.event.*;
|
---|
42 | import java.io.*;
|
---|
43 | import java.lang.*;
|
---|
44 | import java.net.*;
|
---|
45 | import java.util.*;
|
---|
46 | import javax.swing.*;
|
---|
47 | import javax.swing.event.*;
|
---|
48 | import javax.swing.plaf.*;
|
---|
49 | import javax.swing.text.*;
|
---|
50 | import org.greenstone.gatherer.Configuration;
|
---|
51 | import org.greenstone.gatherer.Dictionary;
|
---|
52 | import org.greenstone.gatherer.Gatherer;
|
---|
53 | import org.greenstone.gatherer.collection.Collection;
|
---|
54 | import org.greenstone.gatherer.collection.DeleteCollectionPrompt;
|
---|
55 | import org.greenstone.gatherer.collection.ExportCollectionPrompt;
|
---|
56 | import org.greenstone.gatherer.collection.SaveCollectionBox;
|
---|
57 | import org.greenstone.gatherer.file.FileNode;
|
---|
58 | import org.greenstone.gatherer.file.FileOpenActionListener;
|
---|
59 | import org.greenstone.gatherer.gui.AboutDialog;
|
---|
60 | //import org.greenstone.gatherer.gui.BrowsingPane;
|
---|
61 | import org.greenstone.gatherer.gui.GatherPane;
|
---|
62 | import org.greenstone.gatherer.gui.CreatePane;
|
---|
63 | import org.greenstone.gatherer.gui.Filter;
|
---|
64 | import org.greenstone.gatherer.gui.DesignPane;
|
---|
65 | import org.greenstone.gatherer.gui.MenuBar;
|
---|
66 | import org.greenstone.gatherer.gui.EnrichPane;
|
---|
67 | import org.greenstone.gatherer.gui.MirrorPane;
|
---|
68 | import org.greenstone.gatherer.gui.OpenCollectionDialog;
|
---|
69 | import org.greenstone.gatherer.gui.Preferences;
|
---|
70 | //import org.greenstone.gatherer.gui.PreviewPane;
|
---|
71 | import org.greenstone.gatherer.gui.SimpleOpenCollectionDialog;
|
---|
72 | import org.greenstone.gatherer.gui.metaaudit.MetaAuditFrame;
|
---|
73 | import org.greenstone.gatherer.gui.tree.DragTree;
|
---|
74 | import org.greenstone.gatherer.gui.tree.WorkspaceTree;
|
---|
75 | import org.greenstone.gatherer.help.HelpFrame;
|
---|
76 | import org.greenstone.gatherer.mem.MetadataEditorManager;
|
---|
77 | import org.greenstone.gatherer.msm.ElementWrapper;
|
---|
78 | import org.greenstone.gatherer.msm.Metadata;
|
---|
79 | import org.greenstone.gatherer.shell.GShell;
|
---|
80 | import org.greenstone.gatherer.util.StaticStrings;
|
---|
81 | import org.greenstone.gatherer.util.TreeSynchronizer;
|
---|
82 | import org.greenstone.gatherer.util.Utility;
|
---|
83 |
|
---|
84 | /** 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. */
|
---|
85 | public class GUIManager
|
---|
86 | extends JFrame
|
---|
87 | implements ActionListener, ChangeListener {
|
---|
88 | /** The browsing pane behaves much like an internet browser, or at least will some day. */
|
---|
89 | //public BrowsingPane browser_pane = null;
|
---|
90 | /** The mirror pane contains controls for mirroring internet sites. */
|
---|
91 | public MirrorPane mirror_pane = null;
|
---|
92 | /** The gather pane is more like a file manager where you drag files from one tree to another. */
|
---|
93 | private GatherPane gather_pane = null;
|
---|
94 | /** The enrich pane is used to assign, edit and remove metadata from files within the collection. */
|
---|
95 | public EnrichPane enrich_pane = null;
|
---|
96 | /** The design pane allows you to edit the design of the library in terms of the collection configuration file. */
|
---|
97 | public DesignPane design_pane = null;
|
---|
98 | /** The create pane contains scripting options for importing and building collections into libraries. */
|
---|
99 | public CreatePane create_pane = null;
|
---|
100 | /** The preview pane contains a preview of your build collection. */
|
---|
101 | //public PreviewPane preview_pane = null;
|
---|
102 |
|
---|
103 | public FileOpenActionListener foa_listener = new FileOpenActionListener();
|
---|
104 |
|
---|
105 | /** A reference to the currently instantiated help window, if any. */
|
---|
106 | public HelpFrame help = null;
|
---|
107 | /** The menu bar. */
|
---|
108 | public MenuBar menu_bar = null;
|
---|
109 | public MetaAuditFrame meta_audit;
|
---|
110 | /** Are certain panes currently locked? */
|
---|
111 | private boolean locked = false;
|
---|
112 | /** The size of the Gatherer window. */
|
---|
113 | private Dimension size = null;
|
---|
114 | /** The filters used to dynamically filter the trees at user request. */
|
---|
115 | private HashMap filters = new HashMap();
|
---|
116 | /** The panel within the window that other components are placed on. */
|
---|
117 | private JPanel content_pane = null;
|
---|
118 | /** The dummy export pane. */
|
---|
119 | private JPanel export_pane = new JPanel();
|
---|
120 | /** The last view pane selected. */
|
---|
121 | private JPanel previous_pane;
|
---|
122 | /** The main tab pane containing the different views, available here to trap view change events. */
|
---|
123 | private JTabbedPane tab_pane = null;
|
---|
124 | /** A threaded tab changer to try and avoid NPE on exit. */
|
---|
125 | private TabUpdater tab_updater = null;
|
---|
126 | /** The thread group this manager, and hence its child graphical rendering threads, belong to. In a vain attempts to make the Dictionary work across threads.
|
---|
127 | * @see org.greenstone.gatherer.Dictionary
|
---|
128 | */
|
---|
129 | private ThreadGroup thread_group = null;
|
---|
130 | /** Ensures that expansion events between like collection trees are synchronized. */
|
---|
131 | private TreeSynchronizer collection_tree_sync = null;
|
---|
132 | /** Ensures that expansion events between like workspace trees are synchronized. */
|
---|
133 | private TreeSynchronizer workspace_tree_sync = null;
|
---|
134 | /**Constructor. Enable window events and arranges all other components.
|
---|
135 | * @param size The intial <strong>Dimension</strong> of the screen.
|
---|
136 | */
|
---|
137 | public GUIManager(Dimension size) {
|
---|
138 | super();
|
---|
139 | // Initialization
|
---|
140 | this.help = new HelpFrame();
|
---|
141 | this.size = size;
|
---|
142 | this.collection_tree_sync = new TreeSynchronizer();
|
---|
143 | this.meta_audit = new MetaAuditFrame(collection_tree_sync, null);
|
---|
144 | this.workspace_tree_sync = new TreeSynchronizer();
|
---|
145 |
|
---|
146 | this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
---|
147 |
|
---|
148 | // 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.
|
---|
149 | this.addFocusListener(new GLIGUIFocusListener());
|
---|
150 |
|
---|
151 | // Make the Tool tip hang around for a rediculous amount of time.
|
---|
152 | ToolTipManager.sharedInstance().setDismissDelay(10000);
|
---|
153 | // Get a reference to the main thread group. Create a new thread, which defaults into the same thread group, then get its thread group. Easy.
|
---|
154 | Thread bob = new Thread();
|
---|
155 | thread_group = bob.getThreadGroup();
|
---|
156 | // Set up some other UI stuff. (fonts handled in Gatherer.main())
|
---|
157 | UIManager.put("FileChooser.lookInLabelText", Dictionary.get("SaveCollectionBox.Look_In"));
|
---|
158 | UIManager.put("FileChooser.filesOfTypeLabelText", Dictionary.get("SaveCollectionBox.Files_Of_Type"));
|
---|
159 | UIManager.put("FileChooser.fileNameLabelText", Dictionary.get("SaveCollectionBox.File_Name"));
|
---|
160 | }
|
---|
161 |
|
---|
162 | private class GLIGUIFocusListener
|
---|
163 | extends FocusAdapter {
|
---|
164 | public void focusGained(FocusEvent e) {
|
---|
165 | if(Gatherer.current_modal != null) {
|
---|
166 | Gatherer.current_modal.makeVisible();
|
---|
167 | Gatherer.current_modal.toFront();
|
---|
168 | }
|
---|
169 | }
|
---|
170 | }
|
---|
171 |
|
---|
172 | /** 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.
|
---|
173 | * @param event An <strong>ActionEvent</strong> containing information about the action that has occured.
|
---|
174 | */
|
---|
175 | public void actionPerformed(ActionEvent event) {
|
---|
176 | boolean cont = true;
|
---|
177 | Object esrc = event.getSource();
|
---|
178 | // *************
|
---|
179 | // File Options.
|
---|
180 | // *************
|
---|
181 | if(esrc == menu_bar.file_associations) {
|
---|
182 | Gatherer.assoc_man.edit();
|
---|
183 | }
|
---|
184 | else if(esrc == menu_bar.file_close) {
|
---|
185 | // if(!Gatherer.c_man.saved()) {
|
---|
186 | cont = showSaveCollectionBox(true, false);
|
---|
187 | // }
|
---|
188 | if(cont) {
|
---|
189 | tab_pane.setSelectedComponent(gather_pane);
|
---|
190 | }
|
---|
191 | }
|
---|
192 | else if(esrc == menu_bar.file_delete) {
|
---|
193 | DeleteCollectionPrompt dcp = new DeleteCollectionPrompt();
|
---|
194 | if(dcp.display()) {
|
---|
195 | Gatherer.c_man.closeCollection();
|
---|
196 | }
|
---|
197 | dcp.destroy();
|
---|
198 | dcp = null;
|
---|
199 | System.gc();
|
---|
200 | }
|
---|
201 | else if(esrc == menu_bar.file_export) {
|
---|
202 | ExportCollectionPrompt ecp = new ExportCollectionPrompt();
|
---|
203 | ecp.display();
|
---|
204 | ecp.destroy();
|
---|
205 | ecp = null;
|
---|
206 | }
|
---|
207 | else if(esrc == menu_bar.file_exit) {
|
---|
208 | //menu_bar.exit();
|
---|
209 | exit();
|
---|
210 | }
|
---|
211 | else if(esrc == menu_bar.file_new) {
|
---|
212 | showNewCollectionPrompt();
|
---|
213 | }
|
---|
214 | else if(esrc == menu_bar.file_open) {
|
---|
215 | if (showLoadCollectionBox()) {
|
---|
216 | tab_pane.setSelectedComponent(gather_pane);
|
---|
217 | }
|
---|
218 | }
|
---|
219 | else if(esrc == menu_bar.file_options) {
|
---|
220 | // Just incase the user has edited the GeneralSettings of a collection without losing focus afterwards. Well I'm forever losing foc... ooh shiney.
|
---|
221 | design_pane.loseFocus();
|
---|
222 | // And spawn a new preferences.
|
---|
223 | new Preferences();
|
---|
224 | }
|
---|
225 | else if(esrc == menu_bar.file_save) {
|
---|
226 | Gatherer.c_man.saveCollection(false, false);
|
---|
227 | }
|
---|
228 | // else if(esrc == menu_bar.file_save_as) {
|
---|
229 | // String name = JOptionPane.showInputDialog(this, "Enter new collection filename.");
|
---|
230 | // if(name != null) {
|
---|
231 | // Gatherer.c_man.saveCollectionAs(name);
|
---|
232 | // }
|
---|
233 | // }
|
---|
234 | // *************
|
---|
235 | // Edit Options.
|
---|
236 | // *************
|
---|
237 | else if(esrc == menu_bar.edit_copy) {
|
---|
238 | try {
|
---|
239 | KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
|
---|
240 | // Get the component with selected text as a JTextComponent
|
---|
241 | JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner();//getFocusOwner();
|
---|
242 | text.copy();
|
---|
243 | }
|
---|
244 | catch (Exception cce) {
|
---|
245 | // If the component is not a text component ignore the copy command
|
---|
246 | Gatherer.println(cce.toString());
|
---|
247 | }
|
---|
248 | }
|
---|
249 | else if(esrc == menu_bar.edit_cut) {
|
---|
250 | try {
|
---|
251 | KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
|
---|
252 | // Get the component with selected text as a JTextComponent
|
---|
253 | JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner();
|
---|
254 | // Cut the text to the clipboard
|
---|
255 | text.cut();
|
---|
256 | }
|
---|
257 | catch (ClassCastException cce) {
|
---|
258 | // If the component is not a text component ignore the cut command
|
---|
259 | Gatherer.println(cce.toString());
|
---|
260 | }
|
---|
261 | }
|
---|
262 | else if(esrc == menu_bar.edit_paste) {
|
---|
263 | try {
|
---|
264 | KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
|
---|
265 | // Get the component with selected text as a JTextComponent
|
---|
266 | JTextComponent text = (JTextComponent) kfm.getPermanentFocusOwner();
|
---|
267 | // Cut the text to the clipboard
|
---|
268 | text.paste();
|
---|
269 | }
|
---|
270 | catch (ClassCastException cce) {
|
---|
271 | // If the component is not a text component ignore the paste command
|
---|
272 | Gatherer.println(cce.toString());
|
---|
273 | }
|
---|
274 | }
|
---|
275 | // else if(esrc == menu_bar.edit_search) {
|
---|
276 | // if(sar != null) {
|
---|
277 | // sar.dispose();
|
---|
278 | // }
|
---|
279 | // sar = new SearchAndReplace(false);
|
---|
280 | // }
|
---|
281 | // else if(esrc == menu_bar.edit_replace) {
|
---|
282 | // if(sar != null) {
|
---|
283 | // sar.dispose();
|
---|
284 | // }
|
---|
285 | // sar = new SearchAndReplace(true);
|
---|
286 | // }
|
---|
287 |
|
---|
288 | // *************
|
---|
289 | // Tools Options.
|
---|
290 | // *************
|
---|
291 | // else if(esrc == menu_bar.tools_size) {
|
---|
292 | // FileNode records[] = enrich_pane.getSelectedNode();
|
---|
293 | // if(records != null && records.length > 0) {
|
---|
294 | // ArrayList metadatum = Gatherer.c_man.getCollection().gdm.getMetadata(records[0].getFile());
|
---|
295 | // if(metadatum.size() >= 4) {
|
---|
296 | // Metadata metadata = (Metadata) metadatum.get(0);
|
---|
297 | // ElementWrapper ew = metadata.getElement();
|
---|
298 |
|
---|
299 | // int SIZE = 5000;
|
---|
300 | // Object[] array = new Object[SIZE];
|
---|
301 | // Runtime.getRuntime().gc();
|
---|
302 | // long start = Runtime.getRuntime().freeMemory();
|
---|
303 | // for (int i = 0; i < SIZE; i++) {
|
---|
304 | // array[i] = ew.copy();
|
---|
305 | // }
|
---|
306 | // Runtime.getRuntime().gc();
|
---|
307 | // long end = Runtime.getRuntime().freeMemory();
|
---|
308 | // long difference = (( start - end ) / SIZE);
|
---|
309 | // ///ystem.out.println(difference + " bytes used." );
|
---|
310 | // }
|
---|
311 | // }
|
---|
312 | // }
|
---|
313 |
|
---|
314 | // *************
|
---|
315 | // Help Options.
|
---|
316 | // *************
|
---|
317 | else if(esrc == menu_bar.help_about) {
|
---|
318 | new AboutDialog(this);
|
---|
319 | }
|
---|
320 | // else if(esrc == menu_bar.help_browse) {
|
---|
321 | // help.setView("huntingforfiles");
|
---|
322 | // }
|
---|
323 | else if(esrc == menu_bar.help_build) {
|
---|
324 | help.setView("producingthecollection");
|
---|
325 | }
|
---|
326 | else if(esrc == menu_bar.help_collect) {
|
---|
327 | help.setView("collectingfiles");
|
---|
328 | }
|
---|
329 | else if(esrc == menu_bar.help_design) {
|
---|
330 | help.setView("designingacollection");
|
---|
331 | }
|
---|
332 | else if(esrc == menu_bar.help_general) {
|
---|
333 | help.setView("introduction");
|
---|
334 | }
|
---|
335 | else if(esrc == menu_bar.help_metaedit) {
|
---|
336 | help.setView("enrichingacollection");
|
---|
337 | }
|
---|
338 | else if(esrc == menu_bar.help_mirror) {
|
---|
339 | help.setView("downloadingfiles");
|
---|
340 | }
|
---|
341 | else if(esrc == menu_bar.help_preview) {
|
---|
342 | help.setView("previewingthecollection");
|
---|
343 | }
|
---|
344 | // *****************
|
---|
345 | // Metadata Options.
|
---|
346 | // *****************
|
---|
347 | else if(esrc == menu_bar.metadata_import) {
|
---|
348 | Gatherer.c_man.getCollection().msm.importMDS();
|
---|
349 | }
|
---|
350 | else if(esrc == menu_bar.metadata_edit) {
|
---|
351 | showEditMetadataBox();
|
---|
352 | }
|
---|
353 | else if(esrc == menu_bar.metadata_export) {
|
---|
354 | Gatherer.c_man.getCollection().msm.exportMDS();
|
---|
355 | }
|
---|
356 | else if(esrc == menu_bar.metadata_view) {
|
---|
357 | showMetaAuditBox();
|
---|
358 | }
|
---|
359 | }
|
---|
360 | /** 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.
|
---|
361 | */
|
---|
362 | public void afterDisplay() {
|
---|
363 | // if(Gatherer.config.get("workflow.browse", true)) {
|
---|
364 | // browser_pane.afterDisplay();
|
---|
365 | // }
|
---|
366 | if (mirror_pane != null) {
|
---|
367 | mirror_pane.afterDisplay();
|
---|
368 | }
|
---|
369 | enrich_pane.afterDisplay();
|
---|
370 | }
|
---|
371 | public void closeCurrentCollection() {
|
---|
372 |
|
---|
373 | boolean cont = showSaveCollectionBox(true, false);
|
---|
374 |
|
---|
375 | if(cont) {
|
---|
376 | tab_pane.setSelectedComponent(gather_pane);
|
---|
377 | }
|
---|
378 |
|
---|
379 | }
|
---|
380 | /** Once a collection has been made available to Gatherer, either by its creation or by it being reloaded, we need to inform all the visual components to update necessary data components (such as tree models), enable certain controls that depend on a collection being accessible, and refresh themselves.
|
---|
381 | * @param ready <i>true</i> if the collection is ready for editing, <i>false</i> otherwise.
|
---|
382 | */
|
---|
383 | public void collectionChanged(final boolean ready) {
|
---|
384 | if(Gatherer.config.get("workflow.mirror", true)) {
|
---|
385 | mirror_pane.collectionChanged(ready);
|
---|
386 | }
|
---|
387 | menu_bar.collectionChanged(ready); // Inform the menu bar that the collections changed.
|
---|
388 | gather_pane.collectionChanged(ready); // Used to update the collection workspace.
|
---|
389 | enrich_pane.collectionChanged(ready); // Very important that metaedit pane shows current collection and is listening to latest msm.
|
---|
390 | design_pane.collectionChanged(ready); // Also important config pane is listening to latest msm.
|
---|
391 | create_pane.collectionChanged(ready); // Used to indicate a new BuildOptions model should be loaded.
|
---|
392 | //preview_pane.collectionChanged(ready); // preview should know when teh coll has changed so it can reload the home page
|
---|
393 |
|
---|
394 | if(!locked) {
|
---|
395 | // Now enable tabs as necessary. Do this on event queue to prevent crazy NPEs
|
---|
396 | if(tab_updater == null) {
|
---|
397 | tab_updater = new TabUpdater(tab_pane, ready);
|
---|
398 | }
|
---|
399 | else {
|
---|
400 | tab_updater.setReady(ready);
|
---|
401 | }
|
---|
402 | SwingUtilities.invokeLater(tab_updater);
|
---|
403 | }
|
---|
404 | // Set the title
|
---|
405 | String collection_title = null;
|
---|
406 | String collection_name = null;
|
---|
407 | if (ready) {
|
---|
408 | Collection collection = Gatherer.c_man.getCollection();
|
---|
409 | collection_title = collection.getTitle();
|
---|
410 | collection_name = collection.getName();
|
---|
411 | collection = null;
|
---|
412 | }
|
---|
413 | setTitle(collection_title, collection_name);
|
---|
414 | collection_title = null;
|
---|
415 | collection_name = null;
|
---|
416 | // Now is a good time to force a garbage collect.
|
---|
417 | ///ystem.err.println("Calling garbage collection.");
|
---|
418 | System.gc();
|
---|
419 | }
|
---|
420 |
|
---|
421 | public void destroy() {
|
---|
422 | // Destroying create pane ensures the latest log has been closed
|
---|
423 | if(create_pane != null) {
|
---|
424 | create_pane.destroy();
|
---|
425 | }
|
---|
426 | }
|
---|
427 |
|
---|
428 | /** Enabled events on the window to be trapped, creates all the visual components, then builds the tab and other layouts.
|
---|
429 | */
|
---|
430 | public void display() {
|
---|
431 | content_pane = (JPanel) this.getContentPane();
|
---|
432 | // Enable window-type events to be fired.
|
---|
433 | enableEvents(AWTEvent.WINDOW_EVENT_MASK);
|
---|
434 | // Initialise and layout sub-components, plus other window dressing.
|
---|
435 | try {
|
---|
436 | this.setSize(size);
|
---|
437 |
|
---|
438 | // Set the title
|
---|
439 | String collection_title = null;
|
---|
440 | String collection_name = null;
|
---|
441 | if (Gatherer.c_man.ready()) {
|
---|
442 | Collection collection = Gatherer.c_man.getCollection();
|
---|
443 | collection_title = collection.getTitle();
|
---|
444 | collection_name = collection.getName();
|
---|
445 | collection = null;
|
---|
446 | }
|
---|
447 | setTitle(collection_title, collection_name);
|
---|
448 | collection_title = null;
|
---|
449 | collection_name = null;
|
---|
450 |
|
---|
451 | // Pretty corner icon
|
---|
452 | this.setIconImage(Utility.getImage("gatherer_small.gif").getImage());
|
---|
453 | // BorderLayout for the main screen. I'll try my best to avoid these in subcomponents as they're space greedy.
|
---|
454 | content_pane.setLayout(new BorderLayout());
|
---|
455 | // Create the menu-bar and stick it up the top.
|
---|
456 | menu_bar = new MenuBar(new MenuListenerImpl());
|
---|
457 |
|
---|
458 | //feedback changes
|
---|
459 | //content_pane.add(menu_bar, BorderLayout.NORTH);
|
---|
460 | this.setJMenuBar(menu_bar);
|
---|
461 | // end feedback changes
|
---|
462 |
|
---|
463 | // Create the tabbed pane and plop it in the center where it will
|
---|
464 | // expand to consume all available space like any good gas would.
|
---|
465 | tab_pane = new JTabbedPane();
|
---|
466 | tab_pane.addChangeListener(this);
|
---|
467 | tab_pane.setFont(Gatherer.config.getFont("general.font", false));
|
---|
468 |
|
---|
469 | if(Gatherer.config.get(StaticStrings.WORKFLOW_MIRROR, true)) {
|
---|
470 | mirror_pane = new MirrorPane();
|
---|
471 | tab_pane.addTab("GUI.Mirror", Utility.getImage("mirroring.gif"), mirror_pane);
|
---|
472 | tab_pane.setEnabledAt(tab_pane.indexOfComponent(mirror_pane), Gatherer.config.get(StaticStrings.WORKFLOW_MIRROR, false));
|
---|
473 | }
|
---|
474 |
|
---|
475 | gather_pane = new GatherPane(workspace_tree_sync, collection_tree_sync);
|
---|
476 | gather_pane.display();
|
---|
477 | if(Gatherer.config.get("workflow.gather", true)) {
|
---|
478 | tab_pane.addTab("GUI.Gather", Utility.getImage("collection.gif"), gather_pane);
|
---|
479 | tab_pane.setEnabledAt(tab_pane.indexOfComponent(gather_pane), Gatherer.config.get("workflow.gather", false));
|
---|
480 | }
|
---|
481 |
|
---|
482 | enrich_pane = new EnrichPane(collection_tree_sync);
|
---|
483 | enrich_pane.display();
|
---|
484 | if(Gatherer.config.get("workflow.enrich", true)) {
|
---|
485 | tab_pane.addTab("GUI.Enrich", Utility.getImage("metaedit.gif"), enrich_pane);
|
---|
486 | tab_pane.setEnabledAt(tab_pane.indexOfComponent(enrich_pane), false);
|
---|
487 | }
|
---|
488 |
|
---|
489 | design_pane = new DesignPane();
|
---|
490 | design_pane.display();
|
---|
491 | if(Gatherer.config.get("workflow.design", true)) {
|
---|
492 | tab_pane.addTab("GUI.Design", Utility.getImage("build.gif"), design_pane);
|
---|
493 | tab_pane.setEnabledAt(tab_pane.indexOfComponent(design_pane), false);
|
---|
494 | }
|
---|
495 |
|
---|
496 | if(Gatherer.config.get("workflow.export", true)) {
|
---|
497 | tab_pane.addTab("GUI.Export", Utility.getImage("export.gif"), export_pane);
|
---|
498 | tab_pane.setEnabledAt(tab_pane.indexOfComponent(export_pane), false);
|
---|
499 | }
|
---|
500 |
|
---|
501 | create_pane = new CreatePane();
|
---|
502 | create_pane.display();
|
---|
503 | if(Gatherer.config.get("workflow.create", true)) {
|
---|
504 | tab_pane.addTab("GUI.Create", Utility.getImage("build session.gif"), create_pane);
|
---|
505 | tab_pane.setEnabledAt(tab_pane.indexOfComponent(create_pane), false);
|
---|
506 | }
|
---|
507 |
|
---|
508 | //preview_pane = new PreviewPane();
|
---|
509 | //preview_pane.display();
|
---|
510 | //if(Gatherer.config.get("workflow.preview", true)) {
|
---|
511 | //tab_pane.addTab("GUI.Preview", Utility.getImage("final.gif"), preview_pane);
|
---|
512 | //tab_pane.setEnabledAt(tab_pane.indexOfComponent(preview_pane), false);
|
---|
513 | //}
|
---|
514 |
|
---|
515 | // Select the collect pane if it is available
|
---|
516 | if(Gatherer.config.get("workflow.gather", false)) {
|
---|
517 | tab_pane.setSelectedComponent(gather_pane);
|
---|
518 | }
|
---|
519 | // Otherwise find the first tab that is enabled and select that.
|
---|
520 | else {
|
---|
521 | boolean found = false;
|
---|
522 | for(int i = 0; !found && i < tab_pane.getTabCount(); i++) {
|
---|
523 | if(tab_pane.isEnabledAt(i)) {
|
---|
524 | tab_pane.setSelectedIndex(i);
|
---|
525 | found = true;
|
---|
526 | }
|
---|
527 | }
|
---|
528 | }
|
---|
529 |
|
---|
530 | Dictionary.register(tab_pane);
|
---|
531 | content_pane.add(tab_pane, BorderLayout.CENTER);
|
---|
532 | // Drive a sessionReady event to update all controls to reflect current collection status.
|
---|
533 | collectionChanged(Gatherer.c_man.ready());
|
---|
534 | }
|
---|
535 | catch (Exception e) {
|
---|
536 | Gatherer.printStackTrace(e);
|
---|
537 | // The GUI failing to build is a app killer
|
---|
538 | e.printStackTrace();
|
---|
539 | System.exit(1);
|
---|
540 | }
|
---|
541 | }
|
---|
542 | /** When called this method ensures that all the things needing saving are saved before Gatherer.exit() is called. This includes a save collection prompt if necessary.
|
---|
543 | */
|
---|
544 | public void exit() {
|
---|
545 | // Tell everyone who cares that they are losing focus
|
---|
546 | if(!Gatherer.c_man.ready() || design_pane.canSave()) {
|
---|
547 | boolean cont = true;
|
---|
548 | if(Gatherer.c_man.ready() && !Gatherer.c_man.saved()) {
|
---|
549 | cont = showSaveCollectionBox(false, true);
|
---|
550 | }
|
---|
551 | else {
|
---|
552 | // Deal to help
|
---|
553 | if(help != null) {
|
---|
554 | help.destroy();
|
---|
555 | help = null;
|
---|
556 | }
|
---|
557 | Gatherer.self.exit();
|
---|
558 | }
|
---|
559 | }
|
---|
560 | }
|
---|
561 | /** Retrieve the filter, or if one already exists, spawn a linked copy. */
|
---|
562 | public Filter getFilter(DragTree tree) {
|
---|
563 | Filter filter = (Filter) filters.get(tree.getModel());
|
---|
564 | if (filter == null) {
|
---|
565 | filter = new Filter(tree, null);
|
---|
566 | filters.put(tree.getModel(), filter);
|
---|
567 | return filter;
|
---|
568 | }
|
---|
569 | return filter.spawn(tree);
|
---|
570 | }
|
---|
571 |
|
---|
572 | public Component getSelectedView() {
|
---|
573 | return tab_pane.getSelectedComponent();
|
---|
574 | }
|
---|
575 | /** 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.
|
---|
576 | */
|
---|
577 | public void lockCollection(boolean import_stage, boolean lock) {
|
---|
578 | locked = lock;
|
---|
579 | if(import_stage) {
|
---|
580 | int collection_pos = tab_pane.indexOfComponent(gather_pane);
|
---|
581 | int metaedit_pos = tab_pane.indexOfComponent(enrich_pane);
|
---|
582 | int config_pos = tab_pane.indexOfComponent(design_pane);
|
---|
583 | tab_pane.setEnabledAt(collection_pos, !lock);
|
---|
584 | tab_pane.setEnabledAt(metaedit_pos, !lock);
|
---|
585 | tab_pane.setEnabledAt(config_pos, !lock);
|
---|
586 | }
|
---|
587 | else {
|
---|
588 | int config_pos = tab_pane.indexOfComponent(design_pane);
|
---|
589 | tab_pane.setEnabledAt(config_pos, !lock);
|
---|
590 | }
|
---|
591 | }
|
---|
592 |
|
---|
593 | public void modeChanged(int mode) {
|
---|
594 | // Set the title
|
---|
595 | String collection_title = null;
|
---|
596 | String collection_name = null;
|
---|
597 | if (Gatherer.c_man.ready()) {
|
---|
598 | Collection collection = Gatherer.c_man.getCollection();
|
---|
599 | collection_title = collection.getTitle();
|
---|
600 | collection_name = collection.getName();
|
---|
601 | collection = null;
|
---|
602 | }
|
---|
603 | setTitle(collection_title, collection_name);
|
---|
604 | collection_title = null;
|
---|
605 | collection_name = null;
|
---|
606 | // Now pass on the message to anyone who cares
|
---|
607 | if(gather_pane != null) {
|
---|
608 | gather_pane.modeChanged(mode);
|
---|
609 | }
|
---|
610 | if(design_pane != null) {
|
---|
611 | design_pane.modeChanged(mode);
|
---|
612 | }
|
---|
613 | if(create_pane != null) {
|
---|
614 | create_pane.modeChanged(mode);
|
---|
615 | }
|
---|
616 | if(enrich_pane != null) {
|
---|
617 | enrich_pane.modeChanged(mode);
|
---|
618 | }
|
---|
619 | }
|
---|
620 |
|
---|
621 |
|
---|
622 | public void refreshCollectionTree(int refresh_reason)
|
---|
623 | {
|
---|
624 | if (gather_pane != null) {
|
---|
625 | gather_pane.refreshCollectionTree(refresh_reason);
|
---|
626 | }
|
---|
627 | }
|
---|
628 |
|
---|
629 |
|
---|
630 | public void refreshWorkspaceTree(int refresh_reason)
|
---|
631 | {
|
---|
632 | if (gather_pane != null) {
|
---|
633 | gather_pane.refreshWorkspaceTree(refresh_reason);
|
---|
634 | }
|
---|
635 | }
|
---|
636 |
|
---|
637 |
|
---|
638 | /** Returns to some "initial" pane (when no collection is loaded) */
|
---|
639 | public void returnToInitialPane()
|
---|
640 | {
|
---|
641 | if (gather_pane != null) {
|
---|
642 | tab_pane.setSelectedComponent(gather_pane);
|
---|
643 | }
|
---|
644 | }
|
---|
645 |
|
---|
646 |
|
---|
647 | /** Specifies whether a certain tab is enabled or not. */
|
---|
648 | public void setTabEnabled(String rawname, boolean state) {
|
---|
649 | // Retrieve the dictionary based name.
|
---|
650 | String name = Dictionary.get("GUI." + rawname);
|
---|
651 | int index = tab_pane.indexOfTab(name);
|
---|
652 | // Of course we may not have this tab available.
|
---|
653 | if(index != -1) {
|
---|
654 | // Some tabs are also dependant on if a collection is ready
|
---|
655 | Component component = tab_pane.getComponentAt(index);
|
---|
656 | //if(component == preview_pane) {
|
---|
657 | //tab_pane.setEnabledAt(index, state && Gatherer.c_man != null && Gatherer.c_man.ready() && Gatherer.c_man.built());
|
---|
658 | //}
|
---|
659 | //else
|
---|
660 | if(component == enrich_pane || component == design_pane || component == export_pane || component == create_pane) {
|
---|
661 | tab_pane.setEnabledAt(index, state && Gatherer.c_man != null && Gatherer.c_man.ready());
|
---|
662 | }
|
---|
663 | else {
|
---|
664 | tab_pane.setEnabledAt(index, state);
|
---|
665 | }
|
---|
666 | // If this was the currently selected tab and it is now disabled, change the view to the first enabled tab.
|
---|
667 | if(tab_pane.getSelectedIndex() == index && !state) {
|
---|
668 | boolean found = false;
|
---|
669 | for(int i = 0; !found && i < tab_pane.getTabCount(); i++) {
|
---|
670 | if(tab_pane.isEnabledAt(i)) {
|
---|
671 | tab_pane.setSelectedIndex(i);
|
---|
672 | found = true;
|
---|
673 | }
|
---|
674 | }
|
---|
675 | // If there are no tabs enabled, which should be impossible, then select the first tab
|
---|
676 | if(!found) {
|
---|
677 | tab_pane.setSelectedIndex(0);
|
---|
678 | }
|
---|
679 | }
|
---|
680 | }
|
---|
681 | // If the rawname was mirror then rebuild workspace tree to remove caches.
|
---|
682 | if (rawname.equals("Mirror")) {
|
---|
683 | gather_pane.refreshWorkspaceTree(WorkspaceTree.MAPPED_DIRECTORIES_CHANGED);
|
---|
684 | }
|
---|
685 | }
|
---|
686 |
|
---|
687 | /** 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.
|
---|
688 | * @param title
|
---|
689 | * @param name
|
---|
690 | */
|
---|
691 | public void setTitle(String title, String name) {
|
---|
692 | // Finally display the collection name in the title bar.
|
---|
693 | StringBuffer title_buffer = new StringBuffer(Utility.PROGRAM_NAME);
|
---|
694 | title_buffer.append(StaticStrings.SPACE_CHARACTER);
|
---|
695 | title_buffer.append(StaticStrings.SPACE_CHARACTER);
|
---|
696 | // Describe the current user mode
|
---|
697 | title_buffer.append(StaticStrings.MODE_STR);
|
---|
698 | title_buffer.append(Gatherer.config.getModeAsString());
|
---|
699 | title_buffer.append(StaticStrings.SPACE_CHARACTER);
|
---|
700 | title_buffer.append(StaticStrings.SPACE_CHARACTER);
|
---|
701 | // Now for the current collection
|
---|
702 | title_buffer.append(StaticStrings.COLLECTION_STR);
|
---|
703 | if (title != null && name != null) {
|
---|
704 | title_buffer.append(title);
|
---|
705 | title_buffer.append(StaticStrings.SPACE_CHARACTER);
|
---|
706 | title_buffer.append(StaticStrings.OPEN_PARENTHESIS_CHARACTER);
|
---|
707 | title_buffer.append(name);
|
---|
708 | title_buffer.append(StaticStrings.CLOSE_PARENTHESIS_CHARACTER);
|
---|
709 | }
|
---|
710 | else {
|
---|
711 | title_buffer.append(Dictionary.get("Collection.No_Collection"));
|
---|
712 | }
|
---|
713 | this.setTitle(title_buffer.toString());
|
---|
714 | title_buffer = null;
|
---|
715 | }
|
---|
716 |
|
---|
717 | /** When the edit metadata option is choosen from the menu, this method is called to ensure we only edit the metadata if there is metadata loaded.
|
---|
718 | */
|
---|
719 | public void showEditMetadataBox() {
|
---|
720 | if(Gatherer.c_man.getCollection() != null) {
|
---|
721 | Gatherer.c_man.getCollection().msm.editMDS(null, MetadataEditorManager.NORMAL);
|
---|
722 | }
|
---|
723 | }
|
---|
724 | /** When the load collection option is choosen this method is called to produce the modal file load prompt.
|
---|
725 | */
|
---|
726 | public boolean showLoadCollectionBox() {
|
---|
727 | boolean result = false;
|
---|
728 | // We first try the simple open collection dialog
|
---|
729 | SimpleOpenCollectionDialog dialog = new SimpleOpenCollectionDialog();
|
---|
730 | int user_choice = dialog.display();
|
---|
731 | String filename = null;
|
---|
732 | // The user may choose to go to the advanced 'browse' dialog
|
---|
733 | if(user_choice == SimpleOpenCollectionDialog.OK_OPTION) {
|
---|
734 | filename = dialog.getFileName();
|
---|
735 | }
|
---|
736 | else if(user_choice == SimpleOpenCollectionDialog.BROWSE_OPTION) {
|
---|
737 | File file;
|
---|
738 | if (Gatherer.GS3) {
|
---|
739 | if (Gatherer.config.gsdl3_path != null) {
|
---|
740 | file = new File(Utility.getSitesDir(Gatherer.config.gsdl3_path));
|
---|
741 | } else {
|
---|
742 | file = new File(Utility.BASE_DIR);
|
---|
743 | }
|
---|
744 |
|
---|
745 | } else {
|
---|
746 |
|
---|
747 | if(Gatherer.config.gsdl_path != null) {
|
---|
748 | file = new File(Utility.getCollectDir(Gatherer.config.gsdl_path));
|
---|
749 | }
|
---|
750 | else {
|
---|
751 | file = new File(Utility.BASE_DIR);
|
---|
752 | }
|
---|
753 | }
|
---|
754 | OpenCollectionDialog chooser = new OpenCollectionDialog(file);
|
---|
755 | file = null;
|
---|
756 | filename = chooser.getFileName();
|
---|
757 | chooser.destroy();
|
---|
758 | chooser = null;
|
---|
759 | }
|
---|
760 | dialog.destroy();
|
---|
761 | dialog = null;
|
---|
762 | // User can cancel action.
|
---|
763 | if(filename != null) {
|
---|
764 | // If there is already a collection open, save and close it.
|
---|
765 | if(Gatherer.c_man.ready()) {
|
---|
766 | showSaveCollectionBox(true, false);
|
---|
767 | // Wait until it is closed.
|
---|
768 | try {
|
---|
769 | synchronized(this) {
|
---|
770 | while(Gatherer.c_man.reallyReady()) {
|
---|
771 | wait(10);
|
---|
772 | }
|
---|
773 | }
|
---|
774 | }
|
---|
775 | catch(Exception error) {
|
---|
776 | Gatherer.println("Exception: " + error);
|
---|
777 | Gatherer.printStackTrace(error);
|
---|
778 | }
|
---|
779 | }
|
---|
780 |
|
---|
781 | result = Gatherer.c_man.loadCollection(filename);
|
---|
782 | filename = null;
|
---|
783 | }
|
---|
784 | return result;
|
---|
785 | }
|
---|
786 |
|
---|
787 | /** When called this method causes the MetaAuditBox class in CollectionManager to display a nice dialog box which contains all the metadata assigned in the collection.
|
---|
788 | */
|
---|
789 | public void showMetaAuditBox() {
|
---|
790 | wait(true);
|
---|
791 | meta_audit.display();
|
---|
792 | wait(false);
|
---|
793 | }
|
---|
794 | /** This method is used to open the new collection box on the screen.
|
---|
795 | */
|
---|
796 | public void showNewCollectionPrompt() {
|
---|
797 | NewCollectionMetadataPrompt ncm_prompt = null;
|
---|
798 | // Create the collection details prompt from new collection prompt
|
---|
799 | NewCollectionDetailsPrompt ncd_prompt = new NewCollectionDetailsPrompt();
|
---|
800 | // If no previous collection was indicated as a model design, then show the metadata selection prompt from new collection prompt
|
---|
801 | if(!ncd_prompt.isCancelled() && (ncd_prompt.getBase() == null)) {
|
---|
802 | ncm_prompt = new NewCollectionMetadataPrompt();
|
---|
803 | }
|
---|
804 | // Create the new collection (if not cancelled) in a new thread.
|
---|
805 | if(!ncd_prompt.isCancelled() && (ncm_prompt == null || !ncm_prompt.isCancelled())) {
|
---|
806 | // If there is already a collection open, save and close it.
|
---|
807 | if(Gatherer.c_man.ready()) {
|
---|
808 | showSaveCollectionBox(true, false);
|
---|
809 | // Wait until it is closed.
|
---|
810 | try {
|
---|
811 | synchronized(this) {
|
---|
812 | while(Gatherer.c_man.reallyReady()) {
|
---|
813 | wait(10);
|
---|
814 | }
|
---|
815 | }
|
---|
816 | }
|
---|
817 | catch(Exception error) {
|
---|
818 | Gatherer.println("Exception: " + error);
|
---|
819 | Gatherer.printStackTrace(error);
|
---|
820 | }
|
---|
821 | }
|
---|
822 |
|
---|
823 | // Create new collection.
|
---|
824 | CreationTask task = new CreationTask(ncd_prompt, ncm_prompt);
|
---|
825 | // SwingUtilities.invokeLater(task);
|
---|
826 | task.start();
|
---|
827 | // Close prompt.
|
---|
828 | }
|
---|
829 | // Done
|
---|
830 | ncd_prompt = null;
|
---|
831 | ncm_prompt = null;
|
---|
832 | }
|
---|
833 | private class CreationTask
|
---|
834 | extends Thread {
|
---|
835 | private NewCollectionDetailsPrompt ncd_prompt = null;
|
---|
836 | private NewCollectionMetadataPrompt ncm_prompt = null;
|
---|
837 | public CreationTask(NewCollectionDetailsPrompt ncd_prompt, NewCollectionMetadataPrompt ncm_prompt) {
|
---|
838 | this.ncd_prompt = ncd_prompt;
|
---|
839 | this.ncm_prompt = ncm_prompt;
|
---|
840 | }
|
---|
841 |
|
---|
842 | public void run() {
|
---|
843 | ///ystem.err.println("Running CreationTask...");
|
---|
844 | if(ncm_prompt == null) {
|
---|
845 | Gatherer.c_man.createCollection(ncd_prompt.getDescription(), Gatherer.config.getEmail(), ncd_prompt.getName(), ncd_prompt.getTitle(), ncd_prompt.getBase(), null);
|
---|
846 | }
|
---|
847 | else {
|
---|
848 | Gatherer.c_man.createCollection(ncd_prompt.getDescription(), Gatherer.config.getEmail(), ncd_prompt.getName(), ncd_prompt.getTitle(), null, ncm_prompt.getSets());
|
---|
849 | }
|
---|
850 | // Now that the collection specific settings are loaded we can set the 'view extracted metadata' property
|
---|
851 | // do we want to have this in here???
|
---|
852 | //Gatherer.config.set("general.view_extracted_metadata", Configuration.COLLECTION_SPECIFIC, true);
|
---|
853 | ncd_prompt.dispose();
|
---|
854 | ncd_prompt = null;
|
---|
855 | if(ncm_prompt != null) {
|
---|
856 | ncm_prompt.dispose();
|
---|
857 | ncm_prompt = null;
|
---|
858 | }
|
---|
859 | }
|
---|
860 | }
|
---|
861 |
|
---|
862 |
|
---|
863 | /** This method is used to open the save collection box/prompt on the screen.
|
---|
864 | * @return A <i>boolean</i> which is <i>true</i> if the collection was saved successfully, <i>false</i> otherwise.
|
---|
865 | */
|
---|
866 | public boolean showSaveCollectionBox(boolean close_after, boolean exit_after) {
|
---|
867 | //SaveCollectionBox save_collection_box = new SaveCollectionBox();
|
---|
868 | //Rectangle bounds = save_collection_box.getBounds();
|
---|
869 | //int result = save_collection_box.getUserOption(Gatherer.c_man.getCollection().getName());
|
---|
870 | //switch(result) {
|
---|
871 | //case SaveCollectionBox.SAVE_YES:
|
---|
872 | Gatherer.c_man.setClosingThread(true);
|
---|
873 | Gatherer.c_man.saveCollection(close_after, exit_after);
|
---|
874 | // Wait until it is closed.
|
---|
875 | try {
|
---|
876 | synchronized(this) {
|
---|
877 | while(Gatherer.c_man.reallyReady()) {
|
---|
878 | wait(10);
|
---|
879 | }
|
---|
880 | }
|
---|
881 | }
|
---|
882 | catch(Exception error) {
|
---|
883 | Gatherer.println("Exception: " + error);
|
---|
884 | Gatherer.printStackTrace(error);
|
---|
885 | }
|
---|
886 |
|
---|
887 | Gatherer.c_man.setClosingThread(false);
|
---|
888 |
|
---|
889 | //content_pane.paintImmediately(bounds);
|
---|
890 | return true;
|
---|
891 | //case SaveCollectionBox.SAVE_NO:
|
---|
892 | // Close collection.
|
---|
893 | // if(close_after) {
|
---|
894 | // tab_pane.setSelectedComponent(gather_pane);
|
---|
895 | // Gatherer.c_man.closeCollection();
|
---|
896 | // }
|
---|
897 | // if(exit_after) {
|
---|
898 | // Gatherer.self.exit();
|
---|
899 | // }
|
---|
900 | // return true;
|
---|
901 | //default:
|
---|
902 | // return false;
|
---|
903 | //}
|
---|
904 | }
|
---|
905 | /** 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.
|
---|
906 | * @param event A ChangeEvent containing information about the event that fired this call.
|
---|
907 | */
|
---|
908 | public void stateChanged(ChangeEvent event) {
|
---|
909 | if(previous_pane != null) {
|
---|
910 | if(previous_pane == create_pane) {
|
---|
911 | create_pane.loseFocus();
|
---|
912 | }
|
---|
913 | else if(previous_pane == design_pane) {
|
---|
914 | design_pane.loseFocus();
|
---|
915 | }
|
---|
916 | }
|
---|
917 | // "View assigned metadata" menu item is disabled by default
|
---|
918 | menu_bar.metadata_view.setCanEnable(false);
|
---|
919 | menu_bar.setMetaAuditSuffix(null);
|
---|
920 |
|
---|
921 | menu_bar.tabSelected(tab_pane.getSelectedIndex());
|
---|
922 | int selected_index = tab_pane.getSelectedIndex();
|
---|
923 | if( selected_index == tab_pane.indexOfComponent(gather_pane)) {
|
---|
924 | gather_pane.gainFocus();
|
---|
925 | // "View assigned metadata" menu item is enabled for the "Gather" pane
|
---|
926 | menu_bar.metadata_view.setCanEnable(true);
|
---|
927 | }
|
---|
928 | else if(selected_index == tab_pane.indexOfComponent(enrich_pane)) {
|
---|
929 | enrich_pane.gainFocus();
|
---|
930 | // "View assigned metadata" menu item is enabled for the "Enrich" pane
|
---|
931 | menu_bar.metadata_view.setCanEnable(true);
|
---|
932 | }
|
---|
933 | else if(selected_index == tab_pane.indexOfComponent(design_pane)) {
|
---|
934 | design_pane.gainFocus();
|
---|
935 | }
|
---|
936 | else if(selected_index == tab_pane.indexOfComponent(create_pane)) {
|
---|
937 | create_pane.gainFocus();
|
---|
938 | }
|
---|
939 | else if(selected_index == tab_pane.indexOfComponent(mirror_pane)) {
|
---|
940 | mirror_pane.gainFocus();
|
---|
941 | }
|
---|
942 | //else if(tab_pane.getSelectedIndex() == tab_pane.indexOfComponent(preview_pane)) {
|
---|
943 | //design_pane.saveConfiguration();
|
---|
944 | //preview_pane.gainFocus();
|
---|
945 | //}
|
---|
946 |
|
---|
947 | previous_pane = (JPanel) tab_pane.getSelectedComponent();
|
---|
948 | }
|
---|
949 |
|
---|
950 | private MouseListener mouse_blocker_listener = new MouseAdapter() {};
|
---|
951 |
|
---|
952 | public void wait(boolean waiting) {
|
---|
953 | Component glass_pane = getGlassPane();
|
---|
954 | if(waiting) {
|
---|
955 | // Show wait cursor.
|
---|
956 | glass_pane.addMouseListener(mouse_blocker_listener);
|
---|
957 | glass_pane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
---|
958 | glass_pane.setVisible(true);
|
---|
959 | }
|
---|
960 | else {
|
---|
961 | // Hide wait cursor.
|
---|
962 | glass_pane.setVisible(false);
|
---|
963 | glass_pane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
---|
964 | glass_pane.removeMouseListener(mouse_blocker_listener);
|
---|
965 | }
|
---|
966 | glass_pane = null;
|
---|
967 | }
|
---|
968 |
|
---|
969 | public void workflowUpdate(String raw, boolean state) {
|
---|
970 | WorkflowUpdater task = new WorkflowUpdater(raw, state);
|
---|
971 | SwingUtilities.invokeLater(task);
|
---|
972 | task = null;
|
---|
973 | }
|
---|
974 |
|
---|
975 | /** Called to determine if we should wait for a thread to finish before continuing. We wait for threads if they are named: GSHELL_BUILD, GSHELL_IMPORT, or GSHELL_NEW.
|
---|
976 | * @return <i>true</i> if we should wait for a thread, <i>false</i> if it is safe to continue.
|
---|
977 | */
|
---|
978 | private boolean waitForThread() {
|
---|
979 | Thread active[] = new Thread[thread_group.activeCount()];
|
---|
980 | int size = thread_group.enumerate(active);
|
---|
981 | for(int i = 0; i < size; i++) {
|
---|
982 | if(active[i].getName().equals(GShell.GSHELL_BUILD) ||
|
---|
983 | active[i].getName().equals(GShell.GSHELL_IMPORT) ||
|
---|
984 | active[i].getName().equals(GShell.GSHELL_NEW)) {
|
---|
985 | return true;
|
---|
986 | }
|
---|
987 | }
|
---|
988 | return false;
|
---|
989 | }
|
---|
990 |
|
---|
991 |
|
---|
992 | /**Overridden from JFrame so we can exit safely when window is closed (or destroyed).
|
---|
993 | * @param event A <strong>WindowEvent</strong> containing information about the event that fired this call.
|
---|
994 | */
|
---|
995 | protected void processWindowEvent(WindowEvent event) {
|
---|
996 | if(event.getID() == WindowEvent.WINDOW_CLOSING) {
|
---|
997 | exit();
|
---|
998 | }
|
---|
999 | }
|
---|
1000 | /** 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.
|
---|
1001 | */
|
---|
1002 | private class MenuListenerImpl
|
---|
1003 | implements MenuListener {
|
---|
1004 | /** Called whenever a popup menu is hidden, but we don't care.
|
---|
1005 | * @param e Some <strong>MenuEvent</strong> that we could care less about.
|
---|
1006 | */
|
---|
1007 | public void menuCanceled(MenuEvent e) {
|
---|
1008 | }
|
---|
1009 | /** Called whenever a menu header (ie button) becomes unselected, but we don't care.
|
---|
1010 | * @param e Some <strong>MenuEvent</strong> that we could care less about.
|
---|
1011 | */
|
---|
1012 | public void menuDeselected(MenuEvent e) {
|
---|
1013 | }
|
---|
1014 | /** 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.
|
---|
1015 | * @param e The <strong>MenuEvent</strong> whose source is checked.
|
---|
1016 | */
|
---|
1017 | public void menuSelected(MenuEvent e) {
|
---|
1018 | if(e.getSource() == menu_bar.help) {
|
---|
1019 | if(menu_bar.help.isSelected()) {
|
---|
1020 | menu_bar.help.doClick(10);
|
---|
1021 | }
|
---|
1022 | }
|
---|
1023 | }
|
---|
1024 | }
|
---|
1025 | private class TabUpdater
|
---|
1026 | implements Runnable {
|
---|
1027 | private boolean ready = false;
|
---|
1028 | //private int browse_pos = -1;
|
---|
1029 | private int mirror_pos = -1;
|
---|
1030 | private int config_pos = -1;
|
---|
1031 | private int create_pos = -1;
|
---|
1032 | private int export_pos = -1;
|
---|
1033 | private int metaedit_pos = -1;
|
---|
1034 | //private int preview_pos = -1;
|
---|
1035 | private JTabbedPane tab_pane = null;
|
---|
1036 | public TabUpdater(JTabbedPane tab_pane, boolean ready) {
|
---|
1037 | this.ready = ready;
|
---|
1038 | this.tab_pane = tab_pane;
|
---|
1039 | //browse_pos = tab_pane.indexOfComponent(browser_pane);
|
---|
1040 | mirror_pos = tab_pane.indexOfComponent(mirror_pane);
|
---|
1041 | metaedit_pos = tab_pane.indexOfComponent(enrich_pane);
|
---|
1042 | config_pos = tab_pane.indexOfComponent(design_pane);
|
---|
1043 | export_pos = tab_pane.indexOfComponent(export_pane);
|
---|
1044 | create_pos = tab_pane.indexOfComponent(create_pane);
|
---|
1045 | //preview_pos = tab_pane.indexOfComponent(preview_pane);
|
---|
1046 | }
|
---|
1047 |
|
---|
1048 | public void run() {
|
---|
1049 | // if(browse_pos != -1) {
|
---|
1050 | // if(ready) {
|
---|
1051 | // tab_pane.setEnabledAt(browse_pos, Gatherer.config.get("workflow.browse", false));
|
---|
1052 | // }
|
---|
1053 | // else {
|
---|
1054 | // tab_pane.setEnabledAt(browse_pos, Gatherer.config.get("workflow.browse", true));
|
---|
1055 | // }
|
---|
1056 | // }
|
---|
1057 | if(mirror_pos != -1) {
|
---|
1058 | if(ready) {
|
---|
1059 | tab_pane.setEnabledAt(mirror_pos, Gatherer.config.get("workflow.mirror", false));
|
---|
1060 | }
|
---|
1061 | else {
|
---|
1062 | tab_pane.setEnabledAt(mirror_pos, Gatherer.config.get("workflow.mirror", true));
|
---|
1063 | }
|
---|
1064 | }
|
---|
1065 | if(metaedit_pos != -1) {
|
---|
1066 | tab_pane.setEnabledAt(metaedit_pos, ready && Gatherer.config.get("workflow.enrich", false));
|
---|
1067 | }
|
---|
1068 | if(config_pos != -1) {
|
---|
1069 | tab_pane.setEnabledAt(config_pos, ready && Gatherer.config.get("workflow.design", false) && Gatherer.config.getMode() > Configuration.ASSISTANT_MODE);
|
---|
1070 | }
|
---|
1071 | if(export_pos != -1) {
|
---|
1072 | tab_pane.setEnabledAt(export_pos, ready && Gatherer.config.get("workflow.export", false));
|
---|
1073 | }
|
---|
1074 | if(create_pos != -1) {
|
---|
1075 | tab_pane.setEnabledAt(create_pos, ready && Gatherer.config.get("workflow.create", false));
|
---|
1076 | }
|
---|
1077 | // if(preview_pos != -1) {
|
---|
1078 | // tab_pane.setEnabledAt(preview_pos, Gatherer.c_man != null && Gatherer.c_man.built() && Gatherer.config.get("workflow.preview", false));
|
---|
1079 | // }
|
---|
1080 | }
|
---|
1081 | public void setReady(boolean ready) {
|
---|
1082 | this.ready = ready;
|
---|
1083 | }
|
---|
1084 | }
|
---|
1085 |
|
---|
1086 | private class WorkflowUpdater
|
---|
1087 | implements Runnable {
|
---|
1088 | private boolean state;
|
---|
1089 | private String raw;
|
---|
1090 | public WorkflowUpdater(String raw, boolean state) {
|
---|
1091 | this.raw = raw;
|
---|
1092 | this.state = state;
|
---|
1093 | }
|
---|
1094 | public void run() {
|
---|
1095 | setTabEnabled(raw, state);
|
---|
1096 | }
|
---|
1097 | }
|
---|
1098 | }
|
---|
1099 |
|
---|
1100 |
|
---|