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

Last change on this file since 18376 was 18370, checked in by kjdon, 15 years ago

committed code submitted by Amin Hedjazi for making the GLI right to left. I worked on this code on the rtl-gli branch, then merged the branch back to the trunk at revision 18368. The branch code was slightly different in a couple of places where it shouldn't have been. So don't use the branch code next time. Start a new branch.

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