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

Last change on this file since 7739 was 7521, checked in by kjdon, 20 years ago

clicking preview now saves the config file just in case

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