1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.xmlhammer.gui.input;
23
24 import java.awt.BorderLayout;
25 import java.awt.Component;
26 import java.awt.Dimension;
27 import java.awt.FlowLayout;
28 import java.awt.Font;
29 import java.awt.event.ActionEvent;
30 import java.awt.event.ActionListener;
31 import java.awt.event.ItemEvent;
32 import java.awt.event.ItemListener;
33 import java.io.File;
34 import java.net.URI;
35 import java.util.ArrayList;
36 import java.util.regex.Pattern;
37
38 import javax.swing.Box;
39 import javax.swing.Icon;
40 import javax.swing.ImageIcon;
41 import javax.swing.JButton;
42 import javax.swing.JCheckBox;
43 import javax.swing.JComboBox;
44 import javax.swing.JFileChooser;
45 import javax.swing.JLabel;
46 import javax.swing.JPanel;
47 import javax.swing.JSeparator;
48 import javax.swing.JTextField;
49 import javax.swing.border.EmptyBorder;
50 import javax.swing.event.DocumentEvent;
51 import javax.swing.event.DocumentListener;
52
53 import org.bounce.FormConstraints;
54 import org.bounce.FormLayout;
55 import org.bounce.image.ImageLoader;
56 import org.bounce.util.URIUtils;
57 import org.xmlhammer.gui.history.HistoryComboBox;
58 import org.xmlhammer.gui.history.HistoryComboBoxModel;
59 import org.xmlhammer.gui.history.HistoryUtilities;
60 import org.xmlhammer.gui.overview.CheckBoxNode;
61 import org.xmlhammer.gui.overview.OverviewNode;
62 import org.xmlhammer.gui.overview.OverviewTreeModel;
63 import org.xmlhammer.gui.util.BrowseButton;
64 import org.xmlhammer.gui.util.UndoableCheckBoxItemListener;
65 import org.xmlhammer.model.project.Filter;
66
67 /***
68 * Filter Files by wilcard or regular expression.
69 *
70 * @version $Revision: 1.27 $, $Date: 2008/01/14 21:23:24 $
71 * @author Edwin Dankert <edankert@gmail.com>
72 */
73
74 public class FilterFilesPanel extends JPanel {
75 private static final long serialVersionUID = 3257852090755134776L;
76
77 private static final ImageIcon TEXT_FIELD_ICON = ImageLoader.get().getImage( "/org/xmlhammer/gui/icons/elcl16/textfield_obj.gif");
78 private static final ImageIcon ERROR_ICON = ImageLoader.get().getImage( "/org/xmlhammer/gui/icons/obj16/error_obj.gif");
79
80 private static final ImageIcon HOME_ICON = ImageLoader.get().getImage( "/org/xmlhammer/gui/icons/elcl16/home_nav.gif");
81 private static final ImageIcon UP_ICON = ImageLoader.get().getImage( "/org/xmlhammer/gui/icons/elcl16/prev_nav.gif");
82
83 private ArrayList<OverviewNode> nodes = null;
84
85 private JFileChooser chooser = null;
86 private HistoryComboBox lookInField = null;
87 private DirectoryNode lookInNode = null;
88 private JLabel lookInErrorLabel = null;
89
90 private JCheckBox regexCheck = null;
91 private JCheckBox subdirCheck = null;
92 private HistoryComboBox patternField = null;
93
94 private HistoryComboBox storeInField = null;
95 private DirectoryNode storeInNode = null;
96 private JLabel storeInErrorLabel = null;
97
98 private HistoryComboBox extensionField = null;
99 private PatternNode patternNode = null;
100 private JLabel patternErrorLabel = null;
101
102 public FilterFilesPanel(InputPage parent) {
103 this(parent, false);
104 }
105
106 /***
107 * Constructs a new Input Panel.
108 */
109 public FilterFilesPanel(InputPage parent, boolean resultEnabled) {
110 super( new FormLayout( 11, 5));
111
112 setBorder( new EmptyBorder( 10, 10, 10, 10));
113
114 chooser = new JFileChooser();
115 chooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY);
116
117 JButton dummyBrowseButton = new BrowseButton();
118
119 lookInField = new HistoryComboBox(parent, new HistoryComboBoxModel(HistoryUtilities.getInstance().getDirectories()));
120 lookInField.setPreferredSize(new Dimension( lookInField.getPreferredSize().width, dummyBrowseButton.getPreferredSize().height));
121 ((JTextField)lookInField.getEditor().getEditorComponent()).getDocument().addDocumentListener(new DocumentListener() {
122 public void insertUpdate(DocumentEvent arg0) {
123 checkField(lookInErrorLabel, lookInNode, lookInField);
124 }
125
126 public void removeUpdate(DocumentEvent arg0) {
127 checkField(lookInErrorLabel, lookInNode, lookInField);
128 }
129
130 public void changedUpdate(DocumentEvent arg0) {}
131 });
132
133 if (parent != null) {
134 parent.getProjectView().getFieldManager().addField( lookInField);
135 }
136
137 DirectorySelectionPanel lookInPanel = new DirectorySelectionPanel(lookInField);
138
139 lookInErrorLabel = new JLabel(ERROR_ICON);
140 lookInErrorLabel.setVisible(false);
141 lookInErrorLabel.setBorder(new EmptyBorder(2, 0, 0, 0));
142 lookInErrorLabel.setHorizontalAlignment(JLabel.LEFT);
143
144 JPanel lookInErrorPanel = new JPanel(new FormLayout());
145 lookInErrorPanel.add(lookInPanel, FormLayout.FULL_FILL);
146 lookInErrorPanel.add(lookInErrorLabel, FormLayout.FULL_FILL);
147
148 JLabel lookInLabel = new JLabel("Look in:");
149 lookInLabel.setPreferredSize(new Dimension(lookInLabel.getPreferredSize().width, lookInPanel.getPreferredSize().height));
150 add(lookInLabel, new FormConstraints( FormConstraints.LEFT, FormConstraints.RIGHT, FormConstraints.TOP));
151 add(lookInErrorPanel, FormLayout.RIGHT_FILL);
152
153 add( new JLabel(), FormLayout.LEFT);
154 subdirCheck = new JCheckBox( "Include Subdirectories");
155
156 if (parent != null) {
157 parent.getProjectView().getFieldManager().addField( subdirCheck );
158 }
159
160 add( subdirCheck, FormLayout.RIGHT);
161 subdirCheck.addItemListener(new UndoableCheckBoxItemListener(parent, subdirCheck));
162
163 patternField = new HistoryComboBox(parent, new HistoryComboBoxModel(HistoryUtilities.getInstance().getPatterns()));
164 patternField.setFont( patternField.getFont().deriveFont( Font.PLAIN));
165 patternField.setPreferredSize( new Dimension( patternField.getPreferredSize().width, dummyBrowseButton.getPreferredSize().height));
166 ((JTextField)patternField.getEditor().getEditorComponent()).getDocument().addDocumentListener(new DocumentListener() {
167 public void insertUpdate(DocumentEvent arg0) {
168 checkPattern();
169 }
170
171 public void removeUpdate(DocumentEvent arg0) {
172 checkPattern();
173 }
174
175 public void changedUpdate(DocumentEvent arg0) {}
176 });
177 if (parent != null) {
178 parent.getProjectView().getFieldManager().addField( patternField);
179 }
180
181 add( Box.createVerticalStrut(10), FormLayout.FULL);
182
183 JLabel filler = new JLabel();
184 filler.setPreferredSize( new Dimension( lookInPanel.getPreferredButtonPanelSize().width - 5, lookInPanel.getPreferredButtonPanelSize().height));
185
186 JPanel fieldPanel = new JPanel( new BorderLayout( 5, 0));
187 fieldPanel.add( patternField, BorderLayout.CENTER);
188 fieldPanel.add( filler, BorderLayout.EAST);
189
190 patternErrorLabel = new JLabel(ERROR_ICON);
191 patternErrorLabel.setVisible(false);
192 patternErrorLabel.setBorder(new EmptyBorder(2, 0, 0, 0));
193 patternErrorLabel.setHorizontalAlignment(JLabel.LEFT);
194
195 JPanel patternPanel = new JPanel(new FormLayout());
196 patternPanel.add(fieldPanel, FormLayout.FULL_FILL);
197 patternPanel.add(patternErrorLabel, FormLayout.FULL_FILL);
198
199 JLabel patternLabel = new JLabel("Pattern:");
200 patternLabel.setPreferredSize(new Dimension(patternLabel.getPreferredSize().width, fieldPanel.getPreferredSize().height));
201 add( patternLabel, new FormConstraints( FormConstraints.LEFT, FormConstraints.RIGHT, FormConstraints.TOP));
202 add( patternPanel, FormLayout.RIGHT_FILL);
203
204
205 add( new JLabel(), FormLayout.LEFT);
206 regexCheck = new JCheckBox( "Regular Expression");
207
208 if (parent != null) {
209 parent.getProjectView().getFieldManager().addField( regexCheck);
210 }
211
212 add( regexCheck, FormLayout.RIGHT);
213 regexCheck.addItemListener(new UndoableCheckBoxItemListener(parent, regexCheck));
214 regexCheck.addItemListener(new ItemListener() {
215 public void itemStateChanged(ItemEvent arg0) {
216 checkPattern();
217 }
218 });
219
220 nodes = new ArrayList<OverviewNode>();
221 lookInNode = new DirectoryNode( parent, lookInField);
222 nodes.add(lookInNode);
223 nodes.add( new CheckBoxNode( parent, subdirCheck));
224 patternNode = new PatternNode( parent, patternField, regexCheck);
225 nodes.add(patternNode);
226
227 if (resultEnabled) {
228 add(Box.createVerticalStrut(10), FormLayout.FULL);
229 add(new JSeparator(), FormLayout.FULL_FILL);
230 add(Box.createVerticalStrut(10), FormLayout.FULL);
231
232 storeInField = new HistoryComboBox(parent, new HistoryComboBoxModel(HistoryUtilities.getInstance().getDirectories()));
233 storeInField.setPreferredSize(new Dimension(storeInField.getPreferredSize().width, dummyBrowseButton.getPreferredSize().height));
234 ((JTextField)storeInField.getEditor().getEditorComponent()).getDocument().addDocumentListener(new DocumentListener() {
235 public void insertUpdate(DocumentEvent arg0) {
236 checkField(storeInErrorLabel, storeInNode, storeInField);
237 }
238
239 public void removeUpdate(DocumentEvent arg0) {
240 checkField(storeInErrorLabel, storeInNode, storeInField);
241 }
242
243 public void changedUpdate(DocumentEvent arg0) {}
244 });
245
246 if (parent != null) {
247 parent.getProjectView().getFieldManager().addField(storeInField);
248 }
249
250 DirectorySelectionPanel storeInPanel = new DirectorySelectionPanel(storeInField);
251
252 storeInErrorLabel = new JLabel(ERROR_ICON);
253 storeInErrorLabel.setVisible(false);
254 storeInErrorLabel.setBorder(new EmptyBorder(2, 0, 0, 0));
255 storeInErrorLabel.setHorizontalAlignment(JLabel.LEFT);
256
257 JPanel storeInErrorPanel = new JPanel(new FormLayout());
258 storeInErrorPanel.add(storeInPanel, FormLayout.FULL_FILL);
259 storeInErrorPanel.add(storeInErrorLabel, FormLayout.FULL_FILL);
260
261 JLabel storeInLabel = new JLabel("Store in:");
262 storeInLabel.setPreferredSize(new Dimension(storeInLabel.getPreferredSize().width, storeInPanel.getPreferredSize().height));
263 add(storeInLabel, new FormConstraints(FormConstraints.LEFT, FormConstraints.RIGHT, FormConstraints.TOP));
264 add(storeInErrorPanel, FormLayout.RIGHT_FILL);
265
266 storeInNode = new DirectoryNode( parent, storeInField);
267 nodes.add(storeInNode);
268
269 extensionField = new HistoryComboBox(parent, new HistoryComboBoxModel(HistoryUtilities.getInstance().getExtensions()));
270 extensionField.setFont(extensionField.getFont().deriveFont( Font.PLAIN));
271 extensionField.setPreferredSize(new Dimension(extensionField.getPreferredSize().width, dummyBrowseButton.getPreferredSize().height));
272
273 if (parent != null) {
274 parent.getProjectView().getFieldManager().addField(extensionField);
275 }
276
277 filler = new JLabel();
278 filler.setPreferredSize(new Dimension( lookInPanel.getPreferredButtonPanelSize().width - 5, lookInPanel.getPreferredButtonPanelSize().height));
279
280 fieldPanel = new JPanel( new BorderLayout( 5, 0));
281 fieldPanel.add(extensionField, BorderLayout.CENTER);
282 fieldPanel.add(filler, BorderLayout.EAST);
283
284 add(new JLabel("Extension:"), new FormConstraints( FormConstraints.LEFT, FormConstraints.RIGHT));
285 add(fieldPanel, FormLayout.RIGHT_FILL);
286
287
288
289
290
291
292
293
294 }
295 }
296
297 public void setFilter(URI base, Filter filter) {
298 if ( filter != null) {
299 lookInField.setValue( URIUtils.composePath(base, filter.getDir()));
300
301 patternField.setValue( filter.getPattern());
302 regexCheck.setSelected( filter.isRegex());
303 subdirCheck.setSelected( filter.isIncludeSubdirectories());
304 if (storeInField != null) {
305 storeInField.setValue(URIUtils.composePath(base, filter.getOutDir()));
306 extensionField.setValue(filter.getExtension());
307 }
308 } else {
309 gotoHome(lookInField);
310
311 if (storeInField != null) {
312 gotoHome(storeInField);
313 extensionField.setValue(null);
314 }
315
316 patternField.setValue( null);
317 regexCheck.setSelected( false);
318 subdirCheck.setSelected( false);
319 }
320 }
321
322 private void gotoHome(HistoryComboBox directoryField) {
323 directoryField.setValue((new File(System.getProperty("user.home"))).getAbsolutePath());
324 }
325
326 public Filter getFilter(URI base) {
327 Filter filter = new Filter();
328
329 filter.setDir(URIUtils.getRelativePath(base, new File(lookInField.getValue())));
330 filter.setPattern(patternField.getValue());
331 filter.setRegex(regexCheck.isSelected());
332 filter.setIncludeSubdirectories(subdirCheck.isSelected());
333
334 if (storeInField != null) {
335 filter.setExtension(extensionField.getValue());
336 filter.setOutDir(URIUtils.getRelativePath(base, new File(storeInField.getValue())));
337 }
338
339 return filter;
340 }
341
342 public ArrayList<OverviewNode> getNodes() {
343 return nodes;
344 }
345
346 public boolean isError() {
347 return false;
348 }
349
350 private class PatternNode implements OverviewNode, ItemListener, DocumentListener {
351 private ArrayList<OverviewNode> empty = new ArrayList<OverviewNode>();
352 private JComboBox pattern = null;
353 private JCheckBox check = null;
354 private OverviewNode parent = null;
355 private String error = null;
356
357 public PatternNode( OverviewNode parent, JComboBox pattern, JCheckBox check) {
358 this.parent = parent;
359 this.check = check;
360 this.pattern = pattern;
361
362 Component editor = pattern.getEditor().getEditorComponent();
363 ((JTextField)editor).getDocument().addDocumentListener(this);
364
365 check.addItemListener( this);
366 }
367
368 public String getNodeName() {
369 if ( check.isSelected()) {
370 return (String)pattern.getEditor().getItem() + " (reg exp)";
371 }
372
373 return (String)pattern.getEditor().getItem() + " (wildcard)";
374 }
375
376 public ArrayList<OverviewNode> getChildNodes() {
377 return empty;
378 }
379
380 public OverviewNode getParentNode() {
381 return parent;
382 }
383
384 public Icon getNodeIcon() {
385 return TEXT_FIELD_ICON;
386 }
387
388 public void itemStateChanged( ItemEvent e) {
389 nodeChanged();
390 }
391
392 public void nodeChanged() {
393 OverviewNode node = parent;
394
395 while ( node != null && !(node.getParentNode() instanceof OverviewTreeModel)) {
396 node = node.getParentNode();
397 }
398
399 if ( node != null) {
400 ((OverviewTreeModel)node.getParentNode()).nodePathChanged( this);
401 }
402 }
403
404 public void insertUpdate(DocumentEvent arg0) {
405 nodeChanged();
406 }
407
408 public void removeUpdate(DocumentEvent arg0) {
409 nodeChanged();
410 }
411
412 public void changedUpdate(DocumentEvent arg0) {}
413
414 public void setError(String error) {
415 this.error = error;
416 }
417
418 public String getError() {
419 return error;
420 }
421 }
422
423 private class DirectoryNode implements OverviewNode, ItemListener, DocumentListener {
424 private OverviewNode parent = null;
425 private JComboBox dirField = null;
426 private String error = null;
427
428 public DirectoryNode( OverviewNode parent, JComboBox dirField) {
429 this.dirField = dirField;
430 this.parent = parent;
431
432 ((JTextField)dirField.getEditor().getEditorComponent()).getDocument().addDocumentListener( this);
433 }
434
435 public String getNodeName() {
436 return dirField.getEditor().getItem() + " (dir)";
437 }
438
439 public ArrayList<OverviewNode> getChildNodes() {
440 return new ArrayList<OverviewNode>();
441 }
442
443 public OverviewNode getParentNode() {
444 return parent;
445 }
446
447 public Icon getNodeIcon() {
448 return TEXT_FIELD_ICON;
449 }
450
451 public void itemStateChanged( ItemEvent e) {
452 nodeChanged();
453 }
454
455 public void nodeChanged() {
456 OverviewNode node = parent;
457
458 while ( node != null && !(node.getParentNode() instanceof OverviewTreeModel)) {
459 node = node.getParentNode();
460 }
461
462 if ( node != null) {
463 ((OverviewTreeModel)node.getParentNode()).nodePathChanged(this);
464 }
465 }
466
467 public void setError(String error) {
468 this.error = error;
469 }
470
471 public String getError() {
472 return error;
473 }
474
475 public void insertUpdate(DocumentEvent arg0) {
476 nodeChanged();
477 }
478
479 public void removeUpdate(DocumentEvent arg0) {
480 nodeChanged();
481 }
482
483 public void changedUpdate(DocumentEvent arg0) {}
484 }
485
486 private class DirectorySelectionPanel extends JPanel {
487 private static final long serialVersionUID = 1896718080795277304L;
488
489 private JPanel buttonPanel = null;
490 private HistoryComboBox directoryField = null;
491 private JButton browseButton = null;
492 private JButton homeButton = null;
493 private JButton upButton = null;
494
495 public DirectorySelectionPanel(HistoryComboBox combo) {
496 super(new BorderLayout(0, 0));
497
498 this.directoryField = combo;
499
500 browseButton = new BrowseButton();
501 homeButton = new BrowseButton(HOME_ICON);
502 upButton = new BrowseButton(UP_ICON);
503
504 JPanel uphomePanel = new JPanel( new FlowLayout( FlowLayout.LEFT, 5, 0));
505 uphomePanel.add(upButton);
506 uphomePanel.add(homeButton);
507
508 buttonPanel = new JPanel( new BorderLayout( 11, 0));
509 buttonPanel.add(uphomePanel, BorderLayout.CENTER);
510 buttonPanel.add(browseButton, BorderLayout.EAST);
511
512 add(directoryField, BorderLayout.CENTER);
513 add(buttonPanel, BorderLayout.EAST);
514
515 homeButton.addActionListener( new ActionListener() {
516 public void actionPerformed( ActionEvent e) {
517 gotoHome(directoryField);
518 }
519 });
520
521 upButton.addActionListener( new ActionListener() {
522 public void actionPerformed( ActionEvent e) {
523 upDirectory();
524 }
525 });
526
527 browseButton.addActionListener( new ActionListener() {
528 public void actionPerformed( ActionEvent e) {
529 chooseFile();
530 }
531 });
532 }
533
534 public Dimension getPreferredButtonPanelSize() {
535 return buttonPanel.getPreferredSize();
536 }
537
538 private void chooseFile() {
539 String dir = directoryField.getValue();
540 if ( dir != null && dir.length() > 0) {
541 chooser.setCurrentDirectory(new File(dir));
542 } else if ( ((HistoryComboBoxModel)directoryField.getModel()).getSize() > 0) {
543 chooser.setSelectedFile(new File(((HistoryComboBoxModel)directoryField.getModel()).getElementAt(0).toString()));
544 }
545
546 int value = chooser.showOpenDialog( this);
547
548 if ( value == JFileChooser.APPROVE_OPTION) {
549 directoryField.setValue( chooser.getSelectedFile().getAbsolutePath());
550 }
551 }
552
553 private void upDirectory() {
554 File file = new File(directoryField.getValue());
555
556 if ( file != null) {
557 file = file.getParentFile();
558
559 if (file != null) {
560 directoryField.setValue( file.getAbsolutePath());
561 }
562 }
563 }
564 }
565
566 private void checkPattern() {
567 if (regexCheck.isSelected()) {
568 try {
569 Pattern.compile(patternField.getValue());
570 patternNode.setError(null);
571 patternErrorLabel.setVisible(false);
572 } catch (Throwable cause) {
573 while (cause.getCause() != null) {
574 cause = cause.getCause();
575 }
576
577 patternNode.setError(cause.getMessage());
578 patternErrorLabel.setText(cause.getMessage());
579 patternErrorLabel.setVisible(true);
580 }
581 } else {
582 patternNode.setError(null);
583 patternErrorLabel.setVisible(false);
584 }
585 }
586
587 private void checkField(JLabel errorLabel, DirectoryNode node, HistoryComboBox field) {
588 try {
589 File file = new File(field.getValue());
590
591 if (!file.exists()) {
592 errorLabel.setText("Path should exist");
593 node.setError("Path should exist");
594 errorLabel.setVisible(true);
595 } else if (!file.isAbsolute()) {
596 node.setError("Absolute path expected");
597 errorLabel.setText("Absolute path expected");
598 errorLabel.setVisible(true);
599 } else if (!file.isDirectory()) {
600 node.setError("Path should indicate a directory");
601 errorLabel.setText("Path should indicate a directory");
602 errorLabel.setVisible(true);
603 } else {
604 node.setError(null);
605 errorLabel.setVisible(false);
606 }
607 } catch (Throwable cause) {
608 while (cause.getCause() != null) {
609 cause = cause.getCause();
610 }
611
612 node.setError(cause.getMessage());
613 errorLabel.setText(cause.getMessage());
614 errorLabel.setVisible(true);
615 }
616 }
617 }