source: trunk/gli/src/org/greenstone/gatherer/cdm/SearchTypeManager.java@ 10965

Last change on this file since 10965 was 10965, checked in by kjdon, 18 years ago

moved the index_manager.setMGPPEnabled call into IndexManager

  • Property svn:keywords set to Author Date Id Revision
File size: 22.3 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
29/**************************************************************************************
30 * Written: 16/07/03
31 * Revised:
32 **************************************************************************************/
33import java.awt.*;
34import java.awt.event.*;
35import java.util.*;
36import javax.swing.*;
37import javax.swing.event.*;
38import org.greenstone.gatherer.Configuration;
39import org.greenstone.gatherer.DebugStream;
40import org.greenstone.gatherer.Dictionary;
41import org.greenstone.gatherer.Gatherer;
42import org.greenstone.gatherer.gui.GComboBox;
43import org.greenstone.gatherer.gui.GLIButton;
44import org.greenstone.gatherer.util.JarTools;
45import org.w3c.dom.*;
46
47/** This class maintains an ordered list of the search types available in the collection (MGPP/lucene command available in G2.39 or later). Currently only 'form' and 'plain' are valid.
48 * @author John Thompson, Greenstone Digital Library, University of Waikato
49 * @version 2.4
50 */
51public class SearchTypeManager
52 extends DOMProxyListModel
53{
54 static final private Dimension LABEL_SIZE = new Dimension(150, 25);
55
56 static final public String BUILD_TYPE_LUCENE = "lucene";
57 static final public String BUILD_TYPE_MGPP = "mgpp";
58
59 static final public String[] SEARCH_TYPES = { "plain" , "form"};
60 static final public String[] BUILD_TYPES = { BUILD_TYPE_LUCENE, BUILD_TYPE_MGPP };
61
62 /** the buildtype element in the config file - searchtypemanager looks
63 * after this now */
64 public CollectionMeta build_type = null;
65 /** The controls used to edit the search types. */
66 private Control controls = null;
67 /** A reference to ourselves so our inner classes have access. */
68 private DOMProxyListModel model;
69
70 public SearchTypeManager(Element searchtypes_element) {
71 super(searchtypes_element, CollectionConfiguration.CONTENT_ELEMENT, new SearchType());
72 this.model = this;
73 DebugStream.println("SearchTypeManager: parsed " + getSize() + " search types.");
74 build_type = new CollectionMeta(CollectionDesignManager.collect_config.getBuildType());
75
76 }
77
78 private void addSearchType(SearchType searchtype) {
79 if(!contains(searchtype)) {
80 add(getSize(), searchtype);
81 Gatherer.c_man.configurationChanged();
82 }
83 }
84
85 public Control getControls() {
86 if(controls == null) {
87 controls = new SearchTypeControl();
88 }
89 return controls;
90 }
91
92 /** Return a list of the currently assigned search types as a comma separated string.
93 * @return a String
94 */
95 public String getSearchTypes() {
96 StringBuffer search_types = new StringBuffer();
97 ArrayList types = children();
98 for (int i = 0; i < types.size(); i++) {
99 if (i>0) {
100 search_types.append(",");
101 }
102 search_types.append(((SearchType)types.get(i)).getName());
103 }
104 return search_types.toString();
105 }
106
107 /** By examining the SearchType 'root' we were created with, determine if mgpp is enabled.
108 * @return true if MGPP is enabled, false otherwise
109 */
110 public boolean isSearchTypeEnabled() {
111 return root.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.TRUE_STR);
112 }
113
114 public boolean isMGPP() {
115 return isSearchTypeEnabled() && build_type.getValue(CollectionMeta.TEXT).equals(BUILD_TYPE_MGPP);
116 }
117
118 public boolean isLucene() {
119 return isSearchTypeEnabled() && build_type.getValue(CollectionMeta.TEXT).equals(BUILD_TYPE_LUCENE);
120 }
121
122 private void moveSearchType(SearchType search_type, boolean direction) {
123 // Try to move the classifier one step in the desired direction.
124 int index = indexOf(search_type);
125 if(direction) {
126 index--;
127 }
128 else {
129 index++;
130 }
131 // Check we aren't at an edge
132 if((direction && index < 0) || (!direction && index >= getSize())) {
133 String args[] = new String[2];
134 args[0] = Dictionary.get("CDM.SearchTypeManager.SearchType");
135 args[1] = search_type.toString();
136 String message = null;
137 if (direction) {
138 message = Dictionary.get("CDM.Move.At_Top", args);
139 }
140 else {
141 message = Dictionary.get("CDM.Move.At_Bottom", args);
142 }
143 JOptionPane.showMessageDialog(Gatherer.g_man, message, Dictionary.get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE);
144 return;
145 }
146 remove(search_type);
147 add(index, search_type);
148 Gatherer.c_man.configurationChanged();
149 }
150
151 private void removeSearchType(SearchType searchtype) {
152 if(contains(searchtype)) {
153 remove(searchtype);
154 Gatherer.c_man.configurationChanged();
155 }
156 }
157
158 private class SearchTypeControl
159 extends JPanel
160 implements Control {
161
162 private GComboBox search_type_combobox;
163 private GComboBox build_type_combobox;
164
165 private JButton add_button;
166 private JButton move_down_button;
167 private JButton move_up_button;
168 private JButton remove_button;
169
170 private JCheckBox enable_advanced_searches_checkbox;
171
172 private JLabel current_search_types_label;
173 private JLabel search_type_label;
174 private JLabel title_label;
175
176 private JList current_search_types_list;
177
178 private JTextArea instructions_textarea;
179
180 public SearchTypeControl() {
181
182 // Creation
183 title_label = new JLabel();
184 title_label.setHorizontalAlignment(JLabel.CENTER);
185 Dictionary.registerText(title_label, "CDM.SearchTypeManager.Title");
186
187 JPanel instructions_panel = new JPanel();
188 instructions_textarea = new JTextArea();
189 instructions_textarea.setCaretPosition(0);
190 instructions_textarea.setEditable(false);
191 instructions_textarea.setLineWrap(true);
192 instructions_textarea.setRows(6);
193 instructions_textarea.setWrapStyleWord(true);
194 Dictionary.registerText(instructions_textarea, "CDM.SearchTypeManager.Instructions");
195
196 JPanel spacer_panel = new JPanel();
197
198 JPanel empty_panel = new JPanel();
199
200 JPanel inner_panel = new JPanel();
201
202 JPanel indexer_type_panel = new JPanel();
203 JPanel build_type_panel = new JPanel();
204
205 enable_advanced_searches_checkbox = new JCheckBox();
206 Dictionary.registerText(enable_advanced_searches_checkbox, "CDM.SearchTypeManager.Enable");
207
208 build_type_combobox = new GComboBox(BUILD_TYPES);
209 build_type_combobox.setPreferredSize(LABEL_SIZE);
210 build_type_combobox.setBackgroundNonSelectionColor(Configuration.getColor("coloring.editable_background", false));
211 build_type_combobox.setBackgroundSelectionColor(Configuration.getColor("coloring.collection_selection_background", false));
212 build_type_combobox.setEditable(true);
213 build_type_combobox.setSelectedIndex(1);// mgpp is at 1
214 String selected_value = build_type.getValue(CollectionMeta.TEXT);
215 if (!selected_value.equals("")) {
216 for (int i=0; i<build_type_combobox.getItemCount();i++) {
217 String item = (String)build_type_combobox.getItemAt(i);
218 if (item.equals(selected_value)) {
219 build_type_combobox.setSelectedIndex(i);
220 break;
221 }
222 }
223 } else {
224 //build_type.setValue((String)build_type_combobox.getSelectedItem());
225 build_type.setAssigned(isSearchTypeEnabled());
226
227 }
228 build_type_combobox.setTextNonSelectionColor(Configuration.getColor("coloring.workspace_tree_foreground", false));
229 build_type_combobox.setTextSelectionColor(Configuration.getColor("coloring.collection_selection_foreground", false));
230 Dictionary.registerTooltip(build_type_combobox, "CDM.SearchTypeManager.BuildType_Selection_Tooltip");
231
232 JLabel build_type_label = new JLabel();
233 Dictionary.registerText(build_type_label, "CDM.SearchTypeManager.BuildType_Selection");
234 JPanel current_search_types_panel = new JPanel();
235 current_search_types_label = new JLabel();
236 Dictionary.registerText(current_search_types_label, "CDM.SearchTypeManager.Assigned");
237 current_search_types_list = new JList(model);
238 current_search_types_list.setVisibleRowCount(3);
239
240 JPanel movement_panel = new JPanel();
241
242 move_up_button = new JButton("", JarTools.getImage("arrow-up.gif"));
243 move_up_button.setEnabled(false);
244 move_up_button.setMnemonic(KeyEvent.VK_U);
245
246 Dictionary.registerBoth(move_up_button, "CDM.Move.Move_Up", "CDM.Move.Move_Up_Tooltip");
247
248 move_down_button = new JButton("", JarTools.getImage("arrow-down.gif"));
249 move_down_button.setEnabled(false);
250 move_down_button.setMnemonic(KeyEvent.VK_D);
251
252 Dictionary.registerBoth(move_down_button, "CDM.Move.Move_Down", "CDM.Move.Move_Down_Tooltip");
253
254 JPanel search_type_panel = new JPanel();
255 search_type_label = new JLabel();
256 Dictionary.registerText(search_type_label, "CDM.SearchTypeManager.SearchType_Selection");
257 search_type_combobox = new GComboBox(SEARCH_TYPES);
258 search_type_combobox.setPreferredSize(LABEL_SIZE);
259 search_type_combobox.setBackgroundNonSelectionColor(Configuration.getColor("coloring.editable_background", false));
260 search_type_combobox.setBackgroundSelectionColor(Configuration.getColor("coloring.collection_selection_background", false));
261 search_type_combobox.setEditable(true);
262 search_type_combobox.setSelectedIndex(0);
263 search_type_combobox.setTextNonSelectionColor(Configuration.getColor("coloring.workspace_tree_foreground", false));
264 search_type_combobox.setTextSelectionColor(Configuration.getColor("coloring.collection_selection_foreground", false));
265 Dictionary.registerTooltip(search_type_combobox, "CDM.SearchTypeManager.SearchType_Selection_Tooltip");
266
267 JPanel button_panel = new JPanel();
268 add_button = new GLIButton();
269 add_button.setEnabled(false);
270 add_button.setMnemonic(KeyEvent.VK_A);
271 Dictionary.registerBoth(add_button, "CDM.SearchTypeManager.Add", "CDM.SearchTypeManager.Add_Tooltip");
272
273 remove_button = new GLIButton();
274 remove_button.setEnabled(false);
275 remove_button.setMnemonic(KeyEvent.VK_R);
276 Dictionary.registerBoth(remove_button, "CDM.SearchTypeManager.Remove", "CDM.SearchTypeManager.Remove_Tooltip");
277
278
279 // Connection
280 add_button.addActionListener(new AddActionListener());
281 add_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
282 build_type_combobox.addActionListener(new BuildTypeActionListener());
283 build_type_combobox.addActionListener(CollectionDesignManager.buildcol_change_listener);
284 current_search_types_list.addListSelectionListener(new CurrentSearchTypesListSelectionListener());
285 enable_advanced_searches_checkbox.addActionListener(new EnableAdvancedSearchesActionListener());
286 enable_advanced_searches_checkbox.addActionListener(CollectionDesignManager.buildcol_change_listener);
287 move_up_button.addActionListener(new MoveListener(true));
288 move_up_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
289 move_down_button.addActionListener(new MoveListener(false));
290 move_down_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
291 remove_button.addActionListener(new RemoveActionListener());
292 remove_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
293 SearchTypesActionDocumentListener stadl = new SearchTypesActionDocumentListener();
294 search_type_combobox.addActionListener(stadl);
295 search_type_combobox.addActionListener(CollectionDesignManager.buildcol_change_listener);
296 ((JTextField)search_type_combobox.getEditor().getEditorComponent()).getDocument().addDocumentListener(stadl);
297
298 // Layout
299 instructions_panel.setBorder(BorderFactory.createEmptyBorder(0,0,2,0));
300 instructions_panel.setLayout(new BorderLayout());
301 instructions_panel.add(title_label, BorderLayout.NORTH);
302 instructions_panel.add(new JScrollPane(instructions_textarea), BorderLayout.CENTER);
303
304 movement_panel.setBorder(BorderFactory.createEmptyBorder(0,2,0,0));
305 movement_panel.setLayout(new GridLayout(2,1,5,0));
306 movement_panel.add(move_up_button);
307 movement_panel.add(move_down_button);
308
309 current_search_types_panel.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
310 current_search_types_panel.setLayout(new BorderLayout());
311 current_search_types_panel.add(current_search_types_label, BorderLayout.NORTH);
312 current_search_types_panel.add(new JScrollPane(current_search_types_list), BorderLayout.CENTER);
313 current_search_types_panel.add(movement_panel, BorderLayout.EAST);
314
315 build_type_panel.setLayout(new BorderLayout());
316 build_type_panel.add(build_type_label, BorderLayout.WEST);
317 build_type_panel.add(build_type_combobox, BorderLayout.CENTER);
318
319 indexer_type_panel.setLayout(new GridLayout(1,2,0,5));
320 indexer_type_panel.add(enable_advanced_searches_checkbox);
321 indexer_type_panel.add(build_type_panel);
322
323 button_panel.setBorder(BorderFactory.createEmptyBorder(2,0,0,0));
324 button_panel.setLayout(new GridLayout(1,2,0,5));
325 button_panel.add(add_button);
326 button_panel.add(remove_button);
327
328 search_type_panel.setLayout(new BorderLayout(5,3));
329 search_type_panel.add(search_type_label, BorderLayout.WEST);
330 search_type_panel.add(search_type_combobox, BorderLayout.CENTER);
331 search_type_panel.add(button_panel, BorderLayout.SOUTH);
332
333 inner_panel.setLayout(new BorderLayout());
334 inner_panel.add(indexer_type_panel, BorderLayout.NORTH);
335 inner_panel.add(current_search_types_panel, BorderLayout.CENTER);
336 inner_panel.add(search_type_panel, BorderLayout.SOUTH);
337
338 spacer_panel.setLayout(new BorderLayout());
339 spacer_panel.add(inner_panel, BorderLayout.NORTH);
340 spacer_panel.add(empty_panel, BorderLayout.CENTER);
341
342 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
343 setLayout(new BorderLayout());
344 add(instructions_panel, BorderLayout.NORTH);
345 add(spacer_panel, BorderLayout.CENTER);
346 }
347
348 public void destroy() {
349 }
350
351 public void gainFocus() {
352 instructions_textarea.setCaretPosition(0);
353 validateControls(isSearchTypeEnabled());
354 }
355
356 public void loseFocus() {
357
358 }
359
360 private void validateControls(boolean advanced_search_enabled) {
361 // Enable or disable controls based on whether MGPP is enabled
362 // validate add button, which depends on the current combobox selection and the contents of the assigned search types list
363 Object selected_item = search_type_combobox.getSelectedItem();
364 add_button.setEnabled(advanced_search_enabled && selected_item != null && !model.contains(selected_item));
365 // validate other controls.
366 current_search_types_list.setEnabled(advanced_search_enabled);
367 build_type_combobox.setEnabled(advanced_search_enabled);
368 enable_advanced_searches_checkbox.setSelected(advanced_search_enabled);
369 search_type_combobox.setEnabled(advanced_search_enabled);
370 remove_button.setEnabled(current_search_types_list.getModel().getSize() > 1 && !current_search_types_list.isSelectionEmpty() && advanced_search_enabled);
371 }
372
373 /** Listenes for actions on the Add button, and if detected adds a new search type. */
374 private class AddActionListener
375 implements ActionListener {
376 /** Called when someone actions the Add button.
377 * @param event an ActionEvent containing information about the add button click
378 */
379 public void actionPerformed(ActionEvent event) {
380 Object selected_item = search_type_combobox.getSelectedItem();
381 if(selected_item != null) {
382 if(search_type_combobox.getSelectedIndex() == -1) {
383 search_type_combobox.insertItemAt(selected_item, search_type_combobox.getItemCount());
384 }
385 // Add the search type
386 SearchType new_searchtype = new SearchType((String)selected_item);
387 addSearchType(new_searchtype);
388 }
389 add_button.setEnabled(false);
390 }
391 }
392
393 /** Listens for selections within the search types list and updates the remove button appropriately. */
394 private class CurrentSearchTypesListSelectionListener
395 implements ListSelectionListener {
396 /** Called when the selection in the list changes.
397 * @param event a ListSelectionEvent containing information about the selection change
398 */
399 public void valueChanged(ListSelectionEvent event) {
400 if(!event.getValueIsAdjusting()) {
401 SearchType search_type = null;
402 if ((search_type = (SearchType) current_search_types_list.getSelectedValue()) != null) {
403 int index = model.indexOf(search_type);
404 // Move up is only enabled if the current selection isn't at index 0
405 move_up_button.setEnabled(index != 0);
406 // Move down is only enabled if the current selection isn't at index getSize() - 1
407 move_down_button.setEnabled(index != model.getSize() - 1);
408 // Remove is only enabled if this isn't the last search type
409 remove_button.setEnabled(current_search_types_list.getModel().getSize() > 1);
410 }
411 else {
412 move_up_button.setEnabled(false);
413 move_down_button.setEnabled(false);
414 remove_button.setEnabled(false);
415 }
416 }
417 }
418 }
419
420 /** The most complex listener in this class, this listens for changes to the enable advanced searches checkbox, and when they occur it not only updates the controls on this page, but asks the IndexManager to action the appropriate changes to the underlying DOM so as to support either MG or MGPP styles of indexes. */
421 private class EnableAdvancedSearchesActionListener
422 implements ActionListener {
423 /** Called whenever the checkbox is checked or unchecked.
424 * @param event an ActionEvent containing information about the checking action
425 */
426 public void actionPerformed(ActionEvent event) {
427 Gatherer.g_man.wait(true);
428 boolean advanced_search_enabled = enable_advanced_searches_checkbox.isSelected();
429
430 model.root.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, (advanced_search_enabled ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR));
431 validateControls(advanced_search_enabled);
432 if ((!build_type.isAssigned() && advanced_search_enabled) ||
433 (build_type.isAssigned() && !advanced_search_enabled)) {
434
435 build_type.setAssigned(advanced_search_enabled);
436 Gatherer.c_man.configurationChanged();
437 }
438 if (build_type.isAssigned() && build_type.getValue(true).equals("")) {
439 build_type.setValue((String)build_type_combobox.getSelectedItem());
440 }
441 Gatherer.g_man.wait(false);
442 }
443 }
444
445 private class BuildTypeActionListener
446 implements ActionListener {
447
448 public void actionPerformed(ActionEvent event) {
449 if (!build_type.getValue(CollectionMeta.TEXT).equals((String)build_type_combobox.getSelectedItem())) {
450 build_type.setValue((String)build_type_combobox.getSelectedItem());
451 }
452 }
453
454 }
455 /** Listenes for actions on the Remove button, and if detected removes the currently selected search types. */
456 private class RemoveActionListener
457 implements ActionListener {
458 /** Called when someone actions the Remove button.
459 * @param event an ActionEvent containing information about the remove button click
460 */
461 public void actionPerformed(ActionEvent event) {
462 if(!current_search_types_list.isSelectionEmpty()) {
463 Object[] selected_items = current_search_types_list.getSelectedValues();
464 for(int i = 0; model.getSize() > 1 && i < selected_items.length; i++) {
465 removeSearchType((SearchType)selected_items[i]);
466 }
467 }
468 Object selected_object = search_type_combobox.getSelectedItem();
469 if(selected_object != null) {
470 add_button.setEnabled(!model.contains(selected_object));
471 }
472 else {
473 add_button.setEnabled(false);
474 }
475 remove_button.setEnabled(false);
476 }
477 }
478
479 private class MoveListener
480 implements ActionListener {
481 private boolean move_up;
482 public MoveListener(boolean move_up) {
483 this.move_up = move_up;
484 }
485 public void actionPerformed(ActionEvent event) {
486 // Retrieve the first selected search type (if any)
487 SearchType search_type = null;
488 if((search_type = (SearchType) current_search_types_list.getSelectedValue()) != null) {
489 // Move search type
490 moveSearchType(search_type, move_up);
491 // Reselect the moved search type
492 current_search_types_list.setSelectedValue(search_type, true);
493 }
494 // No selection - no movement
495 else {
496 move_up_button.setEnabled(false);
497 move_down_button.setEnabled(false);
498 }
499 }
500 }
501
502 /** Listens for changes in the search types combobox, and enabled add button appropriately. */
503 private class SearchTypesActionDocumentListener
504 implements ActionListener, DocumentListener {
505 /** Called whenever a selection action occurs on the combobox.
506 * @param event an ActionEvent containing information about the selection event
507 */
508 public void actionPerformed(ActionEvent event) {
509 validateAddButton();
510 }
511
512 /** Gives notification that an attribute or set of attributes changed.
513 * @param event a DocumentEvent containing information about the text changed
514 */
515 public void changedUpdate(DocumentEvent event) {
516 validateAddButton();
517 }
518 /** Gives notification that there was an insert into the document.
519 * @param event a DocumentEvent containing information about the text added
520 */
521 public void insertUpdate(DocumentEvent event) {
522 validateAddButton();
523 }
524
525 /** Gives notification that a portion of the document has been removed.
526 * @param event a DocumentEvent containing information about the text removed
527 */
528 public void removeUpdate(DocumentEvent event) {
529 validateAddButton();
530 }
531
532 /** Change the enable state of the add button depending on the current value in the search type combobox. */
533 private void validateAddButton() {
534 Object selected_object = search_type_combobox.getSelectedItem();
535 if(selected_object != null) {
536 add_button.setEnabled(!model.contains(selected_object));
537 }
538 else {
539 add_button.setEnabled(false);
540 }
541 }
542 }
543 }
544}
Note: See TracBrowser for help on using the repository browser.