KickJava   Java API By Example, From Geeks To Geeks.

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


1 package net.suberic.pooka.gui;
2 import net.suberic.pooka.*;
3 import net.suberic.util.gui.ConfigurablePopupMenu;
4 import net.suberic.util.thread.*;
5 import net.suberic.pooka.gui.filter.DisplayFilter;
6 import net.suberic.pooka.gui.crypto.*;
7 import javax.mail.*;
8 import javax.mail.internet.MimeMessage JavaDoc;
9 import javax.mail.event.*;
10 import javax.swing.*;
11 import javax.print.*;
12 import javax.print.attribute.*;
13 import javax.print.attribute.standard.*;
14 import javax.print.event.*;
15 import java.util.ArrayList JavaDoc;
16 import java.util.Hashtable JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.List JavaDoc;
19 import java.awt.event.*;
20 import java.awt.print.*;
21 import java.io.*;
22
23 public class MessageProxy implements java.awt.datatransfer.ClipboardOwner JavaDoc {
24
25   class SaveMessageThread extends Thread JavaDoc {
26
27     MimeMessage JavaDoc msg;
28     File saveFile;
29     JDialog jd;
30     JProgressBar progressBar;
31     boolean running = true;
32
33     SaveMessageThread(MimeMessage JavaDoc newMsg, File newSaveFile) {
34       msg = newMsg;
35       saveFile = newSaveFile;
36     }
37
38     public void run() {
39       InputStream decodedIS = null;
40       BufferedOutputStream outStream = null;
41
42       int msgSize = 0;
43
44       try {
45         msgSize = msg.getSize();
46
47         createDialog(msgSize);
48         jd.setVisible(true);
49
50         outStream = new BufferedOutputStream(new FileOutputStream(saveFile));
51         int b=0;
52         byte[] buf = new byte[32768];
53
54         b = decodedIS.read(buf);
55         while (b != -1 && running) {
56           outStream.write(buf, 0, b);
57           progressBar.setValue(progressBar.getValue() + b);
58           b = decodedIS.read(buf);
59         }
60
61         jd.dispose();
62
63       } catch (IOException ioe) {
64         if (getMessageUI() != null)
65           getMessageUI().showError(Pooka.getProperty("error.SaveFile", "Error saving file: ") + ioe.getMessage());
66         else
67           Pooka.getUIFactory().showError(Pooka.getProperty("error.SaveFile", "Error saving file: ") + ioe.getMessage());
68         cancelSave();
69       } catch (MessagingException me) {
70         if (getMessageUI() != null)
71           getMessageUI().showError(Pooka.getProperty("error.SaveFile", "Error saving file: ") + me.getMessage());
72         else
73           Pooka.getUIFactory().showError(Pooka.getProperty("error.SaveFile", "Error saving file: ") + me.getMessage());
74         cancelSave();
75       } finally {
76         if (outStream != null) {
77           try {
78             outStream.flush();
79             outStream.close();
80           } catch (IOException ioe) {}
81         }
82       }
83     }
84
85     public void createDialog(int msgSize) {
86       progressBar = new JProgressBar(0, msgSize);
87       progressBar.setBorderPainted(true);
88       progressBar.setStringPainted(true);
89
90       jd = new JDialog();
91       jd.getContentPane().setLayout(new BoxLayout(jd.getContentPane(), BoxLayout.Y_AXIS));
92       JLabel nameLabel = new JLabel(saveFile.getName());
93       JPanel buttonPanel = new JPanel();
94       JButton cancelButton = new JButton(Pooka.getProperty("button.cancel", "Cancel"));
95       cancelButton.addActionListener(new ActionListener() {
96           public void actionPerformed(ActionEvent e) {
97             cancelSave();
98           }
99         });
100       buttonPanel.add(cancelButton);
101
102       jd.getContentPane().add(nameLabel);
103       jd.getContentPane().add(progressBar);
104       jd.getContentPane().add(buttonPanel);
105
106       jd.pack();
107     }
108
109     public void cancelSave() {
110       try {
111         saveFile.delete();
112       } catch (Exception JavaDoc e) {}
113       jd.dispose();
114     }
115   }
116
117   // the underlying MessageInfo
118
MessageInfo messageInfo;
119
120   // the information for the FolderTable
121
HashMap JavaDoc tableInfo;
122
123   // matching Filters.
124
MessageFilter[] matchingFilters;
125
126   // the column Headers for the FolderInfo List; used for loading the
127
// tableInfo.
128
List JavaDoc columnHeaders;
129
130   // if the tableInfo has been loaded yet.
131
boolean loaded = false;
132
133   // if the tableInfo needs to be refreshed.
134
boolean refresh = false;
135
136   // if the display filters have been run
137
boolean filtersMatched = false;
138
139   // commands for the GUI
140
Hashtable JavaDoc commands;
141
142   // The Window associated with this MessageProxy.
143
MessageUI msgWindow;
144
145   // the display modes.
146
public static int RFC_822 = -1;
147   public static int TEXT_ONLY = 0;
148   public static int TEXT_PREFERRED = 5;
149   public static int HTML_PREFERRED = 10;
150   public static int HTML_ONLY = 15;
151
152   // the header modes
153
public static int HEADERS_DEFAULT = 0;
154   public static int HEADERS_FULL = 1;
155   public static int RFC822_STYLE = 2;
156
157   // the types of headers to show for this Message.
158
int headerMode = HEADERS_DEFAULT;
159
160   // whether this should be displayed as html, text, or raw RFC822.
161
int displayMode = getDefaultDisplayMode();
162
163   // the default actions for this MessageProxy.
164
public Action[] defaultActions = null;
165
166   /**
167    * This class should make it easy for us to sort subjects correctly.
168    * It stores both the subject String itself and a sortingString which
169    * is taken to lowercase and also has all of the starting 're:' characters
170    * removed.
171    */

172   public class SubjectLine implements Comparable JavaDoc {
173     String JavaDoc subject;
174     String JavaDoc sortingSubject;
175
176     /**
177      * Constructor.
178      */

179     public SubjectLine(String JavaDoc newSubject) {
180       subject = newSubject;
181       if (subject != null)
182         sortingSubject = subject.toLowerCase();
183       else
184         sortingSubject = new String JavaDoc("");
185
186       int cutoffPoint = 0;
187       while(sortingSubject.startsWith("re:", cutoffPoint))
188         for(cutoffPoint = cutoffPoint + 3; cutoffPoint < sortingSubject.length() && Character.isWhitespace(sortingSubject.charAt(cutoffPoint)); cutoffPoint++) { }
189       if (cutoffPoint != 0)
190         sortingSubject = sortingSubject.substring(cutoffPoint);
191     }
192
193     /**
194      * Compare function.
195      */

196     public int compareTo(Object JavaDoc o) {
197       // proper SubjectLines are always greater than null.
198
if (o == null)
199         return 1;
200
201       if (o instanceof SubjectLine) {
202         return sortingSubject.compareTo(((SubjectLine)o).sortingSubject);
203       } else
204         return sortingSubject.compareToIgnoreCase(o.toString());
205     }
206
207     /**
208      * Override to compare underlying values.
209      */

210     public boolean equals(Object JavaDoc o) {
211       return (compareTo(o) == 0);
212     }
213
214     /**
215      * toString() just returns the original subject.
216      */

217     public String JavaDoc toString() {
218       return subject;
219     }
220   }
221
222   /**
223    * This class should make it easy for us to sort addresses correctly.
224    * It stores both the address itself and a sortingString which
225    * is taken to lowercase and also has any non alphanumeric cruft (quotation
226    * marks, etc.) removed.
227    */

228   public class AddressLine implements Comparable JavaDoc {
229     String JavaDoc address;
230     String JavaDoc sortingAddress;
231
232     /**
233      * Constructor.
234      */

235     public AddressLine(String JavaDoc newAddress) {
236       address = newAddress;
237       if (address != null)
238         sortingAddress = address.toLowerCase();
239       else
240         sortingAddress = new String JavaDoc("");
241
242       while(sortingAddress.length() > 0 && ! Character.isLetterOrDigit(sortingAddress.charAt(0)))
243         sortingAddress = sortingAddress.substring(1);
244     }
245
246     /**
247      * Compare function.
248      */

249     public int compareTo(Object JavaDoc o) {
250       // proper AddressLines are always greater than null.
251
if (o == null)
252         return 1;
253
254       if (o instanceof AddressLine) {
255         return sortingAddress.compareTo(((AddressLine)o).sortingAddress);
256       } else
257         return sortingAddress.compareToIgnoreCase(o.toString());
258     }
259
260     /**
261      * Override to compare underlying values.
262      */

263     public boolean equals(Object JavaDoc o) {
264       return (compareTo(o) == 0);
265     }
266
267     /**
268      * toString() just returns the original address.
269      */

270     public String JavaDoc toString() {
271       return address;
272     }
273   }
274
275   protected MessageProxy() {
276   }
277
278   /**
279    * This creates a new MessageProxy from a set of Column Headers (for
280    * the tableInfo), a Message, and a link to a FolderInfo object.
281    */

282   public MessageProxy(List JavaDoc newColumnHeaders, MessageInfo newMessage) {
283     messageInfo = newMessage;
284     messageInfo.setMessageProxy(this);
285
286     columnHeaders = newColumnHeaders;
287
288   }
289
290   /**
291    * This loads the tableInfo (the fields that will be displayed in the
292    * FolderTable) using the columnHeaders property to know which fields
293    * to load.
294    */

295   public synchronized void loadTableInfo() throws MessagingException {
296     if (!loaded) {
297       tableInfo = createTableInfo();
298
299       this.isSeen();
300
301       this.isDeleted();
302
303       matchFilters();
304
305       loaded=true;
306
307       // notify the JTable that this proxy has loaded.
308
MessageChangedEvent mce = new net.suberic.pooka.event.MessageTableInfoChangedEvent(this, MessageChangedEvent.ENVELOPE_CHANGED, getMessageInfo().getMessage());
309
310       FolderInfo fi = getFolderInfo();
311       if (fi != null) {
312         fi.fireMessageChangedEvent(mce);
313       }
314
315     }
316   }
317
318   /**
319    * Refreshes the MessageProxy by reloading the information for the
320    * MessageInfo, and then updating the FolderTableInfo if necessary.
321    */

322   public synchronized void refreshMessage() throws MessagingException {
323     if (needsRefresh()) {
324       // first, tag this so we won't need to be refereshed again.
325

326       refresh = false;
327
328       // second, refresh the MessageInfo itself.
329

330       getMessageInfo().refreshFlags();
331
332       // third, compare.
333

334       HashMap JavaDoc newTableInfo = createTableInfo();
335
336       // check to see if anything has actually changed
337
boolean hasChanged = (tableInfo == null);
338       // assume that we're not actually changing the values...
339
java.util.Iterator JavaDoc it = newTableInfo.keySet().iterator();
340       while ((! hasChanged) && it.hasNext()) {
341         Object JavaDoc key = it.next();
342         Object JavaDoc newValue = newTableInfo.get(key);
343         Object JavaDoc oldValue = tableInfo.get(key);
344         if (newValue == null) {
345           if (oldValue != null) {
346             hasChanged = true;
347           }
348         } else if (oldValue == null || ! newValue.equals(oldValue)) {
349           hasChanged = true;
350         }
351       }
352
353       // check for the matching filters, also.
354
MessageFilter[] newMatchingFilters = doFilterMatch();
355       if (newMatchingFilters == null) {
356         if (matchingFilters != null)
357           hasChanged = true;
358       } else if (matchingFilters == null) {
359         hasChanged = true;
360       } else if (matchingFilters.length != newMatchingFilters.length) {
361         hasChanged = true;
362       } else {
363         for (int i = 0; hasChanged != true && i < newMatchingFilters.length; i++) {
364           MessageFilter newValue = newMatchingFilters[i];
365           MessageFilter oldValue = matchingFilters[i];
366           if (newValue != oldValue) {
367             hasChanged = true;
368           }
369         }
370       }
371
372       if (hasChanged) {
373         tableInfo = newTableInfo;
374         matchingFilters = newMatchingFilters;
375
376         // notify the JTable that this proxy has loaded.
377
MessageChangedEvent mce = new net.suberic.pooka.event.MessageTableInfoChangedEvent(this, MessageChangedEvent.ENVELOPE_CHANGED, getMessageInfo().getMessage());
378
379         FolderInfo fi = getFolderInfo();
380         if (fi != null) {
381           fi.fireMessageChangedEvent(mce);
382         }
383       }
384
385     }
386
387   }
388
389   /**
390    * Creates a TableInfo List.
391    */

392   protected HashMap JavaDoc createTableInfo() throws MessagingException {
393     int columnCount = columnHeaders.size();
394
395     HashMap JavaDoc returnValue = new HashMap JavaDoc();
396
397     for(int j=0; j < columnCount; j++) {
398       loadTableProperty(columnHeaders.get(j), returnValue);
399     }
400
401     return returnValue;
402   }
403
404   /**
405    * gets the column headers.
406    */

407   java.util.List JavaDoc getColumnHeaders() {
408     return columnHeaders;
409   }
410
411   /**
412    * Loads a value into the TableInfo.
413    */

414   private void loadTableProperty(Object JavaDoc newProperty, HashMap JavaDoc returnValue) {
415     try {
416       Object JavaDoc newValue = null;
417       if (newProperty instanceof String JavaDoc) {
418         String JavaDoc propertyName = (String JavaDoc)newProperty;
419         if (propertyName.startsWith("FLAG"))
420           newValue=getMessageFlag(propertyName);
421         else if (propertyName.equals("attachments"))
422           newValue=new BooleanIcon(getMessageInfo().hasAttachments(), Pooka.getProperty("FolderTable.Attachments.icon", "Attachment.small"), propertyName);
423         else if (propertyName.equals("crypto"))
424           newValue=new BooleanIcon(getMessageInfo().hasEncryption(), Pooka.getProperty("FolderTable.Crypto.icon", "Encrypted.small"), propertyName);
425         else if (propertyName.equalsIgnoreCase("subject"))
426           newValue=new SubjectLine((String JavaDoc) getMessageInfo().getMessageProperty(propertyName));
427         else if (propertyName.equalsIgnoreCase("from"))
428           newValue=new AddressLine((String JavaDoc) getMessageInfo().getMessageProperty(propertyName));
429         else if (propertyName.equalsIgnoreCase("Date")) {
430           newValue = getMessageInfo().getMessageProperty("Date");
431           if (newValue == null) {
432             newValue = getMessageInfo().getMessageProperty("ReceivedDate");
433           }
434         } else {
435           newValue=getMessageInfo().getMessageProperty(propertyName);
436         }
437       } else if (newProperty instanceof SearchTermIconManager) {
438         SearchTermIconManager stm = (SearchTermIconManager) newProperty;
439         newValue=new SearchTermIcon(stm, this);
440       } else if (newProperty instanceof RowCounter) {
441         newValue=newProperty;
442       }
443
444       returnValue.put(newProperty, newValue);
445
446     } catch (Exception JavaDoc e) {
447       // if we catch an exception, keep going for the rest.
448
if (getFolderInfo().getLogger().isLoggable(java.util.logging.Level.WARNING))
449         e.printStackTrace();
450     }
451
452   }
453
454   /**
455    * This matches the FolderInfo's display filters.
456    */

457   public void matchFilters() {
458     if (! filtersMatched ) {
459       // match the given filters for the FolderInfo.
460

461       matchingFilters = doFilterMatch();
462
463       filtersMatched = true;
464     }
465   }
466
467   /**
468    * This returns a list of matching filters, or null if there are no
469    * filters.
470    */

471   private MessageFilter[] doFilterMatch() {
472     MessageFilter[] folderFilters = getFolderInfo().getDisplayFilters();
473     if (folderFilters != null) {
474       List JavaDoc tmpMatches = new ArrayList JavaDoc();
475       for (int i = 0; i < folderFilters.length; i++) {
476         if (folderFilters[i].getSearchTerm() instanceof net.suberic.pooka.filter.DeleteInProgressSearchTerm) {
477           // big hack.
478
if (isDeleteInProgress()) {
479             tmpMatches.add(folderFilters[i]);
480           }
481         } else if (folderFilters[i].getSearchTerm().match(getMessageInfo().getMessage()))
482           tmpMatches.add(folderFilters[i]);
483       }
484
485       MessageFilter[] newMatchingFilters = new MessageFilter[tmpMatches.size()];
486       for (int i = 0; i < tmpMatches.size(); i++) {
487         newMatchingFilters[i] = (MessageFilter) tmpMatches.get(i);
488       }
489
490       return newMatchingFilters;
491     }
492
493     return null;
494   }
495
496   /**
497    * Runs server filters on this Message.
498    */

499   public void runBackendFilters() {
500     MessageInfo info = getMessageInfo();
501     if (info != null)
502       info.runBackendFilters();
503   }
504
505   /**
506    * Attempts to decrypt the given message.
507    */

508   public void decryptMessage() {
509     MessageInfo info = getMessageInfo();
510     if (info != null) {
511       try {
512         if (info.hasEncryption()) {
513
514           MessageCryptoInfo cInfo = info.getCryptoInfo();
515
516           if (cInfo != null && cInfo.isEncrypted()) {
517
518             java.security.Key JavaDoc key = getDefaultProfile().getEncryptionKey(cInfo.getEncryptionType());
519
520             if (key != null) {
521               try {
522                 cInfo.decryptMessage(key, true);
523               } catch (Exception JavaDoc e) {
524                 // ignore here.
525
}
526             }
527
528             if (key == null) {
529               try {
530                 key = selectPrivateKey(Pooka.getProperty("Pooka.crypto.privateKey.forDecrypt", "Select key to decrypt this message."), cInfo.getEncryptionType());
531               } catch (Exception JavaDoc e) {
532                 showError(Pooka.getProperty("Error.encryption.keystoreException", "Error selecting key: "), e);
533               }
534             }
535             // check the encryption
536

537             if (key != null) {
538               try {
539                 cInfo.decryptMessage(key, true);
540               } catch (Exception JavaDoc e) {
541                 showError(Pooka.getProperty("Error.encryption.decryptionFailed", "Decryption Failed: "), e);
542               }
543
544               MessageUI ui = getMessageUI();
545               if (ui != null) {
546
547                 CryptoStatusDisplay csd = ui.getCryptoStatusDisplay();
548
549                 if (csd != null)
550                   csd.cryptoUpdated(cInfo);
551                 try {
552                   ui.refreshDisplay();
553                 } catch (MessagingException me) {
554                   showError(Pooka.getProperty("Error.encryption.decryptionFailed", "Decryption Failed: "), me);
555                 }
556               }
557             }
558           }
559         }
560       } catch (MessagingException me) {
561         showError(Pooka.getProperty("Error.encryption.decryptionFailed", "Decryption Failed: "), me);
562       }
563     }
564   }
565
566   /**
567    * Attempts to check the signature on the given message.
568    */

569   public void checkSignature() {
570     MessageInfo info = getMessageInfo();
571     if (info != null) {
572       MessageCryptoInfo cInfo = info.getCryptoInfo();
573       try {
574         if (cInfo != null && cInfo.isSigned()) {
575           CryptoStatusDisplay csd = null;
576
577           String JavaDoc fromString = "";
578           Address[] fromAddr = getMessageInfo().getMessage().getFrom();
579           if (fromAddr != null && fromAddr.length > 0) {
580             fromString = ((javax.mail.internet.InternetAddress JavaDoc)fromAddr[0]).getAddress();
581           }
582           java.security.Key JavaDoc[] keys = Pooka.getCryptoManager().getPublicKeys(fromString, cInfo.getEncryptionType());
583
584           if (keys == null || keys.length < 1) {
585             java.security.Key JavaDoc newKey = selectPublicKey(Pooka.getProperty("Pooka.crypto.publicKey.forSig", "Select key for verifying the signature on this message."), cInfo.getEncryptionType());
586             keys = new java.security.Key JavaDoc[] { newKey };
587           }
588
589           if (keys != null) {
590             boolean checked = false;
591             for (int i = 0; (! checked) && i < keys.length; i++) {
592               checked = cInfo.checkSignature(keys[i], true);
593             }
594           }
595           MessageUI ui = getMessageUI();
596           if (ui != null) {
597             csd = ui.getCryptoStatusDisplay();
598           }
599
600           if (csd != null)
601             csd.cryptoUpdated(cInfo);
602
603         }
604       } catch (Exception JavaDoc e) {
605         showError(Pooka.getProperty("Error.encryption.signatureValidationFailed", "Signature Validation Failed"), e);
606       }
607     }
608   }
609
610   /**
611    * Imports the keys on this message.
612    */

613   public void importKeys() {
614     MessageInfo info = getMessageInfo();
615     if (info != null) {
616       MessageCryptoInfo cInfo = info.getCryptoInfo();
617       if (cInfo != null) {
618         try {
619           java.security.Key JavaDoc[] newKeys = cInfo.extractKeys();
620           if (newKeys != null && newKeys.length > 0) {
621             // check to see if these match our current keys.
622
String JavaDoc changedMessage = Pooka.getProperty("Pooka.crypto.importKeysMessage", "Import the following keys:") + "\n";
623
624             for (int i = 0; i < newKeys.length; i++) {
625               // FIXME check to see if changed.
626
if (newKeys[i] instanceof net.suberic.crypto.EncryptionKey)
627                 changedMessage = changedMessage + ((net.suberic.crypto.EncryptionKey)newKeys[i]).getDisplayAlias() + "\n";
628               else
629                 changedMessage = changedMessage + newKeys[i].toString() + "\n";
630             }
631
632             int doImport = JOptionPane.NO_OPTION;
633
634             if (getMessageUI() != null)
635               doImport = getMessageUI().showConfirmDialog(changedMessage, Pooka.getProperty("Pooka.crypto.importKeysTitle", "Import keys"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
636             else
637               doImport = Pooka.getUIFactory().showConfirmDialog(changedMessage, Pooka.getProperty("Pooka.crypto.importKeysTitle", "Import keys"), JOptionPane.YES_NO_OPTION);
638
639             if (doImport == JOptionPane.YES_OPTION) {
640               for (int i = 0; i < newKeys.length; i++) {
641                 if (newKeys[i] instanceof net.suberic.crypto.EncryptionKey) {
642                   net.suberic.crypto.EncryptionKey eKey = (net.suberic.crypto.EncryptionKey) newKeys[i];
643                   Pooka.getCryptoManager().addPublicKey(eKey.getDisplayAlias(), eKey, eKey.getEncryptionUtils().getType());
644                 }
645               }
646             }
647
648           } else {
649             if (getMessageUI() != null)
650               getMessageUI().showMessageDialog("No keys found.", "No keys found");
651             else
652               Pooka.getUIFactory().showMessage("No keys found.", "No keys found");
653           }
654         } catch (Exception JavaDoc e) {
655           showError(Pooka.getProperty("Error.encryption.keyExtractionFailed", "Failed to extract keys."), e);
656         }
657       }
658     }
659   }
660
661   /**
662    * Opens up a dialog to select a public key.
663    */

664   public java.security.Key JavaDoc selectPublicKey(String JavaDoc flavorText, String JavaDoc type) throws java.security.GeneralSecurityException JavaDoc {
665     return CryptoKeySelector.selectPublicKey(flavorText, type);
666   }
667
668   /**
669    * Opens up a dialog to select a private key.
670    */

671   public java.security.Key JavaDoc selectPrivateKey(String JavaDoc flavorText, String JavaDoc type) throws java.security.GeneralSecurityException JavaDoc {
672     return CryptoKeySelector.selectPrivateKey(flavorText, type);
673   }
674
675   /**
676    * This loads the Attachment information into the attachments vector.
677    */

678
679   public void loadAttachmentInfo() throws MessagingException {
680     messageInfo.loadAttachmentInfo();
681   }
682
683   /**
684    * Returns the attachments for this Message.
685    */

686   public List JavaDoc getAttachments() throws MessagingException {
687     return messageInfo.getAttachments();
688   }
689
690   /**
691    * Returns whether or not this message has attachments.
692    */

693   public boolean hasAttachments() throws MessagingException {
694     return messageInfo.hasAttachments();
695   }
696
697   /**
698    * This gets a Flag property from the Message.
699    */

700   public BooleanIcon getMessageFlag(String JavaDoc flagName) {
701     try {
702       if (flagName.equals("FLAG.ANSWERED") )
703         return new BooleanIcon(getMessageInfo().flagIsSet(flagName), Pooka.getProperty("FolderTable.Answered.icon", ""), flagName);
704       else if (flagName.equals("FLAG.DELETED"))
705         return new BooleanIcon(getMessageInfo().flagIsSet(flagName),Pooka.getProperty("FolderTable.Deleted.icon", ""), flagName);
706       else if (flagName.equals("FLAG.DRAFT"))
707         return new BooleanIcon(getMessageInfo().flagIsSet(flagName), Pooka.getProperty("FolderTable.Draft.icon", ""), flagName);
708       else if (flagName.equals("FLAG.FLAGGED"))
709         return new BooleanIcon(getMessageInfo().flagIsSet(flagName), Pooka.getProperty("FolderTable.Flagged.icon", ""), flagName);
710       else if (flagName.equals("FLAG.RECENT"))
711         return new BooleanIcon(getMessageInfo().flagIsSet(flagName), Pooka.getProperty("FolderTable.Recent.icon", ""), flagName);
712       else if (flagName.equals("FLAG.NEW"))
713         return new MultiValueIcon(getMessageInfo().flagIsSet("FLAG.SEEN"), getMessageInfo().flagIsSet("FLAG.RECENT"), Pooka.getProperty("FolderTable.New.recentAndUnseenIcon", ""), Pooka.getProperty("FolderTable.New.justUnseenIcon", ""));
714       else if (flagName.equals("FLAG.SEEN"))
715         return new BooleanIcon(getMessageInfo().flagIsSet(flagName), Pooka.getProperty("FolderTable.Seen.icon", ""), flagName);
716       else
717         return new BooleanIcon(false, "", flagName);
718     } catch (MessagingException me) {
719       return new BooleanIcon(false, "", flagName);
720     }
721   }
722
723   /**
724    * this opens a MessageUI for this Message.
725    */

726   public void openWindow() {
727     openWindow(getDefaultDisplayMode(), HEADERS_DEFAULT);
728   }
729
730   /**
731    * this opens a MessageUI for this Message.
732    */

733   public void openWindow(int newDisplayMode, int newHeaderMode) {
734     try {
735       if (getMessageUI() == null) {
736         setDisplayMode(newDisplayMode);
737         setHeaderMode(newHeaderMode);
738
739         MessageUI newUI = Pooka.getUIFactory().createMessageUI(this);
740         setMessageUI(newUI);
741       } else if (newDisplayMode != getDisplayMode() || newHeaderMode != getHeaderMode()) {
742         setDisplayMode(newDisplayMode);
743         setHeaderMode(newHeaderMode);
744         getMessageUI().refreshDisplay();
745       }
746
747       SwingUtilities.invokeLater(new Runnable JavaDoc() {
748           public void run() {
749             getMessageUI().openMessageUI();
750           }
751         });
752
753       getMessageInfo().setSeen(true);
754     } catch (MessagingException me) {
755       showError(Pooka.getProperty("error.Message.openWindow", "Error opening window: "), me);
756     }
757   }
758
759   /**
760    * This creates a NewMessageUI for this MessageProxy and then opens an
761    * editor for it. If
762    */

763   public void openWindowAsNew(boolean removeProxy) {
764     try {
765       // first create the NewMessageProxy from this MessageProxy.
766
Message JavaDoc newMessage = new MimeMessage JavaDoc((MimeMessage JavaDoc)getMessageInfo().getMessage());
767       NewMessageInfo nmi = new NewMessageInfo(newMessage);
768       NewMessageProxy nmp = new NewMessageProxy(nmi);
769       nmi.setDefaultProfile(getDefaultProfile());
770
771       final MessageUI nmu = Pooka.getUIFactory().createMessageUI(nmp, getMessageUI());
772
773       nmp.matchUserProfile();
774
775       SwingUtilities.invokeLater(new Runnable JavaDoc() {
776           public void run() {
777             nmu.openMessageUI();
778           }
779         });
780
781
782       if (removeProxy)
783         deleteMessage();
784     } catch (MessagingException me) {
785       showError(Pooka.getProperty("error.Message.openWindow", "Error opening window: "), me);
786     }
787   }
788
789   /**
790    * Moves the Message into the target Folder.
791    */

792   public void moveMessage(FolderInfo targetFolder) {
793     moveMessage(targetFolder, Pooka.getProperty("Pooka.autoExpunge", "true").equals("true"));
794   }
795
796   /**
797    * Moves the Message into the target Folder.
798    */

799   public void moveMessage(FolderInfo targetFolder, boolean expunge) {
800     try {
801       messageInfo.moveMessage(targetFolder, expunge);
802     } catch (MessagingException me) {
803       showError( Pooka.getProperty("error.Message.CopyErrorMessage", "Error: could not copy messages to folder: ") + targetFolder.toString() +"\n", me);
804       if (Pooka.isDebug())
805         me.printStackTrace();
806     }
807   }
808
809   /**
810    * Copies the Message to the target Folder.
811    */

812   public void copyMessage(FolderInfo targetFolder) {
813     try {
814       messageInfo.copyMessage(targetFolder);
815     } catch (MessagingException me) {
816       showError( Pooka.getProperty("error.Message.CopyErrorMessage", "Error: could not copy messages to folder: ") + targetFolder.toString() +"\n", me);
817       if (Pooka.isDebug())
818         me.printStackTrace();
819     }
820   }
821
822   /**
823    * Creates a NewMessageInfo & Proxy for a message which is a reply
824    * to the current message. Opens a NewMessageUI for said Proxy.
825    */

826   private void replyToMessage(boolean replyAll, boolean withAttachments) {
827     if (getMessageUI() != null)
828       getMessageUI().setBusy(true);
829
830     FolderDisplayUI fw = getFolderDisplayUI();
831     if (fw != null)
832       fw.setBusy(true);;
833
834     try {
835       NewMessageProxy nmp = new NewMessageProxy(getMessageInfo().populateReply(replyAll, withAttachments));
836       nmp.getNewMessageInfo().setDefaultProfile(getDefaultProfile());
837       final MessageUI nmui = Pooka.getUIFactory().createMessageUI(nmp, this.getMessageUI());
838
839       // if this has a messageui up, then make the reply
840
SwingUtilities.invokeLater(new Runnable JavaDoc() {
841           public void run() {
842             nmui.openMessageUI();
843           }
844         });
845
846     } catch (Exception JavaDoc me) {
847       showError(Pooka.getProperty("error.MessageUI.replyFailed", "Failed to create new Message.") + "\n", me);
848     }
849
850     if (fw != null)
851       fw.setBusy(false);
852     if (getMessageUI() != null)
853       getMessageUI().setBusy(false);;
854
855   }
856
857   private void forwardMessage(boolean withAttachments) {
858     //forwardMessage(withAttachments, getDefaultProfile().getDefaultForwardMethod());
859
forwardMessage(withAttachments, MessageInfo.FORWARD_QUOTED);
860   }
861
862   /**
863    * Creates a NewMessageInfo & Proxy for a message which is a forward
864    * to the current message. Opens a NewMessageUI for said Proxy.
865    */

866   private void forwardMessage(boolean withAttachments, int method) {
867     if (getMessageUI() != null)
868       getMessageUI().setBusy(true);
869     FolderDisplayUI fw = getFolderDisplayUI();
870     if (fw != null)
871       fw.setBusy(true);;
872     try {
873       NewMessageProxy nmp = new NewMessageProxy(getMessageInfo().populateForward(withAttachments, method));
874       nmp.getNewMessageInfo().setDefaultProfile(getDefaultProfile());
875       final MessageUI nmui = Pooka.getUIFactory().createMessageUI(nmp, getMessageUI());
876       SwingUtilities.invokeLater(new Runnable JavaDoc() {
877           public void run() {
878             nmui.openMessageUI();
879           }
880         });
881
882     } catch (MessagingException me) {
883       if (getMessageUI() != null)
884         getMessageUI().showError(Pooka.getProperty("error.MessageUI.replyFailed", "Failed to create new Message.") + "\n" + me.getMessage());
885       else
886         Pooka.getUIFactory().showError(Pooka.getProperty("error.MessageUI.replyFailed", "Failed to create new Message.") + "\n" + me.getMessage());
887
888       me.printStackTrace();
889     }
890
891     if (fw != null)
892       fw.setBusy(false);
893     if (getMessageUI() != null)
894       getMessageUI().setBusy(false);;
895
896   }
897
898   /**
899    * Bounces the message. Pops up a dialog to request the address(es)
900    * to which to bounce the message.
901    */

902   public void bounceMessage() {
903
904     String JavaDoc addressString = null;
905     Address[] addresses = null;
906
907     boolean resolved = false;
908     while (! resolved) {
909       if (getMessageUI() != null)
910         addressString = getMessageUI().showInputDialog(Pooka.getProperty("message.bounceMessage.addresses", "Bounce to address(es):"), Pooka.getProperty("message.bounceMessage.title", "Bounce to addresses"));
911       else if (getMessageInfo().getFolderInfo().getFolderDisplayUI() != null) {
912         addressString = getMessageInfo().getFolderInfo().getFolderDisplayUI().showInputDialog(Pooka.getProperty("message.bounceMessage.addresses", "Bounce to address(es):"), Pooka.getProperty("message.bounceMessage.title", "Bounce to addresses"));
913       } else {
914         addressString = Pooka.getUIFactory().showInputDialog(Pooka.getProperty("message.bounceMessage.addresses", "Bounce to address(es):"), Pooka.getProperty("message.bounceMessage.title", "Bounce to addresses"));
915       }
916       if (addressString == null) {
917         resolved = true;
918       } else {
919         try {
920           addresses = javax.mail.internet.InternetAddress.parse(addressString, false);
921           resolved = true;
922         } catch (MessagingException me) {
923           showError(Pooka.getProperty("error.bounceMessage.addresses", "Error parsing address entry."), me);
924         }
925       }
926     }
927
928     if (addresses != null) {
929       bounceMessage(addresses, false);
930     }
931   }
932
933   /**
934    * Bounces the message. Passes on the actual work of bouncing the
935    * message to the underlying MessageInfo, but handles the job of
936    * showing any errors, if they happen.
937    */

938   public void bounceMessage(Address[] addresses, boolean deleteOnSuccess) {
939     bounceMessage(addresses, deleteOnSuccess, true);
940   }
941
942   /**
943    * Bounces the message. Passes on the actual work of bouncing the
944    * message to the underlying MessageInfo, but handles the job of
945    * showing any errors, if they happen.
946    */

947   public void bounceMessage(Address[] addresses, boolean deleteOnSuccess, boolean expunge) {
948     final Address[] final_addresses = addresses;
949     final boolean final_delete = deleteOnSuccess;
950     final boolean final_expunge = expunge;
951
952     ActionThread folderThread = getMessageInfo().getFolderInfo().getFolderThread();
953     folderThread.addToQueue(new javax.swing.AbstractAction JavaDoc() {
954         public void actionPerformed(java.awt.event.ActionEvent JavaDoc ae) {
955           try {
956             getMessageInfo().bounceMessage(final_addresses);
957             if (final_delete)
958               deleteMessage(final_expunge);
959
960           } catch (javax.mail.MessagingException JavaDoc me) {
961             final MessagingException final_me = me;
962             SwingUtilities.invokeLater(new Runnable JavaDoc() {
963                 public void run() {
964                   showError(Pooka.getProperty("error.bounceMessage.error", "Error bouncing Message"), final_me);
965                 }
966               });
967           }
968         }
969       }, new java.awt.event.ActionEvent JavaDoc(this, 0, "message-bounce"));
970   }
971
972   /**
973    * Deletes the Message from the current Folder. If a Trash folder is
974    * set, this method moves the message into the Trash folder. If no
975    * Trash folder is set, this marks the message as deleted. In addition,
976    * if the autoExpunge variable is set to true, it also expunges
977    * the message from the mailbox.
978    */

979   public void deleteMessage(boolean autoExpunge) {
980     // should always be done on FolderThread, not on UI thread.
981
try {
982       setDeleteInProgress(true);
983       getMessageInfo().deleteMessage(autoExpunge);
984       this.close();
985     } catch (MessagingException me) {
986       if (me instanceof NoTrashFolderException) {
987         final boolean finalAutoExpunge = autoExpunge;
988         try {
989           SwingUtilities.invokeAndWait(new Runnable JavaDoc() {
990               public void run() {
991                 try {
992                   if (getMessageUI().showConfirmDialog(Pooka.getProperty("error.Messsage.DeleteNoTrashFolder", "The Trash Folder configured is not available.\nDelete messages anyway?"), Pooka.getProperty("error.Messsage.DeleteNoTrashFolder.title", "Trash Folder Unavailable"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) {
993                     getMessageInfo().remove(finalAutoExpunge);
994                     close();
995                   }
996                 } catch (MessagingException mex) {
997                   showError(Pooka.getProperty("error.Message.DeleteErrorMessage", "Error: could not delete message.") +"\n", mex);
998                 }
999               }
1000            });
1001        } catch (Exception JavaDoc e) {
1002        }
1003      } else {
1004        final Exception JavaDoc mEx = me;
1005        SwingUtilities.invokeLater(new Runnable JavaDoc() {
1006            public void run() {
1007              showError(Pooka.getProperty("error.Message.DeleteErrorMessage", "Error: could not delete message.") +"\n", mEx);
1008            }
1009          });
1010      }
1011    }
1012  }
1013
1014  /**
1015   * Opens up a dialog to save the message to a file.
1016   */

1017  public void saveMessageToFile() {
1018    JFileChooser saveChooser;
1019    String JavaDoc currentDirectoryPath = Pooka.getProperty("Pooka.tmp.currentDirectory", "");
1020    if (currentDirectoryPath == "")
1021      saveChooser = new JFileChooser();
1022    else
1023      saveChooser = new JFileChooser(currentDirectoryPath);
1024
1025    int saveConfirm = saveChooser.showSaveDialog(Pooka.getMainPanel().getContentPanel().getUIComponent());
1026    Pooka.getResources().setProperty("Pooka.tmp.currentDirectory", saveChooser.getCurrentDirectory().getPath(), true);
1027
1028    if (saveConfirm == JFileChooser.APPROVE_OPTION)
1029      try {
1030        getMessageInfo().saveMessageAs(saveChooser.getSelectedFile());
1031      } catch (MessagingException exc) {
1032        if (getMessageUI() != null)
1033          getMessageUI().showError(Pooka.getProperty("error.SaveFile", "Error saving file") + ":\n", Pooka.getProperty("error.SaveFile", "Error saving file"), exc);
1034        else
1035          Pooka.getUIFactory().showError(Pooka.getProperty("error.SaveFile", "Error saving file") + ":\n", Pooka.getProperty("error.SaveFile", "Error saving file"), exc);
1036      }
1037  }
1038
1039  public void showError(String JavaDoc message, Exception JavaDoc ex) {
1040    if (getMessageUI() != null)
1041      getMessageUI().showError(message, ex);
1042    else
1043      Pooka.getUIFactory().showError(message, ex);
1044  }
1045
1046  /**
1047   * Closes this MessageProxy.
1048   *
1049   * For this implementation, the only result is that the MessageUI,
1050   * if any, is closed.
1051   */

1052  public void close() {
1053    Runnable JavaDoc runMe = new Runnable JavaDoc() {
1054        public void run() {
1055          if (getMessageUI() != null)
1056            getMessageUI().closeMessageUI();
1057        }
1058      };
1059    if (SwingUtilities.isEventDispatchThread())
1060      runMe.run();
1061    else
1062      SwingUtilities.invokeLater(runMe);
1063  }
1064
1065  /**
1066   * A convenience method which sets autoExpunge by the value of
1067   * Pooka.autoExpunge, and then calls deleteMessage(boolean autoExpunge)
1068   * with that value.
1069   */

1070  public void deleteMessage() {
1071    deleteMessage(Pooka.getProperty("Pooka.autoExpunge", "true").equals("true"));
1072  }
1073
1074  /**
1075   * This puts the reply prefix 'prefix' in front of each line in the
1076   * body of the Message.
1077   */

1078  public String JavaDoc prefixMessage(String JavaDoc originalMessage, String JavaDoc prefix, String JavaDoc intro) {
1079    StringBuffer JavaDoc newValue = new StringBuffer JavaDoc(originalMessage);
1080
1081    int currentCR = originalMessage.lastIndexOf('\n', originalMessage.length());
1082    while (currentCR != -1) {
1083      newValue.insert(currentCR+1, prefix);
1084      currentCR=originalMessage.lastIndexOf('\n', currentCR-1);
1085    }
1086    newValue.insert(0, prefix);
1087    newValue.insert(0, intro);
1088
1089    return newValue.toString();
1090  }
1091
1092  /**
1093   * This sends the message to the printer, first creating an appropriate
1094   * print dialog, etc.
1095   */

1096  public void printMessage(Object JavaDoc source) {
1097    // starts on FolderThread.
1098

1099    // Load up the message into the MessagePrinter, just to be safe.
1100

1101    try {
1102      MessagePrinter mp = new MessagePrinter(getMessageInfo());
1103      mp.loadText();
1104
1105      // now switch over to the AWTEventThread.
1106

1107      final MessagePrinter messagePrinter = mp;
1108
1109      final Object JavaDoc final_source = source;
1110
1111      SwingUtilities.invokeLater(new Runnable JavaDoc() {
1112          public void run() {
1113
1114            // Set the document type
1115
final DocFlavor messageFormat = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
1116
1117            // bring up a dialog.
1118
PrintService[] services = PrintServiceLookup.lookupPrintServices(messageFormat, null);
1119
1120            PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
1121            PrintService service = ServiceUI.printDialog(null, 50, 50,
1122                                                          services,
1123                                                          PrintServiceLookup.lookupDefaultPrintService(),
1124                                                          messageFormat,
1125                                                          attributes);
1126
1127            if (service != null) {
1128              final PrintRequestAttributeSet final_attributes = attributes;
1129
1130              final Doc myDoc = new SimpleDoc(messagePrinter, messageFormat, null);
1131
1132              final DocPrintJob final_job = service.createPrintJob();
1133
1134              final MessagePrinterDisplay mpd = new MessagePrinterDisplay(messagePrinter, final_job, final_source);
1135
1136              final_job.addPrintJobListener(mpd);
1137
1138              mpd.show();
1139
1140              Runnable JavaDoc runMe = new Runnable JavaDoc() {
1141                  public void run() {
1142                    try {
1143                      final_job.print(myDoc, final_attributes);
1144                    } catch (PrintException pe) {
1145                      if (mpd.getStatus() != MessagePrinterDisplay.CANCELED)
1146                        mpd.showError("Failed to print", pe);
1147                    }
1148                  }
1149                };
1150
1151              Thread JavaDoc messagePrintThread = new Thread JavaDoc(runMe);
1152              messagePrintThread.start();
1153            }
1154          }
1155        });
1156    } catch (MessagingException e) {
1157      showError("error printing", e);
1158    }
1159  }
1160
1161  /**
1162   * This creates and shows a PopupMenu for this component.
1163   */

1164  public void showPopupMenu(JComponent component, MouseEvent e) {
1165    ConfigurablePopupMenu popupMenu = new ConfigurablePopupMenu();
1166    FolderInfo fi = getMessageInfo().getFolderInfo();
1167    if ( fi != null ) {
1168      if (fi.isOutboxFolder()) {
1169        popupMenu.configureComponent("NewMessageProxy.popupMenu", Pooka.getResources());
1170      } else if (fi instanceof net.suberic.pooka.cache.CachingFolderInfo && ! ((net.suberic.pooka.cache.CachingFolderInfo) fi).getCacheHeadersOnly()) {
1171        popupMenu.configureComponent("MessageProxy.cachingPopupMenu", Pooka.getResources());
1172      } else {
1173        popupMenu.configureComponent("MessageProxy.popupMenu", Pooka.getResources());
1174      }
1175    } else {
1176      popupMenu.configureComponent("MessageProxy.popupMenu", Pooka.getResources());
1177    }
1178    popupMenu.setActive(getActions());
1179    popupMenu.show(component, e.getX(), e.getY());
1180
1181  }
1182
1183  /**
1184   * This creates and shows a PopupMenu for this component.
1185   */

1186  public void showAttachmentPopupMenu(JComponent component, MouseEvent e) {
1187    AttachmentPopupMenu atMenu = null;
1188    if (e.isShiftDown()) {
1189      atMenu = new AttachmentPopupMenu(this, AttachmentPopupMenu.SAVE);
1190    } else if (e.isControlDown()) {
1191      atMenu = new AttachmentPopupMenu(this, AttachmentPopupMenu.OPEN_WITH);
1192    } else {
1193      atMenu = new AttachmentPopupMenu(this, AttachmentPopupMenu.OPEN);
1194    }
1195
1196    try {
1197      atMenu.loadAttachments(new java.awt.event.ActionEvent JavaDoc(e, 0, "show-attachments"));
1198      atMenu.show(component, e.getX(), e.getY());
1199    } catch (MessagingException me) {
1200      showError(me.getMessage(), me);
1201    }
1202
1203  }
1204
1205  /**
1206   * As specified by interface net.suberic.pooka.UserProfileContainer.
1207   *
1208   * If the MessageProxy's getMessageInfo().getFolderInfo() is set, this returns the
1209   * DefaultProfile of that getMessageInfo().getFolderInfo(). If the getMessageInfo().getFolderInfo() isn't set
1210   * (should that happen?), this returns null.
1211   */

1212  public UserProfile getDefaultProfile() {
1213    return getMessageInfo().getDefaultProfile();
1214  }
1215
1216  /**
1217   * This returns the tableInfo for this MessageProxy.
1218   */

1219  public synchronized HashMap JavaDoc getTableInfo() throws MessagingException {
1220    if (isLoaded()) {
1221      return tableInfo;
1222    } else {
1223      loadTableInfo();
1224      return tableInfo;
1225    }
1226  }
1227
1228  public FolderInfo getFolderInfo() {
1229    return getMessageInfo().getFolderInfo();
1230  }
1231
1232  public void setTableInfo(HashMap JavaDoc newValue) {
1233    tableInfo=newValue;
1234  }
1235
1236  boolean mDeleted = false;
1237  /**
1238   * A shortcut for getting the deleted status of this message. This
1239   * method is safe to use on the AWTEventThread.
1240   */

1241  public boolean isDeleted() throws MessagingException {
1242    // if there's a delete in progress, return true.
1243
if (isDeleteInProgress())
1244      return true;
1245
1246    // if we're on the appropriate thread, go ahead and check the flags.
1247
if (Thread.currentThread() == getMessageInfo().getFolderInfo().getFolderThread() || Thread.currentThread() instanceof net.suberic.pooka.thread.LoadMessageThread) {
1248      mDeleted= getMessageInfo().getFlags().contains(Flags.Flag.DELETED);
1249    }
1250
1251    return mDeleted;
1252  }
1253
1254  boolean mSeen = false;
1255  /**
1256   * A shortcut for getting the read/unread status of this message. This
1257   * method is safe to use on the AWTEventThread.
1258   */

1259  public boolean isSeen() {
1260    // if we're on the appropriate thread, go ahead and check the flags.
1261
if (Thread.currentThread() == getMessageInfo().getFolderInfo().getFolderThread() || Thread.currentThread() instanceof net.suberic.pooka.thread.LoadMessageThread) {
1262      mSeen = getMessageInfo().isSeen();
1263    }
1264
1265    return mSeen;
1266  }
1267
1268  /**
1269   * Sets the current seen value. Note that this is not safe to use
1270   * on any thread; it should only be used on the propery Folder/Store Thread.
1271   */

1272  public void setSeen(boolean newValue) {
1273    if (newValue != getMessageInfo().isSeen()) {
1274      try {
1275        getMessageInfo().setSeen(newValue);
1276      } catch (MessagingException me) {
1277        showError( Pooka.getProperty("error.MessageUI.setSeenFailed", "Failed to set Seen flag to ") + newValue + "\n", me);
1278      }
1279    }
1280  }
1281
1282  public boolean isLoaded() {
1283    return loaded;
1284  }
1285
1286  /**
1287   * Returns whether or not this MessageProxy should refresh its display
1288   * information.
1289   */

1290  public boolean needsRefresh() {
1291    return refresh;
1292  }
1293
1294  /**
1295   * Notifies this MessageProxy whether or not this MessageProxy needs to
1296   * refresh its display information.
1297   */

1298  public void setRefresh(boolean newValue) {
1299    refresh = newValue;
1300  }
1301
1302  /**
1303   * This sets the loaded value for the MessageProxy to false. This
1304   * should be called only if the TableInfo of the Message has been
1305   * changed and needs to be reloaded.
1306   *
1307   * Note that this also sets the filtersMatched property to false.
1308   */

1309  public synchronized void unloadTableInfo() {
1310    loaded=false;
1311    filtersMatched=false;
1312  }
1313
1314  /**
1315   * This flags the message that we should check again to see which
1316   * filters it matches.
1317   */

1318  public void clearMatchedFilters() {
1319    filtersMatched = false;
1320  }
1321
1322  /**
1323   * Shows whether or not we need to rematch the filters.
1324   */

1325  public boolean matchedFilters() {
1326    return filtersMatched;
1327  }
1328
1329  public MessageUI getMessageUI() {
1330    return msgWindow;
1331  }
1332
1333  public void setMessageUI(MessageUI newValue) {
1334    msgWindow = newValue;
1335    if (newValue == null) {
1336      setHeaderMode(HEADERS_DEFAULT);
1337
1338      setDisplayMode(getDefaultDisplayMode());
1339    }
1340  }
1341
1342  public MessageInfo getMessageInfo() {
1343    return messageInfo;
1344  }
1345
1346  /**
1347   * Returns the current displayMode. Valid values are the following
1348   * constants:
1349   * RFC_822, TEXT_ONLY, TEXT_PREFERRED, HTML_PREFERRED, HTML_ONLY
1350   */

1351  public int getDisplayMode() {
1352    return displayMode;
1353  }
1354  /**
1355   * Sets the displayMode. Note that you will still need to calls something
1356   * like ReadMessageDisplayPanel.resetEditorText() in order to have the
1357   * change take effect.
1358   */

1359  public void setDisplayMode(int newDisplayMode) {
1360    displayMode = newDisplayMode;
1361  }
1362
1363  /**
1364   * Returns the default display mode.
1365   */

1366  public static int getDefaultDisplayMode() {
1367    if (Pooka.getProperty("Pooka.displayHtmlAsDefault", "false").equalsIgnoreCase("true"))
1368      return HTML_PREFERRED;
1369    else
1370      return TEXT_PREFERRED;
1371  }
1372
1373  /**
1374   * Returns the current headerMode. Valid values are the following
1375   * constants:
1376   * HEADERS_DEFAULT, HEADERS_FULL, and RFC822_STYLE.
1377   */

1378  public int getHeaderMode() {
1379    return headerMode;
1380  }
1381  /**
1382   * Sets the headerMode. Note that you will still need to calls something
1383   * like ReadMessageDisplayPanel.resetEditorText() in order to have the
1384   * change take effect.
1385   */

1386  public void setHeaderMode(int newHeaderMode) {
1387    headerMode = newHeaderMode;
1388  }
1389
1390  public FolderDisplayUI getFolderDisplayUI() {
1391    FolderInfo fi = getMessageInfo().getFolderInfo();
1392    if (fi != null)
1393      return fi.getFolderDisplayUI();
1394    else
1395      return null;
1396
1397  }
1398
1399  /**
1400   * Returns the matching filters for this MessageProxy.
1401   */

1402  public MessageFilter[] getMatchingFilters() {
1403    if (filtersMatched) {
1404      return matchingFilters;
1405    }
1406    else {
1407      if (isLoaded()) {
1408        matchFilters();
1409        return matchingFilters;
1410      } else {
1411        return new MessageFilter[0];
1412      }
1413    }
1414  }
1415
1416  // handles cut and paste behaviour
1417

1418  int mActionType = TransferHandler.COPY;
1419  boolean mImportDone = false;
1420  boolean mCutDisallowed = false;
1421  boolean mDeleteInProgress = false;
1422
1423  /**
1424   * Sets the deleteInProgress flag.
1425   */

1426  public void setDeleteInProgress(boolean newValue) {
1427    boolean orig = mDeleteInProgress;
1428    mDeleteInProgress = newValue;
1429    if (orig != mDeleteInProgress) {
1430      setRefresh(true);
1431      try {
1432        refreshMessage();
1433      } catch ( MessagingException me ) {
1434        me.printStackTrace();
1435      }
1436    }
1437  }
1438
1439  /**
1440   * Returns true if this message is slated for removal, but hasn't actually
1441   * been removed yet.
1442   */

1443  public boolean isDeleteInProgress() {
1444    return mDeleteInProgress;
1445  }
1446
1447  /**
1448   * Sets move or copy value.
1449   */

1450  public void setActionType(int pActionType) {
1451    mActionType = pActionType;
1452  }
1453
1454  /**
1455   * Gets the action type for this Transferable.
1456   */

1457  public int getActionType() {
1458    return mActionType;
1459  }
1460
1461  /**
1462   * Returns whether or not the import is done.
1463   */

1464  public boolean getImportDone() {
1465    return mImportDone;
1466  }
1467
1468  /**
1469   * Sets whether or not the import is done.
1470   */

1471  public void setImportDone(boolean pImportDone) {
1472    mImportDone = pImportDone;
1473  }
1474
1475  /**
1476   * Sets whether or not the paste operation vetoes a cut, changing the
1477   * action to a copy.
1478   */

1479  public void setCutDisallowed(boolean pCutDisallowed) {
1480    mCutDisallowed = pCutDisallowed;
1481  }
1482
1483  /**
1484   * Returns whether or not the paste operation vetoed a cut, changing the
1485   * action to a copy.
1486   */

1487  public boolean getCutDisallowed() {
1488    return mCutDisallowed;
1489  }
1490
1491  /**
1492   * Removes this message if the cut/past/move is complete.
1493   */

1494  public boolean removeMessageOnCompletion() {
1495    if (mImportDone && mActionType == javax.swing.TransferHandler.MOVE) {
1496      if ( !mCutDisallowed) {
1497        deleteMessage();
1498        return true;
1499      } else {
1500        // if cut has been disallowed and the import has completed, then
1501
// reset things.
1502
setActionType(TransferHandler.COPY);
1503        setCutDisallowed(false);
1504        setDeleteInProgress(false);
1505      }
1506    }
1507
1508    return false;
1509  }
1510
1511  /**
1512   * indicates that this has been removed from the clipboard.
1513   */

1514  public void lostOwnership(java.awt.datatransfer.Clipboard JavaDoc clipboard,
1515                            java.awt.datatransfer.Transferable JavaDoc contents) {
1516    // reset everything
1517
setActionType(TransferHandler.COPY);
1518    setCutDisallowed(false);
1519    setDeleteInProgress(false);
1520  }
1521
1522  // end cut and paste behaviour code.
1523

1524  public Action getAction(String JavaDoc name) {
1525    if (defaultActions == null) {
1526      getActions();
1527    }
1528    return (Action)commands.get(name);
1529  }
1530
1531  public Action[] getActions() {
1532    if (defaultActions == null) {
1533      ActionThread folderThread = messageInfo.getFolderInfo().getFolderThread();
1534
1535      defaultActions = new Action[] {
1536        new ActionWrapper(new OpenAction(), folderThread),
1537        new ActionWrapper(new OpenDefaultDisplayAction(), folderThread),
1538        new ActionWrapper(new OpenFullDisplayAction(), folderThread),
1539        new ActionWrapper(new OpenRawDisplayAction(), folderThread),
1540        new ActionWrapper(new OpenTextDisplayAction(), folderThread),
1541        new ActionWrapper(new OpenHtmlDisplayAction(), folderThread),
1542        new ActionWrapper(new DefaultOpenAction(), folderThread),
1543        new ActionWrapper(new MoveAction(), folderThread),
1544        new ActionWrapper(new CopyAction(), folderThread),
1545        new ActionWrapper(new ReplyAction(), folderThread),
1546        new ActionWrapper(new ReplyAllAction(), folderThread),
1547        new ActionWrapper(new ReplyWithAttachmentsAction(), folderThread),
1548        new ActionWrapper(new ReplyAllWithAttachmentsAction(), folderThread),
1549        new ActionWrapper(new ForwardAction(), folderThread),
1550        new ActionWrapper(new ForwardWithAttachmentsAction(), folderThread),
1551        new ActionWrapper(new ForwardAsInlineAction(), folderThread),
1552        new ActionWrapper(new ForwardAsAttachmentAction(), folderThread),
1553        new ActionWrapper(new ForwardQuotedAction(), folderThread),
1554        new BounceAction(),
1555        new DeleteAction(),
1556        new ActionWrapper(new PrintAction(), folderThread),
1557        new ActionWrapper(new SaveMessageAction(), folderThread),
1558        new ActionWrapper(new CacheMessageAction(), folderThread),
1559        new ActionWrapper(new SaveAddressAction(), folderThread),
1560        new ActionWrapper(new OpenAsNewAction(), folderThread),
1561        new ActionWrapper(new OpenCopyAction(), folderThread),
1562        new ActionWrapper(new MessageFilterAction(), folderThread),
1563        new ActionWrapper(new SpamAction(), folderThread),
1564        new ActionWrapper(new DecryptAction(), folderThread),
1565        new ActionWrapper(new CheckSignatureAction(), folderThread),
1566        new ActionWrapper(new ImportKeysAction(), folderThread),
1567        new ActionWrapper(new SignatureStatusAction(), folderThread),
1568        new ActionWrapper(new EncryptionStatusAction(), folderThread)
1569      };
1570
1571      commands = new Hashtable JavaDoc();
1572
1573      for (int i = 0; i < defaultActions.length; i++) {
1574        Action a = defaultActions[i];
1575        commands.put(a.getValue(Action.NAME), a);
1576      }
1577
1578    }
1579    return defaultActions;
1580  }
1581
1582  public class OpenAction extends AbstractAction {
1583    protected int displayModeValue = 999;
1584    protected int headerModeValue = 999;
1585
1586    public int getDisplayModeValue() {
1587      return displayModeValue;
1588    }
1589    public int getHeaderModeValue() {
1590      return headerModeValue;
1591    }
1592    protected String JavaDoc cmd = "";
1593    public String JavaDoc getCommand() {
1594      // i should probably actually get this using getValue()...
1595
return cmd;
1596    }
1597    public MessageProxy getMessageProxy() {
1598      return MessageProxy.this;
1599    }
1600    OpenAction() {
1601      super("file-open");
1602      cmd = "file-open";
1603    }
1604
1605    OpenAction(String JavaDoc id) {
1606      super(id);
1607      cmd = id;
1608    }
1609
1610    public void actionPerformed(java.awt.event.ActionEvent JavaDoc e) {
1611
1612      FolderDisplayUI fw = getFolderDisplayUI();
1613      if (fw != null)
1614        fw.setBusy(true);
1615
1616      int newDisplayMode;
1617      if (displayModeValue != 999)
1618        newDisplayMode = displayModeValue;
1619      else
1620        newDisplayMode = getDisplayMode();
1621
1622      int newHeaderMode;
1623      if (headerModeValue != 999)
1624        newHeaderMode = headerModeValue;
1625      else
1626        newHeaderMode = getHeaderMode();
1627
1628      openWindow(newDisplayMode, newHeaderMode);
1629
1630      if (fw != null)
1631        fw.setBusy(false);
1632    }
1633  }
1634
1635  public class OpenDefaultDisplayAction extends OpenAction {
1636
1637    OpenDefaultDisplayAction() {
1638      super("file-open-defaultdisplay");
1639      headerModeValue = HEADERS_DEFAULT;
1640    }
1641  }
1642
1643  public class OpenFullDisplayAction extends OpenAction {
1644
1645    OpenFullDisplayAction() {
1646      super("file-open-fulldisplay");
1647      headerModeValue = HEADERS_FULL;
1648    }
1649  }
1650
1651  public class OpenRawDisplayAction extends OpenAction {
1652    OpenRawDisplayAction() {
1653      super("file-open-rawdisplay");
1654      displayModeValue = RFC_822;
1655    }
1656  }
1657
1658  public class OpenTextDisplayAction extends OpenAction {
1659    OpenTextDisplayAction() {
1660      super("file-open-textdisplay");
1661      displayModeValue = TEXT_ONLY;
1662    }
1663  }
1664
1665  public class OpenHtmlDisplayAction extends OpenAction {
1666    OpenHtmlDisplayAction() {
1667      super("file-open-htmldisplay");
1668      displayModeValue = HTML_ONLY;
1669    }
1670  }
1671
1672  public class DefaultOpenAction extends AbstractAction {
1673    DefaultOpenAction() {
1674      super("file-default-open");
1675    }
1676
1677    public void actionPerformed(java.awt.event.ActionEvent JavaDoc e) {
1678
1679      FolderDisplayUI fw = getFolderDisplayUI();
1680      if (fw != null)
1681        fw.setBusy(true);;
1682
1683      Pooka.getUIFactory().doDefaultOpen(MessageProxy.this);
1684      if (fw != null)
1685        fw.setBusy(false);
1686    }
1687  }
1688
1689  public class MoveAction extends net.suberic.util.DynamicAbstractAction {
1690    MoveAction() {
1691      super("message-move");
1692    }
1693
1694    public void actionPerformed(java.awt.event.ActionEvent JavaDoc e) {
1695      if (getMessageUI() != null)
1696        getMessageUI().setBusy(true);
1697      FolderDisplayUI fw = getFolderDisplayUI();
1698      if (fw != null)
1699        fw.setBusy(true);;
1700      moveMessage((FolderInfo)getValue("target"));
1701      if (fw != null)
1702        fw.setBusy(false);
1703      if (getMessageUI() != null)
1704        getMessageUI().setBusy(false);;
1705    }
1706
1707  }
1708
1709  public class CopyAction extends net.suberic.util.DynamicAbstractAction {
1710    CopyAction() {
1711      super("message-copy");
1712    }
1713
1714    public void actionPerformed(java.awt.event.ActionEvent JavaDoc e) {
1715      if (getMessageUI() != null)
1716        getMessageUI().setBusy(true);
1717      FolderDisplayUI fw = getFolderDisplayUI();
1718      if (fw != null)
1719        fw.setBusy(true);;
1720      copyMessage((FolderInfo)getValue("target"));
1721      if (fw != null)
1722        fw.setBusy(false);
1723      if (getMessageUI() != null)
1724        getMessageUI().setBusy(false);;
1725    }
1726
1727  }
1728
1729
1730  public class ReplyAction extends AbstractAction {
1731
1732    ReplyAction() {
1733      super("message-reply");
1734    }
1735
1736    public void actionPerformed(ActionEvent e) {
1737      replyToMessage(false, false);
1738    }
1739  }
1740
1741  public class ReplyWithAttachmentsAction extends AbstractAction {
1742
1743    ReplyWithAttachmentsAction() {
1744      super("message-reply-with-attachments");
1745    }
1746
1747    public void actionPerformed(ActionEvent e) {
1748      replyToMessage(false, true);
1749    }
1750  }
1751
1752  public class ReplyAllAction extends AbstractAction {
1753
1754    ReplyAllAction() {
1755      super("message-reply-all");
1756    }
1757
1758    public void actionPerformed(ActionEvent e) {
1759      replyToMessage(true, false);
1760    }
1761  }
1762
1763  public class ReplyAllWithAttachmentsAction extends AbstractAction {
1764
1765    ReplyAllWithAttachmentsAction() {
1766      super("message-reply-all-with-attachments");
1767    }
1768
1769    public void actionPerformed(ActionEvent e) {
1770      replyToMessage(true, true);
1771    }
1772  }
1773
1774  public class ForwardAction extends AbstractAction {
1775
1776    ForwardAction() {
1777      super("message-forward");
1778    }
1779
1780    public void actionPerformed(ActionEvent e) {
1781      forwardMessage(false);
1782    }
1783  }
1784
1785  public class ForwardWithAttachmentsAction extends AbstractAction {
1786
1787    ForwardWithAttachmentsAction() {
1788      super("message-forward-with-attachments");
1789    }
1790
1791    public void actionPerformed(ActionEvent e) {
1792      forwardMessage(true);
1793    }
1794  }
1795
1796  public class ForwardAsInlineAction extends AbstractAction {
1797
1798    ForwardAsInlineAction() {
1799      super("message-forward-as-inline");
1800    }
1801
1802    public void actionPerformed(ActionEvent e) {
1803      forwardMessage(false, MessageInfo.FORWARD_AS_INLINE);
1804    }
1805  }
1806
1807  public class ForwardAsAttachmentAction extends AbstractAction {
1808
1809    ForwardAsAttachmentAction() {
1810      super("message-forward-as-attachment");
1811    }
1812
1813    public void actionPerformed(ActionEvent e) {
1814      forwardMessage(false, MessageInfo.FORWARD_AS_ATTACHMENT);
1815    }
1816  }
1817
1818  public class ForwardQuotedAction extends AbstractAction {
1819
1820    ForwardQuotedAction() {
1821      super("message-forward-quoted");
1822    }
1823
1824    public void actionPerformed(ActionEvent e) {
1825      forwardMessage(false, MessageInfo.FORWARD_QUOTED);
1826    }
1827  }
1828
1829
1830  public class BounceAction extends AbstractAction {
1831
1832    BounceAction() {
1833      super("message-bounce");
1834    }
1835
1836    public void actionPerformed(ActionEvent e) {
1837      if (getMessageUI() != null)
1838        getMessageUI().setBusy(true);
1839
1840      bounceMessage();
1841
1842      if (getMessageUI() != null)
1843        getMessageUI().setBusy(false);
1844    }
1845  }
1846
1847  public class DeleteAction extends AbstractAction {
1848    DeleteAction() {
1849      super("message-delete");
1850    }
1851
1852    public void actionPerformed(ActionEvent e) {
1853      // should happen on UI thread.
1854
ActionThread folderThread = messageInfo.getFolderInfo().getFolderThread();
1855
1856      if (getMessageUI() != null)
1857        getMessageUI().setBusy(true);
1858      FolderDisplayUI fw = getFolderDisplayUI();
1859      if (fw != null)
1860        fw.setBusy(true);
1861
1862      if (fw != null && Pooka.getProperty("Pooka.fastDelete", "false").equalsIgnoreCase("true")) {
1863        List JavaDoc v = new ArrayList JavaDoc();
1864        v.add(MessageProxy.this);
1865        FolderDisplayPanel fdp = null;
1866        if (fw instanceof FolderInternalFrame) {
1867          fdp = ((FolderInternalFrame) fw).getFolderDisplay();
1868        } else if (fw instanceof PreviewFolderPanel) {
1869          fdp = ((PreviewFolderPanel) fw).getFolderDisplay();
1870        }
1871        if (fdp != null)
1872          fdp.moveSelectionOnRemoval(v);
1873      }
1874
1875
1876      folderThread.addToQueue(new javax.swing.AbstractAction JavaDoc() {
1877          public void actionPerformed(java.awt.event.ActionEvent JavaDoc ae) {
1878            try {
1879              deleteMessage();
1880            } finally {
1881
1882              FolderDisplayUI fw = getFolderDisplayUI();
1883              if (fw != null)
1884                fw.setBusy(false);
1885            }
1886          }
1887        }, new java.awt.event.ActionEvent JavaDoc(this, 0, "message-bounce"));
1888    }
1889  }
1890
1891
1892  public class PrintAction extends AbstractAction {
1893    PrintAction() {
1894      super("file-print");
1895    }
1896
1897    public void actionPerformed(ActionEvent e) {
1898      if (getMessageUI() != null)
1899        getMessageUI().setBusy(true);
1900      FolderDisplayUI fw = getFolderDisplayUI();
1901      if (fw != null)
1902        fw.setBusy(true);;
1903
1904      printMessage(e.getSource());
1905
1906      if (fw != null)
1907        fw.setBusy(false);
1908      if (getMessageUI() != null)
1909        getMessageUI().setBusy(false);
1910    }
1911  }
1912
1913  public class SaveMessageAction extends AbstractAction {
1914    SaveMessageAction() {
1915      super("file-save-as");
1916    }
1917
1918    public void actionPerformed(ActionEvent e) {
1919      if (getMessageUI() != null)
1920        getMessageUI().setBusy(true);
1921      FolderDisplayUI fw = getFolderDisplayUI();
1922      if (fw != null)
1923        fw.setBusy(true);;
1924      saveMessageToFile();
1925
1926      if (fw != null)
1927        fw.setBusy(false);
1928      if (getMessageUI() != null)
1929        getMessageUI().setBusy(false);
1930    }
1931  }
1932
1933  public class CacheMessageAction extends AbstractAction {
1934    CacheMessageAction() {
1935      super("message-cache");
1936    }
1937
1938    public void actionPerformed(ActionEvent e) {
1939      if (getMessageUI() != null)
1940        getMessageUI().setBusy(true);
1941      FolderDisplayUI fw = getFolderDisplayUI();
1942      if (fw != null)
1943        fw.setBusy(true);;
1944
1945      try {
1946        getMessageInfo().cacheMessage();
1947      } catch (MessagingException me) {
1948        showError(Pooka.getProperty("Pooka.cache.errorCachingMessage", "Error caching message"), me);
1949      }
1950
1951      if (fw != null)
1952        fw.setBusy(false);
1953      if (getMessageUI() != null)
1954        getMessageUI().setBusy(false);
1955    }
1956  }
1957
1958  public class SaveAddressAction extends AbstractAction {
1959    SaveAddressAction() {
1960      super("message-save-address");
1961    }
1962
1963    public void actionPerformed(ActionEvent e) {
1964      if (getMessageUI() != null)
1965        getMessageUI().setBusy(true);
1966      FolderDisplayUI fw = getFolderDisplayUI();
1967      if (fw != null)
1968        fw.setBusy(true);;
1969
1970      try {
1971        UserProfile defaultProfile = getDefaultProfile();
1972        AddressBook book = null;
1973
1974        if (defaultProfile != null) {
1975          book = defaultProfile.getAddressBook();
1976        }
1977
1978        if (book == null) {
1979          // get the default Address Book.
1980
book = Pooka.getAddressBookManager().getDefault();
1981        }
1982        if (book != null)
1983          getMessageInfo().addAddress(book, true);
1984        else {
1985          SwingUtilities.invokeLater(new Runnable JavaDoc() {
1986              public void run() {
1987                getMessageUI().showError(Pooka.getProperty("error.noAddressBook", "No Address Book set as default."));
1988              }
1989            });
1990        }
1991      } catch (MessagingException me) {
1992        showError(Pooka.getProperty("error.savingAddress", "Error saving Address"), me);
1993      }
1994
1995      if (fw != null)
1996        fw.setBusy(false);
1997      if (getMessageUI() != null)
1998        getMessageUI().setBusy(false);
1999    }
2000  }
2001
2002
2003  public class OpenAsNewAction extends AbstractAction {
2004    OpenAsNewAction() {
2005      super("message-open-as-new");
2006    }
2007
2008    public void actionPerformed(ActionEvent e) {
2009      if (getMessageUI() != null)
2010        getMessageUI().setBusy(true);
2011      FolderDisplayUI fw = getFolderDisplayUI();
2012      if (fw != null)
2013        fw.setBusy(true);;
2014
2015      openWindowAsNew(true);
2016
2017      if (fw != null)
2018        fw.setBusy(false);
2019      if (getMessageUI() != null)
2020        getMessageUI().setBusy(false);
2021    }
2022  }
2023
2024  public class OpenCopyAction extends AbstractAction {
2025    OpenCopyAction() {
2026      super("message-open-copy");
2027    }
2028
2029    public void actionPerformed(ActionEvent e) {
2030      if (getMessageUI() != null)
2031        getMessageUI().setBusy(true);
2032      FolderDisplayUI fw = getFolderDisplayUI();
2033      if (fw != null)
2034        fw.setBusy(true);;
2035
2036      openWindowAsNew(false);
2037
2038      if (fw != null)
2039        fw.setBusy(false);
2040      if (getMessageUI() != null)
2041        getMessageUI().setBusy(false);
2042    }
2043  }
2044
2045  public class MessageFilterAction extends AbstractAction {
2046    MessageFilterAction() {
2047      super("message-filter");
2048    }
2049
2050    public void actionPerformed(ActionEvent e) {
2051      if (getMessageUI() != null)
2052        getMessageUI().setBusy(true);
2053      FolderDisplayUI fw = getFolderDisplayUI();
2054      if (fw != null)
2055        fw.setBusy(true);;
2056
2057      runBackendFilters();
2058
2059      if (fw != null)
2060        fw.setBusy(false);
2061      if (getMessageUI() != null)
2062        getMessageUI().setBusy(false);
2063    }
2064  }
2065
2066  public class SpamAction extends AbstractAction {
2067    SpamAction() {
2068      super("message-spam");
2069    }
2070
2071    public void actionPerformed(ActionEvent e) {
2072      if (getMessageUI() != null)
2073        getMessageUI().setBusy(true);
2074      FolderDisplayUI fw = getFolderDisplayUI();
2075      if (fw != null)
2076        fw.setBusy(true);;
2077
2078      MessageInfo info = getMessageInfo();
2079      if (info != null) {
2080        info.runSpamAction();
2081      }
2082
2083      if (fw != null)
2084        fw.setBusy(false);
2085      if (getMessageUI() != null)
2086        getMessageUI().setBusy(false);
2087    }
2088  }
2089
2090  public class DecryptAction extends AbstractAction {
2091    DecryptAction() {
2092      super("message-decrypt");
2093    }
2094
2095    public void actionPerformed(ActionEvent e) {
2096      if (getMessageUI() != null)
2097        getMessageUI().setBusy(true);
2098      FolderDisplayUI fw = getFolderDisplayUI();
2099      if (fw != null)
2100        fw.setBusy(true);;
2101
2102      decryptMessage();
2103
2104      if (fw != null)
2105        fw.setBusy(false);
2106      if (getMessageUI() != null)
2107        getMessageUI().setBusy(false);
2108    }
2109  }
2110
2111  public class CheckSignatureAction extends AbstractAction {
2112    CheckSignatureAction() {
2113      super("message-check-signature");
2114    }
2115
2116    public void actionPerformed(ActionEvent e) {
2117      if (getMessageUI() != null)
2118        getMessageUI().setBusy(true);
2119      FolderDisplayUI fw = getFolderDisplayUI();
2120      if (fw != null)
2121        fw.setBusy(true);;
2122
2123      checkSignature();
2124
2125      if (fw != null)
2126        fw.setBusy(false);
2127      if (getMessageUI() != null)
2128        getMessageUI().setBusy(false);
2129    }
2130  }
2131
2132  public class ImportKeysAction extends AbstractAction {
2133    ImportKeysAction() {
2134      super("message-import-keys");
2135    }
2136
2137    public void actionPerformed(ActionEvent e) {
2138      if (getMessageUI() != null)
2139        getMessageUI().setBusy(true);
2140      FolderDisplayUI fw = getFolderDisplayUI();
2141      if (fw != null)
2142        fw.setBusy(true);;
2143
2144      importKeys();
2145
2146      if (fw != null)
2147        fw.setBusy(false);
2148      if (getMessageUI() != null)
2149        getMessageUI().setBusy(false);
2150    }
2151  }
2152
2153  public class EncryptionStatusAction extends AbstractAction {
2154    EncryptionStatusAction() {
2155      super("message-encryption-status");
2156    }
2157
2158    public void actionPerformed(ActionEvent e) {
2159      if (getMessageUI() != null)
2160        getMessageUI().setBusy(true);
2161      FolderDisplayUI fw = getFolderDisplayUI();
2162      if (fw != null)
2163        fw.setBusy(true);;
2164
2165      if (getMessageUI() != null)
2166        getMessageUI().showMessageDialog("(Encryption Status)", "Encryption Status");
2167      else
2168        Pooka.getUIFactory().showMessage("(Encryption Status)", "Encryption Status");
2169
2170      if (fw != null)
2171        fw.setBusy(false);
2172      if (getMessageUI() != null)
2173        getMessageUI().setBusy(false);
2174    }
2175  }
2176
2177  public class SignatureStatusAction extends AbstractAction {
2178    SignatureStatusAction() {
2179      super("message-signature-status");
2180    }
2181
2182    public void actionPerformed(ActionEvent e) {
2183      if (getMessageUI() != null)
2184        getMessageUI().setBusy(true);
2185      FolderDisplayUI fw = getFolderDisplayUI();
2186      if (fw != null)
2187        fw.setBusy(true);;
2188
2189      if (getMessageUI() != null)
2190        getMessageUI().showMessageDialog("(Signature Status)", "Signature Status");
2191      else
2192        Pooka.getUIFactory().showMessage("(Signature Status)", "Signature Status");
2193
2194      if (fw != null)
2195        fw.setBusy(false);
2196      if (getMessageUI() != null)
2197        getMessageUI().setBusy(false);
2198    }
2199  }
2200}
2201
2202
2203
2204
2205
2206
2207
2208
Popular Tags