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

Last change on this file since 9137 was 9137, checked in by kjdon, 19 years ago

a colleciton now has build_options and import_options instead of just one

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