View Javadoc
1   /*
2    * DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
3    * Copyright (C) 2009  Mickael Guessant
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    *
10   * This program 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
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18   */
19  package davmail.ui.tray;
20  
21  import davmail.BundleMessage;
22  import davmail.DavGateway;
23  import davmail.Settings;
24  import davmail.ui.AboutFrame;
25  import davmail.ui.SettingsFrame;
26  import org.apache.log4j.Level;
27  import org.apache.log4j.Logger;
28  import org.apache.log4j.lf5.LF5Appender;
29  import org.apache.log4j.lf5.LogLevel;
30  import org.apache.log4j.lf5.viewer.LogBrokerMonitor;
31  
32  import javax.swing.*;
33  import java.awt.*;
34  import java.awt.event.ActionEvent;
35  import java.awt.event.ActionListener;
36  
37  /**
38   * Failover GUI for Java 1.5 without SWT
39   */
40  public class FrameGatewayTray implements DavGatewayTrayInterface {
41      protected FrameGatewayTray() {
42      }
43  
44      static JFrame mainFrame;
45      static AboutFrame aboutFrame;
46      static SettingsFrame settingsFrame;
47      LogBrokerMonitor logBrokerMonitor;
48      private static JEditorPane errorArea;
49      private static JLabel errorLabel;
50      private static JEditorPane messageArea;
51      private static Image image;
52      private static Image image2;
53      private static Image inactiveImage;
54      private boolean isActive = true;
55  
56      /**
57       * Return AWT Image icon for frame title.
58       *
59       * @return frame icon
60       */
61      public Image getFrameIcon() {
62          return image;
63      }
64  
65      /**
66       * Switch tray icon between active and standby icon.
67       */
68      public void switchIcon() {
69          isActive = true;
70          SwingUtilities.invokeLater(new Runnable() {
71              public void run() {
72                  Image currentImage = mainFrame.getIconImage();
73                  if (currentImage != null && currentImage.equals(image)) {
74                      mainFrame.setIconImage(image2);
75                  } else {
76                      mainFrame.setIconImage(image);
77                  }
78              }
79          });
80      }
81  
82      /**
83       * Set tray icon to inactive (network down)
84       */
85      public void resetIcon() {
86          SwingUtilities.invokeLater(new Runnable() {
87              public void run() {
88                  mainFrame.setIconImage(image);
89              }
90          });
91      }
92  
93      /**
94       * Set tray icon to inactive (network down)
95       */
96      public void inactiveIcon() {
97          isActive = false;
98          SwingUtilities.invokeLater(new Runnable() {
99              public void run() {
100                 mainFrame.setIconImage(inactiveImage);
101             }
102         });
103     }
104 
105     /**
106      * Check if current tray status is inactive (network down).
107      *
108      * @return true if inactive
109      */
110     public boolean isActive() {
111         return isActive;
112     }
113 
114     /**
115      * Log and display balloon message according to log level.
116      *
117      * @param message text message
118      * @param level   log level
119      */
120     public void displayMessage(final String message, final Level level) {
121         SwingUtilities.invokeLater(new Runnable() {
122             public void run() {
123                 if (errorArea != null && messageArea != null) {
124                     if (level.equals(Level.INFO)) {
125                         errorLabel.setIcon(UIManager.getIcon("OptionPane.informationIcon"));
126                         errorArea.setText(message);
127                     } else if (level.equals(Level.WARN)) {
128                         errorLabel.setIcon(UIManager.getIcon("OptionPane.warningIcon"));
129                         errorArea.setText(message);
130                     } else if (level.equals(Level.ERROR)) {
131                         errorLabel.setIcon(UIManager.getIcon("OptionPane.errorIcon"));
132                         errorArea.setText(message);
133                     }
134                     messageArea.setText(message);
135                 }
136             }
137         });
138     }
139 
140     /**
141      * Open about window
142      */
143     public void about() {
144         SwingUtilities.invokeLater(new Runnable() {
145             public void run() {
146                 aboutFrame.update();
147                 aboutFrame.setVisible(true);
148                 aboutFrame.toFront();
149                 aboutFrame.requestFocus();                
150             }
151         });
152     }
153 
154     /**
155      * Open settings window
156      */
157     public void preferences() {
158         SwingUtilities.invokeLater(new Runnable() {
159             public void run() {
160                 settingsFrame.reload();
161                 settingsFrame.setVisible(true);
162                 settingsFrame.toFront();
163                 settingsFrame.repaint();
164                 settingsFrame.requestFocus();
165             }
166         });
167     }
168 
169     /**
170      * Open logging window.
171      */
172     public void showLogs() {
173         Logger rootLogger = Logger.getRootLogger();
174         LF5Appender lf5Appender = (LF5Appender) rootLogger.getAppender("LF5Appender");
175         if (lf5Appender == null) {
176             logBrokerMonitor = new LogBrokerMonitor(LogLevel.getLog4JLevels()) {
177                 @Override
178                 protected void closeAfterConfirm() {
179                     hide();
180                 }
181             };
182             lf5Appender = new LF5Appender(logBrokerMonitor);
183             lf5Appender.setName("LF5Appender");
184             rootLogger.addAppender(lf5Appender);
185         }
186         lf5Appender.getLogBrokerMonitor().show();
187     }
188 
189     /**
190      * Create tray icon and register frame listeners.
191      */
192     public void init() {
193         SwingUtilities.invokeLater(new Runnable() {
194             public void run() {
195                 createAndShowGUI();
196             }
197         });
198     }
199 
200     public void dispose() {
201         // dispose frames
202         settingsFrame.dispose();
203         aboutFrame.dispose();
204         if (logBrokerMonitor != null) {
205             logBrokerMonitor.dispose();
206         }
207     }
208 
209     protected void buildMenu() {
210         // create a popup menu
211         JMenu menu = new JMenu(BundleMessage.format("UI_DAVMAIL_GATEWAY"));
212         JMenuBar menuBar = new JMenuBar();
213         menuBar.add(menu);
214         mainFrame.setJMenuBar(menuBar);
215 
216         // create an action settingsListener to listen for settings action executed on the tray icon
217         ActionListener aboutListener = new ActionListener() {
218             public void actionPerformed(ActionEvent e) {
219                 about();
220             }
221         };
222         // create menu item for the default action
223         JMenuItem aboutItem = new JMenuItem(BundleMessage.format("UI_ABOUT"));
224         aboutItem.addActionListener(aboutListener);
225         menu.add(aboutItem);
226 
227 
228         // create an action settingsListener to listen for settings action executed on the tray icon
229         ActionListener settingsListener = new ActionListener() {
230             public void actionPerformed(ActionEvent e) {
231                 preferences();
232             }
233         };
234         // create menu item for the default action
235         JMenuItem defaultItem = new JMenuItem(BundleMessage.format("UI_SETTINGS"));
236         defaultItem.addActionListener(settingsListener);
237         menu.add(defaultItem);
238 
239         JMenuItem logItem = new JMenuItem(BundleMessage.format("UI_SHOW_LOGS"));
240         logItem.addActionListener(new ActionListener() {
241             public void actionPerformed(ActionEvent e) {
242                 showLogs();
243             }
244         });
245         menu.add(logItem);
246 
247         // create an action exitListener to listen for exit action executed on the tray icon
248         ActionListener exitListener = new ActionListener() {
249             public void actionPerformed(ActionEvent e) {
250                 try {
251                     DavGateway.stop();
252                 } catch (Exception exc) {
253                     DavGatewayTray.error(exc);
254                 }
255                 // make sure we do exit
256                 System.exit(0);
257             }
258         };
259         // create menu item for the exit action
260         JMenuItem exitItem = new JMenuItem(BundleMessage.format("UI_EXIT"));
261         exitItem.addActionListener(exitListener);
262         menu.add(exitItem);
263     }
264 
265     protected void createAndShowGUI() {
266         System.setProperty("swing.defaultlaf", UIManager.getSystemLookAndFeelClassName());
267 
268         image = DavGatewayTray.loadImage("tray.png");
269         image2 = DavGatewayTray.loadImage(AwtGatewayTray.TRAY_ACTIVE_PNG);
270         inactiveImage = DavGatewayTray.loadImage(AwtGatewayTray.TRAY_INACTIVE_PNG);
271 
272         mainFrame = new JFrame();
273         mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
274         mainFrame.setTitle(BundleMessage.format("UI_DAVMAIL_GATEWAY"));
275         mainFrame.setIconImage(image);
276 
277         JPanel errorPanel = new JPanel();
278         errorPanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_LAST_MESSAGE")));
279         errorPanel.setLayout(new BoxLayout(errorPanel, BoxLayout.X_AXIS));
280         errorArea = new JTextPane();
281         errorArea.setEditable(false);
282         errorArea.setBackground(mainFrame.getBackground());
283         errorLabel = new JLabel();
284         errorPanel.add(errorLabel);
285         errorPanel.add(errorArea);
286 
287         JPanel messagePanel = new JPanel();
288         messagePanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_LAST_LOG")));
289         messagePanel.setLayout(new BoxLayout(messagePanel, BoxLayout.X_AXIS));
290 
291         messageArea = new JTextPane();
292         messageArea.setText(BundleMessage.format("LOG_STARTING_DAVMAIL"));
293         messageArea.setEditable(false);
294         messageArea.setBackground(mainFrame.getBackground());
295         messagePanel.add(messageArea);
296 
297         JPanel mainPanel = new JPanel();
298         mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
299         mainPanel.add(errorPanel);
300         mainPanel.add(messagePanel);
301         mainFrame.add(mainPanel);
302 
303         aboutFrame = new AboutFrame();
304         settingsFrame = new SettingsFrame();
305         buildMenu();
306 
307         mainFrame.setMinimumSize(new Dimension(400, 180));
308         mainFrame.pack();
309         // workaround MacOSX
310         if (mainFrame.getSize().width < 400 || mainFrame.getSize().height < 180) {
311             mainFrame.setSize(Math.max(mainFrame.getSize().width, 400),
312                     Math.max(mainFrame.getSize().height, 180));
313         }
314         // center frame
315         mainFrame.setLocation(mainFrame.getToolkit().getScreenSize().width / 2 -
316                 mainFrame.getSize().width / 2,
317                 mainFrame.getToolkit().getScreenSize().height / 2 -
318                         mainFrame.getSize().height / 2);
319         mainFrame.setVisible(true);
320 
321         // display settings frame on first start
322         if (Settings.isFirstStart()) {
323             settingsFrame.setVisible(true);
324             settingsFrame.toFront();
325             settingsFrame.repaint();
326             settingsFrame.requestFocus();
327         }
328     }
329 }