source: trunk/gli/src/org/greenstone/gatherer/gui/Filter.java@ 12366

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

Changed text handling to use Dictionary.get rather than Dictionary.setText or Dictionary.registerBoth etc. also removed mnemonics cos they suck for other languages

  • Property svn:keywords set to Author Date Id Revision
File size: 12.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 * <BR><BR>
9 *
10 * Author: John Thompson, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37package org.greenstone.gatherer.gui;
38
39import java.awt.*;
40import java.awt.event.*;
41import java.util.*;
42import java.util.regex.*;
43import javax.swing.*;
44import javax.swing.tree.*;
45import org.greenstone.gatherer.Dictionary;
46import org.greenstone.gatherer.Gatherer;
47import org.greenstone.gatherer.file.FileSystemModel;
48import org.greenstone.gatherer.gui.tree.DragTree;
49
50/** <p>This object allows the user to set a filter on one of the workspace trees, specifying a preset type, or a regular expression that a files must match to be in the tree. Note that all directories are included. This class includes the controls for editing the filter. The trick is that several instances of the Filter class can share the same internal data (termed a 'run' of filters), so that the filter set on the GatherPane and the EnrichPane are virtually the same.</p>
51 * <p>The regular expression typed uses '*' as a wildcard character (equivalent to '.*'), and does not use '.' to match any single character (use '?' instead).</p>
52 * @author John Thompson, Greenstone Digital Library, University of Waikato
53 * @version 2.3
54 */
55public class Filter
56 extends JPanel {
57 /** The other filters in this run of filters, used to ensure they all show the same thing. */
58 private ArrayList others = null;
59 /** Is this the first filter of this run of filters created (later filters will share the same information). */
60 private boolean first = true;
61 /** Prevent any changes we make in the class from causing events which we then process causing events... */
62 private boolean ignore = false;
63 /** A reference to ourselves so inner classes can refer to us. */
64 private Filter this_filter = null;
65 /** The check box to enable/disable filter. */
66 private JCheckBox checkbox = null;
67 /** The editable combobox where you either choose a predefined filter, or type a new pseudo-regular expression. */
68 private GComboBox combobox = null;
69 /** The label shown on the filter controls. */
70 private JLabel label = null;
71 /** A reference to the tree this filter is being applied to. */
72 private DragTree tree = null;
73 /** The default size for the label. */
74 static final private Dimension SIZE = new Dimension(100,30);
75 /** Preprogrammed default filters. */
76 static final private String DEFAULTS[] = {"^.*\\.html?$", "^.*\\.xml$", "^.*\\.txt$", "(^.*\\.jpe?g$)|(^.*\\.png$)|(^.*\\.gif$)|(^.*\\.bmp$)|(^.*\\.tiff?$)"};
77
78 /** Constructor.
79 * @param tree A reference to the <strong>JTree</strong> being affected.
80 */
81 public Filter(DragTree tree) {
82 this(tree, null);
83 }
84
85 /** Constructor.
86 * @param tree A reference to the <strong>JTree</strong> being affected.
87 * @param others An <strong>ArrayList</strong> of the other Filters already in this run.
88 */
89 public Filter(DragTree tree, ArrayList others) {
90 super();
91 if (others == null) {
92 others = new ArrayList();
93 }
94 this.others = others;
95 this.others.add(this);
96 this.this_filter = this;
97 this.tree = tree;
98 // Create components.
99 combobox = new GComboBox(true);
100 try {
101 combobox.add(new Entry());
102 }
103 catch (Exception error) {
104 error.printStackTrace();
105 }
106 for(int i = 0; i < DEFAULTS.length; i++) {
107 try {
108 Entry entry = new Entry(Dictionary.get("Filter." + i), Pattern.compile(DEFAULTS[i]));
109 combobox.add(entry);
110 }
111 catch (Exception error) {
112 error.printStackTrace();
113 }
114 }
115 label = new JLabel(Dictionary.get("Filter.Filter_Tree"));
116 combobox.setToolTipText(Dictionary.get("Collection.Filter_Tooltip"));
117
118 // Add listeners.
119 combobox.addActionListener(new ComboBoxListener());
120 // Layout.
121 label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
122
123 setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
124 setLayout(new BorderLayout());
125 add(label, BorderLayout.WEST);
126 add(combobox, BorderLayout.CENTER);
127 }
128 /** Retrieve the combobox associated with this filter.
129 * @return A <strong>GComboBox</strong>.
130 */
131 public GComboBox getComboBox() {
132 return combobox;
133 }
134
135 /** Used to restore the filter state to enabled, the normal state during collection editing.
136 * @param state The new state for the filter. <i>true</i> for enabled, <i>false</i> otherwise.
137 */
138 public void setEnabled(boolean state) {
139 ignore = true;
140 combobox.setEnabled(state);
141 ignore = false;
142 }
143
144 /** Set the combobox model for this filter.
145 * @param model The new <strong>ComboBoxModel</strong> to use.
146 */
147 public void setComboBoxModel(ComboBoxModel model) {
148 combobox.setModel(model);
149 }
150
151 /** Ensure that a certain entry is selected from the combobox.
152 * @param selection The <strong>Entry</strong> that should be selected.
153 */
154 public void setComboBoxSelection(Entry selection) {
155 ignore = true;
156 combobox.setSelectedItem(selection);
157 ignore = false;
158 }
159
160 /** Sets whether this combobox is editable or not
161 * @param value true to make the control editable, false otherwise
162 */
163 public void setEditable(boolean value) {
164 combobox.setEditable(value);
165 }
166
167 /** Set to signify that this filter is the first in a new run of filters.
168 * @param first <i>true</i> if this is the first filter in a run, <i>false</i> if it will just be added to the current run.
169 */
170 public void setFirst(boolean first) {
171 this.first = first;
172 }
173
174 /** Spawn produces a copy of this filter, which has new controls, but shares listeners with this filter, and vice versa. Thus we can have two synchronized, but differing sets of controls.
175 * @param tree_spawn The <strong>JTree</strong> this filter will affect.
176 * @return A new <strong>Filter</strong> which is in the same run as this filter.
177 */
178 public Filter spawn(DragTree tree_spawn) {
179 Filter filter = new Filter(tree_spawn, others);
180 filter.setFirst(false); // No spawned copies should generate error messages, but fail silently.
181 filter.setComboBoxModel(combobox.getModel());
182 filter.setComboBoxSelection((Entry)combobox.getSelectedItem());
183 return filter;
184 }
185
186 /** Encode an expression in pseudo-regular expression into regular expression.
187 * @param raw The pseudo-regular expression <strong>String</strong> which includes several characters which differ in meaning from regular expression queries.
188 * @return A proper regular expression as a <strong>String</strong>.
189 */
190 private String encode(String raw) {
191 StringBuffer working = new StringBuffer();
192 for(int i = 0; i < raw.length(); i++) {
193 char c = raw.charAt(i);
194 switch(c) {
195 case '.':
196 working.append("\\.");
197 break;
198 case '*':
199 working.append(".*");
200 break;
201 case '?':
202 working.append(".");
203 break;
204 default:
205 working.append(Character.toLowerCase(c));
206 }
207 }
208 return working.toString();
209 }
210 /** This method applies the given pattern to the tree registered as belonging to this filter.*/
211 private void setFilter(Pattern pattern) {
212 // Show busy cursor.
213 Gatherer.g_man.wait(true);
214 FileSystemModel model = (FileSystemModel) tree.getModel();
215 // Apply filter
216 if(pattern != null) {
217 model.setFilter(pattern.pattern());
218 }
219 else {
220 model.setFilter(null);
221 }
222 // Ask tree to completely refresh
223 tree.refresh(null);
224 // Restore cursor
225 Gatherer.g_man.wait(false);
226 }
227
228 /** Listens for changes in the combobox as when one is detected attempts to compile a regular expression from whatever text was entered. If successful, or if the item chosen was a predefined filter, it then applies the filter to the target tree. */
229 private class ComboBoxListener
230 implements ActionListener {
231 /** Called when a new item is selected from the filter combobox, we treat the new entry as a pseudo-regular expression, compile it and then apply it to the tree.
232 * @param event An <strong>ActionEvent</strong> containing more information about the change performed.
233 * @see org.greenstone.gatherer.gui.Filter.Entry
234 */
235 public void actionPerformed(ActionEvent event) {
236 try {
237 Object temp = combobox.getSelectedItem();
238 Entry entry = null;
239 if(temp instanceof String) {
240 String temp_str = (String) temp;
241 ///ystem.err.println("Filter = " + temp_str);
242
243 // Ignore any string which matches a predefined filter
244 if(temp_str.equals(Dictionary.get("Filter.All_Files"))) {
245 }
246 // HTM & HTML
247 else if(temp_str.equals(Dictionary.get("Filter.0"))) {
248 }
249 // XML
250 else if(temp_str.equals(Dictionary.get("Filter.1"))) {
251 }
252 // Text files
253 else if(temp_str.equals(Dictionary.get("Filter.2"))) {
254 }
255 // Images
256 else if(temp_str.equals(Dictionary.get("Filter.3"))) {
257 }
258 else {
259 // Make sure the filter isn't already in the list
260 boolean already_exists = false;
261 for (int i = 0; i < combobox.getItemCount(); i++) {
262 if (temp_str.equals(combobox.getItemAt(i).toString())) {
263 already_exists = true;
264 entry = (Entry) combobox.getItemAt(i);
265 break;
266 }
267 }
268
269 if (already_exists == false) {
270 entry = new Entry(temp_str, Pattern.compile(encode(temp_str)));
271 int position = combobox.getItemCount();
272 combobox.insertItemAt(entry, position);
273 combobox.setSelectedIndex(position);
274 }
275 }
276 }
277 else {
278 ///ystem.err.println("Custom Filter");
279 entry = (Entry) temp;
280 }
281 if(entry != null) {
282 setFilter(entry.getPattern());
283 }
284 // Else we ignore this event as being one of the painfully erroneous events we receive because we've been silly enough to have an editable combobox.
285 }
286 catch (PatternSyntaxException error) {
287 if(first) {
288 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("Filter.Invalid_Pattern"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
289 }
290 }
291 }
292 }
293 /** An object that holds a filter entry. This is string used for the filter pattern and, if not custom built, its name. */
294 private class Entry
295 implements Comparable {
296 /** The compiled pattern created from a regular expression. */
297 private Pattern pattern = null;
298 /** The name of this filter entry. */
299 private String name = null;
300 /** Constructor. */
301 public Entry() {
302 }
303 /** Constructor.
304 * @param name The name of this entry as a <strong>String</strong>.
305 * @param pattern The compiled regular expression as a <strong>Pattern</strong>.
306 */
307 public Entry(String name, Pattern pattern) {
308 this.name = name;
309 this.pattern = pattern;
310 }
311 /** Compare two Entrys for ordering.
312 * @param object The other Entry to compare to, as an <strong>Object</strong>.
313 * @return An <i>int</i> indicating the respective ordering, as defined in java.lang.String#compareTo
314 */
315 public int compareTo(Object object) {
316 return toString().compareTo(object.toString());
317 }
318 /** Retrieve the pattern associated with this entry.
319 * @return The <strong>Pattern</strong>.
320 */
321 public Pattern getPattern() {
322 return pattern;
323 }
324 /** Translate this entry into a textual representation.
325 * @return A <strong>String</strong> containing the representation.
326 */
327 public String toString() {
328 String result = null;
329 if (name != null) {
330 result = name;
331 }
332 else if (pattern == null) {
333 result = Dictionary.get("Filter.All_Files");
334 }
335 else {
336 result = pattern.pattern();
337 }
338 return result;
339 }
340 }
341}
Note: See TracBrowser for help on using the repository browser.