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  
28  import javax.swing.*;
29  import java.awt.*;
30  import java.awt.event.ActionListener;
31  import java.util.ArrayList;
32  
33  /**
34   * Failover GUI for Java 1.5 without SWT
35   */
36  public class FrameGatewayTray implements DavGatewayTrayInterface {
37      protected FrameGatewayTray() {
38      }
39  
40      static JFrame mainFrame;
41      static AboutFrame aboutFrame;
42      static SettingsFrame settingsFrame;
43      private static JEditorPane errorArea;
44      private static JLabel errorLabel;
45      private static JEditorPane messageArea;
46      private static ArrayList<Image> frameIcons;
47      private static Image image;
48      private static Image activeImage;
49      private static Image inactiveImage;
50      private boolean isActive = true;
51  
52      /**
53       * Return AWT Image icon for frame title.
54       *
55       * @return frame icon
56       */
57      @Override
58      public java.util.List<Image> getFrameIcons() {
59          return frameIcons;
60      }
61  
62      /**
63       * Switch tray icon between active and standby icon.
64       */
65      public void switchIcon() {
66          isActive = true;
67          SwingUtilities.invokeLater(() -> {
68              Image currentImage = mainFrame.getIconImage();
69              if (currentImage != null && currentImage.equals(image)) {
70                  mainFrame.setIconImage(activeImage);
71              } else {
72                  mainFrame.setIconImage(image);
73              }
74          });
75      }
76  
77      /**
78       * Set tray icon to inactive (network down)
79       */
80      public void resetIcon() {
81          SwingUtilities.invokeLater(() -> mainFrame.setIconImage(image));
82      }
83  
84      /**
85       * Set tray icon to inactive (network down)
86       */
87      public void inactiveIcon() {
88          isActive = false;
89          SwingUtilities.invokeLater(() -> mainFrame.setIconImage(inactiveImage));
90      }
91  
92      /**
93       * Check if current tray status is inactive (network down).
94       *
95       * @return true if inactive
96       */
97      public boolean isActive() {
98          return isActive;
99      }
100 
101     /**
102      * Log and display balloon message according to log level.
103      *
104      * @param message text message
105      * @param level   log level
106      */
107     public void displayMessage(final String message, final Level level) {
108         SwingUtilities.invokeLater(() -> {
109             if (errorArea != null && messageArea != null) {
110                 if (level.equals(Level.INFO)) {
111                     errorLabel.setIcon(UIManager.getIcon("OptionPane.informationIcon"));
112                     errorArea.setText(message);
113                 } else if (level.equals(Level.WARN)) {
114                     errorLabel.setIcon(UIManager.getIcon("OptionPane.warningIcon"));
115                     errorArea.setText(message);
116                 } else if (level.equals(Level.ERROR)) {
117                     errorLabel.setIcon(UIManager.getIcon("OptionPane.errorIcon"));
118                     errorArea.setText(message);
119                 }
120                 messageArea.setText(message);
121             }
122         });
123     }
124 
125     /**
126      * Open about window
127      */
128     public void about() {
129         SwingUtilities.invokeLater(() -> {
130             aboutFrame.update();
131             aboutFrame.setVisible(true);
132             aboutFrame.toFront();
133             aboutFrame.requestFocus();
134         });
135     }
136 
137     /**
138      * Open settings window
139      */
140     public void preferences() {
141         SwingUtilities.invokeLater(() -> {
142             settingsFrame.reload();
143             settingsFrame.setVisible(true);
144             settingsFrame.toFront();
145             settingsFrame.repaint();
146             settingsFrame.requestFocus();
147         });
148     }
149 
150     /**
151      * Create tray icon and register frame listeners.
152      */
153     public void init() {
154         SwingUtilities.invokeLater(this::createAndShowGUI);
155     }
156 
157     public void dispose() {
158         // dispose frames
159         settingsFrame.dispose();
160         aboutFrame.dispose();
161     }
162 
163     protected void buildMenu() {
164         // create a popup menu
165         JMenu menu = new JMenu(BundleMessage.format("UI_DAVMAIL_GATEWAY"));
166         JMenuBar menuBar = new JMenuBar();
167         menuBar.add(menu);
168         mainFrame.setJMenuBar(menuBar);
169 
170         // create an action settingsListener to listen for settings action executed on the tray icon
171         ActionListener aboutListener = e -> about();
172         // create menu item for the default action
173         JMenuItem aboutItem = new JMenuItem(BundleMessage.format("UI_ABOUT"));
174         aboutItem.addActionListener(aboutListener);
175         menu.add(aboutItem);
176 
177 
178         // create an action settingsListener to listen for settings action executed on the tray icon
179         ActionListener settingsListener = e -> preferences();
180         // create menu item for the default action
181         JMenuItem defaultItem = new JMenuItem(BundleMessage.format("UI_SETTINGS"));
182         defaultItem.addActionListener(settingsListener);
183         menu.add(defaultItem);
184 
185         JMenuItem logItem = new JMenuItem(BundleMessage.format("UI_SHOW_LOGS"));
186         logItem.addActionListener(e -> DavGatewayTray.showLogs());
187         menu.add(logItem);
188 
189         // create an action exitListener to listen for exit action executed on the tray icon
190         ActionListener exitListener = e -> {
191             try {
192                 DavGateway.stop();
193             } catch (Exception exc) {
194                 DavGatewayTray.error(exc);
195             }
196             // make sure we do exit
197             System.exit(0);
198         };
199         // create menu item for the exit action
200         JMenuItem exitItem = new JMenuItem(BundleMessage.format("UI_EXIT"));
201         exitItem.addActionListener(exitListener);
202         menu.add(exitItem);
203     }
204 
205     protected void createAndShowGUI() {
206         // set cross platform look and feel on Linux, except is swing.defaultlaf is set
207         if (Settings.isLinux() && System.getProperty("swing.defaultlaf") == null) {
208             System.setProperty("swing.defaultlaf", UIManager.getCrossPlatformLookAndFeelClassName());
209         } else {
210             System.setProperty("swing.defaultlaf", UIManager.getSystemLookAndFeelClassName());
211         }
212         String imageName = AwtGatewayTray.TRAY_PNG;
213         String activeImageName = AwtGatewayTray.TRAY_ACTIVE_PNG;
214         String inactiveImageName = AwtGatewayTray.TRAY_INACTIVE_PNG;
215         // use hi res icons on Linux
216         if (Settings.isLinux()) {
217             imageName = AwtGatewayTray.TRAY128_PNG;
218             activeImageName = AwtGatewayTray.TRAY128_ACTIVE_PNG;
219             inactiveImageName = AwtGatewayTray.TRAY128_INACTIVE_PNG;
220         }
221         image = DavGatewayTray.loadImage(imageName);
222         activeImage = DavGatewayTray.loadImage(activeImageName);
223         inactiveImage = DavGatewayTray.loadImage(inactiveImageName);
224 
225         frameIcons = new ArrayList<>();
226         frameIcons.add(image);
227         frameIcons.add(DavGatewayTray.loadImage(AwtGatewayTray.TRAY128_PNG));
228 
229         mainFrame = new JFrame();
230         mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
231         mainFrame.setTitle(BundleMessage.format("UI_DAVMAIL_GATEWAY"));
232         mainFrame.setIconImages(frameIcons);
233 
234         JPanel errorPanel = new JPanel();
235         errorPanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_LAST_MESSAGE")));
236         errorPanel.setLayout(new BoxLayout(errorPanel, BoxLayout.X_AXIS));
237         errorArea = new JTextPane();
238         errorArea.setEditable(false);
239         errorArea.setBackground(mainFrame.getBackground());
240         errorLabel = new JLabel();
241         errorPanel.add(errorLabel);
242         errorPanel.add(errorArea);
243 
244         JPanel messagePanel = new JPanel();
245         messagePanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_LAST_LOG")));
246         messagePanel.setLayout(new BoxLayout(messagePanel, BoxLayout.X_AXIS));
247 
248         messageArea = new JTextPane();
249         messageArea.setText(BundleMessage.format("LOG_STARTING_DAVMAIL"));
250         messageArea.setEditable(false);
251         messageArea.setBackground(mainFrame.getBackground());
252         messagePanel.add(messageArea);
253 
254         JPanel mainPanel = new JPanel();
255         mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
256         mainPanel.add(errorPanel);
257         mainPanel.add(messagePanel);
258         mainFrame.add(mainPanel);
259 
260         aboutFrame = new AboutFrame();
261         settingsFrame = new SettingsFrame();
262         buildMenu();
263 
264         mainFrame.setMinimumSize(new Dimension(400, 250));
265         mainFrame.pack();
266         // workaround MacOSX
267         if (mainFrame.getSize().width < 400 || mainFrame.getSize().height < 180) {
268             mainFrame.setSize(Math.max(mainFrame.getSize().width, 400),
269                     Math.max(mainFrame.getSize().height, 180));
270         }
271         // center frame
272         mainFrame.setLocation(mainFrame.getToolkit().getScreenSize().width / 2 -
273                 mainFrame.getSize().width / 2,
274                 mainFrame.getToolkit().getScreenSize().height / 2 -
275                         mainFrame.getSize().height / 2);
276         mainFrame.setVisible(true);
277 
278         // display settings frame on first start
279         if (Settings.isFirstStart()) {
280             settingsFrame.setVisible(true);
281             settingsFrame.toFront();
282             settingsFrame.repaint();
283             settingsFrame.requestFocus();
284         }
285     }
286 }