001: // The contents of this file are subject to the Mozilla Public License Version
002: // 1.1
003: //(the "License"); you may not use this file except in compliance with the
004: //License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
005: //
006: //Software distributed under the License is distributed on an "AS IS" basis,
007: //WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
008: //for the specific language governing rights and
009: //limitations under the License.
010: //
011: //The Original Code is "The Columba Project"
012: //
013: //The Initial Developers of the Original Code are Frederik Dietz and Timo
014: // Stich.
015: //Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
016: //
017: //All Rights Reserved.
018: package org.columba.mail.gui.filtertoolbar;
019:
020: import java.awt.event.ActionEvent;
021: import java.awt.event.ActionListener;
022: import java.awt.event.ItemEvent;
023: import java.awt.event.ItemListener;
024: import java.awt.event.KeyEvent;
025: import java.awt.event.KeyListener;
026:
027: import javax.swing.BorderFactory;
028: import javax.swing.JButton;
029: import javax.swing.JPanel;
030: import javax.swing.JRadioButtonMenuItem;
031: import javax.swing.JTextField;
032: import javax.swing.event.DocumentEvent;
033: import javax.swing.event.DocumentListener;
034:
035: import org.columba.api.selection.ISelectionListener;
036: import org.columba.api.selection.SelectionChangedEvent;
037: import org.columba.core.command.CommandProcessor;
038: import org.columba.core.filter.FilterCriteria;
039: import org.columba.core.folder.api.IFolder;
040: import org.columba.core.gui.base.ButtonWithMnemonic;
041: import org.columba.core.gui.base.ComboMenu;
042: import org.columba.core.gui.util.CTextField;
043: import org.columba.mail.command.IMailFolderCommandReference;
044: import org.columba.mail.command.MailFolderCommandReference;
045: import org.columba.mail.filter.MailFilterFactory;
046: import org.columba.mail.folder.IMailbox;
047: import org.columba.mail.folder.virtual.VirtualFolder;
048: import org.columba.mail.gui.config.search.SearchFrame;
049: import org.columba.mail.gui.frame.MailFrameMediator;
050: import org.columba.mail.gui.table.command.ViewHeaderListCommand;
051: import org.columba.mail.gui.tree.FolderTreeModel;
052: import org.columba.mail.resourceloader.MailImageLoader;
053: import org.columba.mail.util.MailResourceLoader;
054:
055: import com.jgoodies.forms.builder.PanelBuilder;
056: import com.jgoodies.forms.layout.CellConstraints;
057: import com.jgoodies.forms.layout.FormLayout;
058:
059: /**
060: * Filter toolbar lets you do quick searches on folder contents.
061: *
062: * @author fdietz
063: */
064:
065: public class FilterToolbar extends JPanel implements ActionListener,
066: ItemListener, ISelectionListener {
067:
068: public JButton clearButton;
069:
070: private JButton searchButton;
071:
072: private ComboMenu criteriaComboMenu;
073:
074: private JTextField textField;
075:
076: private MailFrameMediator frameMediator;
077:
078: private IFolder sourceFolder;
079:
080: private String selectedItem;
081:
082: private boolean active;
083:
084: String[] strs = new String[] { "subject_contains", "from_contains",
085: "to_contains", "cc_contains", "bcc_contains",
086: "body_contains", "separator", "unread_messages",
087: "flagged_messages", "high_priority", "spam_message",
088: "separator", "custom_search" };
089:
090: private IFolder selectedFolder;
091:
092: public FilterToolbar(MailFrameMediator frameMediator) {
093: super ();
094: this .frameMediator = frameMediator;
095:
096: selectedItem = strs[0];
097:
098: initComponents();
099: layoutComponents();
100:
101: frameMediator.registerTreeSelectionListener(this );
102: }
103:
104: private ComboMenu createComboMenu() {
105: ComboMenu c = new ComboMenu();
106: for (int i = 0; i < strs.length; i++) {
107: if (strs[i].equals("separator"))
108: c.addSeparator();
109: else {
110: JRadioButtonMenuItem m = c.addMenuItem(strs[i],
111: MailResourceLoader.getString("filter",
112: "filter", strs[i]));
113:
114: switch (i) {
115: case 7:
116: m.setIcon(MailImageLoader
117: .getSmallIcon("message-mail-unread.png"));
118: break;
119: case 8:
120: m.setIcon(MailImageLoader.getSmallIcon("flag.png"));
121: break;
122: case 9:
123: m.setIcon(MailImageLoader
124: .getSmallIcon("priority-high.png"));
125: break;
126: case 10:
127: m.setIcon(MailImageLoader
128: .getSmallIcon("mail-mark-junk.png"));
129: break;
130: }
131: }
132: }
133:
134: return c;
135: }
136:
137: public void initComponents() {
138:
139: criteriaComboMenu = createComboMenu();
140: criteriaComboMenu.addItemListener(this );
141:
142: textField = new CTextField();
143:
144: textField.addActionListener(this );
145: textField.setActionCommand("TEXTFIELD");
146: textField.addKeyListener(new MyKeyListener());
147:
148: clearButton = new ButtonWithMnemonic(MailResourceLoader
149: .getString("menu", "mainframe", "filtertoolbar_clear"));
150: clearButton.setToolTipText(MailResourceLoader.getString("menu",
151: "mainframe", "filtertoolbar_clear_tooltip"));
152: clearButton.setActionCommand("CLEAR");
153: clearButton.addActionListener(this );
154: clearButton.setEnabled(false);
155:
156: searchButton = new JButton("Search");
157: searchButton.setActionCommand("SEARCH");
158: searchButton.addActionListener(this );
159: searchButton.setDefaultCapable(true);
160: searchButton.setEnabled(false);
161: }
162:
163: public void layoutComponents() {
164: setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
165:
166: FormLayout l = new FormLayout(
167: "default, 3dlu, fill:default:grow, 3dlu, default, 3dlu, default",
168: "fill:default:grow");
169: PanelBuilder b = new PanelBuilder(l, this );
170:
171: CellConstraints c = new CellConstraints();
172:
173: b.add(criteriaComboMenu, c.xy(1, 1));
174:
175: b.add(textField, c.xy(3, 1));
176:
177: b.add(searchButton, c.xy(5, 1));
178:
179: b.add(clearButton, c.xy(7, 1));
180:
181: }
182:
183: private int getIndex(String name) {
184: for (int i = 0; i < strs.length; i++) {
185: if (name.equals(strs[i]))
186: return i;
187: }
188:
189: return -1;
190: }
191:
192: public void actionPerformed(ActionEvent e) {
193: String action = e.getActionCommand();
194:
195: if (action.equals("SEARCH")) {
196: executeSearch();
197:
198: } else if (action.equals("CLEAR")) {
199:
200: resetToolbar();
201:
202: // select search folder
203: MailFolderCommandReference r = new MailFolderCommandReference(
204: sourceFolder);
205: frameMediator.setTreeSelection(r);
206:
207: frameMediator.setTableSelection(r);
208: CommandProcessor.getInstance().addOp(
209: new ViewHeaderListCommand(frameMediator, r));
210: }
211:
212: }
213:
214: /**
215: *
216: */
217: private void resetToolbar() {
218: active = false;
219: clearButton.setEnabled(false);
220:
221: textField.setText("");
222: }
223:
224: /**
225: * Execute search.
226: */
227: private void executeSearch() {
228: clearButton.setEnabled(true);
229: active = true;
230:
231: // get selected search criteria
232: int index = getIndex(selectedItem);
233:
234: // create filter criteria based on selected type
235: FilterCriteria c = createFilterCriteria(index);
236:
237: if (!selectedFolder.getId().equals("106"))
238: sourceFolder = selectedFolder;
239:
240: // set criteria for search folder
241: VirtualFolder searchFolder = prepareSearchFolder(c,
242: sourceFolder);
243:
244: try {
245: // add search to history
246: searchFolder.addSearchToHistory();
247: } catch (Exception e) {
248: e.printStackTrace();
249: }
250:
251: // select search folder
252:
253: MailFolderCommandReference r = new MailFolderCommandReference(
254: searchFolder);
255:
256: frameMediator.setTableSelection(r);
257:
258: CommandProcessor.getInstance().addOp(
259: new ViewHeaderListCommand(frameMediator, r));
260: }
261:
262: /**
263: * Create new virtual folder with filter criteria settings and selected it.
264: *
265: * @param c
266: * filter criteria settings
267: * @return source folder
268: */
269: private VirtualFolder prepareSearchFolder(FilterCriteria c,
270: IFolder folder) {
271: // get search folder
272: VirtualFolder searchFolder = (VirtualFolder) FolderTreeModel
273: .getInstance().getFolder("106");
274:
275: // remove old filters
276: searchFolder.getFilter().getFilterRule().removeAll();
277:
278: // add filter criteria
279: searchFolder.getFilter().getFilterRule().add(c);
280:
281: // don't search in subfolders recursively
282: searchFolder.getConfiguration().setString("property",
283: "include_subfolders", "false");
284:
285: String uid = folder.getId();
286:
287: // set source folder UID
288: searchFolder.getConfiguration().setString("property",
289: "source_uid", uid);
290:
291: searchFolder.deactivate();
292:
293: return searchFolder;
294: }
295:
296: /**
297: * Create filter criteria, based on current selection.
298: *
299: * @param index
300: * selected criteria
301: * @return newly created filter criteria
302: */
303: private FilterCriteria createFilterCriteria(int index) {
304: String pattern = textField.getText();
305: FilterCriteria c = null;
306: switch (index) {
307:
308: case 0:
309: c = MailFilterFactory.createSubjectContains(pattern);
310: break;
311: case 1:
312: c = MailFilterFactory.createFromContains(pattern);
313: break;
314: case 2:
315: c = MailFilterFactory.createToContains(pattern);
316: break;
317: case 3:
318: c = MailFilterFactory.createCcContains(pattern);
319: break;
320: case 4:
321: c = MailFilterFactory.createBccContains(pattern);
322: break;
323: case 5:
324: c = MailFilterFactory.createBodyContains(pattern);
325: break;
326: case 7:
327: c = MailFilterFactory.createUnreadMessages();
328: break;
329: case 8:
330: c = MailFilterFactory.createFlaggedMessages();
331: break;
332: case 9:
333: c = MailFilterFactory.createHighPriority();
334: break;
335: case 10:
336: c = MailFilterFactory.createSpamMessages();
337: break;
338:
339: }
340:
341: return c;
342: }
343:
344: public void setPattern(String pattern) {
345: textField.setText(pattern);
346: }
347:
348: /**
349: * Execute search when pressing RETURN in the textfield.
350: *
351: * @author fdietz
352: */
353: class MyKeyListener implements KeyListener {
354: public void keyTyped(KeyEvent e) {
355: }
356:
357: public void keyPressed(KeyEvent e) {
358: }
359:
360: public void keyReleased(KeyEvent e) {
361: char ch = e.getKeyChar();
362:
363: if (ch == KeyEvent.VK_ENTER) {
364: executeSearch();
365: }
366: }
367: }
368:
369: /**
370: * Execute search while user is typing pattern in textfield.
371: *
372: * @author fdietz
373: */
374: class MyDocumentListener implements DocumentListener {
375:
376: public void insertUpdate(DocumentEvent e) {
377: update();
378: }
379:
380: public void removeUpdate(DocumentEvent e) {
381: update();
382: }
383:
384: public void changedUpdate(DocumentEvent e) {
385: // Plain text components don't fire these events
386: }
387:
388: public void update() {
389: if (sourceFolder == null)
390: return;
391:
392: }
393: }
394:
395: /**
396: * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)
397: */
398: public void itemStateChanged(ItemEvent event) {
399: selectedItem = (String) event.getItem();
400:
401: // execute custom search
402: if (selectedItem.equals("custom_search")) {
403: executeCustomSearch();
404: criteriaComboMenu.setSelectedItem(0);
405: return;
406: }
407:
408: // enable/disable textfield in-dependency of selected criteria
409: int selectedIndex = getIndex(selectedItem);
410: if (selectedIndex >= 0 && selectedIndex <= 5) {
411: textField.setEnabled(true);
412: textField.requestFocus();
413: } else {
414: textField.setEnabled(false);
415:
416: // directly execute search
417: executeSearch();
418: }
419:
420: }
421:
422: /**
423: * Open the search dialog, with pre-filled settings.
424: *
425: */
426: private void executeCustomSearch() {
427: IMailbox searchFolder = (IMailbox) FolderTreeModel
428: .getInstance().getFolder("106");
429:
430: IMailbox folder = (IMailbox) frameMediator.getTableSelection()
431: .getSourceFolder();
432:
433: if (folder == null) {
434: return;
435: }
436:
437: new SearchFrame(frameMediator, searchFolder, folder);
438: }
439:
440: /*
441: * (non-Javadoc)
442: *
443: * @see org.columba.core.gui.selection.ISelectionListener#selectionChanged(org.columba.core.gui.selection.SelectionChangedEvent)
444: */
445: public void selectionChanged(SelectionChangedEvent e) {
446: // get currently selected folder
447: IMailFolderCommandReference ref = frameMediator
448: .getTreeSelection();
449:
450: if (ref != null) {
451: selectedFolder = ref.getSourceFolder();
452: searchButton.setEnabled(true);
453: } else {
454: searchButton.setEnabled(false);
455: }
456:
457: if (active) {
458: resetToolbar();
459: active = false;
460: }
461: }
462: }
|