source: trunk/gli/src/org/greenstone/gatherer/gui/CreatePane.java@ 8353

Last change on this file since 8353 was 8353, checked in by mdewsnip, 20 years ago

Changed the collectionChanged() functions to refresh(), and added an extra parameter for more control over refreshing.

  • Property svn:keywords set to Author Date Id Revision
File size: 36.6 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * <BR><BR>
9 *
10 * Author: John Thompson, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37package org.greenstone.gatherer.gui;
38
39import java.awt.*;
40import java.awt.event.*;
41import java.io.*;
42import javax.swing.*;
43import javax.swing.event.*;
44import javax.swing.text.*;
45import javax.swing.tree.*;
46import org.greenstone.gatherer.Configuration;
47import org.greenstone.gatherer.Dictionary;
48import org.greenstone.gatherer.Gatherer;
49import org.greenstone.gatherer.cdm.SearchTypeManager;
50import org.greenstone.gatherer.collection.BuildOptions;
51import org.greenstone.gatherer.collection.Collection;
52import org.greenstone.gatherer.shell.GBasicProgressMonitor;
53import org.greenstone.gatherer.shell.GBuildProgressMonitor;
54import org.greenstone.gatherer.shell.GImportProgressMonitor;
55import org.greenstone.gatherer.shell.GShell;
56import org.greenstone.gatherer.shell.GShellEvent;
57import org.greenstone.gatherer.shell.GShellListener;
58import org.greenstone.gatherer.shell.GShellProgressMonitor;
59import org.greenstone.gatherer.util.AppendLineOnlyFileDocument;
60import org.greenstone.gatherer.util.StaticStrings;
61
62/** This class provides a GUI view showing some statistics on your current collection, and options for building it. As the collection is built this initial view is replaced with one showing progress bars and a message log of the creation process. This log can be later accessed via the options tree located in the center of the initial pane. This class is also responsible for creating the GShellProgressMonitors that are then attatched to external shell processes, and calling the methods in the CollectionManager for actually importing and building the collection. <br><BR>
63 * <center><table width=80% border=2 cellspacing=0 cellpadding=2><tr><td align=center colspan=4>
64 * The (i)mport and/or (b)uild options supported:</td></tr>
65 * <tr background=black><font color=white><td>Script</td><td>Associated Argument</td><td>Control</td><td>Comments</td></font></tr>
66 * <tr><td>b</td><td>-allclassifications</td><td>JCheckBox</td><td>&nbsp;</td></tr>
67 * <tr><td>i/b</td><td>-archivedir</td><td>JTextField</td><td>&nbsp;</td></tr>
68 * <tr><td>b</td><td>-builddir</td><td>JTextField</td><td>&nbsp;</td></tr>
69 * <tr><td>i/b</td><td>-debug</td><td>JCheckBox</td><td>&nbsp;</td></tr>
70 * <tr><td>i/b</td><td>-collectdir</td><td>JTextField</td><td>&nbsp;</td></tr>
71 * <tr><td>b</td><td>-create_images</td><td>JCheckBox</td><td>&nbsp;</td></tr>
72 * <tr><td>i</td><td>-groupsize</td><td>JSpinner </td><td>&nbsp;</td></tr>
73 * <tr><td>i</td><td>-gzip</td><td>JCheckBox</td><td>&nbsp;</td></tr>
74 * <tr><td>i</td><td>-importdir</td><td>JTextField</td><td>&nbsp;</td></tr>
75 * <tr><td>b</td><td>-index</td><td>GCheckList</td><td>&nbsp;</td></tr>
76 * <tr><td>i/b</td><td>-keepold</td><td>JCheckBox</td><td>sanity check removeold</td></tr>
77 * <tr><td>i/b</td><td>-maxdocs</td><td>JSpinner</td><td>&nbsp;</td></tr>
78 * <tr><td>b</td><td>-mode</td><td>JComboBox</td><td>"all", "compress_text", "infodb", "build_index"</td></tr>
79 * <tr><td>b</td><td>-no_text</td><td>JCheckBox</td><td>&nbsp;</td></tr>
80 * <tr><td>i</td><td>-OIDtype</td><td>JComboBox</td><td>"hash","incremental"</td></tr>
81 * <tr><td>i/b</td><td>-out</td><td>JTextField</td><td>&nbsp;</td></tr>
82 * <tr><td>i</td><td>-removeold</td><td>JCheckBox</td><td>sanity check keepold</td></tr>
83 * <tr><td>i</td><td>-sortmeta</td><td>JComboBox</td><td>&nbsp;</td></tr>
84 * <tr><td>i/b</td><td>-verbosity</td><td>JSpinner</td><td>1, 3</td></tr>
85 * </table></center>
86 * @author John Thompson, Greenstone Digital Library, University of Waikato
87 * @version 2.3
88 */
89public class CreatePane
90 extends JPanel
91 implements GShellListener {
92
93 static private Dimension ARGUMENT_SIZE = new Dimension(800,90);
94 /** The threshold for when the simple view is replaced by the complex one. */
95 static private final int THRESHOLD = Configuration.EXPERT_MODE;
96 /** An identifier for the control panel within the card layout. */
97 static private String CONTROL = "Control";
98 /** An identifier for the progress panel within the card layout. */
99 static private String PROGRESS = "Progress";
100 /** An identifier for the simple panel within the card layout. */
101 static private String SIMPLE = "Simple";
102
103 /** Determines the current view that should be shown for this pane. */
104 public boolean processing = false;
105 /** The options pane generates all the various option sheet configuations. */
106 public OptionsPane options_pane = null;
107 private AppendLineOnlyFileDocument document;
108 /** A card layout is used to store the separate configuration and progress panes. */
109 private CardLayout card_layout = null;
110 /** Stores a reference to the current collection. */
111 private Collection previous_collection = null;
112 /** This monitor tracks the build processes progress. */
113 private GShellProgressMonitor build_monitor = null;
114 /** This monitor tracks the import processes progress. */
115 private GShellProgressMonitor import_monitor = null;
116 /** The button for begining the building processes. */
117 private JButton build_button = null;
118 /** The button for stopping the building processes. */
119 private JButton cancel_button = null;
120 /** The button for viewing the collection. */
121 private JButton preview_button = null;
122 private JButton simple_build_button;
123 private JButton simple_cancel_button;
124 private JButton simple_preview_button;
125 /** The label displaying the number of documents in this collection. */
126 private JLabel document_count = null;
127 /** The label alongside the build progress bar gets some special treatment so... */
128 private JLabel progress_build_label = null;
129 /** The label alongside the import progress bar gets some special treatment so... */
130 private JLabel progress_import_label = null;
131 private JPanel bar_area;
132 /** The panel on which buttons are rendered on higher detail modes. */
133 private JPanel button_pane;
134 /** The pane which contains the controls for configuration. */
135 private JPanel control_pane = null;
136 /** The pane which has the card layout as its manager. */
137 private JPanel main_pane = null;
138 /** The pane which contains the progress information. */
139 private JPanel progress_pane = null;
140 /** The pane on the right-hand side - shows the requested options view */
141 private JPanel right = null;
142 /** The simple panel on which all of the available arguments are rendered. */
143 private JPanel sargument_configuration_panel;
144 /** The panel on which buttons are rendered on lower details modes. */
145 private JPanel sbutton_panel;
146 /** A simplified version for lower detail modes containing both the control and progress panes smooshed together. */
147 private JPanel simple_panel;
148 /** The inner panel of the simple pane which is global so that the bar_area can be added and removed from it. */
149 private JPanel sinner_panel;
150 /** The outer panel of the simple pane which is global so that the arguments pane can be added and removed from it. */
151 private JPanel souter_panel;
152 /** The scrolling pane for the log. */
153 private JScrollPane log_scroll;
154 /** The scrolling pane the simple arguments are rendered within. */
155 private JScrollPane sargument_configuration_scroll;
156 /** the scrolling pane the righthand side is inside - only used for import and build options. the log and log list are not inside a scrollpane */
157 private JScrollPane scroll_pane;
158 /** The message log for the entire session. */
159 private JTextArea log_textarea;
160 /** A tree used to display the currently available option views. */
161 private OptionTree tree = null;
162 /** An array used to pass arguments with dictionary calls. */
163 private String args[] = null;
164 /** The homepage address of the current collection */
165 private String homepage = null;
166
167
168 /** The constructor creates important helper classes, and initializes all the components.
169 * @see org.greenstone.gatherer.collection.CollectionManager
170 * @see org.greenstone.gatherer.gui.BuildOptions
171 * @see org.greenstone.gatherer.gui.CreatePane.BuildButtonListener
172 * @see org.greenstone.gatherer.gui.CreatePane.CancelButtonListener
173 * @see org.greenstone.gatherer.gui.CreatePane.OptionTree
174 * @see org.greenstone.gatherer.gui.OptionsPane
175 * @see org.greenstone.gatherer.shell.GBasicProgressMonitor
176 * @see org.greenstone.gatherer.shell.GBuildProgressMonitor
177 * @see org.greenstone.gatherer.shell.GImportProgressMonitor
178 * @see org.greenstone.gatherer.shell.GShellProgressMonitor
179 */
180 public CreatePane() {
181 Collection collection = Gatherer.c_man.getCollection();
182 log_textarea = new JTextArea();
183 log_scroll = new JScrollPane(log_textarea);
184
185 // Create components
186 card_layout = new CardLayout();
187 // Control Pane
188 control_pane = new JPanel();
189 tree = new OptionTree();
190 button_pane = new JPanel();
191
192 // Progress Pane
193 progress_pane = new JPanel(); // One owner of the bar component
194 bar_area = new JPanel(); // This component will be shared about
195
196 progress_import_label = new JLabel();
197 Dictionary.registerText(progress_import_label, "CreatePane.Import_Progress");
198
199 import_monitor = new GImportProgressMonitor(); //GBasicProgressMonitor();
200 Gatherer.c_man.registerImportMonitor(import_monitor);
201
202 progress_build_label = new JLabel();
203 Dictionary.registerText(progress_build_label, "CreatePane.Build_Progress");
204
205 build_monitor = new GBuildProgressMonitor(import_monitor.getSharedProgress()); //GBasicProgressMonitor();
206 Gatherer.c_man.registerBuildMonitor(build_monitor);
207
208 // And the simple panel
209 simple_panel = new JPanel();
210 sbutton_panel = new JPanel();
211 sinner_panel = new JPanel();
212
213 // Buttons
214 BuildButtonListener bbl = new BuildButtonListener();
215 CancelButtonListener cbl = new CancelButtonListener();
216 PreviewButtonListener pbl = new PreviewButtonListener();
217
218 build_button = new GLIButton();
219 build_button.addActionListener(bbl);
220 build_button.setMnemonic(KeyEvent.VK_B);
221 Dictionary.registerBoth(build_button, "CreatePane.Build_Collection", "CreatePane.Build_Collection_Tooltip");
222
223 cancel_button = new GLIButton();
224 cancel_button.addActionListener(cbl);
225 cancel_button.setEnabled(false);
226 cancel_button.setMnemonic(KeyEvent.VK_C);
227 Dictionary.registerBoth(cancel_button, "CreatePane.Cancel_Build", "CreatePane.Cancel_Build_Tooltip");
228
229 preview_button = new GLIButton();
230 preview_button.addActionListener(pbl);
231 if(Gatherer.c_man != null) {
232 preview_button.setEnabled(Gatherer.c_man.built());
233 }
234 else {
235 preview_button.setEnabled(false);
236 }
237 preview_button.setMnemonic(KeyEvent.VK_P);
238 Dictionary.registerBoth(preview_button, "CreatePane.Preview_Collection", "CreatePane.Preview_Collection_Tooltip");
239
240 simple_build_button = new GLIButton();
241 simple_build_button.addActionListener(bbl);
242 simple_build_button.setMnemonic(KeyEvent.VK_B);
243 Dictionary.registerBoth(simple_build_button, "CreatePane.Build_Collection", "CreatePane.Build_Collection_Tooltip");
244
245 simple_cancel_button = new GLIButton();
246 simple_cancel_button.addActionListener(cbl);
247 simple_cancel_button.setEnabled(false);
248 simple_cancel_button.setMnemonic(KeyEvent.VK_C);
249 Dictionary.registerBoth(simple_cancel_button, "CreatePane.Cancel_Build", "CreatePane.Cancel_Build_Tooltip");
250
251 simple_preview_button = new GLIButton();
252 simple_preview_button.addActionListener(pbl);
253 if(Gatherer.c_man != null) {
254 simple_preview_button.setEnabled(Gatherer.c_man.built());
255 }
256 else {
257 simple_preview_button.setEnabled(false);
258 }
259 simple_preview_button.setMnemonic(KeyEvent.VK_P);
260 Dictionary.registerBoth(simple_preview_button, "CreatePane.Preview_Collection", "CreatePane.Preview_Collection_Tooltip");
261
262 bbl = null;
263 cbl = null;
264 pbl = null;
265 }
266
267
268 public void destroy() {
269 if(document != null) {
270 document.destroy();
271 }
272 }
273
274 /** This method is called to actually layout the components.
275 * @see org.greenstone.gatherer.Configuration
276 * @see org.greenstone.gatherer.Gatherer
277 */
278 public void display() {
279
280 int current_mode = Configuration.getMode();
281
282 // Build control_pane
283 JPanel left = new JPanel();
284 left.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
285 left.setLayout(new BorderLayout());
286 left.add(tree, BorderLayout.CENTER);
287
288 right = new JPanel();
289 right.setBorder(BorderFactory.createEmptyBorder(0,0,5,5));
290 right.setLayout(new BorderLayout());
291
292 JPanel options_area = new JPanel();
293 options_area.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5,5,5,5), BorderFactory.createTitledBorder(Dictionary.get("CreatePane.Options_Title"))));
294 options_area.setLayout(new BorderLayout());
295 options_area.add(left, BorderLayout.WEST);
296 options_area.add(right, BorderLayout.CENTER);
297
298 button_pane = new JPanel();
299 button_pane.setBorder(BorderFactory.createEmptyBorder(5,10,10,10));
300 button_pane.setLayout(new GridLayout(1,3));
301 button_pane.add(build_button);
302 button_pane.add(cancel_button);
303 button_pane.add(preview_button);
304
305 control_pane.setLayout(new BorderLayout());
306 control_pane.add(options_area, BorderLayout.CENTER);
307 control_pane.add(button_pane, BorderLayout.SOUTH);
308
309 // Build progress_pane
310
311 JPanel labels_pane = new JPanel();
312 labels_pane.setLayout(new GridLayout(2,1,0,5));
313 labels_pane.add(progress_import_label);
314 labels_pane.add(progress_build_label);
315
316 JPanel monitors_pane = new JPanel();
317 monitors_pane.setLayout(new GridLayout(2,1,0,5));
318 monitors_pane.add(import_monitor.getProgress());
319 monitors_pane.add(build_monitor.getProgress());
320
321 bar_area.setBorder(BorderFactory.createEmptyBorder(10,10,5,10));
322 bar_area.setLayout(new BorderLayout(5,5));
323 bar_area.add(labels_pane, BorderLayout.WEST);
324 bar_area.add(monitors_pane, BorderLayout.CENTER);
325
326 progress_pane.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
327 progress_pane.setLayout(new BorderLayout());
328 progress_pane.add(bar_area, BorderLayout.NORTH);
329 if(current_mode >= THRESHOLD) {
330 progress_pane.add(log_scroll, BorderLayout.CENTER);
331 }
332
333 // Simple panel
334 sbutton_panel.setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
335 sbutton_panel.setLayout(new GridLayout(3,1));
336 sbutton_panel.add(simple_build_button);
337 sbutton_panel.add(simple_cancel_button);
338 sbutton_panel.add(simple_preview_button);
339
340 JPanel simple_bar_area = new JPanel(new GridLayout(3,1));
341 simple_bar_area.setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
342 simple_bar_area.add(import_monitor.getSharedProgress());
343
344 sinner_panel.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
345 sinner_panel.setLayout(new BorderLayout());
346 sinner_panel.add(sbutton_panel, BorderLayout.WEST);
347 sinner_panel.add(simple_bar_area, BorderLayout.CENTER);
348
349 if(options_pane != null) {
350 sargument_configuration_panel = options_pane.buildImport(null);
351 sargument_configuration_panel = options_pane.buildBuild(sargument_configuration_panel);
352 }
353 else {
354 sargument_configuration_panel = new JPanel();
355 }
356 sargument_configuration_scroll = new JScrollPane(sargument_configuration_panel);
357 sargument_configuration_scroll.setPreferredSize(ARGUMENT_SIZE);
358 souter_panel = new JPanel();
359 souter_panel.setSize(new Dimension(400,800));
360 souter_panel.setLayout(new GridLayout(2,1));
361 souter_panel.add(sargument_configuration_scroll);
362 souter_panel.add(sinner_panel);
363
364 simple_panel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
365 simple_panel.setLayout(new BorderLayout());
366 simple_panel.add(souter_panel, BorderLayout.NORTH);
367 if(current_mode < THRESHOLD) {
368 simple_panel.add(log_scroll, BorderLayout.CENTER);
369 }
370
371 // Main pane
372 main_pane = new JPanel(card_layout);
373 if(current_mode < THRESHOLD) { // Simple mode - add first
374 main_pane.add(simple_panel, SIMPLE);
375 }
376 main_pane.add(control_pane, CONTROL);
377 main_pane.add(progress_pane, PROGRESS);
378 if(current_mode >= THRESHOLD) { // Expert mode - add last
379 main_pane.add(simple_panel, SIMPLE);
380 }
381
382 this.setLayout(new BorderLayout());
383 this.add(main_pane, BorderLayout.CENTER);
384 }
385
386 /** This method is called whenever the 'Create' tab is selected from the view bar. It allows this view to perform any preactions required prior to display. In this case this entails gathering up to date information about the status of the collection including number of documents etc.
387 * @see org.greenstone.gatherer.Gatherer
388 * @see org.greenstone.gatherer.collection.CollectionManager
389 * @see org.greenstone.gatherer.gui.CreatePane.OptionTree
390 */
391 public void gainFocus() {
392 if(Configuration.getMode() < THRESHOLD) {
393 card_layout.show(main_pane, SIMPLE);
394 }
395 else if(!processing) {
396 // Move the buttons to control
397 control_pane.add(button_pane, BorderLayout.SOUTH);
398 card_layout.show(main_pane, CONTROL);
399 }
400 else {
401 // Move the buttons to progress
402 progress_pane.add(button_pane, BorderLayout.SOUTH);
403 card_layout.show(main_pane, PROGRESS);
404 }
405 // Refresh the set of controls.
406 TreePath path = tree.getSelectionPath();
407 tree.clearSelection();
408 tree.setSelectionPath(path);
409 }
410
411 /** We are informed when this view pane loses focus so we can update build options. */
412 public void loseFocus() {
413 tree.valueChanged(null);
414 }
415
416 /** All implementation of GShellListener must include this method so the listener can be informed of messages from the GShell.
417 * @param event A <strong>GShellEvent</strong> that contains, amoung other things, the message.
418 */
419 public synchronized void message(GShellEvent event) {
420 // Ignore the messages from RecPlug with 'show_progress' set (used for progress bars)
421 if (event.getMessage().startsWith("import.pl> RecPlug - ")) {
422 return;
423 }
424 document.appendLine(event.getMessage());
425 log_textarea.setCaretPosition(document.getLengthToNearestLine());
426 }
427
428 /** Called when the detail mode has changed which in turn may cause several import/build configuration arguments to be available/hidden
429 * @param mode the new mode as an int
430 */
431 public void modeChanged(int mode) {
432 // If we are below the complexity threshold ensure the simple controls are being shown
433 if(Configuration.getMode() < THRESHOLD) {
434 // Update the arguments
435 souter_panel.remove(sargument_configuration_scroll);
436 souter_panel.remove(sinner_panel);
437 if(options_pane != null) {
438 sargument_configuration_panel = options_pane.buildImport(null);
439 sargument_configuration_panel = options_pane.buildBuild(sargument_configuration_panel);
440 }
441 else {
442 sargument_configuration_panel = new JPanel();
443 }
444 sargument_configuration_scroll = new JScrollPane(sargument_configuration_panel);
445 sargument_configuration_scroll.setPreferredSize(ARGUMENT_SIZE);
446 souter_panel.add(sargument_configuration_scroll);
447 souter_panel.add(sinner_panel);
448 // Remove the shared components from the expert panels
449 progress_pane.remove(log_scroll);
450 // And add to simple one
451 simple_panel.add(log_scroll, BorderLayout.CENTER);
452 // And bring the card to the front
453 card_layout.show(main_pane, SIMPLE);
454 }
455 // And if we are above the threshold change to the complex controls
456 else {
457 // Remove the shared components from the simple panel
458 simple_panel.remove(log_scroll);
459 // And add then to the expert ones
460 progress_pane.add(log_scroll, BorderLayout.CENTER);
461 // And bring the appropriate card to the front
462 if(!processing) {
463 control_pane.add(button_pane, BorderLayout.SOUTH);
464 card_layout.show(main_pane, CONTROL);
465 }
466 else {
467 progress_pane.add(button_pane, BorderLayout.SOUTH);
468 card_layout.show(main_pane, PROGRESS);
469 }
470 }
471 tree.valueChanged(null); // Ensure tree argument panels are rebuilt
472 }
473
474 /** All implementation of GShellListener must include this method so the listener can be informed when a GShell begins its task. Implementation side-effect, not actually used.
475 * @param event A <strong>GShellEvent</strong> that contains details of the initial state of the <strong>GShell</strong> before task comencement.
476 */
477 public synchronized void processBegun(GShellEvent event) {
478 // We don't care. We'll get a more acurate start from the progress monitors.
479 }
480 /** All implementation of GShellListener must include this method so the listener can be informed when a GShell completes its task.
481 * @param event A <strong>GShellEvent</strong> that contains details of the final state of the <strong>GShell</strong> after task completion.
482 */
483 public synchronized void processComplete(GShellEvent event) {
484 if(event.getStatus() == GShell.OK) {
485 if(event.getType() == GShell.BUILD) {
486 processing = false;
487 build_button.setEnabled(true);
488 cancel_button.setEnabled(false);
489 //preview_button.setEnabled(true);
490 simple_build_button.setEnabled(true);
491 simple_cancel_button.setEnabled(false);
492 //simple_preview_button.setEnabled(true);
493 int status = event.getStatus();
494 document.setSpecialCharacter(OptionsPane.SUCCESSFUL);
495 options_pane.resetFileEntry();
496 build_monitor.reset();
497 import_monitor.reset();
498 if(Configuration.getMode() >= THRESHOLD) {
499 control_pane.add(button_pane, BorderLayout.SOUTH);
500 card_layout.show(main_pane, CONTROL);
501 }
502 }
503 // Otherwise its completed import but still got build to go
504 }
505 else {
506 processing = false;
507 cancel_button.setEnabled(false);
508 build_button.setEnabled(true);
509 // The build may have failed, but a previous index may still be in place
510 //preview_button.setEnabled(Gatherer.c_man.built());
511
512 simple_build_button.setEnabled(true);
513 simple_cancel_button.setEnabled(false);
514 //simple_preview_button.setEnabled(Gatherer.c_man.built());
515 if(event.getStatus() == GShell.CANCELLED) {
516 document.setSpecialCharacter(OptionsPane.CANCELLED);
517 }
518 else {
519 document.setSpecialCharacter(OptionsPane.UNSUCCESSFUL);
520 }
521 options_pane.resetFileEntry();
522 if(Configuration.getMode() >= THRESHOLD) {
523 control_pane.add(button_pane, BorderLayout.SOUTH);
524 card_layout.show(main_pane, CONTROL);
525 }
526 }
527 }
528
529
530 /** This method is invoked at any time there has been a significant change in the collection, such as saving, loading or creating.
531 * @param ready A <strong>boolean</strong> indicating if a collection is currently available.
532 * @see org.greenstone.gatherer.Gatherer
533 * @see org.greenstone.gatherer.collection.CollectionManager
534 * @see org.greenstone.gatherer.gui.BuildOptions
535 * @see org.greenstone.gatherer.gui.OptionsPane
536 */
537 public void refresh(int refresh_reason, boolean ready)
538 {
539 if(Gatherer.c_man == null || !ready) {
540 return;
541 }
542 Collection current_collection = Gatherer.c_man.getCollection();
543 if (current_collection != previous_collection && !Gatherer.c_man.isImporting()) {
544 this.options_pane = new OptionsPane(current_collection.build_options);
545 if (previous_collection != null) {
546 // clear the log
547 Document log_document = log_textarea.getDocument();
548 if (log_document instanceof AppendLineOnlyFileDocument) {
549 ((AppendLineOnlyFileDocument) log_document).destroy();
550 }
551 }
552 previous_collection = current_collection;
553
554 }
555 // If we are in simple mode, we have to rebuild the simple arguments list
556 if(Configuration.getMode() < THRESHOLD) {
557 souter_panel.remove(sargument_configuration_scroll);
558 souter_panel.remove(sinner_panel);
559 sargument_configuration_panel = options_pane.buildImport(null);
560 sargument_configuration_panel = options_pane.buildBuild(sargument_configuration_panel);
561 sargument_configuration_scroll = new JScrollPane(sargument_configuration_panel);
562 sargument_configuration_scroll.setPreferredSize(ARGUMENT_SIZE);
563 souter_panel.add(sargument_configuration_scroll);
564 souter_panel.add(sinner_panel);
565 }
566 tree.valueChanged(null);
567
568 // now do the preview stuff
569 if (!Gatherer.c_man.built() || Configuration.exec_address == null) {
570 preview_button.setEnabled(false);
571 simple_preview_button.setEnabled(false);
572 } else {
573 preview_button.setEnabled(true);
574 simple_preview_button.setEnabled(true);
575 }
576 }
577
578
579 private void configureHomeURL() {
580 // set up the home page for the current collection
581 Collection current_collection = Gatherer.c_man.getCollection();
582 String site = Configuration.site_name; // for GS3 colls
583 String extra_args = "";
584 SearchTypeManager st_man = current_collection.cdm.searchtype_manager;
585 if (!Gatherer.GS3 && st_man.isMGPPEnabled()) {
586 // we need some more args on the url
587 String search_types = st_man.getSearchTypes();
588 if (search_types.equals("")) {
589 extra_args = "&ct=1&qt=0&qto=3";
590 } else if (search_types.equals("plain")) {
591 extra_args = "&ct=1&qt=0&qto=1";
592 } else if (search_types.equals("form")) {
593 extra_args = "&ct=1&qt=1&qto=2";
594 } else if (search_types.equals("plain,form")) {
595 extra_args = "&ct=1&qt=0&qto=3";
596 } else if (search_types.equals("form,plain")) {
597 extra_args = "&ct=1&qt=1&qto=3";
598 }
599 }
600 // Remember to add unique timestamp
601 if (Gatherer.GS3) {
602 homepage = Configuration.exec_address.toString() + Configuration.getServletPath()+ "?a=p&sa=about&c=" + current_collection.getName()+"&l="+Configuration.getLanguage(); //+extra_args + StaticStrings.TIMESTAMP_ARGUMENT + System.currentTimeMillis();
603 } else {
604 homepage = Configuration.exec_address.toString() + "?a=p&p=about&c=" + current_collection.getName()+"&l="+Configuration.getLanguage()+extra_args + StaticStrings.TIMESTAMP_ARGUMENT + System.currentTimeMillis();
605 }
606 }
607
608
609 /** This class serves as the listener for actions on the build button. */
610 private class BuildButtonListener
611 implements ActionListener {
612 /** This method causes a call to be made to CollectionManager.importCollection(), which then imports and builds the collection as necessary.
613 * @param event An <strong>ActionEvent</strong> who, thanks to the power of object oriented programming, we don't give two hoots about.
614 * @see org.greenstone.gatherer.Gatherer
615 * @see org.greenstone.gatherer.collection.CollectionManager
616 * @see org.greenstone.gatherer.gui.BuildOptions
617 * @see org.greenstone.gatherer.shell.GShellProgressMonitor
618 */
619 public void actionPerformed(ActionEvent event) {
620 // First we force the build options to be updated if we haven't already.
621 tree.valueChanged(null);
622
623 // Remember that for lower thresholds the above doesn't work, so try this instead
624 if(Configuration.getMode() < THRESHOLD) {
625 options_pane.update(sargument_configuration_panel);
626 }
627
628 // Now go about building.
629 build_button.setEnabled(false);
630 cancel_button.setEnabled(true);
631 preview_button.setEnabled(false);
632
633 simple_build_button.setEnabled(false);
634 simple_cancel_button.setEnabled(true);
635 simple_preview_button.setEnabled(false);
636
637 document = options_pane.createNewLogDocument();
638 log_textarea.setDocument(document);
639 options_pane.log_textarea.setDocument(document);
640 // Change the view.
641 processing = true;
642 if(Configuration.getMode() >= THRESHOLD) {
643 progress_pane.add(button_pane, BorderLayout.SOUTH);
644 card_layout.show(main_pane, PROGRESS);
645 }
646 // Reset the stop flag in all the process monitors, just incase.
647 ((GBuildProgressMonitor)build_monitor).reset();
648 import_monitor.setStop(false);
649 // Set removeold automatically.
650 if(Gatherer.c_man.ready() && Gatherer.c_man.built()) {
651 Gatherer.c_man.getCollection().build_options.setImportValue("removeold", true, null);
652 }
653 // Call CollectionManagers method to build collection.
654 Gatherer.c_man.importCollection();
655 }
656 }
657 /** This class serves as the listener for actions on the cancel button. */
658 private class CancelButtonListener
659 implements ActionListener {
660 /** This method attempts to cancel the current GShell task. It does this by first telling CollectionManager not to carry out any further action. This it turn tells the GShell to break from the current job immediately, without waiting for the processEnded message, and then kills the thread in an attempt to stop the process. The results of such an action are debatable.
661 * @param event An <strong>ActionEvent</strong> who, thanks to the power of object oriented programming, we don't give two hoots about.
662 * @see org.greenstone.gatherer.Gatherer
663 * @see org.greenstone.gatherer.collection.CollectionManager
664 * @see org.greenstone.gatherer.gui.BuildOptions
665 * @see org.greenstone.gatherer.shell.GShellProgressMonitor
666 */
667 public void actionPerformed(ActionEvent event) {
668 build_button.setEnabled(true);
669 cancel_button.setEnabled(false);
670 preview_button.setEnabled(false);
671
672 simple_build_button.setEnabled(true);
673 simple_cancel_button.setEnabled(false);
674 simple_preview_button.setEnabled(false);
675
676 processing = false;
677 document.setSpecialCharacter(OptionsPane.CANCELLED);
678 if(Configuration.getMode() >= THRESHOLD) {
679 control_pane.add(button_pane, BorderLayout.SOUTH);
680 card_layout.show(main_pane, CONTROL);
681 }
682 // Set the stop flag in all the process monitor.
683 import_monitor.setStop(true);
684 import_monitor.reset();
685 build_monitor.setStop(true);
686 build_monitor.reset();
687 // Set removeold automatically.
688 Gatherer.c_man.getCollection().build_options.setImportValue("removeold", true, null);
689 // Remove the collection lock.
690 //Gatherer.g_man.lockCollection(false, false);
691 }
692 }
693
694 private class PreviewButtonListener
695 implements ActionListener {
696
697 public void actionPerformed(ActionEvent event) {
698 Gatherer.c_man.getCollection().cdm.save(); // save the config file just in case
699 configureHomeURL();
700 Gatherer.self.spawnBrowser(homepage);
701
702 }
703 }
704
705 /** The OptionTree is simply a tree structure that has a root node labelled "Options" and then has a child node for each available options screen. These screens are either combinations of the available import and build arguments, or a message log detailing the shell processes progress. */
706 private class OptionTree
707 extends JTree
708 implements TreeSelectionListener {
709 /** The model behind the tree. */
710 private DefaultTreeModel model = null;
711 /** The previous options view displayed, which is sometimes needed to refresh properly. */
712 private JPanel previous_pane = null;
713 /** The node corresponding to the building options view. */
714 private OptionTreeNode building = null;
715 /** The node corresponding to the importing options view. */
716 private OptionTreeNode importing = null;
717 /** The node corresponding to the log view. */
718 private OptionTreeNode log = null;
719 /** The root node of the options tree, which has no associated options view. */
720 private OptionTreeNode options = null;
721 /** Constructor.
722 * @see org.greenstone.gatherer.gui.CreatePane.OptionTreeNode
723 */
724 public OptionTree() {
725 super();
726
727 ToolTipManager.sharedInstance().registerComponent(this);
728 addTreeSelectionListener(this);
729 getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
730 setCellRenderer(new ToolTipTreeCellRenderer());
731 setRootVisible(false);
732 setToggleClickCount(1);
733
734 // Create tree.
735 building = new OptionTreeNode(Dictionary.get("CreatePane.Build"));
736 building.setToolTipText(Dictionary.get("CreatePane.Build_Tooltip"));
737 importing = new OptionTreeNode(Dictionary.get("CreatePane.Import"));
738 importing.setToolTipText(Dictionary.get("CreatePane.Import_Tooltip"));
739 log = new OptionTreeNode(Dictionary.get("CreatePane.Log"));
740 log.setToolTipText(Dictionary.get("CreatePane.Log_Tooltip"));
741 options = new OptionTreeNode(Dictionary.get("CreatePane.Options"));
742
743 model = new DefaultTreeModel(options);
744 setModel(model);
745 model.insertNodeInto(importing, options, 0);
746 model.insertNodeInto(building, options, 1);
747 model.insertNodeInto(log, options, 2);
748 // Expand the root node
749 expandPath(new TreePath(options));
750 }
751 /** Any implementation of TreeSelectionListener must include this method to allow this listener to know when the selection has changed. Here we swap the options view depending on the selected OptionTreeNode.
752 * @param event A <Strong>TreeSelectionEvent</strong> which contains all the information garnered when the event occured.
753 * @see org.greenstone.gatherer.gui.CreatePane.OptionTreeNode
754 */
755 public void valueChanged(TreeSelectionEvent event) {
756 TreePath path = null;
757 OptionTreeNode node = null;
758 //if(event != null) {
759 //path = event.getPath();
760 path = getSelectionPath();
761 if(path != null) {
762 node = (OptionTreeNode)path.getLastPathComponent();
763 }
764 //}
765 if(previous_pane != null) {
766 //target_pane.remove(previous_pane);
767 options_pane.update(previous_pane);
768 if(scroll_pane != null) {
769 right.remove(scroll_pane);
770 }
771 else {
772 right.remove(previous_pane);
773 }
774 previous_pane = null;
775 scroll_pane = null;
776 }
777 if(node != null && node.equals(building)) {
778 previous_pane = options_pane.buildBuild(null);
779 scroll_pane = new JScrollPane(previous_pane);
780 right.add(scroll_pane, BorderLayout.CENTER);
781 //target_pane.add(previous_pane, BorderLayout.CENTER);
782 }
783 else if(node != null && node.equals(importing)) {
784 previous_pane = options_pane.buildImport(null);
785 scroll_pane = new JScrollPane(previous_pane);
786 right.add(scroll_pane, BorderLayout.CENTER);
787 //target_pane.add(previous_pane, BorderLayout.CENTER);
788 }
789 else {
790 previous_pane = options_pane.buildLog();
791 right.add(previous_pane, BorderLayout.CENTER);
792 right.updateUI(); // we need to repaint the log pane, cos it hasn't changed since last time
793 ///ystem.err.println("I've added the log back to the right pane again.");
794 //target_pane.add(previous_pane, BorderLayout.CENTER);
795 }
796 //scroll_pane.setViewportView(previous_pane);
797 //previous_pane.validate();
798 right.validate();
799 //System.err.println("Current pane size: " + previous_pane.getSize());
800 //System.err.println("While its preferred size is: " + previous_pane.getPreferredSize());
801 }
802 }
803
804 /** The <strong>OptionTree</strong> is built from these nodes, each of which has several methods used in creating the option panes.
805 */
806 private class OptionTreeNode
807 extends DefaultMutableTreeNode
808 implements Comparable {
809 /** The text label given to this node in the tree. */
810 private String title = null;
811 /** a tool tip to be used for this node in the tree */
812 private String tool_tip = null;
813 /** Constructor.
814 * @param title The <strong>String</strong> which serves as this nodes title.
815 */
816 public OptionTreeNode(String title) {
817 super();
818 this.title = title;
819 }
820
821 /** This method compares two nodes for ordering.
822 * @param obj The <strong>Object</strong> to compare to.
823 * @return An <strong>int</strong> of one of the possible values -1, 0 or 1 indicating if this node is less than, equal to or greater than the target node respectively.
824 */
825 public int compareTo(Object obj) {
826 return title.compareTo(obj.toString());
827 }
828
829 /** This method checks if two nodes are equivalent.
830 * @param obj The <strong>Object</strong> to be tested against.
831 * @return A <strong>boolean</strong> which is <i>true</i> if the objects are equal, <i>false</i> otherwise.
832 */
833 public boolean equals(Object obj) {
834 if(compareTo(obj) == 0) {
835 return true;
836 }
837 return false;
838 }
839
840 /** get the tool tip */
841 public String getToolTipText() {
842 return tool_tip;
843 }
844
845 /** set the tool tip */
846 public void setToolTipText(String tip) {
847 tool_tip = tip;
848 }
849
850 /** Method to translate this node into a textual representation.
851 * @return A <strong>String</strong> which in this case is the title.
852 */
853 public String toString() {
854 return title;
855 }
856 }
857
858 // Adds tooltips to the tree nodes
859 private class ToolTipTreeCellRenderer
860 extends DefaultTreeCellRenderer {
861
862 public Component getTreeCellRendererComponent(JTree tree,
863 Object value,
864 boolean sel,
865 boolean expanded,
866 boolean leaf,
867 int row,
868 boolean hasFocus) {
869
870 super.getTreeCellRendererComponent(tree, value, sel,
871 expanded, leaf, row,
872 hasFocus);
873 if (value instanceof OptionTreeNode) {
874 String tip = ((OptionTreeNode) value).getToolTipText();
875 if (tip != null) {
876 setToolTipText(tip);
877 }
878 }
879 return this;
880 }
881 }
882}
Note: See TracBrowser for help on using the repository browser.