KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > SnowMailClient > SnowMailClientApp


1 /*
2 SnowMail mail client
3 Copyright (C) 2003-2007 Stephan Heiss <stephanchaud@yahoo.fr>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
19 The full text of the LGPL text is present in the help menu of SnowMail
20 and in the snowmail jar file, in the folder SnowMailClient.
21 or at its original location: http://www.gnu.org/copyleft/lesser.html
22 */

23 package SnowMailClient;
24
25 import snow.updater.Updater;
26 import snow.utils.DateUtils;
27 import SnowMailClient.model.Address;
28 import SnowMailClient.view.folders.*;
29 import SnowMailClient.view.*;
30 import SnowMailClient.view.html.*;
31 import SnowMailClient.view.actions.*;
32 import SnowMailClient.model.AddressBook;
33 import SnowMailClient.model.folders.*;
34 import SnowMailClient.model.accounts.*;
35 import SnowMailClient.model.StyledTextDocument;
36 import SnowMailClient.MailEngine.MyX509TrustManager;
37 import SnowMailClient.MailEngine.transfer.*;
38 import SnowMailClient.crypto.*;
39 import SnowMailClient.utils.storage.Backup;
40 import SnowMailClient.Synthesizer.SynthesizerDemo;
41 import SnowMailClient.Language.Language;
42 import SnowMailClient.Language.Editor.TranslationEditor;
43 import khumpangame.MoveApp;
44 import SnowMailClient.SpamFilter.*;
45 import snow.FileEncryptor.*;
46 import SnowMailClient.gnupg.GnuPGLink;
47 import SnowMailClient.gnupg.Views.KeysViewer;
48 import snow.lookandfeel.*;
49 import snow.utils.storage.*;
50 import snow.utils.gui.*;
51 import snow.crypto.*;
52 import java.util.prefs.Preferences JavaDoc;
53
54 import java.awt.*;
55 import java.awt.image.*;
56 import java.awt.event.*;
57 import java.awt.datatransfer.*;
58 import javax.swing.*;
59 import javax.swing.tree.*;
60 import javax.swing.text.*;
61 import javax.swing.border.*;
62 import javax.net.ssl.*;
63 import javax.crypto.SecretKey;
64 import java.security.cert.*;
65 import java.security.*;
66 import javax.swing.plaf.metal.*;
67
68 import java.util.*;
69 import java.text.*;
70 import java.io.*;
71 import java.net.*;
72 import java.beans.*;
73
74
75 /** Todo:
76    1) create a correct address managment (add/remove, spam/...)
77    2) update spam stats...
78 */

79 public final class SnowMailClientApp extends JFrame
80 {
81   public static boolean debug = false; // not final, maybe set in the command line
82

83
84   // models for data storage
85
private final AppProperties properties = new AppProperties();
86   private StorageTreeModel storageTreeModel = null;
87   private final MailAccounts mailAccounts = new MailAccounts();
88   private final AddressBook addressBook = new AddressBook(false);
89   private final AddressBook spamBook = new AddressBook(true);
90   private final WordStatistic wordStatistic = new WordStatistic();
91   private final GnuPGLink gnuPGLink = new GnuPGLink();
92
93   final private Backup backup = new Backup();
94
95   // views
96
private FoldersView foldersView = null;
97   private FolderView folderView = null;
98   private MailView mailView;
99   private final JToolBar toolbar = new JToolBar("SnowMail Toolbar");
100   private final SearchTreePanel searchTreePanel;
101
102   public final Vector<JComponent> advancedComponents = new Vector<JComponent>();
103   public final void addAdvancedComponent(final JComponent comp)
104   {
105      advancedComponents.add(comp);
106      comp.setVisible(this.advancedMode);
107   }
108
109
110   private static File snowMailRoot = null;
111
112   private JSplitPane splitPaneHorizontal,
113      splitPaneVerticalLeft2, splitPaneVerticalRight;
114
115   private static final String JavaDoc TITLE = "SnowMail";
116   private static final String JavaDoc VERSION = "2.5";
117   private static final String JavaDoc SUBVERSION = "03";
118   private static final String JavaDoc DATE = "July 2007";
119
120   final String JavaDoc newestVersionURL = "http://snowmail.sn.funpic.de/snowmailclient.jar.pack.gz";
121
122   public final static String JavaDoc LicenceHTMLBodyText =
123       "<html><body><h2>SnowMail -- a mail client that may be secure.</h2>"
124      +"<p>"
125      +"<h3>Copyright (c) 2003-2007 Stephan Heiss (StephanChaud@yahoo.fr)"
126      +"<br>Homepage: http://snowmail.sn.funpic.de</h3>"
127
128      +"<p> <pre>"
129      +"This library is free software; you can redistribute it and/or"
130      +"\r\nmodify it under the terms of the GNU Lesser General Public"
131      +"\nLicense as published by the Free Software Foundation; either"
132      +"\nversion 2.1 of the License, or (at your option) any later version."
133      +"\n"
134      +"\nThis library is distributed in the hope that it will be useful,"
135      +"\nbut WITHOUT ANY WARRANTY; without even the implied warranty of"
136      +"\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU"
137      +"\nLesser General Public License for more details."
138
139      +"\n"
140      +"\nYou should have received a copy of the GNU Lesser General Public"
141      +"\nLicense along with this library; if not, write to the Free Software"
142      +"\nFoundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA"
143      +"\r\n"
144
145      +"\nThe full text of the LGPL text is present in the help menu of SnowMail"
146      +"\nand in the snowmail jar file, in the folder SnowMailClient."
147      +"\nor at its original location: http://www.gnu.org/copyleft/lesser.html\n"
148      ;
149
150   /** @deprecated console ### maybe not is useful for status */
151 @Deprecated JavaDoc
152   private final StyledTextDocument globalConsole = new StyledTextDocument();
153   private JTextPane consolePane;
154   private JScrollPane consoleScroll;
155
156   private static SnowMailClientApp ref;
157   private JCheckBoxMenuItem[] metalThemesMenuItems = null;
158
159   private boolean advancedMode = false;
160
161
162   private SnowMailClientApp()
163   {
164     super();
165
166
167     if(!Preferences.userRoot().getBoolean("snowmail_lic_acc4", false))
168     {
169       // first start...
170
int rep = JOptionPane.showConfirmDialog(null,
171         LicenceHTMLBodyText
172         +"\nDo you agree with that licence ?",
173         "SnowMail License Agreement (GPL)", JOptionPane.YES_NO_OPTION
174       );
175       if(rep!=JOptionPane.YES_OPTION) System.exit(0);
176
177       Preferences.userRoot().putBoolean("snowmail_lic_acc4", true);
178     }
179
180     // not "visible", but exist => see the icon and application in windows
181
setLocation(0,0);
182     setSize(0,0);
183     setTitle(TITLE+" "+VERSION);
184
185
186     // title is set at the end
187
this.setIconImage(SnowMailClientApp.loadImageIcon("pics/snowmailicon.PNG").getImage());
188
189     ref = this;
190
191     setVisible(true);
192
193     final ProgressModalDialog startupProgress = new ProgressModalDialog(this,
194        Language.translate("Starting of ") + TITLE, false, false); // no more modal...
195

196     startupProgress.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); // if the user closes! ### NOT WORKING !!!
197
startupProgress.setShowCancel(false);
198     startupProgress.setProgressBounds(100);
199     startupProgress.setLocationRelativeTo(null);
200     startupProgress.start();
201
202     // root folder must exist
203
checkRootDir();
204
205     startupProgress.setProgressValue(10, Language.translate("Check SSL certificates")+"...");
206     initializeSSLCertificateInfo();
207
208     // keys
209
startupProgress.setProgressValue(15, Language.translate("Loading keys")+"...");
210     try
211     {
212       SecretKeyManager skm = SecretKeyManager.getInstance();
213
214       File ksFile = new File(snowMailRoot, "userkeystore");
215
216       // exists only if the user setted a secret pass
217
if(ksFile.exists())
218       {
219          try
220          {
221             Vector<Object JavaDoc> vec = FileCipherManager.getInstance().decipherVectorFromFile_ASK_KEY_IF_NEEDED(
222               ksFile, startupProgress,
223               Language.translate("Snowmail passphrase"),
224               Language.translate("Enter your secret passphrase to start SnowMail") );
225             skm.createFromVectorRepresentation( vec );
226          }
227          catch(BadPasswordException e)
228          {
229             System.exit(0); // Fatal...
230
}
231       }
232       else
233       {
234         // create it !
235
}
236     }
237     catch(Exception JavaDoc e)
238     {
239       e.printStackTrace();
240     }
241
242     searchTreePanel = new SearchTreePanel();
243
244     // leave the EDT !
245
Thread JavaDoc t = new Thread JavaDoc()
246     {
247        public void run()
248        {
249           initializeSnowMail(startupProgress);
250        }
251     };
252     t.start();
253
254   }
255
256   private void initializeSnowMail(final ProgressModalDialog startupProgress)
257   {
258
259
260
261     // properties
262
startupProgress.setProgressValue(20, Language.translate("Loading properties")+"...");
263     try
264     {
265       File propFile = new File(snowMailRoot, "properties");
266       if(propFile.exists())
267       {
268         properties.createFromVectorRepresentation( this.readVectorFromFile( propFile, startupProgress ));
269       }
270     }
271     catch(Exception JavaDoc e)
272     {
273       e.printStackTrace();
274     }
275
276     this.advancedMode = properties.getBoolean("advancedMode", true);
277
278     // Backup
279
//
280
try
281     {
282       File bcFile = new File(snowMailRoot, "backup");
283       if(bcFile.exists())
284       {
285         backup.createFromVectorRepresentation( readVectorFromFile( bcFile, startupProgress ));
286       }
287     }
288     catch(Exception JavaDoc e)
289     {
290       e.printStackTrace();
291     }
292
293
294     // models
295
startupProgress.setProgressValue(30, Language.translate("Reading system mail folders")+"...");
296     try
297     {
298       File mailStorageRoot = new File(snowMailRoot, "MailStorage");
299       storageTreeModel = new StorageTreeModel(mailStorageRoot);
300       EventQueue.invokeLater(new Runnable JavaDoc() { public void run() {
301          foldersView = new FoldersView(storageTreeModel, SnowMailClientApp.this);
302       }});
303
304     }
305     catch(Exception JavaDoc e)
306     {
307       e.printStackTrace();
308     }
309
310     // accounts
311
startupProgress.setProgressValue(60, Language.translate("Reading mail accounts")+"...");
312     try
313     {
314       File accountsFile = new File(snowMailRoot, "accounts");
315       if(accountsFile.exists())
316       {
317         mailAccounts.createFromVectorRepresentation( readVectorFromFile( accountsFile, startupProgress ));
318       }
319     }
320     catch(Exception JavaDoc e)
321     {
322       e.printStackTrace();
323     }
324
325     // address book
326
startupProgress.setProgressValue(70, Language.translate("Reading address book")+"...");
327     try
328     {
329       File adbFile = new File(snowMailRoot, "addressBook");
330       if(adbFile.exists())
331       {
332         addressBook.createFromVectorRepresentation( readVectorFromFile( adbFile, startupProgress ));
333       }
334     }
335     catch(Exception JavaDoc e)
336     {
337       e.printStackTrace();
338     }
339
340     // spam book
341
startupProgress.setProgressValue(80, Language.translate("Reading spam book")+"...");
342     try
343     {
344       File spamFile = new File(snowMailRoot, "spamBook");
345       if(spamFile.exists())
346       {
347         spamBook.createFromVectorRepresentation( readVectorFromFile( spamFile, startupProgress ));
348       }
349     }
350     catch(Exception JavaDoc e)
351     {
352       e.printStackTrace();
353     }
354
355     // statistics
356
//
357
startupProgress.setProgressValue(85, Language.translate("Reading spam statistics")+"...");
358     try
359     {
360       File statFile = new File(snowMailRoot, "wordStatistic");
361       if(statFile.exists())
362       {
363         this.wordStatistic.createFromVectorRepresentation(
364            readVectorFromFile( statFile, startupProgress ));
365       }
366     }
367     catch(Exception JavaDoc e)
368     {
369       e.printStackTrace();
370     }
371     catch(Error JavaDoc e)
372     {
373       e.printStackTrace();
374     }
375
376
377     // GnuPG
378
//
379
startupProgress.setProgressValue(90, Language.translate("Reading GnuPG keys")+"...");
380     File file = new File(snowMailRoot, "gnuPGLink");
381     try
382     {
383        if(file.exists())
384        {
385          this.gnuPGLink.createFromVectorRepresentation(
386              readVectorFromFile( file, startupProgress ));
387        }
388     }
389     catch(Exception JavaDoc e)
390     {
391       e.printStackTrace();
392     }
393     catch(Error JavaDoc e)
394     {
395       e.printStackTrace();
396     }
397
398
399
400     startupProgress.setProgressValue(95, Language.translate("Building views")+"...");
401
402 EventQueue.invokeLater(new Runnable JavaDoc() { public void run() {
403
404     mailView = new MailView(mailAccounts);
405     folderView = new FolderView(properties, foldersView, mailView);
406
407     // gui
408
getContentPane().setLayout(new BorderLayout(0,0));
409     getContentPane().add(toolbar, BorderLayout.NORTH);
410     toolbar.setOpaque(false);
411
412     // splits
413
//
414
SnowBackgroundPanel consolePanel = new SnowBackgroundPanel(new BorderLayout());
415     advancedComponents.add(consolePanel);
416     consolePane = new JTextPane(globalConsole.doc);
417     consolePane.setOpaque(false);
418     consoleScroll = new JScrollPane(consolePane);
419     consoleScroll.setOpaque(false);
420     consoleScroll.getViewport().setOpaque(false);
421     consolePanel.add(consoleScroll, BorderLayout.CENTER);
422
423   /* splitPaneVerticalLeft1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
424       searchTreePanel = new SearchTreePanel(),
425       consolePanel);
426     splitPaneVerticalLeft1.setOneTouchExpandable(true);*/

427
428     splitPaneVerticalLeft2 = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
429       foldersView,
430       searchTreePanel);
431     splitPaneVerticalLeft2.setOneTouchExpandable(true);
432
433
434     splitPaneVerticalRight = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
435       folderView,
436       mailView);
437     splitPaneVerticalRight.setOneTouchExpandable(true);
438
439     splitPaneHorizontal = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
440       splitPaneVerticalLeft2,
441       splitPaneVerticalRight);
442     splitPaneHorizontal.setOneTouchExpandable(true);
443
444     getContentPane().add(splitPaneHorizontal, BorderLayout.CENTER);
445
446     splitPaneHorizontal.setBorder(null);
447    // splitPaneVerticalLeft1.setBorder(null);
448
splitPaneVerticalLeft2.setBorder(null);
449     splitPaneVerticalRight.setBorder(null);
450     //new EmptyBorder(fontSize, fontSize, fontSize, fontSize)
451

452     // view installations
453

454
455
456     setMenu();
457
458     // ui sizes from props
459
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
460     properties.setComponentSizeFromINIFile(SnowMailClientApp.this, "SnowMailClientApp",
461       (int)(screen.getWidth()-100), (int)(screen.getHeight()-100), 50,50);
462     /*splitPaneVerticalLeft1.setDividerLocation(
463       properties.getInteger("splitPaneVerticalLeft", (int)(screen.getHeight()/2)));*/

464
465     splitPaneVerticalLeft2.setDividerLocation(
466       properties.getInteger("splitPaneVerticalLeft2", (int)(screen.getHeight()/2)));
467
468     splitPaneVerticalRight.setDividerLocation(
469       properties.getInteger("splitPaneVerticalRight", (int)(screen.getHeight()/3)));
470
471     splitPaneHorizontal.setDividerLocation(
472       properties.getInteger("splitPaneHorizontal", (int)(screen.getWidth()/4)));
473
474     mailView.hideAttachmentSplit();
475
476     addWindowListener(new WindowAdapter()
477     {
478         @Override JavaDoc public void windowClosed(WindowEvent e)
479         {
480            terminateApplication();
481         }
482         // Invoked when a window has been closed.
483
@Override JavaDoc public void windowClosing(WindowEvent e)
484         {
485            terminateApplication();
486         }
487         // Invoked when a window is in the process of being closed.
488
});
489
490     consolePane.addPropertyChangeListener(
491      new PropertyChangeListener()
492      {
493         public void propertyChange(PropertyChangeEvent e)
494         {
495             String JavaDoc name = e.getPropertyName();
496             if (name.equals("UI"))
497              {
498                SwingUtilities.invokeLater( new Runnable JavaDoc()
499                 {
500                    public void run()
501                    {
502                      updateSpecialUI();
503                    }
504                 });
505              }
506         /* else
507             {
508               System.out.println(">"+name);
509             }*/

510         }
511      });
512
513
514     // set snowmail title and made app visible !
515
//
516
String JavaDoc firstSendAccount = Language.translate("No mail account for sending set");
517     MailAccount ma0 = mailAccounts.getSendMailAccount();
518     if(ma0!=null) firstSendAccount = ma0.getAddress();
519     setTitle(TITLE+" "+VERSION+" ["+firstSendAccount+"]");
520
521     for(JComponent comp : advancedComponents)
522     {
523       comp.setVisible(advancedMode);
524     }
525
526     // MAIN VISIBLE !
527
setVisible(true);
528     startupProgress.setVisible(false);
529
530     DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, Language.getInstance().getLocale());
531     DateFormat df2 = DateFormat.getTimeInstance(DateFormat.SHORT, Language.getInstance().getLocale());
532
533     getGlobalConsole().appendLine(Language.translate("Started the")+" "
534        +df.format(new Date())+Language.translate(" at ")+df2.format(new Date())+"\n");
535
536     // set global passphrase, if necessary
537
//FileCipherManager.getInstance();
538
if(!SecretKeyManager.getInstance().isUserKeySet())
539     {
540           //SecretKeyManager.getInstance().
541
PassphraseSettingDialog psd = new PassphraseSettingDialog(SnowMailClientApp.this,
542               Language.translate("Snowmail Passphrase setting"),
543               true,
544               Language.translate("Please enter and confirm the snowMail global passphrase.\nThis passphrase will protect all your stored data."));
545
546           if(!psd.wasCancelled())
547           {
548             try
549             {
550               SecretKeyManager.getInstance().setUserKeyForEncryption( psd.getKey() );
551             }
552             catch(Exception JavaDoc ee) { System.exit(-1); }
553           }
554           else
555           {
556             JOptionPane.showMessageDialog(SnowMailClientApp.this,
557                Language.translate("SnowMail require a global passphrase"),
558                Language.translate("Error"), JOptionPane.ERROR_MESSAGE);
559             System.exit(-1);
560           }
561     }
562
563     lookForNextBirthdays(15);
564
565 }});
566
567    }
568
569 // TODO: allow to mark as "acknowledged"...
570
private void lookForNextBirthdays(int daysForward)
571    {
572       StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
573       for(int i=0; i<addressBook.getNumberOfAddresses(); i++)
574       {
575          Address a = addressBook.getAddressAt(i);
576          // TODO...
577
if(a.getBirthday()>0)
578          {
579             int d = DateUtils.getDaysUntilBirthday(a.getBirthday());
580             if(d==0)
581             {
582                sb.append("\r\n"+a+" "+Language.translate("has birthday today"));
583             }
584             else if(d==1)
585             {
586                sb.append("\r\n"+a+" "+Language.translate("has birthday tomorrow"));
587             }
588             else if(d==1)
589             {
590                sb.append("\r\n"+a+" "+Language.translate("had birthday yesterday"));
591             }
592             else if(d>1)
593             {
594                if(d<60)
595                {
596                  sb.append("\r\n"+a+" "+Language.translate("has birthday in % days",""+d));
597                }
598             }
599             else if(d<-1)
600             {
601                if(d>-30)
602                {
603                  sb.append("\r\n"+a+" "+Language.translate("had birthday % days ago",""+(-d)));
604                }
605             }
606
607          }
608       }
609
610       if(sb.length()>0)
611       {
612          JTextArea ta = new JTextArea(sb.toString().trim(),10,50);
613          ta.setEditable(false);
614          JOptionPane.showMessageDialog(this, new JScrollPane(ta), Language.translate("Soon and recent birthdays"), JOptionPane.INFORMATION_MESSAGE);
615       }
616    }
617
618    public void makeSearchTreeVisible()
619    {
620      splitPaneVerticalLeft2.setDividerLocation(0.6);
621    }
622
623
624    private void updateSpecialUI()
625    {
626       //fontSize = UIManager.getFont("Label.font").getSize();
627
// the textpane don't update correctly his opacity itself !!
628
consolePane.setOpaque(false);
629       consoleScroll.setOpaque(false);
630       consoleScroll.getViewport().setOpaque(false);
631
632     splitPaneHorizontal.setBorder(null);
633     //splitPaneVerticalLeft1.setBorder(null);
634
splitPaneVerticalLeft2.setBorder(null);
635     splitPaneVerticalRight.setBorder(null);
636
637
638       //System.out.println("Snow client app UI updated !!");
639
}
640
641    /** Only after the constructor has been called ! */
642    public static SnowMailClientApp getInstance() { return ref; }
643
644    public FoldersView getFoldersView() { return foldersView; }
645    public FolderView getFolderView() { return folderView; }
646    public MailView getMailView() { return mailView; }
647    public AppProperties getProperties() { return properties; }
648    public File getSnowMailRoot() { return snowMailRoot; }
649    public Backup getBackup() { return backup; }
650    public StorageTreeModel getFoldersModel() { return storageTreeModel; }
651    public AddressBook getAddressBook() { return addressBook; }
652    public AddressBook getSpamBook() { return spamBook; }
653   @Deprecated JavaDoc
654    public StyledTextDocument getGlobalConsole() { return globalConsole; }
655    public SearchTreePanel getSearchPanel() { return this.searchTreePanel; }
656    public WordStatistic getWordStatistic() { return wordStatistic; }
657    public MailAccounts getAccounts() { return mailAccounts; }
658    public GnuPGLink getGnuPGLink() { return gnuPGLink; }
659
660    private void setMenu()
661    {
662       // File
663
//
664
JMenuBar menuBar = new JMenuBar();
665
666       this.setJMenuBar(menuBar);
667       JMenu fileMenu = new JMenu(Language.translate("File"));
668       getJMenuBar().add(fileMenu);
669
670       final JMenuItem modeItem = new JMenuItem( (advancedMode?Language.translate("Change to simple mode"):Language.translate("Change to advanced mode")) );
671       //passItem.setIcon(SnowMailClientApp.loadImageIcon("pics/key.PNG"));
672
fileMenu.add(modeItem);
673       fileMenu.addSeparator();
674       modeItem.addActionListener(new ActionListener()
675       {
676         public void actionPerformed(ActionEvent e)
677         {
678           advancedMode = !advancedMode;
679           modeItem.setText((advancedMode?Language.translate("Change to simple mode"):Language.translate("Change to advanced mode")));
680           for(JComponent comp : advancedComponents)
681           {
682             comp.setVisible(advancedMode);
683           }
684         }
685       });
686
687       JMenuItem saveItem = new JMenuItem(Language.translate("Save all opened folders"));
688       saveItem.setIcon(SnowMailClientApp.loadImageIcon("pics/save.PNG"));
689       saveItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_S, KeyEvent.CTRL_MASK ) );
690       fileMenu.add(saveItem);
691       saveItem.addActionListener(new ActionListener()
692       {
693         public void actionPerformed(ActionEvent e)
694         {
695           Thread JavaDoc t = new Thread JavaDoc(){
696             public void run()
697             {
698               setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
699               saveAllMails(false); // ATTENTION: if true, the view must "reload"
700
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
701             }};
702           t.setPriority(Thread.NORM_PRIORITY-1);
703           t.start();
704         }
705       });
706
707
708       JMenuItem passItem = new JMenuItem(Language.translate("Set storage passphrase"));
709       passItem.setIcon(SnowMailClientApp.loadImageIcon("pics/key.PNG"));
710       fileMenu.addSeparator();
711       fileMenu.add(passItem);
712       passItem.addActionListener(new ActionListener()
713       {
714         public void actionPerformed(ActionEvent e)
715         {
716           // ask for the old password
717
SecretKey sk = SecretKeyManager.getInstance().getUserKeyForEncryption();
718           if(sk!=null)
719           {
720             SecretKeyID skid = SecretKeyUtilities.computeSignature(sk);
721             PassphraseDialog pd = new PassphraseDialog(SnowMailClientApp.this,
722                 Language.translate("Snowmail passphrase"), true, skid, null,
723                 Language.translate("Enter the old passphrase"));
724
725             if(!pd.matchesID())
726             {
727               return;
728             }
729           }
730
731           //2:
732
PassphraseSettingDialog psd = new PassphraseSettingDialog(SnowMailClientApp.this,
733               Language.translate("Snowmail Passphrase setting"),
734               true,
735               Language.translate("Please enter and confirm the new SnowMail passphrase"));
736           if(!psd.wasCancelled())
737           {
738             try
739             {
740               SecretKeyManager.getInstance().setUserKeyForEncryption( psd.getKey() );
741             }
742             catch(Exception JavaDoc ee) {}
743           }
744
745         }
746       });
747
748
749       JMenuItem backupNowItem = new JMenuItem(Language.translate("Do a backup now"));
750       this.addAdvancedComponent(backupNowItem);
751       //backupNowItem.setIcon(SnowMailClientApp.loadImageIcon("pics/zip.PNG"));
752
fileMenu.addSeparator();
753       fileMenu.add(backupNowItem);
754       backupNowItem.addActionListener(new ActionListener()
755       {
756         public void actionPerformed(ActionEvent e)
757         {
758           Thread JavaDoc t = new Thread JavaDoc(){
759             public void run() {
760               backup.doBackupNow();
761             }};
762           t.setPriority(Thread.NORM_PRIORITY-1);
763           t.start();
764         }
765       });
766
767       JMenuItem backupItem = new JMenuItem(new BackupConfigurationAction());
768       fileMenu.add(backupItem);
769
770       JMenuItem quitItem = new JMenuItem(Language.translate("Quit"), Icons.CrossIcon.shared10);
771       quitItem.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_Q, KeyEvent.CTRL_MASK ) );
772       fileMenu.addSeparator();
773       fileMenu.add(quitItem);
774       quitItem.addActionListener(new ActionListener()
775       {
776         public void actionPerformed(ActionEvent e)
777         {
778           terminateApplication();
779         }
780       });
781
782       // Mail and accounts
783
//
784

785       JMenu mailMenu = new JMenu(Language.translate("Mail"));
786       getJMenuBar().add(mailMenu);
787
788 /* ReceiveAction receiveAction = new ReceiveAction(
789          this, this.mailAccounts,
790          storageTreeModel.getInboxFolder(),
791          storageTreeModel.getOutboxFolder()); */

792
793       MailTransferAction receiveAction = new MailTransferAction( MailTransferModel.TransferType.Receive );
794       MailTransferAction sendAction2 = new MailTransferAction( MailTransferModel.TransferType.Send );
795       MailTransferAction sendAndReceiveAction = new MailTransferAction( MailTransferModel.TransferType.SendAndReceive );
796
797 /*
798       SendAction sendAction = new SendAction(
799          this, this.mailAccounts,
800          storageTreeModel.getSentFolder(),
801          storageTreeModel.getOutboxFolder(),
802          this.folderView); */

803
804       PreviewAllAction previewAllAction = new PreviewAllAction();
805
806       mailMenu.add(receiveAction);
807       mailMenu.add(sendAction2);
808       mailMenu.add(sendAndReceiveAction);
809       //mailMenu.add(new SendAndReceiveAction( sendAction, rac));
810

811       mailMenu.addSeparator();
812       CreateNewMail createNewMailAction = new CreateNewMail(mailAccounts, storageTreeModel.getComposeFolder());
813       mailMenu.add(createNewMailAction);
814
815       ReplyAction replyAction = new ReplyAction(folderView, mailAccounts, storageTreeModel.getComposeFolder(), false);
816       mailMenu.add(replyAction);
817
818       ReplyAction replyAllAction = new ReplyAction(folderView, mailAccounts, storageTreeModel.getComposeFolder(), true);
819       JMenuItem replyAllMI = new JMenuItem(replyAllAction);
820       mailMenu.add(replyAllMI);
821       this.advancedComponents.add(replyAllMI);
822
823       ForwardAction forwardAction = new ForwardAction(folderView, mailAccounts, storageTreeModel.getComposeFolder());
824       mailMenu.add(forwardAction);
825
826       mailMenu.addSeparator();
827       JMenuItem miCopyClip = new JMenuItem(new CopyMessagesToClipboardAsText(folderView));
828       mailMenu.add(miCopyClip);
829       this.advancedComponents.add(miCopyClip);
830       mailMenu.add(new DeleteMailAction(folderView, storageTreeModel.getDeletedFolder()));
831
832
833       JSeparator sep = new JSeparator();
834       mailMenu.add(sep);
835       this.addAdvancedComponent(sep);
836
837       JMenuItem sma = new JMenuItem(new SaveMailAction(folderView));
838       mailMenu.add(sma);
839       this.addAdvancedComponent(sma);
840
841       JMenuItem ime = new JMenuItem(new ImportMailMessage(folderView));
842       mailMenu.add(ime);
843       this.addAdvancedComponent(ime);
844
845       toolbar.add(createToolbarButton(createNewMailAction));
846       toolbar.add(createToolbarButton(replyAction));
847
848       toolbar.addSeparator();
849       //toolbar.add(createToolbarButton(receiveAction));
850
toolbar.add(createToolbarButton(receiveAction));
851
852
853       JComponent previewButton = createToolbarButton(previewAllAction);
854       this.addAdvancedComponent(previewButton);
855       toolbar.add(previewButton);
856
857       toolbar.add(createToolbarButton(sendAction2));
858
859       toolbar.addSeparator();
860       EditAddressBookAction addressAction = new EditAddressBookAction(this, addressBook, properties);
861       toolbar.add(createToolbarButton(addressAction));
862
863       toolbar.addSeparator();
864       EditAccountsAction accountsAction = new EditAccountsAction(this, mailAccounts, properties);
865       toolbar.add(createToolbarButton(accountsAction));
866
867       mailMenu.addSeparator();
868       mailMenu.add(accountsAction);
869       mailMenu.add(addressAction);
870
871
872       // GnuPG
873
//
874

875       JMenu cryptoMenu = new JMenu(Language.translate("Crypto"));
876       getJMenuBar().add(cryptoMenu);
877
878       JMenu gpgMenu = new JMenu(Language.translate("GnuPG"));
879       cryptoMenu.add(gpgMenu);
880
881       JMenuItem configureGnuPG = new JMenuItem(Language.translate("Configure GnuPG"));
882       gpgMenu.add(configureGnuPG);
883       configureGnuPG.addActionListener(new ActionListener()
884       {
885         public void actionPerformed(ActionEvent e)
886         {
887            gnuPGLink.askGPGPath(SnowMailClientApp.this);
888         }
889       });
890
891       JMenuItem gpgOverview = new JMenuItem(Language.translate("GnuPG explorer"));
892       gpgMenu.add(gpgOverview);
893       gpgOverview.addActionListener(new ActionListener()
894       {
895         public void actionPerformed(ActionEvent e)
896         {
897            //gnuPGLink.askGPGPath(SnowMailClientApp.this);
898
new KeysViewer();
899         }
900       });
901
902       // Spam filter
903
//
904

905       JMenu spamMenu = new JMenu(Language.translate("SPAM Filter"));
906       getJMenuBar().add(spamMenu);
907       this.addAdvancedComponent(spamMenu);
908
909
910       spamMenu.add(new AddToSpamAction(folderView));
911       spamMenu.add(new AddToHAMAction(folderView));
912       spamMenu.add(new RemoveSPAMCategory(folderView));
913
914       JMenuItem trainSpamFilterMI = new JMenuItem(Language.translate("Train Spam Filter with all mails"));
915       spamMenu.addSeparator();
916       spamMenu.add(trainSpamFilterMI);
917       trainSpamFilterMI.addActionListener(new ActionListener()
918       {
919         public void actionPerformed(ActionEvent e)
920         {
921           Thread JavaDoc t = new Thread JavaDoc()
922           {
923             public void run()
924             {
925                trainSpamFilterAction();
926             }
927           };
928           t.setPriority(Thread.NORM_PRIORITY-1);
929           t.start();
930         }
931       });
932
933       JMenuItem viewSpamStatMI = new JMenuItem(Language.translate("View statistics word list"));
934       this.addAdvancedComponent(viewSpamStatMI);
935       spamMenu.addSeparator();
936       spamMenu.add(viewSpamStatMI);
937       viewSpamStatMI.addActionListener(new ActionListener()
938       {
939         public void actionPerformed(ActionEvent e)
940         {
941           new StatViewer(SnowMailClientApp.this);
942         }
943       });
944
945       JComponent exportStatAction = new JMenuItem(new ExportStatisticsAction());
946       spamMenu.add(exportStatAction);
947       this.addAdvancedComponent(exportStatAction);
948
949       // Language
950
//
951
JMenu languageMenu = new JMenu(Language.translate("Language"));
952       getJMenuBar().add(languageMenu);
953       addAdvancedComponent(languageMenu);
954
955       // English is not in the list
956
String JavaDoc[] languages = Language.getInstance().getAvailableInternalLanguages();
957       if(languages.length==0)
958       {
959          // english is already in the list
960
languages = Language.getInstance().getAvailableLanguages();
961       }
962       else
963       {
964          // add english
965
String JavaDoc[] languages2 = new String JavaDoc[languages.length+1];
966          for(int i=0; i<languages.length; i++)
967          {
968            languages2[i+1] = languages[i];
969          }
970          languages2[0] = Language.ENGLISH;
971          languages = languages2;
972       }
973
974       ButtonGroup languageGroup = new ButtonGroup();
975       for(int i=0; i<languages.length; i++)
976       {
977         JCheckBoxMenuItem li = new JCheckBoxMenuItem(languages[i],
978            languages[i].equals(Language.getInstance().getActualTranslation()));
979         languageGroup.add(li);
980         final String JavaDoc language = languages[i];
981         languageMenu.add(li);
982         li.addActionListener(new ActionListener()
983         {
984           public void actionPerformed(ActionEvent e)
985           {
986              Language.getInstance().setActualTranslation(language,true);
987              JOptionPane.showMessageDialog(SnowMailClientApp.this,
988                 Language.translate("Please restart SnowMail to activate the new language."),
989                 Language.translate("Language selection"),
990                 JOptionPane.INFORMATION_MESSAGE
991              );
992
993           }
994         });
995       }
996
997       JMenuItem languageEditorMI = new JMenuItem(Language.translate("Interface Translation Editor"));
998       advancedComponents.add(languageEditorMI);
999       languageMenu.addSeparator();
1000      languageMenu.add(languageEditorMI);
1001      languageEditorMI.addActionListener(new ActionListener()
1002      {
1003        public void actionPerformed(ActionEvent e)
1004        {
1005          new TranslationEditor();
1006        }
1007      });
1008
1009      /*
1010      // Look and Feel
1011      //
1012      JMenu lfMenu = new JMenu(Language.translate("Look and Feel"));
1013      getJMenuBar().add(lfMenu);
1014      this.addAdvancedComponent(lfMenu);
1015
1016      // the menu items are aleady defined
1017      for(int i=0; i<metalThemes.length; i++)
1018      {
1019        lfMenu.add(metalThemesMenuItems[i]);
1020        final int ii = i;
1021        metalThemesMenuItems[i].addActionListener(new ActionListener()
1022        {
1023          public void actionPerformed(ActionEvent e)
1024          {
1025            properties.setInteger("matalTheme_index", ii);
1026            try
1027            {
1028              setMetalTheme(ii);
1029            }
1030            catch(Exception ex)
1031            {
1032              System.out.println("Exception: "+ex.getMessage());
1033            }
1034          }
1035        });
1036      }
1037
1038
1039      JMenuItem custMI = new JMenuItem(Language.translate("Customize actual theme"));
1040      custMI.setIcon(SnowMailClientApp.loadImageIcon("pics/CustomizeTheme.PNG"));
1041      lfMenu.addSeparator();
1042      lfMenu.add(custMI);
1043      custMI.addActionListener(new ActionListener()
1044        {
1045          public void actionPerformed(ActionEvent e)
1046          {
1047            new ThemesCustomizerFrame(ref, properties);
1048          }
1049        }); */

1050
1051      JMenu lfMenu = ThemesManager.getInstance().getThemesMenu();
1052      getJMenuBar().add(lfMenu);
1053      addAdvancedComponent(lfMenu);
1054
1055
1056       if(debug)
1057       {
1058         JMenu debugMenu = new JMenu(Language.translate("Debug"));
1059         getJMenuBar().add(debugMenu);
1060         debugMenu.add(new NewMailFromContent(mailAccounts, storageTreeModel.getComposeFolder()));
1061       }
1062
1063      // Utilities
1064
//
1065
//JMenu utilitiesMenu = new JMenu(Language.translate("Utilities"));
1066
//advancedComponents.add(utilitiesMenu);
1067
//getJMenuBar().add(utilitiesMenu);
1068
JMenuItem encryptMenuItem = new JMenuItem(Language.translate("Encrypt a File"));
1069      cryptoMenu.addSeparator();
1070      cryptoMenu.add(encryptMenuItem);
1071      this.addAdvancedComponent(encryptMenuItem);
1072      encryptMenuItem.addActionListener(new ActionListener()
1073      { public void actionPerformed(ActionEvent e)
1074        {
1075          Thread JavaDoc t = new Thread JavaDoc(){ public void run()
1076          {
1077            SimpleFileEncryptorUI.simpleEncryptFileUI(
1078                  SnowMailClientApp.getInstance().getProperties(),
1079                  SnowMailClientApp.getInstance());
1080          }};
1081          t.setPriority(Thread.NORM_PRIORITY-1);
1082          t.start();
1083        }
1084      });
1085
1086      JMenuItem decryptMenuItem = new JMenuItem(Language.translate("Decrypt a File"));
1087      cryptoMenu.add(decryptMenuItem);
1088      this.addAdvancedComponent(decryptMenuItem);
1089      decryptMenuItem.addActionListener(new ActionListener()
1090      { public void actionPerformed(ActionEvent e)
1091        {
1092          Thread JavaDoc t = new Thread JavaDoc(){ public void run() {
1093            SimpleFileEncryptorUI.simpleDecryptFileUI(
1094                  SnowMailClientApp.getInstance().getProperties(),
1095                  SnowMailClientApp.getInstance()
1096            );
1097          }};
1098          t.setPriority(Thread.NORM_PRIORITY-1);
1099          t.start();
1100        }
1101      });
1102
1103      JMenuItem verifyHashMenuItem = new JMenuItem(Language.translate("Compute or verify HashCode"));
1104      cryptoMenu.add(verifyHashMenuItem);
1105      this.addAdvancedComponent(verifyHashMenuItem);
1106      verifyHashMenuItem.addActionListener(new ActionListener()
1107      { public void actionPerformed(ActionEvent e)
1108        {
1109          new HashCodeDialog(SnowMailClientApp.this, SnowMailClientApp.this.properties);
1110        }
1111      });
1112
1113      JMenuItem sslo = new JMenuItem(Language.translate("SSL Trusted Certificates"));
1114      cryptoMenu.addSeparator();
1115      cryptoMenu.add(sslo);
1116      sslo.addActionListener(new ActionListener()
1117      {
1118        public void actionPerformed(ActionEvent e)
1119        {
1120           new TruststoreView(SnowMailClientApp.this);
1121        }
1122      });
1123
1124      // Help
1125
//
1126
JMenu helpMenu = new JMenu(Language.translate("Help"));
1127      getJMenuBar().add(helpMenu);
1128
1129      JMenuItem game = new JMenuItem(Language.translate("Khun Pan: a nice game"));
1130      helpMenu.add(game);
1131      helpMenu.addSeparator();
1132      game.addActionListener(new ActionListener()
1133      { public void actionPerformed(ActionEvent e)
1134        {
1135           new MoveApp(false);
1136        }
1137      });
1138
1139      JMenuItem crackMenuItem = new JMenuItem(Language.translate("Password crack tool"));
1140      helpMenu.add(crackMenuItem);
1141      crackMenuItem.addActionListener(new ActionListener()
1142      { public void actionPerformed(ActionEvent e)
1143        {
1144          new PasswordSearchDialog(new JDialog(), null, null);
1145        }
1146      });
1147
1148
1149      JMenuItem updater = new JMenuItem("look for new version");
1150      helpMenu.addSeparator();
1151      helpMenu.add(updater);
1152      updater.addActionListener(new ActionListener()
1153      {
1154        public void actionPerformed(ActionEvent ae)
1155        {
1156           final String JavaDoc name= "snowmailclient.jar";
1157
1158           File jar = Updater.getJarCurrentlyRunning(name);
1159
1160           if(jar==null)
1161           {
1162                 JOptionPane.showMessageDialog(null, "There is no "+name
1163                   +" \nin the classpath of the current running application."
1164                   +"\n\nSo I cannot replace it with a new version."
1165                   +"\n\nIf you started snowmail via JNLP, you have the latest version",
1166                   "Snowmail updater", JOptionPane.WARNING_MESSAGE);
1167                 return;
1168           }
1169
1170           Thread JavaDoc t = new Thread JavaDoc(){ public void run() {
1171             long[] dateAndSize = null;
1172             try
1173             {
1174                dateAndSize = Updater.getDateAndSizeOnServer(new URL(newestVersionURL));
1175             }
1176             catch(Exception JavaDoc e) {
1177                   JOptionPane.showMessageDialog(null, "No connection to "+newestVersionURL
1178                     +"\n\ncheck your network", "Snowmail updater", JOptionPane.WARNING_MESSAGE);
1179                   return;
1180             }
1181
1182             try
1183             {
1184
1185                if(Updater.isNewVersionAvailable(name, newestVersionURL))
1186                {
1187                   // TODO
1188
if(JOptionPane.showConfirmDialog(null, "There is a new version available,do you want to update ?",
1189                      "New version available",
1190                      JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE)==JOptionPane.YES_OPTION)
1191                   {
1192                      Updater.updateAndLaunchReplacerTask(name, newestVersionURL);
1193                   }
1194                }
1195                else
1196                {
1197                   JOptionPane.showMessageDialog(null, "Your version seems to be actual.");
1198                }
1199             }
1200             catch(Exception JavaDoc e) {
1201                JOptionPane.showMessageDialog(null, ""+e.getMessage(),"Snowmail updater error", JOptionPane.ERROR_MESSAGE);
1202                e.printStackTrace();
1203             }
1204           }};
1205           t.start();
1206        }
1207      });
1208
1209
1210      JMenuItem helpMenuItem = new JMenuItem(Language.translate("About"));
1211      helpMenu.addSeparator();
1212      helpMenu.add(helpMenuItem);
1213      helpMenuItem.addActionListener(new ActionListener()
1214      { public void actionPerformed(ActionEvent e)
1215        {
1216          HTMLViewer htmv = new HTMLViewer(SnowMailClientApp.this,
1217              Language.translate("SnowMail HTML Viewer - About SnowMail"), true, false, false);
1218          htmv.setContent(
1219              "<html><body><H2>SnowMail version "+VERSION+"_"+SUBVERSION+", "+DATE+"</H2>\n\n"
1220              +"<br> + Multiple POP/SMTP accounts"
1221              +"<br> + Virtual keyboard to type unicode characters. Polish, Lituanian and Russian maps"
1222              +"<br> + SSL connections (if the mail server support them and the certificates are present in the truststore file)"
1223              +"<br> + GnuPG 1.4 support for signing/encrypting outgoing mails and verify/decrypt incoming mails, "
1224              +"<br> keys explorer, import, keypair generation, ownertrust edit"
1225              +"<br> + Strong passphrase cryptography (128 bits Blowfish) used for saving mail folders and account data"
1226              +"<br> + Addressbook (acting as whitelist) and blacklist"
1227              +"<br> + Statistical SPAM filter"
1228              +"<br> + Quick messages preview with header spam analysis"
1229              +"<br> + Full MIME tree view (content structure and attachments)"
1230              +"<br> + Internal secure HTML viewer (filtered without links, scripts and images)"
1231              +"<br> + Free software licensed under the LGPL."
1232              +"<br> + 100% pure Java 5, own protocol implementations, from the RFC's"
1233              +"<br><br>Homepage: http://snowmail.sn.funpic.de/"
1234              +"<br>Author: Stephan Heiss, stephanchaud@yahoo.fr"
1235              +"</body></html>");
1236
1237          htmv.setSize(600,520);
1238          centerComponentOnMainFrame(htmv);
1239          htmv.animateBackground(true);
1240          htmv.setVisible(true);
1241          htmv.animateBackground(false);
1242        }
1243      });
1244
1245      JMenuItem licenceMenuItem = new JMenuItem(Language.translate("License"));
1246      helpMenu.add(licenceMenuItem);
1247      licenceMenuItem.addActionListener(new ActionListener()
1248      { public void actionPerformed(ActionEvent e)
1249        {
1250          HTMLViewer hv = new HTMLViewer(SnowMailClientApp.this,
1251            "SnowMail License", true, true, true);
1252          hv.setSize(600,520);
1253          centerComponentOnMainFrame(hv);
1254
1255
1256          /*JOptionPane.showMessageDialog(null,
1257            LicenceHTMLBodyText,
1258            "SnowMail License", JOptionPane.INFORMATION_MESSAGE);*/

1259          String JavaDoc lt = loadLicense();
1260          hv.setContent(LicenceHTMLBodyText + "<p><h3>LGPL License</h3><p><pre><small>" + lt+"</small></pre>");
1261          hv.setVisible(true);
1262
1263        }
1264      });
1265
1266      // Memory label at the right
1267
//
1268
MemoryInfoPanel mip = new MemoryInfoPanel();
1269      //gridBagConstraints.anchor = gridBagConstraints.LINE_END;
1270
menuBar.add(Box.createHorizontalGlue());
1271      menuBar.add(mip);
1272      this.addAdvancedComponent(mip);
1273
1274   }
1275
1276   private String JavaDoc loadLicense()
1277   {
1278          try
1279          {
1280            InputStream is = null;
1281            File f = new File("SnowMailClient/license_lgpl.txt");
1282            if(f.exists())
1283            {
1284              is = new FileInputStream(f);
1285            }
1286            else
1287            {
1288              URL url = SnowMailClientApp.class.getResource("license_lgpl.txt");
1289              is = url.openStream();
1290            }
1291            return FileUtils.getStringContent(is);
1292
1293          }
1294          catch(Exception JavaDoc ex)
1295          {
1296
1297            ex.printStackTrace();
1298            return "ERROR, cannot read license: "+ex.getMessage();
1299          }
1300   }
1301
1302
1303   /** to be called outside from EDT
1304     trains the filter and class all mails...
1305   */

1306   private void trainSpamFilterAction()
1307   {
1308     ProgressModalDialog progressDialog = new ProgressModalDialog(
1309         SnowMailClientApp.getInstance(),
1310         Language.translate("SPAM filter generation"), false, false);
1311
1312     progressDialog.setCommentLabel(Language.translate("Analysing all mails")+"...");
1313     progressDialog.start();
1314
1315     try
1316     {
1317        progressDialog.setProgressBounds( storageTreeModel.getTotalNumberOfFolders() * 2 );
1318
1319        // Training
1320
//
1321
wordStatistic.deleteStatistic();
1322        storageTreeModel.analyseAllMailsToTrainSPAMFilter(progressDialog);
1323        progressDialog.setProgressComment(Language.translate("Building word statistic"));
1324
1325        if( wordStatistic.getNumberOfSPAMMails()==0 )
1326        {
1327          throw new Exception JavaDoc(Language.translate("You have %1 hams and %2 spam mails.",
1328             ""+wordStatistic.getNumberOfHAMMails(),
1329             ""+wordStatistic.getNumberOfSPAMMails())
1330             +"\n"+Language.translate("You must first define some spam mails."));
1331        }
1332        if( wordStatistic.getNumberOfHAMMails()==0 )
1333        {
1334          throw new Exception JavaDoc(Language.translate("You have %1 hams and %2 spam mails.",
1335             ""+wordStatistic.getNumberOfHAMMails(),
1336             ""+wordStatistic.getNumberOfSPAMMails())
1337             +"\n"+Language.translate("You must have at least one non-spam mail!"));
1338        }
1339
1340        wordStatistic.buildStatistics(progressDialog);
1341
1342
1343        // Analysis
1344
//
1345
progressDialog.setCommentLabel(Language.translate("Filtering all mails")+"...");
1346        storageTreeModel.filterAllMailsIntoSPAMCategory(progressDialog);
1347
1348        progressDialog.closeDialog();
1349
1350        JTextArea text = new JTextArea(wordStatistic.toStringStat());
1351        text.setEditable(false);
1352        JDialog dialog = new JDialog(SnowMailClientApp.getInstance(), Language.translate("SPAM Filter results"), true);
1353        text.setBackground(dialog.getBackground());
1354        JScrollPane jsp = new JScrollPane(text);
1355        jsp.setOpaque(false);
1356        text.setOpaque(false);
1357        jsp.getViewport().setOpaque(false);
1358
1359        dialog.getContentPane().setLayout(new BorderLayout());
1360        CloseControlPanel ccp = new CloseControlPanel(dialog, false, false, Language.translate("Close"));
1361        dialog.getContentPane().add(ccp, BorderLayout.SOUTH);
1362        dialog.getContentPane().add(jsp, BorderLayout.CENTER);
1363        dialog.setSize(400,400);
1364        centerComponentOnMainFrame(dialog);
1365        dialog.setVisible(true);
1366     }
1367     catch(Exception JavaDoc e2)
1368     {
1369       e2.printStackTrace();
1370       JOptionPane.showMessageDialog(this,
1371          Language.translate("Error")+": "+e2.getMessage(),
1372          Language.translate("Error occured during SPAM filter training"),
1373          JOptionPane.ERROR_MESSAGE);
1374     }
1375     finally
1376     {
1377       progressDialog.closeDialog();
1378     }
1379
1380   }
1381
1382   private JButton createToolbarButton(Action a)
1383   {
1384     //return a;/*
1385
JButton bt = new JButton(a);
1386     bt.setFocusPainted(false);
1387     return bt;
1388   }
1389
1390
1391   private void checkRootDir()
1392   {
1393    if(snowMailRoot.exists())
1394    {
1395      if(!snowMailRoot.isDirectory())
1396      {
1397        JOptionPane.showMessageDialog(null,
1398          Language.translate("The snowmail root folder can't be created, a file with the same name already exists")+":"
1399          +"\n "+snowMailRoot.getAbsolutePath()
1400          +"\n"+
1401          Language.translate("Delete this file and restart SnowMail."),
1402          Language.translate("Fatal Error"), JOptionPane.ERROR_MESSAGE);
1403
1404        System.exit(0);
1405      }
1406    }
1407    else
1408    {
1409      // create
1410
if(!snowMailRoot.mkdirs())
1411      {
1412        JOptionPane.showMessageDialog(null,
1413          Language.translate("The snowmail root folder can't be created.")
1414          +"\n "+snowMailRoot.getAbsolutePath()
1415          +"\n"
1416          +Language.translate("Please check that you have the sufficient privileges for this directory and restart SnowMail"),
1417          Language.translate("Fatal Error"), JOptionPane.ERROR_MESSAGE);
1418
1419        System.exit(0);
1420      }
1421    }
1422  } // Constructor
1423

1424
1425  /** cause the actual edited mail to save and
1426      The opened folders to save in file
1427  */

1428  public void saveAllMails(boolean close)
1429  {
1430    // all folders
1431
mailView.saveActualMessage(); // cause current to save
1432
try
1433    {
1434      this.storageTreeModel.storeAllOpenedFolders(close);
1435    }
1436    catch(Exception JavaDoc e)
1437    {
1438      e.printStackTrace();
1439    }
1440  }
1441
1442  private void terminateApplication()
1443  {
1444    final ProgressModalDialog p = new ProgressModalDialog(this, Language.translate("Closing of %", TITLE), false, true);
1445
1446    Thread JavaDoc t = new Thread JavaDoc()
1447    {
1448      public void run()
1449      {
1450         int_terminate(p);
1451      }
1452    };
1453    t.start();
1454  }
1455
1456  /** called in a thread to show UI progress
1457  */

1458  private void int_terminate(ProgressModalDialog startupProgress)
1459  {
1460    this.getAccounts().closeAllOpenedPOPConnections();
1461
1462    mailView.callBeforeTerminating();
1463
1464    startupProgress.setShowCancel(false);
1465    startupProgress.setProgressBounds(100);
1466    centerComponentOnMainFrame(startupProgress);
1467    startupProgress.start();
1468
1469
1470    properties.saveComponentSizeInINIFile(this, "SnowMailClientApp");
1471    properties.setInteger("splitPaneHorizontal", splitPaneHorizontal.getDividerLocation());
1472   // properties.setInteger("splitPaneVerticalLeft", splitPaneVerticalLeft1.getDividerLocation());
1473
properties.setInteger("splitPaneVerticalLeft2", splitPaneVerticalLeft2.getDividerLocation());
1474    properties.setInteger("splitPaneVerticalRight", splitPaneVerticalRight.getDividerLocation());
1475
1476    properties.setBoolean("advancedMode", advancedMode);
1477
1478
1479    foldersView.terminateViewAndSaveSelection(properties);
1480
1481    // properties
1482
startupProgress.setProgressValue(10, Language.translate("Saving properties")+"...");
1483    try
1484    {
1485      File propFile = new File(snowMailRoot, "properties");
1486      saveVectorToFile( propFile, properties.getVectorRepresentation());
1487    }
1488    catch(Exception JavaDoc e)
1489    {
1490      e.printStackTrace();
1491    }
1492
1493
1494    // keys, stored ONLY IF THE USER HAS SET A PASSWORD
1495
// otherwise, we will NOT save them with the default password !!!
1496

1497    startupProgress.setProgressValue(20, Language.translate("Saving keys")+"...");
1498    try
1499    {
1500
1501      if( SecretKeyManager.getInstance().isUserKeySet() )
1502      {
1503        File keyFile = new File(snowMailRoot, "userkeystore");
1504        saveVectorToFile( keyFile, SecretKeyManager.getInstance().getVectorRepresentation());
1505      }
1506    }
1507    catch(Exception JavaDoc e)
1508    {
1509      e.printStackTrace();
1510    }
1511
1512    // accounts
1513
startupProgress.setProgressValue(30, Language.translate("Saving accounts")+"...");
1514    try
1515    {
1516      File accountsFile = new File(snowMailRoot, "accounts");
1517      saveVectorToFile(accountsFile, mailAccounts.getVectorRepresentation() );
1518    }
1519    catch(Exception JavaDoc e)
1520    {
1521      e.printStackTrace();
1522    }
1523
1524    // addressBook
1525
startupProgress.setProgressValue(40, Language.translate("Saving addresses")+"...");
1526    try
1527    {
1528      File adbFile = new File(snowMailRoot, "addressBook");
1529      saveVectorToFile(adbFile, addressBook.getVectorRepresentation() );
1530    }
1531    catch(Exception JavaDoc e)
1532    {
1533      e.printStackTrace();
1534    }
1535
1536    // spamBook
1537
startupProgress.setProgressValue(45, Language.translate("Saving spam addresses")+"...");
1538    try
1539    {
1540      File spamFile = new File(snowMailRoot, "spamBook");
1541      saveVectorToFile(spamFile, spamBook.getVectorRepresentation() );
1542    }
1543    catch(Exception JavaDoc e)
1544    {
1545      e.printStackTrace();
1546    }
1547
1548    // statistic spam filter
1549
startupProgress.setProgressValue(50, Language.translate("Saving statistics")+"...");
1550    try
1551    {
1552      File statFile = new File(snowMailRoot, "wordStatistic");
1553      saveVectorToFile(statFile, this.wordStatistic.getVectorRepresentation() );
1554    }
1555    catch(Exception JavaDoc e)
1556    {
1557      e.printStackTrace();
1558    }
1559
1560    // only saved if encrypted on the disk !
1561
if( SecretKeyManager.getInstance().isUserKeySet() )
1562    {
1563      startupProgress.setProgressValue(55, Language.translate("Saving GnuPG passwords")+"...");
1564      try
1565      {
1566        File propFile = new File(snowMailRoot, "gnuPGLink");
1567        saveVectorToFile( propFile, this.gnuPGLink.getVectorRepresentation());
1568      }
1569      catch(Exception JavaDoc e)
1570      {
1571        e.printStackTrace();
1572      }
1573    }
1574
1575
1576    startupProgress.setProgressValue(65, Language.translate("Saving all opened folders")+"...");
1577    saveAllMails(false);
1578
1579    startupProgress.setVisible(false);
1580
1581    // backup
1582
startupProgress.setProgressValue(60, Language.translate("Backup")+"...");
1583    try
1584    {
1585      backup.checkDoBackup();
1586      File bcFile = new File(snowMailRoot, "backup"); // only the settings !
1587
saveVectorToFile( bcFile, backup.getVectorRepresentation());
1588    }
1589    catch(Exception JavaDoc e)
1590    {
1591      e.printStackTrace();
1592    }
1593
1594    // bye bye, see you soon, hopefully
1595
System.exit(0);
1596  }
1597
1598
1599  /** read /decipher the file
1600  */

1601  private Vector<Object JavaDoc> readVectorFromFile(File file, Object JavaDoc frameOrDialog_parent) throws Exception JavaDoc
1602  {
1603
1604     try
1605     {
1606        // normally, it don't ask,because the key will be prompted
1607
// when the keyfile is read
1608
// exceptions: the keyfile is deleted
1609
// an old file has replaced one of the system files (properties, or spamlist...)
1610
Vector<Object JavaDoc> v = FileCipherManager.getInstance().decipherVectorFromFile_ASK_KEY_IF_NEEDED(
1611                file,
1612                frameOrDialog_parent,
1613                Language.translate("Passphrase protected file"),
1614                Language.translate("Enter your Snowmail secret passphrase"));
1615        return v;
1616     }
1617     catch(Exception JavaDoc ee)
1618     {
1619       // important: don't let user in...
1620
System.exit(0);
1621       return null;
1622     }
1623  }
1624
1625  /** used to store the snowmail files (not mail folders)
1626      keymanager, ...
1627  */

1628  private void saveVectorToFile(File file, Vector<Object JavaDoc> v) throws Exception JavaDoc
1629  {
1630     FileCipherManager.getInstance().encipherVectorToFile(v, file,
1631                  SecretKeyManager.getInstance().getActualKey());
1632  }
1633
1634  /** used to center dialogs on this main frame
1635   */

1636   public static void centerComponentOnMainFrame(Component c)
1637   {
1638       int x, y, w, h;
1639       if(ref==null || ref.getSize().getWidth()<100)
1640       {
1641          Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1642          x = 0;
1643          y = 0;
1644          w = (int) screen.getWidth();
1645          h = (int) screen.getHeight();
1646       }
1647       else
1648       {
1649          x = (int) ref.getLocation().getX();
1650          y = (int) ref.getLocation().getY();
1651          w = (int) ref.getSize().getWidth();
1652          h = (int) ref.getSize().getHeight();
1653       }
1654
1655       int px = x + (int) (w - c.getSize().getWidth())/2;
1656       int py = y + (int) (h - c.getSize().getHeight())/2;
1657       if(px<0) px = 0;
1658       if(py<0) py = 0;
1659       c.setLocation(px,py);
1660   }
1661
1662  /** load an ImageIcon, either in the jar file (during the normal execution)
1663      or in the source path, during the development.
1664      Every images are read in the event dispatch thread to avoid some runtime exceptions.
1665  */

1666  public static ImageIcon loadImageIcon(final String JavaDoc name)
1667  {
1668    final ImageIcon[] iconContainer = new ImageIcon[1];
1669    SwingSafeRunnable ssr = new SwingSafeRunnable(new Runnable JavaDoc()
1670    {
1671      public void run()
1672      {
1673        URL url = SnowMailClientApp.class.getResource(name);
1674        if(url!=null)
1675        {
1676           iconContainer[0] = new ImageIcon(Toolkit.getDefaultToolkit().getImage(url));
1677        }
1678        else
1679        {
1680           iconContainer[0] = new ImageIcon("SnowMailClient/" + name);
1681        }
1682      }
1683    }, true);
1684    ssr.run();
1685    return iconContainer[0];
1686  }
1687
1688
1689  public static void copyToClipboard(final String JavaDoc content)
1690  {
1691     Clipboard clip = java.awt.Toolkit.getDefaultToolkit().getSystemClipboard();
1692     Transferable transferable = new Transferable()
1693     {
1694        public DataFlavor[] getTransferDataFlavors()
1695        {
1696          return new DataFlavor[]{ DataFlavor.plainTextFlavor};
1697        }
1698        public boolean isDataFlavorSupported(DataFlavor f)
1699        {
1700          return f.equals(DataFlavor.plainTextFlavor);
1701        }
1702        public Object JavaDoc getTransferData(DataFlavor f) { return content; }
1703     };
1704     clip.setContents(
1705       transferable,
1706       new ClipboardOwner()
1707       {
1708         public void lostOwnership(Clipboard c, Transferable t)
1709         {
1710         }
1711       });
1712  }
1713
1714
1715  public static JPanel wrapLeft(Component c)
1716  {
1717    JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0));
1718    p.setOpaque(false);
1719    p.add(c);
1720    return p;
1721  }
1722
1723  public static JPanel wrapRight(Component c)
1724  {
1725    JPanel p = new JPanel(new FlowLayout(FlowLayout.RIGHT,0,0));
1726    p.setOpaque(false);
1727    p.add(c);
1728    return p;
1729  }
1730
1731
1732/** Initially contains the snowraver ssl certificate.
1733* TODO: dynamically add/remove certs.
1734* file:///C:/java/docs/docs1.6/guide/security/jsse/JSSERefGuide.html#X509TrustManager
1735*/

1736  private void initializeSSLCertificateInfo()
1737  {
1738     File trustStoreFile = new File(this.getSnowMailRoot(),
1739              "trustStore.certificates");
1740
1741     System.setProperty("javax.net.ssl.trustStore", trustStoreFile.getAbsolutePath() );
1742
1743     if(!trustStoreFile.exists())
1744     {
1745       // copy the default keystore
1746
if(!copySSLTrustStore(trustStoreFile))
1747       {
1748          JOptionPane.showMessageDialog(
1749            null,
1750             Language.translate("No SSL Truststore fount at\n %"
1751                +"\nThis keystore must contain all your trusted sites certificates."
1752                +"\nWithout this keystore, you'll not be able to manage SSL connections validation.",
1753                trustStoreFile.getAbsolutePath()
1754            ),
1755            Language.translate("TrustStore is not present"),
1756            JOptionPane.ERROR_MESSAGE);
1757       }
1758     }
1759     else
1760     {
1761       //ok System.out.println("TrustStore present: "+trustStoreFile.getAbsolutePath());
1762
}
1763
1764
1765  }
1766
1767
1768  private boolean copySSLTrustStore(File file)
1769  {
1770        // smart intelligent clever mode,
1771
// try to extract from jarfile
1772
ClassLoader JavaDoc cl = SnowMailClientApp.class.getClassLoader();
1773
1774        FileOutputStream fos = null;
1775        try
1776        {
1777          URL url = cl.getResource("trustStore.certificates");
1778          InputStream is = null;
1779          if(url!=null)
1780          {
1781            is = url.openStream();
1782          }
1783          else
1784          {
1785            is = new FileInputStream("trustStore.certificates");
1786          }
1787
1788
1789          if(is!=null)
1790          {
1791            // copy
1792
File parentDir = file.getParentFile();
1793            if(!parentDir.exists()) parentDir.mkdirs();
1794            fos = new FileOutputStream(file);
1795
1796            byte[] buffer = new byte[256];
1797            int read = 0;
1798            while((read=is.read(buffer))!=-1)
1799            {
1800              fos.write(buffer,0,read);
1801            }
1802            return true;
1803          }
1804          else
1805          {
1806            System.out.println("URL is null, cannot copy certificate");
1807            return false;
1808          }
1809        }
1810        catch(Exception JavaDoc e)
1811        {
1812          e.printStackTrace();
1813          return false;
1814        }
1815        finally
1816        {
1817          if(fos!=null) {try{ fos.close(); } catch(Exception JavaDoc ee){}}
1818        }
1819  }
1820
1821
1822  /** Options (with examples)
1823          -homeDir="c:/document and settings/mr.bean"
1824          -DEBUG=TRUE
1825  */

1826  public static void main( String JavaDoc[] arguments )
1827  {
1828
1829     parseArguments(arguments);
1830
1831     if(debug)
1832     {
1833        RepaintManager.setCurrentManager(new debug.CheckThreadViolationRepaintManager());
1834     }
1835
1836     if(snowMailRoot==null)
1837     {
1838       // default dir, if not set as argument
1839
snowMailRoot = new File(System.getProperty("user.home"), "snowmail");
1840     }
1841
1842     // Activate the language
1843
Language.baseDirectory = snowMailRoot.getAbsolutePath();
1844     Language.getInstance();
1845
1846     // cause dialogs to be localized
1847
Locale.setDefault( Language.getInstance().getLocale() );
1848
1849
1850
1851     // initialize the L&F defaults
1852
ThemesManager.baseDirectory = snowMailRoot.getAbsolutePath();
1853     ThemesManager.getInstance();
1854     JFrame.setDefaultLookAndFeelDecorated(true);
1855     JDialog.setDefaultLookAndFeelDecorated(true);
1856
1857
1858     EventQueue.invokeLater(new Runnable JavaDoc() { public void run() {
1859        new SnowMailClientApp();
1860     }});
1861
1862
1863     // jing some bells
1864
//SynthesizerDemo.main(null);
1865

1866  } // main
1867

1868
1869  /** is static because must be evaluated before instance created...
1870  */

1871  private static void parseArguments(String JavaDoc[] args)
1872  {
1873    if(args==null || args.length==0) return;
1874
1875    debug = false;
1876    for(int i=0; i<args.length; i++)
1877    {
1878      //System.out.println("Start argument "+args[i]);
1879
if(args[i].toUpperCase().startsWith("-HOMEDIR="))
1880      {
1881         String JavaDoc snowMailRootName = removeQuotes(args[i].substring(9).trim()).trim();
1882         snowMailRoot = new File(snowMailRootName);
1883
1884         System.out.println("homeDir = "+snowMailRootName);
1885      }
1886/* if(args[i].toUpperCase().startsWith("-USERNAME="))
1887      {
1888         String userName = RemoveQuotes(args[i].substring(10).trim()).trim();
1889         //snowMailRoot = new File(snowMailRootName);
1890
1891         System.out.println("User name = "+userName);
1892      }*/

1893      if(args[i].toUpperCase().startsWith("-DEBUG=TRUE")
1894       ||args[i].equalsIgnoreCase("-DEBUG"))
1895      {
1896         debug = true;
1897      }
1898
1899    }
1900  }
1901
1902  /** @return the text without starting quotes " or '
1903  */

1904  public static String JavaDoc removeQuotes(String JavaDoc _text)
1905  {
1906         String JavaDoc text = _text;
1907         if(text.charAt(0)=='\"'
1908         || text.charAt(0)=='\'')
1909         {
1910           text = text.substring(1);
1911         }
1912
1913         if(text.charAt(text.length()-1)=='\"'
1914         || text.charAt(text.length()-1)=='\'')
1915         {
1916           text = text.substring(1);
1917         }
1918         return text;
1919
1920  }
1921
1922} // SnowMailClientApp
Popular Tags