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

Last change on this file since 6160 was 6051, checked in by jmt12, 21 years ago

Here is the result of sixteen hours work over the weekend. I'm too tired to comment them all separately, but here are some of the highlights:
Rewrote how the 'base on collection' method actually retrieves and updates the collection configuration - ensuring the CDM.CollectionConfiguration class is used instead of the retarded Collection.CollectionConfiguration (which coincidently has had a name change to BasicCollectionConfiguration). Went through code search for places where the two versions had been confused. Rewrote large swathes of GDMDocument so as to differentiate between normal and extracted metadata - an attempt to prevent the snowballing extracted metadata problem. Fixed problem where GLI was correctly recieving the last few lines of an external process. The collection shortname is no longer visible, nor is the confusing double name for metadata elements. Also coloured folders in the trees are kaput. The users email is now saved as part of the GLI configuration and is used as appropriate to fill out collection fields. There are new options on the right click menus over trees to allow the expansion and collapsing of folders. 'Show Files' now shows all types (or at least 6 types) of image properly (arg, the plagues of copy and paste). 'Based On' collections are public, plugin list automatically moves to next entry if plugin removed (I guess we should do the same in every other screen?) and metadata arguments in plugins/classifiers are no longer editable. There are about a dozen other small things, but I can't remember them. Hope I remembered to set all of the files to UNIX line-endings.

  • Property svn:keywords set to Author Date Id Revision
File size: 12.0 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 CollectionPane and the MetaEditPane 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,25);
75 /** Preprogrammed default filters. */
76 static final private String DEFAULTS[] = {"^.*\\.html?$", "^.*\\.xml$", "^.*\\.txt$", "(^.*\\.jpe?g$)|(^.*\\.png$)|(^.*\\.gif$)|(^.*\\.bmp$)|(^.*\\.tif$)"};
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();
100 combobox.add(new Entry());
101 for(int i = 0; i < DEFAULTS.length; i++) {
102 try {
103 Entry entry = new Entry(Dictionary.get("Filter." + i), Pattern.compile(DEFAULTS[i]));
104 combobox.add(entry);
105 }
106 catch (Exception error) {
107 error.printStackTrace();
108 }
109 }
110 combobox.setEditable(true);
111 label = new JLabel();
112 label.setPreferredSize(SIZE);
113 Dictionary.setText(label, "Filter.Filter_Tree");
114 // Add listeners.
115 combobox.addActionListener(new ComboBoxListener());
116 // Layout.
117 label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
118
119 setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
120 setLayout(new BorderLayout());
121 add(label, BorderLayout.WEST);
122 add(combobox, BorderLayout.CENTER);
123 }
124 /** Retrieve the combobox associated with this filter.
125 * @return A <strong>GComboBox</strong>.
126 */
127 public GComboBox getComboBox() {
128 return combobox;
129 }
130
131 /** Used to restore the filter state to enabled, the normal state during collection editing.
132 * @param state The new state for the filter. <i>true</i> for enabled, <i>false</i> otherwise.
133 */
134 public void setEnabled(boolean state) {
135 ignore = true;
136 combobox.setEditable(state);
137 combobox.setEnabled(state);
138 ignore = false;
139 }
140
141 /** Set the combobox model for this filter.
142 * @param model The new <strong>ComboBoxModel</strong> to use.
143 */
144 public void setComboBoxModel(ComboBoxModel model) {
145 combobox.setModel(model);
146 }
147
148 /** Ensure that a certain entry is selected from the combobox.
149 * @param selection The <strong>Entry</strong> that should be selected.
150 */
151 public void setComboBoxSelection(Entry selection) {
152 ignore = true;
153 combobox.setSelectedItem(selection);
154 ignore = false;
155 }
156
157 /** Set to signify that this filter is the first in a new run of filters.
158 * @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.
159 */
160 public void setFirst(boolean first) {
161 this.first = first;
162 }
163
164 /** 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.
165 * @param tree_spawn The <strong>JTree</strong> this filter will affect.
166 * @return A new <strong>Filter</strong> which is in the same run as this filter.
167 */
168 public Filter spawn(DragTree tree_spawn) {
169 Filter filter = new Filter(tree_spawn, others);
170 filter.setFirst(false); // No spawned copies should generate error messages, but fail silently.
171 filter.setComboBoxModel(combobox.getModel());
172 filter.setComboBoxSelection((Entry)combobox.getSelectedItem());
173 return filter;
174 }
175
176 /** Encode an expression in pseudo-regular expression into regular expression.
177 * @param raw The pseudo-regular expression <strong>String</strong> which includes several characters which differ in meaning from regular expression queries.
178 * @return A proper regular expression as a <strong>String</strong>.
179 */
180 private String encode(String raw) {
181 StringBuffer working = new StringBuffer();
182 for(int i = 0; i < raw.length(); i++) {
183 char c = raw.charAt(i);
184 switch(c) {
185 case '.':
186 working.append("\\.");
187 break;
188 case '*':
189 working.append(".*");
190 break;
191 case '?':
192 working.append(".");
193 break;
194 default:
195 working.append(Character.toLowerCase(c));
196 }
197 }
198 return working.toString();
199 }
200 /** This method applies the given pattern to the tree registered as belonging to this filter.*/
201 private void setFilter(Pattern pattern) {
202 // Show busy cursor.
203 Gatherer.g_man.wait(true);
204 FileSystemModel model = (FileSystemModel) tree.getModel();
205 // Apply filter
206 if(pattern != null) {
207 model.setFilter(pattern.pattern());
208 }
209 else {
210 model.setFilter(null);
211 }
212 // Ask tree to completely refresh
213 tree.refresh(null);
214 // Restore cursor
215 Gatherer.g_man.wait(false);
216 }
217
218 /** 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. */
219 private class ComboBoxListener
220 implements ActionListener {
221 /** 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.
222 * @param event An <strong>ActionEvent</strong> containing more information about the change performed.
223 * @see org.greenstone.gatherer.gui.Filter.Entry
224 */
225 public void actionPerformed(ActionEvent event) {
226 try {
227 Object temp = combobox.getSelectedItem();
228 Entry entry = null;
229 if(temp instanceof String) {
230 String temp_str = (String) temp;
231 ///ystem.err.println("Filter = " + temp_str);
232
233 // Ignore any string which matches a predefined filter
234 if(temp_str.equals(Dictionary.get("Filter.All_Files"))) {
235 }
236 // HTM & HTML
237 else if(temp_str.equals(Dictionary.get("Filter.0"))) {
238 }
239 // XML
240 else if(temp_str.equals(Dictionary.get("Filter.1"))) {
241 }
242 // Text files
243 else if(temp_str.equals(Dictionary.get("Filter.2"))) {
244 }
245 // Images
246 else if(temp_str.equals(Dictionary.get("Filter.3"))) {
247 }
248 else {
249 // Make sure the filter isn't already in the list
250 boolean already_exists = false;
251 for (int i = 0; i < combobox.getItemCount(); i++) {
252 if (temp_str.equals(combobox.getItemAt(i).toString())) {
253 already_exists = true;
254 entry = (Entry) combobox.getItemAt(i);
255 break;
256 }
257 }
258
259 if (already_exists == false) {
260 entry = new Entry(temp_str, Pattern.compile(encode(temp_str)));
261 int position = combobox.getItemCount();
262 combobox.insertItemAt(entry, position);
263 combobox.setSelectedIndex(position);
264 }
265 }
266 }
267 else {
268 ///ystem.err.println("Custom Filter");
269 entry = (Entry) temp;
270 }
271 if(entry != null) {
272 setFilter(entry.getPattern());
273 }
274 // 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.
275 }
276 catch (PatternSyntaxException error) {
277 if(first) {
278 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("Filter.Invalid_Pattern"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
279 }
280 }
281 }
282 }
283 /** An object that holds a filter entry. This is string used for the filter pattern and, if not custom built, its name. */
284 private class Entry
285 implements Comparable {
286 /** The compiled pattern created from a regular expression. */
287 private Pattern pattern = null;
288 /** The name of this filter entry. */
289 private String name = null;
290 /** Constructor. */
291 public Entry() {
292 }
293 /** Constructor.
294 * @param name The name of this entry as a <strong>String</strong>.
295 * @param pattern The compiled regular expression as a <strong>Pattern</strong>.
296 */
297 public Entry(String name, Pattern pattern) {
298 this.name = name;
299 this.pattern = pattern;
300 }
301 /** Compare two Entrys for ordering.
302 * @param object The other Entry to compare to, as an <strong>Object</strong>.
303 * @return An <i>int</i> indicating the respective ordering, as defined in java.lang.String#compareTo
304 */
305 public int compareTo(Object object) {
306 return toString().compareTo(object.toString());
307 }
308 /** Retrieve the pattern associated with this entry.
309 * @return The <strong>Pattern</strong>.
310 */
311 public Pattern getPattern() {
312 return pattern;
313 }
314 /** Translate this entry into a textual representation.
315 * @return A <strong>String</strong> containing the representation.
316 */
317 public String toString() {
318 String result = null;
319 if (name != null) {
320 result = name;
321 }
322 else if (pattern == null) {
323 result = Dictionary.get("Filter.All_Files");
324 }
325 else {
326 result = pattern.pattern();
327 }
328 return result;
329 }
330 }
331}
Note: See TracBrowser for help on using the repository browser.