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

Last change on this file since 5655 was 5593, checked in by mdewsnip, 21 years ago

Changed calls to the Dictionary.

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