source: trunk/gli/src/org/greenstone/gatherer/cdm/ClassifierManager.java@ 12634

Last change on this file since 12634 was 12634, checked in by mdewsnip, 18 years ago

Added a couple of bits for the new plugins/classifiers stuff when remote building.

  • Property svn:keywords set to Author Date Id Revision
File size: 27.2 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 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.cdm;
28
29import java.awt.*;
30import java.awt.event.*;
31import java.io.*;
32import java.net.*;
33import java.util.*;
34import java.util.jar.*;
35import javax.swing.*;
36import javax.swing.event.*;
37import org.apache.xerces.parsers.*;
38import org.greenstone.gatherer.Configuration;
39import org.greenstone.gatherer.DebugStream;
40import org.greenstone.gatherer.Dictionary;
41import org.greenstone.gatherer.Gatherer;
42import org.greenstone.gatherer.LocalGreenstone;
43import org.greenstone.gatherer.gui.DesignPaneHeader;
44import org.greenstone.gatherer.gui.GComboBox;
45import org.greenstone.gatherer.gui.GLIButton;
46import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
47import org.greenstone.gatherer.util.JarTools;
48import org.greenstone.gatherer.util.StaticStrings;
49import org.greenstone.gatherer.util.Utility;
50import org.greenstone.gatherer.util.XMLTools;
51import org.w3c.dom.*;
52import org.xml.sax.*;
53
54/** This class is responsible for keeping track of all the classifiers assigned to this collection, and providing methods for adding and removing them.
55 * @author John Thompson, Greenstone Digital Library, University of Waikato
56 * @version 2.3
57 */
58public class ClassifierManager
59 extends DOMProxyListModel
60{
61 // A list of all the classifiers in the core Greenstone "perllib/classify" folder (arguments may not be loaded)
62 private ArrayList core_greenstone_classifiers_list = null;
63
64 /** The controls for editing the contents of this manager. */
65 private Control controls = null;
66
67 private DOMProxyListModel model;
68
69 /** Constructor.
70 * @see org.greenstone.gatherer.cdm.DynamicListModel
71 * @see org.greenstone.gatherer.collection.CollectionManager
72 */
73 public ClassifierManager() {
74 super(CollectionDesignManager.collect_config.getDocumentElement(), CollectionConfiguration.CLASSIFY_ELEMENT, new Classifier());
75 this.model = this;
76 DebugStream.println("ClassifierManager: " + getSize() + " classifiers parsed.");
77
78 core_greenstone_classifiers_list = loadClassifiersList();
79 }
80
81
82 // --------------------------------------------------------------------------------------------------------
83
84
85 /** Retrieve a list of the classifiers that are available to be added to the collection. */
86 private Object[] getAvailableClassifiers()
87 {
88 ArrayList available = new ArrayList();
89
90 // Add all the non-abstract core Greenstone classifiers
91 for (int i = 0; i < core_greenstone_classifiers_list.size(); i++) {
92 Classifier classifier = (Classifier) core_greenstone_classifiers_list.get(i);
93 if (!classifier.isAbstract()) {
94 available.add(classifier);
95 }
96 }
97
98 // Sort the available classifiers into alphabetical order
99 Collections.sort(available);
100
101 return available.toArray();
102 }
103
104
105 public Classifier getClassifier(String classifier_name, boolean arguments_required)
106 {
107 for (int i = 0; i < core_greenstone_classifiers_list.size(); i++) {
108 Classifier classifier = (Classifier) core_greenstone_classifiers_list.get(i);
109 if (classifier.getName().equals(classifier_name)) {
110 if (arguments_required) {
111 if (classifier.getArguments().size() == 0) {
112 loadClassifierInfo(classifier);
113 }
114 else {
115 System.err.println("Already loaded arguments for " + classifier_name + "!");
116 }
117 }
118 return classifier;
119 }
120 }
121
122 return null;
123 }
124
125
126 private void loadClassifierInfo(Classifier classifier)
127 {
128 System.err.println("Loading arguments for " + classifier.getName() + "...");
129
130 // Run classifierfo.pl to get the list of classifiers
131 try {
132 StringBuffer xml = null;
133 if (Gatherer.isGsdlRemote) {
134 // !! TO DO
135 }
136 else {
137 ArrayList args = new ArrayList();
138 if (Utility.isWindows()) {
139 args.add(Configuration.perl_path);
140 args.add("-S");
141 }
142 args.add(LocalGreenstone.getBinScriptDirectoryPath() + "classinfo.pl");
143 args.add("-xml");
144 args.add("-language");
145 args.add(Configuration.getLanguage());
146 args.add(classifier.getName());
147
148 // Run the classinfo.pl process
149 Runtime runtime = Runtime.getRuntime();
150 Process process = runtime.exec((String[]) args.toArray(new String[] { }));
151 InputStream input_stream = process.getErrorStream();
152 xml = XMLTools.readXMLStream(input_stream);
153 }
154
155 if (xml.length() > 0) {
156 parseClassifierInfoXML(classifier, xml.toString());
157 }
158 else {
159 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.ClassifierManager.Classifier_XML_Parse_Failed", classifier.getName()), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
160 }
161 }
162 catch (Exception exception) {
163 DebugStream.printStackTrace(exception);
164 }
165 }
166
167
168 private ArrayList loadClassifiersList()
169 {
170 System.err.println("In loadClassifiersList()...");
171
172 // Run classifierfo.pl to get the list of classifiers
173 try {
174 StringBuffer xml = null;
175 if (Gatherer.isGsdlRemote) {
176 String classinfo_output = RemoteGreenstoneServer.getScriptOptions("classinfo.pl", "&listall");
177 xml = new StringBuffer(classinfo_output);
178 }
179 else {
180 ArrayList args = new ArrayList();
181 if (Utility.isWindows()) {
182 args.add(Configuration.perl_path);
183 args.add("-S");
184 }
185 args.add(LocalGreenstone.getBinScriptDirectoryPath() + "classinfo.pl");
186 args.add("-listall");
187 args.add("-xml");
188
189 // Run the classinfo.pl process
190 Runtime runtime = Runtime.getRuntime();
191 Process process = runtime.exec((String[]) args.toArray(new String[] { }));
192 InputStream input_stream = process.getErrorStream();
193 xml = XMLTools.readXMLStream(input_stream);
194 }
195
196 if (xml.length() > 0) {
197 return parseClassifiersListXML(xml.toString());
198 }
199 else {
200 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.ClassifierManager.Classifier_List_XML_Parse_Failed"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
201 }
202 }
203 catch (Exception exception) {
204 DebugStream.printStackTrace(exception);
205 }
206
207 return null;
208 }
209
210
211 private void parseClassifierInfoXML(Classifier classifier, String xml)
212 {
213 Document document = XMLTools.parseXML(new StringReader(xml));
214 parseClassifierInfoXMLNode(classifier, document.getDocumentElement());
215 }
216
217
218 private void parseClassifierInfoXMLNode(Classifier classifier, Node root_node)
219 {
220 for (Node node = root_node.getFirstChild(); node != null; node = node.getNextSibling()) {
221 String node_name = node.getNodeName();
222
223 if (node_name.equalsIgnoreCase("Name")) {
224 classifier.setName(XMLTools.getValue(node));
225 }
226 else if (node_name.equals("Desc")) {
227 classifier.setDescription(XMLTools.getValue(node));
228 }
229 else if (node_name.equals("Abstract")) {
230 classifier.setIsAbstract(XMLTools.getValue(node).equalsIgnoreCase(CollectionConfiguration.YES_STR));
231 }
232 // Parse the classifier arguments
233 else if (node_name.equalsIgnoreCase("Arguments")) {
234 for (Node argument_node = node.getFirstChild(); argument_node != null; argument_node = argument_node.getNextSibling()) {
235 // An option
236 if (argument_node.getNodeName().equalsIgnoreCase("Option")) {
237 Argument argument = new Argument();
238 argument.parseXML((Element) argument_node);
239 classifier.addArgument(argument);
240 }
241 }
242 }
243 // A super classifier class
244 else if (node_name.equalsIgnoreCase("ClassInfo")) {
245 Classifier super_classifier = new Classifier();
246 parseClassifierInfoXMLNode(super_classifier, node);
247 classifier.setSuper(super_classifier);
248 }
249 }
250 }
251
252
253 private ArrayList parseClassifiersListXML(String xml)
254 {
255 ArrayList classifiers_list = new ArrayList();
256
257 Document document = XMLTools.parseXML(new StringReader(xml));
258 Node root = document.getDocumentElement();
259 for (Node node = root.getFirstChild(); node != null; node = node.getNextSibling()) {
260 String node_name = node.getNodeName();
261
262 if (node_name.equals("ClassInfo")) {
263 Classifier classifier = new Classifier();
264 parseClassifierInfoXMLNode(classifier, node);
265 classifiers_list.add(classifier);
266 }
267 }
268
269 return classifiers_list;
270 }
271
272
273 // --------------------------------------------------------------------------------------------------------
274
275
276 /** Method to assign a classifier.
277 * @param classifier The base <strong>Classifier</strong> to assign.
278 * @see org.greenstone.gatherer.cdm.DynamicListModel
279 */
280 private void assignClassifier(Classifier classifier) {
281 if(!contains(classifier)) {
282 Element element = classifier.getElement();
283 // Locate where we should insert this new classifier.
284 Node target_node = CollectionConfiguration.findInsertionPoint(element);
285 add(root, classifier, target_node);
286 Gatherer.c_man.configurationChanged();
287 }
288 }
289
290
291 /** Destructor. */
292 public void destroy()
293 {
294 if (controls != null) {
295 controls.destroy();
296 controls = null;
297 }
298 }
299
300
301 /** Method to retrieve the classifier with the given index.
302 * @param index The index of the desired classifier as an <i>int</i>.
303 * @return The requested Classifier or <i>null</i> if no such classifier exists.
304 */
305 public Classifier getClassifier(int index) {
306 if(0 <= index && index < getSize()) {
307 return (Classifier) getElementAt(index);
308 }
309 return null;
310 }
311
312 /** Method to retrieve the control for this manager.
313 * @return the Control for editing classifiers
314 */
315 public Control getControls() {
316 if(controls == null) {
317 // Build controls
318 this.controls = new ClassifierControl();
319 }
320 return controls;
321 }
322
323 /** Called when the detail mode has changed which in turn may cause several design elements to be available/hidden
324 * @param mode the new mode as an int
325 */
326 public void modeChanged(int mode) {
327
328 }
329
330
331
332 /** Determine if the Phind classifier has been assigned.
333 * @return true if it has, false otherwise
334 */
335 public boolean isPhindClassifierAssigned() {
336 for(int i = 0; i < getSize(); i++) {
337 Classifier classifier = (Classifier) getElementAt(i);
338 if(classifier.getName().equalsIgnoreCase(StaticStrings.PHIND_CLASSIFIER)) {
339 return true;
340 }
341 classifier = null;
342 }
343 return false;
344 }
345
346 /** Method to move a classifier in the list order.
347 * @param classifier the Classifier you want to move.
348 * @param direction true to move the classifier up, false to move it down.
349 * @param all true to move to move all the way, false for a single step.
350 */
351 private void moveClassifier(Classifier classifier, boolean direction, boolean all) {
352 if(getSize() < 2) {
353 DebugStream.println("Not enough classifiers to allow moving.");
354 return;
355 }
356 if(all) {
357 // Move to top
358 if(direction) {
359 // Remove the moving classifier
360 remove(classifier);
361 // Retrieve the first classifier
362 Classifier first_classifier = (Classifier) getElementAt(0);
363 // Add the moving classifier before the first classifier
364 addBefore(classifier, first_classifier);
365 first_classifier = null;
366 }
367 else {
368 // Remove the moving classifier
369 remove(classifier);
370 // And add after last classifier
371 add(getSize(), classifier);
372 }
373 }
374 else {
375 // Try to move the classifier one step in the desired direction.
376 int index = indexOf(classifier);
377 ///ystem.err.println("Index of " + classifier + " = " + index);
378 if(direction) {
379 index--;
380 if(index < 0) {
381 String args[] = new String[2];
382 args[0] = Dictionary.get("CDM.ClassifierManager.Classifier");
383 args[1] = classifier.getName();
384 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.Move.At_Top", args), Dictionary.get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE);
385 return;
386 }
387 remove(classifier);
388 add(index, classifier);
389 }
390 else {
391 index++;
392 if(index >= getSize()) {
393 String args[] = new String[2];
394 args[0] = Dictionary.get("CDM.ClassifierManager.Classifier_Str");
395 args[1] = classifier.getName();
396 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.Move.At_Bottom", args), Dictionary.get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE);
397 return;
398 }
399 remove(classifier);
400 add(index, classifier);
401 }
402 }
403
404 Gatherer.c_man.configurationChanged();
405 // tell the format manager to update the names of its format statements
406 Gatherer.c_man.getCollection().cdm.format_manager.refresh();
407 }
408
409 /** This method removes an assigned classifier. I was tempted to call it unassign, but remove is more consistant. Note that there is no way to remove a classifier from the library.
410 * @param classifier The Classifier to remove
411 * @see org.greenstone.gatherer.cdm.DynamicListModel
412 */
413 private void removeClassifier(Classifier classifier) {
414 remove(classifier);
415 Gatherer.c_man.configurationChanged();
416 }
417
418
419 /** A class which provides controls for assigned and editing classifiers. */
420 private class ClassifierControl
421 extends JPanel
422 implements Control {
423 /** A combobox containing all of the known classifiers, including those that may have already been assigned. */
424 private JComboBox classifier_combobox = null;
425 /** Button for adding classifiers. */
426 private JButton add = null;
427 /** Button for configuring the selected classifier. */
428 private JButton configure = null;
429 private JButton move_down_button;
430 private JButton move_up_button;
431
432 /** Button to remove the selected classifier. */
433 private JButton remove = null;
434
435 /** A list of assigned classifiers. */
436 private JList classifier_list = null;
437
438 /** Constructor.
439 * @see org.greenstone.gatherer.cdm.ClassifierManager.ClassifierControl.AddListener
440 * @see org.greenstone.gatherer.cdm.ClassifierManager.ClassifierControl.ConfigureListener
441 * @see org.greenstone.gatherer.cdm.ClassifierManager.ClassifierControl.RemoveListener
442 */
443 public ClassifierControl()
444 {
445 // Create
446 add = new GLIButton(Dictionary.get("CDM.ClassifierManager.Add"), Dictionary.get("CDM.ClassifierManager.Add_Tooltip"));
447
448 JPanel button_pane = new JPanel();
449 JPanel central_pane = new JPanel();
450
451configure = new GLIButton(Dictionary.get("CDM.ClassifierManager.Configure"), Dictionary.get("CDM.ClassifierManager.Configure_Tooltip"));
452 configure.setEnabled(false);
453
454 JPanel header_pane = new DesignPaneHeader("CDM.GUI.Classifiers", "classifiers");
455
456 ClassifierComboboxListener ccl = new ClassifierComboboxListener();
457 classifier_combobox = new JComboBox(getAvailableClassifiers());
458 classifier_combobox.setEditable(false);
459 if(classifier_combobox.getItemCount() > 0) {
460 classifier_combobox.setSelectedIndex(0);
461 ccl.itemStateChanged(new ItemEvent(classifier_combobox, 0, null, ItemEvent.SELECTED));
462 }
463
464 JLabel classifier_label = new JLabel(Dictionary.get("CDM.ClassifierManager.Classifier"));
465
466 classifier_list = new JList(model);
467 classifier_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
468 JLabel classifier_list_label = new JLabel(Dictionary.get("CDM.ClassifierManager.Assigned"));
469
470 classifier_list_label.setOpaque(true);
471
472 JPanel classifier_list_pane = new JPanel();
473 JPanel classifier_pane = new JPanel();
474 remove = new GLIButton(Dictionary.get("CDM.ClassifierManager.Remove"), Dictionary.get("CDM.ClassifierManager.Remove_Tooltip"));
475 remove.setEnabled(false);
476
477 JPanel temp = new JPanel(new BorderLayout());
478
479 JPanel move_button_pane = new JPanel();
480
481 move_up_button = new GLIButton(Dictionary.get("CDM.Move.Move_Up"), JarTools.getImage("arrow-up.gif"), Dictionary.get("CDM.Move.Move_Up_Tooltip"));
482 move_up_button.setEnabled(false);
483
484 move_down_button = new GLIButton(Dictionary.get("CDM.Move.Move_Down"), JarTools.getImage("arrow-down.gif"), Dictionary.get("CDM.Move.Move_Down_Tooltip"));
485 move_down_button.setEnabled(false);
486
487 // Listeners
488 add.addActionListener(new AddListener());
489 add.addActionListener(CollectionDesignManager.buildcol_change_listener);
490 classifier_combobox.addItemListener(ccl);
491 configure.addActionListener(new ConfigureListener());
492 configure.addActionListener(CollectionDesignManager.buildcol_change_listener);
493 remove.addActionListener(new RemoveListener());
494 remove.addActionListener(CollectionDesignManager.buildcol_change_listener);
495 classifier_list.addMouseListener(new ClickListener());
496 classifier_list.addListSelectionListener(new ListListener());
497 ccl = null;
498
499 MoveListener ml = new MoveListener();
500 move_down_button.addActionListener(ml);
501 move_down_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
502 move_up_button.addActionListener(ml);
503 move_up_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
504
505 // Layout
506 move_button_pane.setLayout(new GridLayout(4,1));
507 move_button_pane.add(move_up_button);
508 move_button_pane.add(new JPanel());
509 move_button_pane.add(new JPanel());
510 move_button_pane.add(move_down_button);
511
512 classifier_list_label.setBorder(BorderFactory.createEmptyBorder(0,2,0,2));
513
514 classifier_list_pane.setLayout(new BorderLayout());
515 classifier_list_pane.add(classifier_list_label, BorderLayout.NORTH);
516 classifier_list_pane.add(new JScrollPane(classifier_list), BorderLayout.CENTER);
517 classifier_list_pane.add(move_button_pane, BorderLayout.EAST);
518
519 classifier_label.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
520
521 classifier_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
522 classifier_pane.setLayout(new BorderLayout(5,0));
523 classifier_pane.add(classifier_label, BorderLayout.WEST);
524 classifier_pane.add(classifier_combobox, BorderLayout.CENTER);
525
526 button_pane.setLayout(new GridLayout(1, 3));
527 button_pane.add(add);
528 button_pane.add(configure);
529 button_pane.add(remove);
530
531 temp.add(classifier_pane, BorderLayout.NORTH);
532 temp.add(button_pane, BorderLayout.SOUTH);
533
534 central_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
535 central_pane.setLayout(new BorderLayout());
536 central_pane.add(classifier_list_pane, BorderLayout.CENTER);
537 central_pane.add(temp, BorderLayout.SOUTH);
538
539 setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
540 setLayout(new BorderLayout());
541 add(header_pane, BorderLayout.NORTH);
542 add(central_pane, BorderLayout.CENTER);
543 }
544
545 /** Method which acts like a destructor, tidying up references to persistant objects.
546 */
547 public void destroy() {
548 add = null;
549 classifier_combobox = null;
550 classifier_list = null;
551 configure = null;
552 //instructions = null;
553 remove = null;
554 }
555
556 public void gainFocus() {
557 }
558
559 public void loseFocus() {
560 }
561
562 /** This class listens for actions upon the add button in the controls, and if detected calls the assignClassifier() method.
563 */
564 private class AddListener
565 implements ActionListener {
566 /** Any implementation of ActionListener must include this method so that we can be informed when an action has occured on one of our target controls, so that we can add the selected Classifier.
567 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
568 * @see org.greenstone.gatherer.Gatherer
569 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration
570 * @see org.greenstone.gatherer.cdm.Classifier
571 */
572 public void actionPerformed(ActionEvent event) {
573 Object selected_object = classifier_combobox.getSelectedItem();
574 // If there is something in the combobox, but we haven't registered a selection, then add the object and select it!
575 if(selected_object != null) {
576 // Retrieve the base classifier
577 Classifier base_classifier = getClassifier(selected_object.toString(), true);
578
579 // Create a new element in the DOM
580 Element element = CollectionDesignManager.collect_config.document.createElement(CollectionConfiguration.CLASSIFY_ELEMENT);
581 element.setAttribute(CollectionConfiguration.TYPE_ATTRIBUTE, base_classifier.getName());
582 Classifier new_classifier = new Classifier(element, base_classifier);
583
584 element = null;
585 // Automatically chain to configuration. This ensures required arguments are filled out.
586 ArgumentConfiguration ac = new ArgumentConfiguration(new_classifier);
587 if(ac.display()) {
588 if(!model.contains(new_classifier)) {
589 assignClassifier(new_classifier);
590 classifier_list.setSelectedValue(new_classifier, true);
591 }
592 else {
593 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.ClassifierManager.Classifier_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
594 }
595 }
596 ac = null;
597 new_classifier = null;
598 }
599 }
600 }
601
602 /** This listener reacts to changes in the current selection of the classifier combobox. */
603 private class ClassifierComboboxListener
604 implements ItemListener {
605 /** When a user selects a certain classifier, update the tooltip to show the classifier description. */
606 public void itemStateChanged(ItemEvent event) {
607 if(event.getStateChange() == ItemEvent.SELECTED) {
608 // Retrieve the selected classifier
609 Classifier current_selection = (Classifier) classifier_combobox.getSelectedItem();
610 // And reset the tooltip.
611 classifier_combobox.setToolTipText(Utility.formatHTMLWidth(current_selection.getDescription(), 40));
612 current_selection = null;
613 }
614 }
615 }
616
617 /** Listens for double clicks apon the list and react as if the configure button was pushed. */
618 private class ClickListener
619 extends MouseAdapter {
620 /** Called whenever the mouse is clicked over a registered component, we use this to chain through to the configure prompt.
621 * @param event A <strong>MouseEvent</strong> containing information about the mouse click.
622 */
623 public void mouseClicked(MouseEvent event) {
624 if(event.getClickCount() == 2 ) {
625 if(!classifier_list.isSelectionEmpty()) {
626 Classifier classifier = (Classifier) classifier_list.getSelectedValue();
627 ArgumentConfiguration ac = new ArgumentConfiguration(classifier);
628 if(ac.display()) {
629 refresh(classifier);
630 }
631 ac.destroy();
632 ac = null;
633 // cos I can't be bothered checking every argument to see if it has changed or not, we'll asasume that the configuration has changed if someone has clicked configure
634 Gatherer.c_man.configurationChanged();
635 }
636 }
637 }
638 }
639
640 /** This class listens for actions upon the configure button in the controls, and if detected creates a new ArgumentConfiguration dialog box to allow for configuration.
641 */
642 private class ConfigureListener
643 implements ActionListener {
644 /** Any implementation of <i>ActionListener</i> must include this method so that we can be informed when an action has occured on one of our target controls.
645 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
646 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration
647 * @see org.greenstone.gatherer.cdm.Classifier
648 */
649 public void actionPerformed(ActionEvent event) {
650 if(!classifier_list.isSelectionEmpty()) {
651 Classifier classifier = (Classifier) classifier_list.getSelectedValue();
652 ArgumentConfiguration ac = new ArgumentConfiguration(classifier);
653 if(ac.display()) {
654 refresh(classifier);
655 }
656 ac.destroy();
657 ac = null;
658 // cos I can't be bothered checking every argument to see if it has changed or not, we'll asasume that the configuration has changed if someone has clicked configure
659 Gatherer.c_man.configurationChanged();
660 }
661 }
662 }
663
664 /** listens for changes in the list selection and enables the configure and remove buttons if there is a selection, disables them if there is no selection */
665 private class ListListener
666 implements ListSelectionListener {
667
668 public void valueChanged(ListSelectionEvent e) {
669 if (!e.getValueIsAdjusting()) { // we get two events for one change in list selection - use the false one ( the second one)
670 if (classifier_list.isSelectionEmpty()) {
671 move_up_button.setEnabled(false);
672 move_down_button.setEnabled(false);
673 configure.setEnabled(false);
674 remove.setEnabled(false);
675 }
676 else {
677 configure.setEnabled(true);
678 remove.setEnabled(true);
679 int selected_index = classifier_list.getSelectedIndex();
680 move_up_button.setEnabled(selected_index !=0);
681 move_down_button.setEnabled(selected_index != model.getSize()-1);
682 }
683 }
684 }
685 }
686
687 /** Listens for actions apon the move buttons in the manager controls, and if detected calls the <i>moveClassifier()</i> method of the manager with the appropriate details. */
688 private class MoveListener
689 implements ActionListener {
690 /** Any implementation of <i>ActionListener</i> must include this method so that we can be informed when an action has occured on one of our target controls.
691 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
692 */
693 public void actionPerformed(ActionEvent event) {
694 if(!classifier_list.isSelectionEmpty()) {
695 Object object = classifier_list.getSelectedValue();
696 if(object instanceof Classifier) {
697 Classifier classifier = (Classifier) object;
698 if(event.getSource() == move_up_button) {
699 moveClassifier(classifier, true, false);
700 }
701 else if(event.getSource() == move_down_button) {
702 moveClassifier(classifier, false, false);
703 }
704 classifier_list.setSelectedValue(classifier, true);
705 }
706 }
707 }
708 }
709
710 /** This class listens for actions upon the remove button in the controls, and if detected calls the <i>removeClassifier()</i> method.
711 */
712 private class RemoveListener
713 implements ActionListener {
714 /** Any implementation of <i>ActionListener</i> must include this method so that we can be informed when an action has occured on one of our target controls.
715 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
716 */
717 public void actionPerformed(ActionEvent event) {
718 if(classifier_list.isSelectionEmpty()) {
719 remove.setEnabled(false);
720 return;
721 }
722 int selected_index = classifier_list.getSelectedIndex();
723 Object selected_classifier = classifier_list.getSelectedValue();
724 if (!(selected_classifier instanceof Classifier)) {
725 return; // what else could we have here???
726 }
727 removeClassifier((Classifier)selected_classifier);
728
729 if (selected_index >= classifier_list.getModel().getSize()) {
730 selected_index--;
731 }
732 if (selected_index >=0) {
733 classifier_list.setSelectedIndex(selected_index);
734 } else {
735 // no more classifiers in the list
736 remove.setEnabled(false);
737 }
738 }
739 }
740 }
741}
Note: See TracBrowser for help on using the repository browser.