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

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

Removed all occurrences of classes explicitly importing other classes in the same package.

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