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

Last change on this file since 8236 was 8236, checked in by mdewsnip, 20 years ago

Replaced all Gatherer.print* with DebugStream.print*.

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