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

Last change on this file since 6394 was 6389, checked in by jmt12, 20 years ago

Introduced the idea of detail modes - these have an effect on several parts of the gui, such as disabling or hiding all regular expression based controls, simplifying the output from perl scripts and (having been given yet another new last minute feature to implement) displays a completely different create pane. Mode is stored in the config.xml and is changable via the Preferences controls

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