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   * Tray icon handler based on java 1.6
39   */
40  @SuppressWarnings("Since15")
41  public class AwtGatewayTray implements DavGatewayTrayInterface {
42      protected static final String TRAY_ACTIVE_PNG = "tray2.png";
43      protected static final String TRAY_PNG = "tray.png";
44      protected static final String TRAY_INACTIVE_PNG = "trayinactive.png";
45  
46      protected AwtGatewayTray() {
47      }
48  
49      static AboutFrame aboutFrame;
50      static SettingsFrame settingsFrame;
51      ActionListener settingsListener;
52  
53      static TrayIcon trayIcon;
54      private static Image image;
55      private static Image image2;
56      private static Image inactiveImage;
57      static LogBrokerMonitor logBrokerMonitor;
58      private boolean isActive = true;
59  
60      /**
61       * Return AWT Image icon for frame title.
62       *
63       * @return frame icon
64       */
65      public Image getFrameIcon() {
66          return image;
67      }
68  
69      /**
70       * Switch tray icon between active and standby icon.
71       */
72      public void switchIcon() {
73          isActive = true;
74          SwingUtilities.invokeLater(new Runnable() {
75              public void run() {
76                  if (trayIcon.getImage().equals(image)) {
77                      trayIcon.setImage(image2);
78                  } else {
79                      trayIcon.setImage(image);
80                  }
81              }
82          });
83      }
84  
85      /**
86       * Set tray icon to inactive (network down)
87       */
88      public void resetIcon() {
89          SwingUtilities.invokeLater(new Runnable() {
90              public void run() {
91                  trayIcon.setImage(image);
92              }
93          });
94      }
95  
96      /**
97       * Set tray icon to inactive (network down)
98       */
99      public void inactiveIcon() {
100         isActive = false;
101         SwingUtilities.invokeLater(new Runnable() {
102             public void run() {
103                 trayIcon.setImage(inactiveImage);
104             }
105         });
106     }
107 
108     /**
109      * Check if current tray status is inactive (network down).
110      *
111      * @return true if inactive
112      */
113     public boolean isActive() {
114         return isActive;
115     }
116 
117     /**
118      * Display balloon message for log level.
119      *
120      * @param message text message
121      * @param level   log level
122      */
123     public void displayMessage(final String message, final Level level) {
124         SwingUtilities.invokeLater(new Runnable() {
125             public void run() {
126                 if (trayIcon != null) {
127                     TrayIcon.MessageType messageType = null;
128                     if (level.equals(Level.INFO)) {
129                         messageType = TrayIcon.MessageType.INFO;
130                     } else if (level.equals(Level.WARN)) {
131                         messageType = TrayIcon.MessageType.WARNING;
132                     } else if (level.equals(Level.ERROR)) {
133                         messageType = TrayIcon.MessageType.ERROR;
134                     }
135                     if (messageType != null) {
136                         trayIcon.displayMessage(BundleMessage.format("UI_DAVMAIL_GATEWAY"), message, messageType);
137                     }
138                     trayIcon.setToolTip(BundleMessage.format("UI_DAVMAIL_GATEWAY") + '\n' + message);
139                 }
140             }
141         });
142     }
143 
144     /**
145      * Open about window
146      */
147     public void about() {
148         SwingUtilities.invokeLater(new Runnable() {
149             public void run() {
150                 aboutFrame.update();
151                 aboutFrame.setVisible(true);
152                 aboutFrame.toFront();
153                 aboutFrame.requestFocus();
154             }
155         });
156     }
157 
158     /**
159      * Open settings window
160      */
161     public void preferences() {
162         SwingUtilities.invokeLater(new Runnable() {
163             public void run() {
164                 settingsFrame.reload();
165                 settingsFrame.setVisible(true);
166                 settingsFrame.toFront();
167                 settingsFrame.repaint();
168                 settingsFrame.requestFocus();
169             }
170         });
171     }
172 
173     /**
174      * Create tray icon and register frame listeners.
175      */
176     public void init() {
177         SwingUtilities.invokeLater(new Runnable() {
178             public void run() {
179                 createAndShowGUI();
180             }
181         });
182     }
183 
184     public void dispose() {
185         SystemTray.getSystemTray().remove(trayIcon);
186 
187         // dispose frames
188         settingsFrame.dispose();
189         aboutFrame.dispose();
190         if (logBrokerMonitor != null) {
191             logBrokerMonitor.dispose();
192         }
193     }
194 
195     protected void createAndShowGUI() {
196         System.setProperty("swing.defaultlaf", UIManager.getSystemLookAndFeelClassName());
197 
198         // get the SystemTray instance
199         SystemTray tray = SystemTray.getSystemTray();
200         image = DavGatewayTray.loadImage(getTrayIconPath());
201         image2 = DavGatewayTray.loadImage(getTrayIconActivePath());
202         inactiveImage = DavGatewayTray.loadImage(getTrayIconInactivePath());
203 
204         // create a popup menu
205         PopupMenu popup = new PopupMenu();
206 
207         aboutFrame = new AboutFrame();
208         // create an action settingsListener to listen for settings action executed on the tray icon
209         ActionListener aboutListener = new ActionListener() {
210             public void actionPerformed(ActionEvent e) {
211                 about();
212             }
213         };
214         // create menu item for the default action
215         MenuItem aboutItem = new MenuItem(BundleMessage.format("UI_ABOUT"));
216         aboutItem.addActionListener(aboutListener);
217         popup.add(aboutItem);
218 
219         settingsFrame = new SettingsFrame();
220         // create an action settingsListener to listen for settings action executed on the tray icon
221         settingsListener = new ActionListener() {
222             public void actionPerformed(ActionEvent e) {
223                 preferences();
224             }
225         };
226         // create menu item for the default action
227         MenuItem defaultItem = new MenuItem(BundleMessage.format("UI_SETTINGS"));
228         defaultItem.addActionListener(settingsListener);
229         popup.add(defaultItem);
230 
231         MenuItem logItem = new MenuItem(BundleMessage.format("UI_SHOW_LOGS"));
232         logItem.addActionListener(new ActionListener() {
233             public void actionPerformed(ActionEvent e) {
234                 Logger rootLogger = Logger.getRootLogger();
235                 LF5Appender lf5Appender = (LF5Appender) rootLogger.getAppender("LF5Appender");
236                 if (lf5Appender == null) {
237                     logBrokerMonitor = new LogBrokerMonitor(LogLevel.getLog4JLevels()) {
238                         @Override
239                         protected void closeAfterConfirm() {
240                             hide();
241                         }
242                     };
243                     lf5Appender = new LF5Appender(logBrokerMonitor);
244                     lf5Appender.setName("LF5Appender");
245                     rootLogger.addAppender(lf5Appender);
246                 }
247                 lf5Appender.getLogBrokerMonitor().show();
248             }
249         });
250         popup.add(logItem);
251 
252         // create an action exitListener to listen for exit action executed on the tray icon
253         ActionListener exitListener = new ActionListener() {
254             public void actionPerformed(ActionEvent e) {
255                 try {
256                     DavGateway.stop();
257                 } catch (Exception exc) {
258                     DavGatewayTray.error(exc);
259                 }
260                 // make sure we do exit
261                 System.exit(0);
262             }
263         };
264         // create menu item for the exit action
265         MenuItem exitItem = new MenuItem(BundleMessage.format("UI_EXIT"));
266         exitItem.addActionListener(exitListener);
267         popup.add(exitItem);
268 
269         /// ... add other items
270         // construct a TrayIcon
271         trayIcon = new TrayIcon(image, BundleMessage.format("UI_DAVMAIL_GATEWAY"), popup);
272         // set the TrayIcon properties
273         trayIcon.addActionListener(settingsListener);
274         // ...
275         // add the tray image
276         try {
277             tray.add(trayIcon);
278         } catch (AWTException e) {
279             DavGatewayTray.warn(new BundleMessage("LOG_UNABLE_TO_CREATE_TRAY"), e);
280         }
281 
282         // display settings frame on first start
283         if (Settings.isFirstStart()) {
284             settingsFrame.setVisible(true);
285             settingsFrame.toFront();
286             settingsFrame.repaint();
287             settingsFrame.requestFocus();
288         }
289     }
290 
291     protected String getTrayIconPath() {
292         return AwtGatewayTray.TRAY_PNG;
293     }
294 
295     protected String getTrayIconActivePath() {
296         return AwtGatewayTray.TRAY_ACTIVE_PNG;
297     }
298 
299     protected String getTrayIconInactivePath() {
300         return AwtGatewayTray.TRAY_INACTIVE_PNG;
301     }
302 }