1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package net.sf.jhylafax;
21
22 import gnu.hylafax.HylaFAXClient;
23 import gnu.inet.ftp.ConnectionEvent;
24 import gnu.inet.ftp.ConnectionListener;
25 import gnu.inet.ftp.ServerResponseException;
26
27 import java.awt.BorderLayout;
28 import java.awt.Font;
29 import java.awt.Image;
30 import java.awt.MenuItem;
31 import java.awt.event.ActionEvent;
32 import java.awt.event.KeyEvent;
33 import java.awt.event.WindowAdapter;
34 import java.awt.event.WindowEvent;
35 import java.beans.PropertyChangeEvent;
36 import java.beans.PropertyChangeListener;
37 import java.io.BufferedInputStream;
38 import java.io.BufferedOutputStream;
39 import java.io.File;
40 import java.io.FileNotFoundException;
41 import java.io.FileOutputStream;
42 import java.io.IOException;
43 import java.io.InputStream;
44 import java.lang.reflect.InvocationTargetException;
45 import java.net.URL;
46 import java.util.List;
47 import java.util.Locale;
48 import java.util.MissingResourceException;
49 import java.util.Properties;
50
51 import javax.swing.Action;
52 import javax.swing.JComponent;
53 import javax.swing.JDialog;
54 import javax.swing.JFrame;
55 import javax.swing.JLabel;
56 import javax.swing.JMenu;
57 import javax.swing.JMenuBar;
58 import javax.swing.JMenuItem;
59 import javax.swing.JPanel;
60 import javax.swing.JTabbedPane;
61 import javax.swing.JTextArea;
62 import javax.swing.JToolBar;
63 import javax.swing.KeyStroke;
64 import javax.swing.SwingUtilities;
65 import javax.swing.UIManager;
66 import javax.swing.plaf.basic.BasicBorders;
67
68 import net.sf.jhylafax.JobHelper.StatusResponse;
69 import net.sf.jhylafax.addressbook.AddressBook;
70
71 import org.apache.commons.logging.Log;
72 import org.apache.commons.logging.LogFactory;
73 import org.apache.log4j.BasicConfigurator;
74 import org.apache.log4j.PropertyConfigurator;
75 import org.xnap.commons.gui.AboutDialog;
76 import org.xnap.commons.gui.Builder;
77 import org.xnap.commons.gui.Dialogs;
78 import org.xnap.commons.gui.ErrorDialog;
79 import org.xnap.commons.gui.action.AbstractXNapAction;
80 import org.xnap.commons.gui.factory.DefaultFactory;
81 import org.xnap.commons.gui.shortcut.ActionShortcut;
82 import org.xnap.commons.gui.util.GUIHelper;
83 import org.xnap.commons.gui.util.IconHelper;
84 import org.xnap.commons.gui.util.LabelUpdater;
85 import org.xnap.commons.gui.util.WhatsThisAction;
86 import org.xnap.commons.i18n.I18n;
87 import org.xnap.commons.i18n.I18nFactory;
88 import org.xnap.commons.i18n.I18nManager;
89 import org.xnap.commons.io.Job;
90 import org.xnap.commons.io.ProgressMonitor;
91 import org.xnap.commons.io.UserAbortException;
92 import org.xnap.commons.settings.SettingStore;
93 import org.xnap.commons.util.FileHelper;
94
95
96
97
98
99
100 @SuppressWarnings("serial")
101 public class JHylaFAX extends JFrame implements LocaleChangeListener {
102
103 public final static I18n i18n = I18nFactory.getI18n(JHylaFAX.class);
104 public final static String JDK14_LOG_CONFIG_KEY = "java.util.logging.config.file";
105 public final static Locale[] SUPPORTED_LOCALES = {
106 Locale.ENGLISH,
107
108 new Locale("ca"),
109 new Locale("cs"),
110 new Locale("de"),
111 new Locale("es"),
112 new Locale("fr"),
113 new Locale("it"),
114
115 new Locale("nl"),
116
117 new Locale("pl"),
118 new Locale("pt", "BR"),
119 new Locale("ru"),
120 new Locale("sv"),
121 new Locale("tr"),
122 };
123 private final static Log logger = LogFactory.getLog(JHylaFAX.class);
124 private static final int BUFFER_SIZE = 1024 * 512;
125 private static JHylaFAX app;
126 private static String version;
127 private JTabbedPane mainTabbedPane;
128 private JMenu fileMenu;
129 private SettingsDialogAction settingsDialogAction;
130 private JPanel statusBarPanel;
131 private JLabel statusLabel;
132 private JLabel serverInfoLabel;
133 private ExitAction exitAction;
134 private UpdateStatusAction updateStatusAction;
135 private HylaFAXClient connection;
136 private JToolBar mainToolBar;
137 private SendAction sendAction;
138 private PollAction pollAction;
139 private JMenu helpMenu;
140 private AboutAction aboutAction;
141 private String password;
142 private String adminPassword;
143 private ConnectionHandler connectionHandler = new ConnectionHandler();
144 private ActionShortcut sendActionShortcut;
145 private AddressBook addressBook;
146 private AddressBookAction addressBookAction;
147 private ActionShortcut updateStatusActionShortcut;
148 private ReceiveQueuePanel recvqPanel;
149 private JobQueuePanel sendqPanel;
150 private JobQueuePanel pollqPanel;
151 private JobQueuePanel doneqPanel;
152 private DocumentQueuePanel docqPanel;
153 private SettingsWizardAction settingsWizardAction;
154 private JobQueue jobQueue = new JobQueue();
155 private NotificationTimer notificationTimer = new NotificationTimer();
156 private File addressBookFile;
157 private Object connectionLock = new Object();
158 private FaxTray tray;
159
160 public JHylaFAX() {
161 app = this;
162
163 try {
164 Settings.load(getSettingsFile());
165
166
167 Settings.DEFAULT_COMPLETION_MODE.updateMode();
168 }
169 catch (FileNotFoundException e) {
170 logger.debug("Error loading settings", e);
171
172 }
173 catch (IOException e) {
174 logger.debug("Error loading settings", e);
175 ErrorDialog.showError(this, i18n.tr("Could not load settings"),
176 i18n.tr("JHylaFAX Error"),
177 e);
178 }
179
180 updateResourceBundle();
181 I18nManager.getInstance().addLocaleChangeListener(new LabelUpdater());
182
183 initializeToolkit();
184 initialize();
185
186 restoreLayout();
187
188 PropertyChangeListener disconnector = new PropertyChangeListener() {
189 public void propertyChange(PropertyChangeEvent evt) {
190 if (connection != null) {
191 try {
192 connection.quit();
193 }
194 catch (Exception e) {
195 logger.debug("Error closing connection", e);
196 }
197 connection = null;
198 }
199 }
200 };
201 Settings.HOSTNAME.addPropertyChangeListener(disconnector);
202 Settings.PORT.addPropertyChangeListener(disconnector);
203 Settings.USE_PASSIVE.addPropertyChangeListener(disconnector);
204 Settings.USERNAME.addPropertyChangeListener(disconnector);
205
206 Settings.LOCALE.addPropertyChangeListener(new PropertyChangeListener() {
207 public void propertyChange(PropertyChangeEvent evt) {
208 updateResourceBundle();
209 }
210 });
211
212 notificationTimer.settingsUpdated();
213 }
214
215 private void restoreLayout() {
216 SettingStore store = new SettingStore(Settings.backstore);
217 store.restoreWindow("window.main", 40, 40, 540, 400, this);
218
219 recvqPanel.restoreLayout(store, new String[] { "sender", "pages", "time", "filename", "filesize", "error" });
220 sendqPanel.restoreLayout(store, new String[] { "id", "priority", "sender", "number", "dials", "pages", "error", "state" });
221 pollqPanel.restoreLayout(store, new String[] { "id", "priority", "sender", "number", "dials", "pages", "error", "state" });
222 doneqPanel.restoreLayout(store, new String[] { "id", "priority", "sender", "number", "dials", "pages", "error", "state" });
223 docqPanel.restoreLayout(store, new String[] { "permissions", "owner", "modified", "filename", "filesize", "time" });
224 }
225
226 private void saveLayout() {
227 SettingStore store = new SettingStore(Settings.backstore);
228 store.saveWindow("window.main", this);
229
230 recvqPanel.saveLayout(store);
231 sendqPanel.saveLayout(store);
232 pollqPanel.saveLayout(store);
233 doneqPanel.saveLayout(store);
234 docqPanel.saveLayout(store);
235 }
236
237 private void updateResourceBundle() {
238 try {
239 I18nManager.getInstance().setDefaultLocale(Settings.LOCALE.getValue());
240 }
241 catch (MissingResourceException e) {
242 logger.warn("Error loading resource bundle", e);
243 }
244 }
245
246 public static void initializeToolkit()
247 {
248
249 UIManager.put("swing.boldMetal", Boolean.FALSE);
250 UIManager.put("SplitPaneDivider.border",
251 new BasicBorders.MarginBorder());
252 UIManager.put("TitledBorder.font", UIManager.getFont("Label.font").deriveFont(Font.BOLD));
253 UIManager.put("TitledBorder.titleColor", UIManager.getColor("Label.foreground").brighter());
254
255 Builder.setProperty(DefaultFactory.ENHANCED_TEXT_FIELD_MENU_KEY, true);
256 }
257
258 private void initialize() {
259 initializeIcon();
260 initializeActions();
261 initializeShortCuts();
262 initializeMenuBar();
263 initializeContent();
264 initializeToolBar();
265 initializeStatusBar();
266 initializeSystemTray();
267
268 updateLabels();
269 updateServerInfo();
270 }
271
272 private void initializeIcon() {
273 List<? extends Image> images = IconHelper.getApplicationIcons("kdeprintfax.png");
274 if (images != null) {
275 setIconImages(images);
276 }
277 }
278
279 private void initializeActions() {
280 updateStatusAction = new UpdateStatusAction();
281 settingsDialogAction = new SettingsDialogAction();
282 settingsWizardAction = new SettingsWizardAction();
283 addressBookAction = new AddressBookAction();
284 exitAction = new ExitAction();
285 sendAction = new SendAction();
286 pollAction = new PollAction();
287 aboutAction = new AboutAction();
288 }
289
290 private void initializeShortCuts() {
291 sendActionShortcut = new ActionShortcut(sendAction);
292 sendActionShortcut.setKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_MASK));
293
294 updateStatusActionShortcut = new ActionShortcut(updateStatusAction);
295 updateStatusActionShortcut.setKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0));
296 }
297
298 private void initializeContent() {
299 setTitle("JHylaFAX");
300 setLayout(new BorderLayout());
301 addWindowListener(new WindowAdapter() {
302 public void windowClosing(WindowEvent event) {
303 exit();
304 }
305 });
306
307 mainTabbedPane = new JTabbedPane();
308 mainTabbedPane.setBorder(GUIHelper.createEmptyBorder(10));
309 getContentPane().add(mainTabbedPane, BorderLayout.CENTER);
310
311 recvqPanel = new ReceiveQueuePanel("recvq");
312 mainTabbedPane.addTab("", IconHelper.getTabTitleIcon("folder_inbox.png"), recvqPanel);
313
314 sendqPanel = new JobQueuePanel("sendq");
315 mainTabbedPane.addTab("", IconHelper.getTabTitleIcon("folder_outbox.png"), sendqPanel);
316
317 doneqPanel = new JobQueuePanel("doneq");
318 mainTabbedPane.addTab("", IconHelper.getTabTitleIcon("folder_sent_mail.png"), doneqPanel);
319
320 pollqPanel = new JobQueuePanel("pollq");
321 if (Settings.SHOW_POLLQ.getValue()) {
322 mainTabbedPane.addTab("", IconHelper.getTabTitleIcon("folder_print.png"), pollqPanel);
323 }
324
325 docqPanel = new DocumentQueuePanel("docq");
326 mainTabbedPane.addTab("", IconHelper.getTabTitleIcon("folder_txt.png"), docqPanel);
327 }
328
329 private void initializeSystemTray() {
330 tray = new FaxTray();
331
332 if (tray.isSupported()) {
333 tray.getPopupMenu().add(new MenuItem((String) exitAction.getValue(Action.NAME)));
334 }
335 }
336
337 public void exit()
338 {
339 if (addressBook != null) {
340 try {
341 addressBook.saveLayout(new SettingStore(Settings.backstore));
342 addressBook.store(addressBookFile);
343 }
344 catch (Exception e) {
345 logger.debug("Error storing addressbook", e);
346 ErrorDialog.showError(JHylaFAX.this,
347 i18n.tr("Could not store addressbook"),
348 i18n.tr("JHylaFAX Error"),
349 e);
350 }
351 }
352
353 saveLayout();
354
355 try {
356 Settings.store(getSettingsFile());
357 }
358 catch (IOException e) {
359 logger.debug("Error storing settings", e);
360 ErrorDialog.showError(JHylaFAX.this,
361 i18n.tr("Could not store settings"),
362 i18n.tr("JHylaFAX Error"),
363 e);
364 }
365 System.exit(0);
366 }
367
368 private void initializeToolBar() {
369 mainToolBar = new JToolBar();
370
371
372 getContentPane().add(mainToolBar, BorderLayout.NORTH);
373
374 mainToolBar.add(Builder.createToolBarButton(sendAction));
375 mainToolBar.addSeparator();
376 mainToolBar.add(Builder.createToolBarButton(updateStatusAction));
377 mainToolBar.addSeparator();
378 mainToolBar.add(Builder.createToolBarButton(addressBookAction));
379 mainToolBar.addSeparator();
380 mainToolBar.add(Builder.createToolBarButton(settingsDialogAction));
381 }
382
383 private void initializeMenuBar() {
384 JMenuBar menuBar = new JMenuBar();
385 setJMenuBar(menuBar);
386
387 fileMenu = new JMenu();
388 menuBar.add(fileMenu);
389 JComponent item = Builder.createMenuItem(sendAction);
390 sendActionShortcut.setMenuItem((JMenuItem)item);
391 fileMenu.add(item);
392 fileMenu.add(Builder.createMenuItem(pollAction));
393 fileMenu.addSeparator();
394 item = Builder.createMenuItem(updateStatusAction);
395 fileMenu.add(item);
396 updateStatusActionShortcut.setMenuItem((JMenuItem)item);
397 fileMenu.addSeparator();
398 fileMenu.add(Builder.createMenuItem(settingsDialogAction));
399 fileMenu.add(Builder.createMenuItem(settingsWizardAction));
400 fileMenu.addSeparator();
401 fileMenu.add(Builder.createMenuItem(addressBookAction));
402 fileMenu.addSeparator();
403 fileMenu.add(Builder.createMenuItem(exitAction));
404
405 helpMenu = new JMenu();
406 menuBar.add(helpMenu);
407 helpMenu.add(Builder.createMenuItem(new WhatsThisAction()));
408 helpMenu.addSeparator();
409 helpMenu.add(Builder.createMenuItem(aboutAction));
410 }
411
412 private void initializeStatusBar() {
413 statusBarPanel = new JPanel(new BorderLayout());
414 getContentPane().add(statusBarPanel, BorderLayout.SOUTH);
415
416 statusLabel = new JLabel();
417 statusBarPanel.add(statusLabel, BorderLayout.CENTER);
418
419 serverInfoLabel = new JLabel();
420 statusBarPanel.add(serverInfoLabel, BorderLayout.EAST);
421 }
422
423 public static JHylaFAX getInstance() {
424 return app;
425 }
426
427 public HylaFAXClient getConnection(ProgressMonitor monitor) throws IOException, ServerResponseException {
428 synchronized (connectionLock) {
429 monitor.setText(i18n.tr("Connecting to {0}", Settings.HOSTNAME.getValue() + ":" + Settings.PORT.getValue()));
430
431 if (connection == null) {
432 connection = new HylaFAXClient();
433 connection.addConnectionListener(connectionHandler);
434 connection.setPassive(Settings.USE_PASSIVE.getValue());
435 }
436
437 logger.info("Connecting to HylaFAX server at " + Settings.HOSTNAME.getValue() + ":" + Settings.PORT.getValue());
438 connection.open(Settings.HOSTNAME.getValue(), Settings.PORT.getValue());
439
440
441 if (password == null) {
442 password = Settings.PASSWORD.getValue();
443 }
444 while (true) {
445 if (connection.user(Settings.USERNAME.getValue())) {
446 if (password.length() == 0) {
447 password = requestPassword(monitor, false);
448 if (password == null) {
449 throw new UserAbortException();
450 }
451 }
452 try {
453 connection.pass(password);
454 } catch (ServerResponseException e) {
455
456 password = "";
457 continue;
458 }
459 }
460 break;
461 }
462
463
464 if (adminPassword == null) {
465 adminPassword = Settings.ADMIN_PASSWORD.getValue();
466 }
467 if (Settings.ADMIN_MODE.getValue()) {
468 while (true) {
469 if (adminPassword.length() == 0) {
470 adminPassword = requestPassword(monitor, true);
471 if (adminPassword == null) {
472
473 break;
474 }
475 }
476 try {
477 connection.admin(adminPassword);
478 } catch (ServerResponseException e) {
479
480 adminPassword = "";
481 continue;
482 }
483 break;
484 }
485 }
486
487 return connection;
488 }
489 }
490
491 private String requestPassword(final ProgressMonitor monitor, final boolean admin) throws ServerResponseException {
492 final String[] password = new String[1];
493 Runnable runner = new Runnable() {
494 public void run() {
495 String host = Settings.USERNAME.getValue() + "@"
496 + Settings.HOSTNAME.getValue();
497 password[0] = Dialogs.requestPassword(monitor.getComponent(),
498 (admin)
499 ? i18n.tr("Enter admin password for {0}:", host)
500 : i18n.tr("Enter password for {0}:", host),
501 i18n.tr("JHylaFAX Connection"));
502 }
503 };
504 try {
505 SwingUtilities.invokeAndWait(runner);
506 return password[0];
507 }
508 catch (InterruptedException e) {
509 logger.error("Unexpected exception while waiting for password", e);
510 throw new ServerResponseException(i18n.tr("Abort by user."));
511 }
512 catch (InvocationTargetException e) {
513 logger.error("Unexpected exception while waiting for password", e);
514 throw new ServerResponseException(i18n.tr("Abort by user."));
515 }
516 }
517
518 public static File getSettingsFile() throws IOException {
519 return new File(FileHelper.getHomeDir("jhylafax"), "jhlafax.prefs");
520 }
521
522 public static File getAddressBookFile() throws IOException {
523 if (Settings.CUSTOMIZE_ADDRESS_BOOK_FILENAME.getValue()) {
524 return new File(Settings.ADDRESS_BOOK_FILENAME.getValue());
525 }
526 else {
527 return new File(FileHelper.getHomeDir("jhylafax"),
528 Settings.ADDRESS_BOOK_FILENAME.getDefaultValue());
529 }
530 }
531
532 public <T> T runJob(final Job<T> job) throws Exception {
533 return jobQueue.runJob(null, job);
534 }
535
536 public <T> T runJob(JDialog owner, final Job<T> job) throws Exception {
537 return jobQueue.runJob(owner, job);
538 }
539
540 public void updateServerInfo() {
541 serverInfoLabel.setText(
542 Settings.HOSTNAME.getValue() + ":" + Settings.PORT.getValue());
543 }
544
545 public void updateLabels() {
546 fileMenu.setText(i18n.tr("File"));
547 helpMenu.setText(i18n.tr("Help"));
548
549 for (int i = 0; i < mainTabbedPane.getTabCount(); i++) {
550 AbstractQueuePanel panel = (AbstractQueuePanel)mainTabbedPane.getComponent(i);
551 panel.updateLabels();
552 String queueName = panel.getQueueName();
553 if (queueName.equals("recvq")) { mainTabbedPane.setTitleAt(i, i18n.tr("Received")); }
554 else if (queueName.equals("sendq")) { mainTabbedPane.setTitleAt(i, i18n.tr("Sending")); }
555 else if (queueName.equals("pollq")) { mainTabbedPane.setTitleAt(i, i18n.tr("Pollable")); }
556 else if (queueName.equals("doneq")) { mainTabbedPane.setTitleAt(i, i18n.tr("Done")); }
557 else if (queueName.equals("docq")) { mainTabbedPane.setTitleAt(i, i18n.tr("Documents")); }
558 }
559
560 sendAction.putValue(Action.NAME, i18n.tr("Send Fax..."));
561 sendAction.putValue(Action.SHORT_DESCRIPTION, i18n.tr("Opens a dialog for sending a fax"));
562
563 pollAction.putValue(Action.NAME, i18n.tr("Poll Fax..."));
564 pollAction.putValue(Action.SHORT_DESCRIPTION, i18n.tr("Opens a dialog for polling a fax"));
565
566 addressBookAction.putValue(Action.NAME, i18n.tr("Address Book"));
567
568 updateStatusAction.putValue(Action.NAME, i18n.tr("Update Status"));
569 updateStatusAction.putValue(Action.SHORT_DESCRIPTION, i18n.tr("Queries the status from the server"));
570
571 settingsDialogAction.putValue(Action.NAME, i18n.tr("Settings..."));
572 settingsDialogAction.putValue(Action.SHORT_DESCRIPTION, i18n.tr("Displays the settings dialog"));
573 settingsDialogAction.updateLabels();
574
575 settingsWizardAction.putValue(Action.NAME, i18n.tr("Setup Wizard..."));
576 settingsWizardAction.putValue(Action.SHORT_DESCRIPTION, i18n.tr("Displays the settings wizard"));
577 settingsWizardAction.updateLabels();
578
579 exitAction.putValue(Action.NAME, i18n.tr("Exit"));
580 exitAction.putValue(Action.SHORT_DESCRIPTION, i18n.tr("Closes the application"));
581
582 aboutAction.putValue(Action.NAME, i18n.tr("About..."));
583 aboutAction.putValue(Action.SHORT_DESCRIPTION, i18n.tr("Opens a dialog that displays funny information"));
584
585 GUIHelper.setMnemonics(getJMenuBar());
586 }
587
588
589
590
591 public static void main(final String[] args) {
592 final ArgsHandler handler = new ArgsHandler();
593 handler.evaluate(args);
594
595 evaluateArgumentsPreVisible(handler);
596
597 ThreadGroup tg = new ThreadGroup("JHylaFAXThreadGroup") {
598 public void uncaughtException(Thread t,Throwable e) {
599 e.printStackTrace();
600 }
601 };
602
603
604
605 Thread mainRunner = new Thread(tg, "JHylaFAXMain") {
606 public void run() {
607 setContextClassLoader(JHylaFAX.class.getClassLoader());
608
609 JHylaFAX app = new JHylaFAX();
610 app.setVisible(true);
611
612 app.evaluateArgumentsPostVisible(handler);
613 }
614 };
615 mainRunner.start();
616 }
617
618 private static void evaluateArgumentsPreVisible(ArgsHandler handler)
619 {
620
621 URL url = JHylaFAX.class.getResource(handler.getLogConfigFilename());
622 if (url != null) {
623 PropertyConfigurator.configure(url);
624 } else {
625 System.err.println("Could not find logging configuration: "
626 + handler.getLogConfigFilename());
627 BasicConfigurator.configure();
628 }
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645 }
646
647 protected void evaluateArgumentsPostVisible(ArgsHandler handler)
648 {
649 if (!Settings.HAS_SEEN_WIZARD.getValue()) {
650 SettingsWizard wizard = new SettingsWizard(JHylaFAX.this);
651 wizard.setModal(true);
652 wizard.setLocationRelativeTo(JHylaFAX.this);
653 wizard.setVisible(true);
654 }
655
656 if (Settings.UPDATE_ON_STARTUP.getValue()) {
657 updateTables();
658 }
659
660 String[] filenames = handler.getFilenames();
661 String[] numbers = handler.getNumbers();
662 File tempFile = null;
663
664 if (handler.getReadStdin()) {
665 tempFile = saveStdInToFile();
666 if (tempFile != null) {
667
668 String[] newFilenames = new String[filenames.length + 1];
669 newFilenames[0] = tempFile.getAbsolutePath();
670 System.arraycopy(filenames, 0, newFilenames, 1, filenames.length);
671 filenames = newFilenames;
672 }
673 }
674
675 if (filenames.length > 0 || numbers.length > 0) {
676 SendDialog dialog = new SendDialog(this);
677
678 for (String number : numbers) {
679
680 dialog.setNumber(number);
681 }
682
683 if (filenames.length > 0) {
684 dialog.setDocument(filenames[0]);
685 for (int i = 1; i < filenames.length; i++) {
686 dialog.addDocument(filenames[i]);
687 }
688 }
689
690 dialog.setQuitAfterSending(handler.getQuitAfterSending());
691 dialog.setLocationRelativeTo(JHylaFAX.this);
692 dialog.setVisible(true);
693 }
694 }
695
696 private File saveStdInToFile()
697 {
698 File tempFile;
699 try {
700 tempFile = File.createTempFile("jhylafax", null);
701 tempFile.deleteOnExit();
702 }
703 catch (IOException e) {
704 logger.debug("Error creating temporary file", e);
705 ErrorDialog.showError(JHylaFAX.getInstance(),
706 i18n.tr("Error creating temporary file"),
707 i18n.tr("JHylaFAX Error"),
708 e);
709 return null;
710 }
711
712
713
714 try {
715 BufferedInputStream in = new BufferedInputStream(System.in);
716 try {
717 BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(tempFile));
718 try {
719 byte[] buf = new byte[BUFFER_SIZE];
720 while (true) {
721 int bytesRead = in.read(buf);
722 if (bytesRead <= 0) {
723 break;
724 }
725 out.write(buf, 0, bytesRead);
726 }
727 }
728 finally {
729 out.close();
730 }
731 }
732 finally {
733 in.close();
734 }
735 }
736 catch (IOException e) {
737 logger.debug("Error creating temporary file", e);
738 ErrorDialog.showError(JHylaFAX.getInstance(),
739 i18n.tr("Error creating temporary file"),
740 i18n.tr("JHylaFAX Error"),
741 e);
742 return null;
743 }
744 return tempFile;
745 }
746
747 public void updateTables()
748 {
749 updateTables(JobHelper.updateStatus());
750 }
751
752 public void updateTables(StatusResponse response)
753 {
754 jobQueue.setLastUpdate(System.currentTimeMillis());
755 if (response != null) {
756 updateServerInfo();
757 statusLabel.setText(response.status);
758 statusLabel.setToolTipText("<html><pre><b>" + response.verboseStatus + "</b></pre>");
759 recvqPanel.setData(response.recvq);
760 sendqPanel.setData(response.sendq);
761 pollqPanel.setData(response.pollq);
762 doneqPanel.setData(response.doneq);
763 docqPanel.setData(response.docq);
764 }
765 }
766
767 private class AboutAction extends AbstractXNapAction {
768
769 private AboutDialog dialog;
770
771 public AboutAction() {
772 putValue(ICON_FILENAME, "jhylafax.png");
773 }
774
775 public void actionPerformed(ActionEvent e)
776 {
777 if (dialog == null) {
778 dialog = new AboutDialog();
779 dialog.setTitle(i18n.tr("About JHylaFax {0}", getVersion()));
780 dialog.setLocationRelativeTo(JHylaFAX.this);
781 dialog.addHTMLTab(i18n.tr("General Information"), "about.html", true);
782 JTextArea textArea = dialog.addTab(i18n.tr("License"), "LICENSE.jhylafax");
783 textArea.setFont(new Font("Monospaced", Font.PLAIN, 10));
784
785 dialog.addHTMLTab(i18n.tr("3rd Party Software"), "LICENSE.other.html", true);
786
787 dialog.getTabbedPane().setSelectedIndex(0);
788 }
789
790 if (!dialog.isVisible()) {
791 dialog.setVisible(true);
792 }
793 }
794
795 }
796
797 private class AddressBookAction extends AbstractXNapAction {
798
799 public AddressBookAction() {
800 putValue(ICON_FILENAME, "contents.png");
801 }
802
803 public void actionPerformed(ActionEvent e)
804 {
805 getAddressBook().setVisible(true);
806 }
807
808 }
809
810 private class SendAction extends AbstractXNapAction {
811
812 public SendAction() {
813 putValue(ICON_FILENAME, "mail_new.png");
814 }
815
816 public void actionPerformed(ActionEvent e)
817 {
818 SendDialog dialog = new SendDialog(JHylaFAX.this);
819 dialog.setLocationRelativeTo(JHylaFAX.this);
820 dialog.setVisible(true);
821 }
822
823 }
824
825 private class PollAction extends AbstractXNapAction {
826
827 public PollAction() {
828 putValue(ICON_FILENAME, "mail_get.png");
829 }
830
831 public void actionPerformed(ActionEvent e)
832 {
833 PollDialog dialog = new PollDialog(JHylaFAX.this);
834 dialog.setLocationRelativeTo(JHylaFAX.this);
835 dialog.setVisible(true);
836 }
837
838 }
839
840 private class SettingsDialogAction extends AbstractXNapAction
841 implements LocaleChangeListener {
842
843 private SettingsDialog dialog;
844
845 public SettingsDialogAction() {
846 putValue(ICON_FILENAME, "configure.png");
847 }
848
849 public void updateLabels()
850 {
851 if (dialog != null) {
852 dialog.updateLabels();
853 }
854 }
855
856 public void actionPerformed(ActionEvent e)
857 {
858 if (dialog == null) {
859 dialog = new SettingsDialog(JHylaFAX.this);
860 dialog.setLocationRelativeTo(JHylaFAX.this);
861 }
862
863 if (!dialog.isVisible()) {
864 dialog.revert();
865 dialog.setVisible(true);
866 }
867 }
868
869 }
870
871 private class SettingsWizardAction extends AbstractXNapAction
872 implements LocaleChangeListener {
873
874 public SettingsWizardAction() {
875 putValue(ICON_FILENAME, "wizard.png");
876 }
877
878 public void updateLabels() {
879 }
880
881 public void actionPerformed(ActionEvent e)
882 {
883 SettingsWizard wizard = new SettingsWizard(JHylaFAX.this);
884 wizard.setLocationRelativeTo(JHylaFAX.this);
885 wizard.setVisible(true);
886 }
887
888 }
889
890 private class ExitAction extends AbstractXNapAction {
891
892 public ExitAction() {
893 putValue(ICON_FILENAME, "exit.png");
894 }
895
896 public void actionPerformed(ActionEvent e)
897 {
898 exit();
899 }
900
901 }
902
903 private class UpdateStatusAction extends AbstractXNapAction {
904
905 public UpdateStatusAction() {
906 putValue(ICON_FILENAME, "reload.png");
907 }
908
909 public void actionPerformed(ActionEvent e) {
910 updateTables();
911 }
912
913 }
914
915 private class ConnectionHandler implements ConnectionListener {
916
917 public void connectionOpened(ConnectionEvent event) {
918 logger.info("Connected to "
919 + event.getRemoteInetAddress().getHostAddress()
920 + ":" + event.getRemotePort());
921 }
922
923 public void connectionClosed(ConnectionEvent event) {
924 logger.info("Disconnected from "
925 + event.getRemoteInetAddress().getHostAddress()
926 + ":" + event.getRemotePort());
927 connection.removeConnectionListener(this);
928 connection = null;
929 }
930
931 public void connectionFailed(Exception e) {
932 logger.info("Connection failed", e);
933 connection.removeConnectionListener(this);
934 connection = null;
935 }
936
937 }
938
939 public AddressBook getAddressBook()
940 {
941 if (addressBook == null) {
942 addressBook = new AddressBook();
943
944 addressBook.restoreLayout(new SettingStore(Settings.backstore));
945
946 try {
947 addressBookFile = getAddressBookFile();
948 if (addressBookFile.exists()) {
949 addressBook.load(addressBookFile);
950 }
951 }
952 catch (Exception e) {
953 logger.debug("Error loading addressbook", e);
954 ErrorDialog.showError(JHylaFAX.this,
955 i18n.tr("Could not load addressbook"),
956 i18n.tr("JHylaFAX Error"),
957 e);
958 }
959 }
960 return addressBook;
961 }
962
963 public void showError(String message, Exception e)
964 {
965 ErrorDialog.showError(this, message, i18n.tr("JHylaFAX Error"), e);
966 }
967
968 public void showError(String message)
969 {
970 Dialogs.showError(this, message, i18n.tr("JHylaFAX Error"));
971 }
972
973 public void resetAllTables() {
974 recvqPanel.resetTable();
975 sendqPanel.resetTable();
976 pollqPanel.resetTable();
977 doneqPanel.resetTable();
978 docqPanel.resetTable();
979 }
980
981 public void runNotification(Notification notification)
982 {
983 jobQueue.addNotification(notification);
984 }
985
986 public void settingsUpdated()
987 {
988 notificationTimer.settingsUpdated();
989 }
990
991 public synchronized static String getVersion() {
992 if (version == null) {
993 try {
994 InputStream in = JHylaFAX.class.getResourceAsStream("version.properties");
995 try {
996 Properties p = new Properties();
997 p.load(in);
998 version = p.getProperty("jhylafax.version", "");
999 } finally {
1000 in.close();
1001 }
1002 } catch (IOException e) {
1003 logger.debug("Error loading version properties", e);
1004 }
1005 }
1006 return version;
1007 }
1008
1009 }