KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > suberic > pooka > gui > FolderInternalFrame


1 package net.suberic.pooka.gui;
2 import net.suberic.pooka.*;
3 import net.suberic.pooka.gui.search.SearchForm;
4 import javax.mail.*;
5 import javax.mail.internet.MimeMessage JavaDoc;
6 import javax.mail.event.*;
7 import javax.mail.search.SearchTerm JavaDoc;
8 import java.awt.*;
9 import java.awt.event.*;
10 import javax.swing.*;
11 import javax.swing.plaf.basic.*;
12 import javax.swing.table.*;
13 import javax.swing.text.TextAction JavaDoc;
14 import java.util.*;
15 import net.suberic.pooka.event.MessageLoadedEvent;
16 import net.suberic.util.gui.*;
17 import net.suberic.util.event.*;
18 import net.suberic.util.thread.*;
19 import net.suberic.util.swing.*;
20
21 /**
22  * This basically is just the GUI representation of the Messages in
23  * a Folder. Most of the real work is done by the FolderInfo
24  * class. Also, most of the display is done by the FolderDisplayPanel.
25  */

26
27 public class FolderInternalFrame extends JInternalFrame implements FolderDisplayUI {
28   FolderInfo folderInfo = null;
29   FolderDisplayPanel folderDisplay = null;
30   FolderStatusBar folderStatusBar = null;
31   MessagePanel messagePanel = null;
32   ConfigurableToolbar toolbar;
33   ConfigurableKeyBinding keyBindings;
34   boolean enabled = true;
35
36   /**
37    * Creates a Folder window from the given Folder.
38    */

39   public FolderInternalFrame(FolderInfo newFolderInfo, MessagePanel newMessagePanel) {
40     super(newFolderInfo.getFolderDisplayName(), true, true, true, true);
41
42     this.getContentPane().setLayout(new BorderLayout());
43
44     messagePanel = newMessagePanel;
45
46     setFolderInfo(newFolderInfo);
47
48     getFolderInfo().setFolderDisplayUI(this);
49
50     defaultActions = new Action JavaDoc[] {
51       new CloseAction(),
52       new ActionWrapper(new ExpungeAction(), getFolderInfo().getFolderThread()),
53       new NextMessageAction(),
54       new PreviousMessageAction(),
55       new NextUnreadMessageAction(),
56       new GotoMessageAction(),
57       new SearchAction(),
58       new SelectAllAction()
59     };
60
61     // note: you have to set the Status Bar before you create the
62
// FolderDisplayPanel, or else you'll get a null pointer exception
63
// from the LoadMessageThread.
64

65     setFolderStatusBar(new FolderStatusBar(this.getFolderInfo()));
66
67     folderDisplay = new FolderDisplayPanel(getFolderInfo());
68
69     if (getFolderInfo() != null && getFolderInfo().isOutboxFolder())
70       toolbar = new ConfigurableToolbar("OutboxWindowToolbar", Pooka.getResources());
71     else
72       toolbar = new ConfigurableToolbar("FolderWindowToolbar", Pooka.getResources());
73     this.getContentPane().add("North", toolbar);
74     this.getContentPane().add("Center", folderDisplay);
75     this.getContentPane().add("South", getFolderStatusBar());
76
77     int height = Integer.parseInt(Pooka.getProperty(getFolderInfo().getFolderProperty() + ".windowLocation.height", Pooka.getProperty("FolderWindow.height", "380")));
78     int width = Integer.parseInt(Pooka.getProperty(getFolderInfo().getFolderProperty() + ".windowLocation.width", Pooka.getProperty("FolderWindow.width","570")));
79
80     this.setPreferredSize(new Dimension(width, height));
81
82     this.setSize(this.getPreferredSize());
83
84     keyBindings = new ConfigurableKeyBinding(this, "FolderWindow.keyBindings", Pooka.getResources());
85
86     keyBindings.setActive(getActions());
87     toolbar.setActive(getActions());
88
89     // if the FolderInternalFrame itself gets the focus, pass it on to
90
// the folderDisplay
91

92     this.addFocusListener(new FocusAdapter() {
93         public void focusGained(FocusEvent e) {
94           folderDisplay.requestFocusInWindow();
95         }
96       });
97
98     FocusTraversalPolicy ftp = new LayoutFocusTraversalPolicy() {
99         public Component getInitialComponent(JInternalFrame jif) {
100           if (jif instanceof FolderInternalFrame) {
101             return ((FolderInternalFrame) jif).getFolderDisplay();
102           }
103
104           return super.getInitialComponent(jif);
105         }
106       };
107     this.setFocusTraversalPolicy(ftp);
108
109     getFolderDisplay().getMessageTable().getSelectionModel().addListSelectionListener(new SelectionListener());
110
111     this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
112
113     this.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter JavaDoc() {
114         public void internalFrameClosed(javax.swing.event.InternalFrameEvent JavaDoc e) {
115           saveWindowSettings();
116           getFolderInfo().setFolderDisplayUI(null);
117         }
118       });
119
120     if (getUI() instanceof BasicInternalFrameUI) {
121       ((BasicInternalFrameUI) getUI()).getNorthPane().addMouseListener(new MouseAdapter() {
122
123           public void mousePressed(MouseEvent evt) {
124             if (evt.getButton() == MouseEvent.BUTTON2) {
125               try {
126                 Object JavaDoc messagePanel = SwingUtilities.getAncestorOfClass(Class.forName("net.suberic.pooka.gui.MessagePanel"), FolderInternalFrame.this);
127                 if (messagePanel != null) {
128                   ((MessagePanel) messagePanel).unselectAndMoveToBack(FolderInternalFrame.this);
129                   evt.consume();
130                 }
131               } catch (Exception JavaDoc e) {
132                 getLogger().log(java.util.logging.Level.FINE, "exception lowering FolderInternalFrame", e);
133               }
134             }
135           }
136
137         });
138     }
139   }
140
141
142   public FolderInternalFrame(PreviewFolderPanel pfp, MessagePanel newMessagePanel) {
143     super(pfp.getFolderInfo().getFolderDisplayName(), true, true, true, true);
144
145     FolderInfo newFolderInfo = pfp.getFolderInfo();
146
147     this.getContentPane().setLayout(new BorderLayout());
148
149     messagePanel = newMessagePanel;
150
151     setFolderInfo(newFolderInfo);
152
153     defaultActions = new Action JavaDoc[] {
154       new CloseAction(),
155       new ActionWrapper(new ExpungeAction(), getFolderInfo().getFolderThread()),
156       new NextMessageAction(),
157       new PreviousMessageAction(),
158       new GotoMessageAction(),
159       new SearchAction()
160     };
161
162     // note: you have to set the Status Bar before you create the
163
// FolderDisplayPanel, or else you'll get a null pointer exception
164
// from the LoadMessageThread.
165

166     setFolderStatusBar(new FolderStatusBar(this.getFolderInfo()));
167
168     folderDisplay = pfp.getFolderDisplay();
169     toolbar = new ConfigurableToolbar("FolderWindowToolbar", Pooka.getResources());
170     this.getContentPane().add("North", toolbar);
171     this.getContentPane().add("Center", folderDisplay);
172     this.getContentPane().add("South", getFolderStatusBar());
173
174     int height = Integer.parseInt(Pooka.getProperty(getFolderInfo().getFolderProperty() + ".windowLocation.height", Pooka.getProperty("FolderWindow.height", "380")));
175     int width = Integer.parseInt(Pooka.getProperty(getFolderInfo().getFolderProperty() + ".windowLocation.width", Pooka.getProperty("FolderWindow.width","570")));
176
177     this.setPreferredSize(new Dimension(width, height));
178
179     this.setSize(this.getPreferredSize());
180
181     keyBindings = new ConfigurableKeyBinding(this, "FolderWindow.keyBindings", Pooka.getResources());
182
183     keyBindings.setActive(getActions());
184     toolbar.setActive(getActions());
185
186     // if the FolderInternalFrame itself gets the focus, pass it on to
187
// the folderDisplay
188

189     this.addFocusListener(new FocusAdapter() {
190         public void focusGained(FocusEvent e) {
191           folderDisplay.requestFocusInWindow();
192         }
193       });
194
195     getFolderDisplay().getMessageTable().getSelectionModel().addListSelectionListener(new SelectionListener());
196
197     this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
198
199     this.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter JavaDoc() {
200         public void internalFrameClosed(javax.swing.event.InternalFrameEvent JavaDoc e) {
201           saveWindowSettings();
202           getFolderInfo().setFolderDisplayUI(null);
203         }
204       });
205
206     if (getUI() instanceof BasicInternalFrameUI) {
207       ((BasicInternalFrameUI) getUI()).getNorthPane().addMouseListener(new MouseAdapter() {
208
209           public void mousePressed(MouseEvent evt) {
210             if (evt.getButton() == MouseEvent.BUTTON2) {
211               try {
212                 Object JavaDoc messagePanel = SwingUtilities.getAncestorOfClass(Class.forName("net.suberic.pooka.gui.MessagePanel"), FolderInternalFrame.this);
213                 if (messagePanel != null) {
214                   ((MessagePanel) messagePanel).unselectAndMoveToBack(FolderInternalFrame.this);
215                   evt.consume();
216                 }
217               } catch (Exception JavaDoc e) {
218                 getLogger().log(java.util.logging.Level.FINE, "exception lowering FolderInternalFrame", e);
219               }
220             }
221           }
222
223         });
224     }
225   }
226
227   /**
228    * Saves the FolderInternalFrame's current settings.
229    */

230   public void saveWindowSettings() {
231     String JavaDoc folderProperty = getFolderInfo().getFolderProperty();
232
233     // we have to do these as absolute values.
234
MessagePanel mp = getMessagePanel();
235
236     int x = getX() + ((JScrollPane)mp.getUIComponent()).getHorizontalScrollBar().getValue();
237     int y = getY() + ((JScrollPane)mp.getUIComponent()).getVerticalScrollBar().getValue();
238
239     Pooka.setProperty(folderProperty + ".windowLocation.x", Integer.toString(x));
240     Pooka.setProperty(folderProperty + ".windowLocation.y", Integer.toString(y));
241
242     Pooka.setProperty(folderProperty + ".windowLocation.height", Integer.toString(getHeight()));
243     Pooka.setProperty(folderProperty + ".windowLocation.width", Integer.toString(getWidth()));
244
245     getFolderDisplay().saveTableSettings();
246   }
247
248   /**
249    * Searches the underlying FolderInfo's messages for messages matching
250    * the search term.
251    */

252   public void searchFolder() {
253     getFolderInfo().showSearchFolder();
254   }
255
256   /**
257    * This method takes the currently selected row(s) and returns the
258    * appropriate MessageProxy object.
259    *
260    * If no rows are selected, null is returned.
261    */

262   public MessageProxy getSelectedMessage() {
263     return getFolderDisplay().getSelectedMessage();
264   }
265
266   /**
267    * This resets the size to that of the parent component.
268    */

269   public void resize() {
270     this.setSize(getParent().getSize());
271   }
272
273   /**
274    * This opens the FolderInternalFrame.
275    */

276   public void openFolderDisplay() {
277     openFolderDisplay(true);
278   }
279
280   /**
281    * This opens the FolderInternalFrame.
282    */

283   public void openFolderDisplay(boolean selected) {
284     final boolean fSelected = selected;
285     Runnable JavaDoc runMe = new Runnable JavaDoc() {
286         public void run() {
287           getMessagePanel().openFolderWindow(FolderInternalFrame.this, fSelected);
288         }
289       };
290     if (SwingUtilities.isEventDispatchThread())
291       runMe.run();
292     else
293       SwingUtilities.invokeLater(runMe);
294   }
295
296   /**
297    * This closes the FolderInternalFrame.
298    */

299   public void closeFolderDisplay(){
300     Runnable JavaDoc runMe = new Runnable JavaDoc() {
301         public void run() {
302
303           try {
304             saveWindowSettings();
305             setClosed(true);
306           } catch (java.beans.PropertyVetoException JavaDoc e) {
307           }
308         }
309       };
310     if (SwingUtilities.isEventDispatchThread()) {
311       runMe.run();
312     } else {
313       SwingUtilities.invokeLater(runMe);
314     }
315
316
317   }
318
319   /**
320    * This expunges all the messages marked as deleted in the folder.
321    */

322   public void expungeMessages() {
323     try {
324       getFolderInfo().getFolder().expunge();
325     } catch (MessagingException me) {
326       showError(Pooka.getProperty("error.Message.ExpungeErrorMessage", "Error: could not expunge messages.") +"\n" + me.getMessage());
327     }
328   }
329
330   /**
331    * This shows an Error Message window. We include this so that
332    * the MessageProxy can call the method without caring about the
333    * actual implementation of the Dialog.
334    */

335   public void showError(String JavaDoc errorMessage, String JavaDoc title) {
336     final String JavaDoc errorMsg = errorMessage;
337     final String JavaDoc realTitle = title;
338     Runnable JavaDoc runMe = new Runnable JavaDoc() {
339         public void run() {
340           JOptionPane.showInternalMessageDialog(getMessagePanel(), errorMsg, realTitle, JOptionPane.ERROR_MESSAGE);
341         }
342       };
343
344     if (SwingUtilities.isEventDispatchThread()) {
345       runMe.run();
346     } else {
347       SwingUtilities.invokeLater(runMe);
348     }
349   }
350
351   /**
352    * This shows an Error Message window. We include this so that
353    * the MessageProxy can call the method without caring about the
354    * actual implementation of the Dialog.
355    */

356   public void showError(String JavaDoc errorMessage) {
357     showError(errorMessage, Pooka.getProperty("Error", "Error"));
358   }
359
360   /**
361    * This shows an Error Message window. We include this so that
362    * the MessageProxy can call the method without caring about the
363    * actual implementation of the Dialog.
364    */

365   public void showError(String JavaDoc errorMessage, Exception JavaDoc e) {
366     showError(errorMessage, Pooka.getProperty("Error", "Error"), e);
367   }
368
369   /**
370    * This shows an Error Message window. We include this so that
371    * the MessageProxy can call the method without caring about the
372    * actual implementation of the Dialog.
373    */

374   public void showError(String JavaDoc errorMessage, String JavaDoc title, Exception JavaDoc e) {
375     showError(errorMessage + e.getMessage(), title);
376     e.printStackTrace();
377   }
378
379   /**
380    * This formats a display message.
381    */

382   public String JavaDoc formatMessage(String JavaDoc message) {
383     return Pooka.getUIFactory().formatMessage(message);
384   }
385
386   /**
387    * This shows an Input window. We include this so that the
388    * MessageProxy can call the method without caring about the actual
389    * implementation of the dialog.
390    */

391   public String JavaDoc showInputDialog(String JavaDoc pInputMessage, String JavaDoc pTitle) {
392     final String JavaDoc inputMessage = pInputMessage;
393     final String JavaDoc title = pTitle;
394     final ResponseWrapper fResponseWrapper = new ResponseWrapper();
395
396     Runnable JavaDoc runMe = new Runnable JavaDoc() {
397         public void run() {
398           fResponseWrapper.setString(JOptionPane.showInternalInputDialog(getMessagePanel(), inputMessage, title, JOptionPane.QUESTION_MESSAGE));
399         }
400       };
401
402     if (! SwingUtilities.isEventDispatchThread()) {
403       try {
404         SwingUtilities.invokeAndWait(runMe);
405       } catch (Exception JavaDoc e) {
406       }
407     } else {
408       runMe.run();
409     }
410
411     return fResponseWrapper.getString();
412   }
413
414   /**
415    * As specified by interface net.suberic.pooka.gui.FolderDisplayUI.
416    *
417    * This skips to the given message.
418    */

419   public int selectMessage(int messageNumber) {
420     return getFolderDisplay().selectMessage(messageNumber);
421   }
422
423   /**
424    * As specified by interface net.suberic.pooka.gui.FolderDisplayUI.
425    *
426    * This makes the given row visible.
427    */

428   public void makeSelectionVisible(int messageNumber) {
429     getFolderDisplay().makeSelectionVisible(messageNumber);
430   }
431
432   public int selectNextMessage() {
433     return getFolderDisplay().selectNextMessage();
434   }
435
436   public int selectPreviousMessage() {
437     return getFolderDisplay().selectPreviousMessage();
438   }
439
440   public int selectNextUnreadMessage() {
441     return getFolderDisplay().selectNextUnreadMessage();
442   }
443
444   /**
445    * As specified by interface net.suberic.pooka.gui.FolderDisplayUI.
446    *
447    * This resets the FolderTableModel in the MessageTable.
448    */

449   public void resetFolderTableModel(FolderTableModel ftm) {
450     getFolderDisplay().resetFolderTableModel(ftm);
451   }
452
453   /**
454    * As specified by interface net.suberic.pooka.gui.FolderDisplayUI.
455    *
456    */

457   public void showStatusMessage(String JavaDoc msg) {
458     Pooka.getUIFactory().showStatusMessage(getFolderInfo().getFolderID() + ": " + msg);
459   }
460
461   /**
462    * As specified by interface net.suberic.pooka.gui.FolderDisplayUI.
463    *
464    */

465   public void clearStatusMessage() {
466     Pooka.getUIFactory().clearStatus();
467   }
468
469   /**
470    * As specified by interface net.suberic.pooka.gui.FolderDisplayUI.
471    *
472    * This implementation sets the cursor to either Cursor.WAIT_CURSOR
473    * if busy, or Cursor.DEFAULT_CURSOR if not busy.
474    */

475   public void setBusy(boolean newBusy) {
476     final boolean newValue = newBusy;
477
478     Runnable JavaDoc runMe = new Runnable JavaDoc() {
479         public void run() {
480           if (newValue)
481             FolderInternalFrame.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
482           else
483             FolderInternalFrame.this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
484         }
485       };
486
487     if (SwingUtilities.isEventDispatchThread())
488       runMe.run();
489     else
490       SwingUtilities.invokeLater(runMe);
491   }
492
493   /**
494    * Displays a status message for the folder.
495    */

496   public void updateStatus(String JavaDoc message) {
497     Pooka.getUIFactory().showStatusMessage(message);
498   }
499
500   /**
501    * Displays a status message for the folder.
502    */

503   public void updateStatus(Event e, String JavaDoc message) {
504     if (message != null)
505       updateStatus(message);
506
507   }
508
509   // Accessor methods.
510

511   public MessagePanel getMessagePanel() {
512     if (messagePanel != null)
513       return messagePanel;
514     else {
515       ContentPanel cp = Pooka.getMainPanel().getContentPanel();
516       if (cp instanceof MessagePanel)
517         return (MessagePanel) cp;
518       else
519         return null;
520     }
521   }
522
523   public FolderDisplayPanel getFolderDisplay() {
524     return folderDisplay;
525   }
526
527   public void setFolderInfo(FolderInfo newValue) {
528     folderInfo=newValue;
529   }
530
531   public FolderInfo getFolderInfo() {
532     return folderInfo;
533   }
534
535   public FolderStatusBar getFolderStatusBar() {
536     return folderStatusBar;
537   }
538
539   public void setFolderStatusBar(FolderStatusBar newValue) {
540     folderStatusBar = newValue;
541   }
542
543   public java.util.logging.Logger JavaDoc getLogger() {
544     return java.util.logging.Logger.getLogger("Pooka.debug.gui");
545   }
546
547   /**
548    * gets the actions handled both by the FolderInternalFrame and the
549    * selected Message(s).
550    */

551
552   public class SelectionListener implements javax.swing.event.ListSelectionListener JavaDoc {
553     SelectionListener() {
554     }
555
556     public void valueChanged(javax.swing.event.ListSelectionEvent JavaDoc e) {
557       // the main menus are handled by the FolderDisplayPanel itself.
558
if (toolbar != null)
559         toolbar.setActive(getActions());
560       if (keyBindings != null)
561         keyBindings.setActive(getActions());
562     }
563   }
564
565   /**
566    * This registers the Keyboard action not only for the FolderInternalFrame
567    * itself, but also for pretty much all of its children, also. This
568    * is to work around something which I think is a bug in jdk 1.2.
569    * (this is not really necessary in jdk 1.3.)
570    *
571    * Overrides JComponent.registerKeyboardAction(ActionListener anAction,
572    * String aCommand, KeyStroke aKeyStroke, int aCondition)
573    */

574
575   public void registerKeyboardAction(ActionListener anAction,
576                                      String JavaDoc aCommand, KeyStroke aKeyStroke, int aCondition) {
577     super.registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition);
578
579     getFolderDisplay().registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition);
580     folderStatusBar.registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition);
581     toolbar.registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition);
582   }
583
584   /**
585    * This unregisters the Keyboard action not only for the FolderInternalFrame
586    * itself, but also for pretty much all of its children, also. This
587    * is to work around something which I think is a bug in jdk 1.2.
588    * (this is not really necessary in jdk 1.3.)
589    *
590    * Overrides JComponent.unregisterKeyboardAction(KeyStroke aKeyStroke)
591    */

592
593   public void unregisterKeyboardAction(KeyStroke aKeyStroke) {
594     super.unregisterKeyboardAction(aKeyStroke);
595
596     getFolderDisplay().unregisterKeyboardAction(aKeyStroke);
597     folderStatusBar.unregisterKeyboardAction(aKeyStroke);
598     toolbar.unregisterKeyboardAction(aKeyStroke);
599   }
600
601   /**
602    * As specified by net.suberic.pooka.UserProfileContainer
603    */

604
605   public UserProfile getDefaultProfile() {
606     if (getFolderInfo() != null) {
607       return getFolderInfo().getDefaultProfile();
608     }
609     else {
610       return null;
611     }
612   }
613
614   /**
615    * Returns whether or not this window is enabled. This should be true
616    * just about all of the time. The only time it won't be true is if
617    * the Folder is closed or disconnected, and the mail store isn't set
618    * up to work in disconnected mode.
619    */

620   public boolean isEnabled() {
621     return enabled;
622   }
623
624   /**
625    * This sets whether or not the window is enabled. This should only
626    * be set to false when the Folder is no longer available.
627    */

628   public void setEnabled(boolean newValue) {
629     enabled = newValue;
630   }
631
632   // MessageLoadedListener
633

634   /**
635    * Displays that a message has been loaded.
636    *
637    * Defined in net.suberic.pooka.event.MessageLoadedListener.
638    */

639   public void handleMessageLoaded(MessageLoadedEvent e) {
640     final MessageLoadedEvent event = e;
641
642     Runnable JavaDoc runMe = new Runnable JavaDoc() {
643
644         public void run() {
645           if (event.getType() == MessageLoadedEvent.LOADING_STARTING) {
646             if (getFolderStatusBar().getTracker() != null) {
647               getFolderStatusBar().setTracker(new LoadMessageTracker(event.getLoadedMessageCount(), 0, event.getNumMessages()));
648               getFolderStatusBar().getLoaderPanel().add(getFolderStatusBar().getTracker());
649             }
650           } else if (event.getType() == MessageLoadedEvent.LOADING_COMPLETE) {
651
652             if (getFolderStatusBar().getTracker() != null) {
653               getFolderStatusBar().getLoaderPanel().remove(getFolderStatusBar().getTracker());
654               getFolderStatusBar().setTracker(null);
655             }
656           } else if (event.getType() == MessageLoadedEvent.MESSAGES_LOADED) {
657             if (getFolderStatusBar().getTracker() != null)
658               getFolderStatusBar().getTracker().handleMessageLoaded(event);
659           }
660           getFolderStatusBar().repaint();
661         }
662       };
663
664     if (!SwingUtilities.isEventDispatchThread()) {
665       SwingUtilities.invokeLater(runMe);
666     } else {
667       runMe.run();
668     }
669   }
670
671   // ConnectionListener
672

673   /**
674    *
675    */

676   public void closed(ConnectionEvent e) {
677
678   }
679
680   /**
681    *
682    */

683   public void disconnected(ConnectionEvent e) {
684
685   }
686
687   /**
688    *
689    */

690   public void opened(ConnectionEvent e) {
691
692   }
693
694   // MessageCountListener
695
/**
696    *
697    */

698   public void messagesAdded(MessageCountEvent e) {
699     if (getFolderStatusBar() != null)
700       getFolderStatusBar().messagesAdded(e);
701   }
702
703   /**
704    * Called in response to a messagesRemoved event. Should always be
705    * called on the parent FolderThread.
706    */

707   public void messagesRemoved(MessageCountEvent e) {
708     if (getFolderStatusBar() != null)
709       getFolderStatusBar().messagesRemoved(e);
710
711     Runnable JavaDoc updateAdapter = new Runnable JavaDoc() {
712         public void run() {
713           //getMessagePanel().getMainPanel().refreshActiveMenus();
714
if (toolbar != null)
715             toolbar.setActive(getActions());
716           if (keyBindings != null)
717             keyBindings.setActive(getActions());
718         }
719       };
720     if (SwingUtilities.isEventDispatchThread())
721       updateAdapter.run();
722     else
723       SwingUtilities.invokeLater(updateAdapter);
724
725   }
726
727   // MessageChangedListener
728
public void messageChanged(MessageChangedEvent e) {
729     if (getFolderStatusBar() != null)
730       getFolderStatusBar().messageChanged(e);
731     if (getFolderDisplay() != null)
732       getFolderDisplay().moveSelectionOnRemoval(e);
733
734     final MessageInfo mi = getFolderInfo().getMessageInfo(e.getMessage());
735     if (mi != null) {
736       SwingUtilities.invokeLater(new Runnable JavaDoc() {
737           public void run() {
738             // really, all we should do here is update the individual
739
// row.
740
// getFolderDisplay().repaint();
741
if (mi.getMessageProxy() != null)
742               getFolderDisplay().repaintMessage(mi.getMessageProxy());
743           }
744         });
745     }
746   }
747
748   /**
749    * This checks to see if the message which has been removed is
750    * currently selected. If so, we unselect it and select the next
751    * row.
752    */

753   private void moveSelectionOnRemoval(MessageChangedEvent e) {
754     try {
755       // don't bother if we're just going to autoexpunge it...
756
if ((!Pooka.getProperty("Pooka.autoExpunge", "true").equalsIgnoreCase("true")) && e.getMessageChangeType() == MessageChangedEvent.FLAGS_CHANGED && (e.getMessage().isExpunged() || e.getMessage().getFlags().contains(Flags.Flag.DELETED))) {
757         MessageProxy selectedProxy = getSelectedMessage();
758         if ( selectedProxy != null && selectedProxy.getMessageInfo().getMessage().equals(e.getMessage())) {
759           SwingUtilities.invokeLater(new Runnable JavaDoc() {
760               public void run() {
761                 selectNextMessage();
762               }
763             });
764         }
765       }
766     } catch (MessagingException me) {
767     }
768   }
769
770   /**
771    * This checks to see if the message which has been removed is
772    * currently selected. If so, we unselect it and select the next
773    * row.
774    */

775   private void moveSelectionOnRemoval(MessageCountEvent e) {
776     MessageProxy selectedProxy = getSelectedMessage();
777     Message JavaDoc[] removedMsgs = e.getMessages();
778     if (selectedProxy != null) {
779       boolean found = false;
780       Message JavaDoc currentMsg = selectedProxy.getMessageInfo().getMessage();
781       for (int i = 0; (found == false && i < removedMsgs.length); i++) {
782         if (currentMsg.equals(removedMsgs[i])) {
783           found = true;
784         }
785       }
786
787       if (found) {
788         SwingUtilities.invokeLater(new Runnable JavaDoc() {
789             public void run() {
790               selectNextMessage();
791             }
792           });
793       }
794     }
795   }
796
797   /**
798    * Calls getFolderDisplay().removeRows(removedProxies).
799    * This is the preferred way to remove rows from the FolderTableModel.
800    */

801   public void removeRows(java.util.Vector JavaDoc removedProxies) {
802     getFolderDisplay().removeRows(removedProxies);
803   }
804
805   /**
806    * Gets the Actions for this component.
807    */

808   public Action JavaDoc[] getActions() {
809     if (isEnabled()) {
810       Action JavaDoc[] returnValue = defaultActions;
811
812       if (getFolderDisplay() != null) {
813         returnValue = TextAction.augmentList(getFolderDisplay().getActions(), returnValue);
814       }
815
816       return returnValue;
817     } else {
818       return null;
819     }
820
821     /*
822       if (isEnabled()) {
823       Action[] returnValue;
824       MessageProxy m = getSelectedMessage();
825
826       if (m != null)
827       returnValue = TextAction.augmentList(m.getActions(), getDefaultActions());
828       else
829       returnValue = getDefaultActions();
830
831       if (folderInfo.getActions() != null)
832       returnValue = TextAction.augmentList(folderInfo.getActions(), returnValue);
833
834       return returnValue;
835       } else {
836       return null;
837       }
838     */

839
840
841   }
842
843   public Action JavaDoc[] getDefaultActions() {
844     return defaultActions;
845   }
846
847   //-----------actions----------------
848

849   // The actions supported by the window itself.
850

851   private Action JavaDoc[] defaultActions;
852
853   class CloseAction extends AbstractAction {
854
855     CloseAction() {
856       super("file-close");
857     }
858
859     public void actionPerformed(ActionEvent e) {
860       closeFolderDisplay();
861     }
862   }
863
864   public class ExpungeAction extends AbstractAction {
865
866     ExpungeAction() {
867       super("message-expunge");
868     }
869
870     public void actionPerformed(ActionEvent e) {
871       expungeMessages();
872     }
873   }
874
875
876   public class NextMessageAction extends AbstractAction {
877
878     NextMessageAction() {
879       super("message-next");
880     }
881
882     public void actionPerformed(ActionEvent e) {
883       selectNextMessage();
884     }
885   }
886
887   public class PreviousMessageAction extends AbstractAction {
888
889     PreviousMessageAction() {
890       super("message-previous");
891     }
892
893     public void actionPerformed(ActionEvent e) {
894       selectPreviousMessage();
895     }
896   }
897
898   public class NextUnreadMessageAction extends AbstractAction {
899
900     NextUnreadMessageAction() {
901       super("message-next-unread");
902     }
903
904     public void actionPerformed(ActionEvent e) {
905       selectNextUnreadMessage();
906     }
907   }
908
909   public class GotoMessageAction extends AbstractAction {
910
911     GotoMessageAction() {
912       super("message-goto");
913     }
914
915     public void actionPerformed(ActionEvent e) {
916       getFolderStatusBar().activateGotoDialog();
917     }
918   }
919
920   public class SearchAction extends AbstractAction {
921
922     SearchAction() {
923       super("folder-search");
924     }
925
926     public void actionPerformed(ActionEvent e) {
927       searchFolder();
928     }
929   }
930
931   public class SelectAllAction extends AbstractAction {
932
933     SelectAllAction() {
934       super("select-all");
935     }
936
937     public void actionPerformed(ActionEvent e) {
938       getFolderDisplay().selectAll();
939     }
940   }
941
942 }
943
944
945
946
947
948
Popular Tags