1 package net.suberic.pooka.gui; 2 import net.suberic.pooka.Pooka; 3 import net.suberic.pooka.StoreInfo; 4 import java.util.*; 5 import java.awt.*; 6 import java.awt.event.*; 7 import java.io.*; 8 import java.beans.*; 9 import javax.swing.*; 10 import javax.swing.text.*; 11 import javax.swing.border.*; 12 import javax.mail.Session ; 13 import javax.mail.MessagingException ; 14 import javax.mail.event.MessageCountEvent ; 15 import javax.help.*; 16 import java.util.logging.Logger ; 17 18 import net.suberic.pooka.MailQueue; 19 import net.suberic.pooka.UserProfile; 20 import net.suberic.util.gui.*; 21 22 28 29 public class MainPanel extends JPanel implements net.suberic.pooka.UserProfileContainer, ActionContainer { 30 private JSplitPane splitPane; 31 private ConfigurableMenuBar mainMenu; 32 private ConfigurableToolbar mainToolbar; 33 private FolderPanel folderPanel; 34 private ContentPanel contentPanel; 35 private InfoPanel infoPanel; 36 private Session session; 37 private MailQueue mailQueue; 38 private UserProfile currentUser = null; 39 private ConfigurableKeyBinding keyBindings; 40 41 protected PookaFocusManager focusManager; 42 43 private static int CONTENT_LAST = 0; 45 private static int FOLDER_LAST = 5; 46 47 public MainPanel(JFrame frame) { 48 session = Pooka.getDefaultSession(); 49 50 mailQueue = new MailQueue(Pooka.getDefaultSession()); 51 52 } 53 54 57 public void configureMainPanel() { 58 62 this.setLayout(new BorderLayout()); 63 64 contentPanel = Pooka.getUIFactory().createContentPanel(); 65 folderPanel = new FolderPanel(this); 66 infoPanel = new InfoPanel(); 67 infoPanel.setMessage("Pooka"); 68 69 splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); 70 71 splitPane.setLeftComponent(folderPanel); 72 splitPane.setRightComponent(contentPanel.getUIComponent()); 73 splitPane.setDividerLocation(folderPanel.getPreferredSize().width + 1); 74 75 this.add("Center", splitPane); 76 77 mainMenu = new ConfigurableMenuBar("MenuBar", Pooka.getResources()); 78 mainToolbar = Pooka.getUIFactory().createMainToolbar(); 79 80 if (mainToolbar != null) 81 this.add("North", mainToolbar); 82 83 keyBindings = new ConfigurableKeyBinding(this, "MainPanel.keyBindings", Pooka.getResources()); 84 keyBindings.setCondition(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 86 87 Pooka.getHelpBroker().enableHelpKey(this, "pooka.intro", Pooka.getHelpBroker().getHelpSet()); 88 89 getParentFrame().addWindowListener(new WindowAdapter() { 90 public void windowClosing(WindowEvent e) { 91 exitPooka(true); 92 } 93 }); 94 95 focusManager = new PookaFocusManager(); 96 97 this.addFocusListener(new FocusAdapter() { 98 public void focusGained(FocusEvent e) { 99 focusManager.passFocus(); 101 } 102 }); 103 104 refreshCurrentUser(); 106 107 if (Pooka.getUIFactory().getMessageNotificationManager() != null) { 109 Pooka.getUIFactory().getMessageNotificationManager().setMainPanel(this); 110 } 111 contentPanel.getUIComponent().requestFocusInWindow(); 113 114 } 115 116 124 public Action[] getActions() { 125 Action[] actions = getDefaultActions(); 126 Component focusedComponent = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); 127 128 boolean foundParent = false; 129 130 if (focusedComponent != null) { 131 if (contentPanel != null) { 132 if (SwingUtilities.isDescendingFrom(focusedComponent, contentPanel.getUIComponent())) { 133 foundParent = true; 134 focusManager.setLastStatus(CONTENT_LAST); 135 if (contentPanel.getActions() != null) { 136 actions = TextAction.augmentList(contentPanel.getActions(), actions); 137 } 138 } 139 } 140 141 if (! foundParent && folderPanel != null) { 142 if (SwingUtilities.isDescendingFrom(focusedComponent, folderPanel)) { 143 foundParent = true; 144 focusManager.setLastStatus(FOLDER_LAST); 145 if (folderPanel.getActions() != null) { 146 actions = TextAction.augmentList(folderPanel.getActions(), actions); 147 } 148 } 149 } 150 } 151 152 if (! foundParent) { 153 int lastStatus = focusManager.getLastStatus(); 156 if (lastStatus == CONTENT_LAST && contentPanel != null) { 157 if (contentPanel.getActions() != null) { 158 actions = TextAction.augmentList(contentPanel.getActions(), actions); 159 } 160 } else if (lastStatus == FOLDER_LAST && folderPanel != null) { 161 if (folderPanel.getActions() != null) { 162 actions = TextAction.augmentList(folderPanel.getActions(), actions); 163 } 164 165 } 166 } 167 return actions; 168 } 169 170 171 178 179 public void refreshActiveMenus() { 180 Action[] currentActions = getActions(); 181 mainMenu.setActive(currentActions); 182 if (mainToolbar != null) 183 mainToolbar.setActive(currentActions); 184 contentPanel.refreshActiveMenus(); 185 keyBindings.setActive(currentActions); 186 if (Pooka.getUIFactory().getMessageNotificationManager() != null) 187 Pooka.getUIFactory().getMessageNotificationManager().clearNewMessageFlag(); 188 } 189 190 198 protected void refreshCurrentUser() { 199 UserProfile selectedProfile = getDefaultProfile(); 200 if (selectedProfile != null) { 201 currentUser = selectedProfile; 202 } else { 203 currentUser = Pooka.getPookaManager().getUserProfileManager().getDefaultProfile(); 204 } 205 } 206 207 214 public UserProfile getDefaultProfile() { 215 UserProfile returnValue = null; 216 217 if (contentPanel != null) { 218 returnValue = contentPanel.getDefaultProfile(); 219 } 220 221 if (returnValue != null) 222 return returnValue; 223 224 if (folderPanel != null) 225 returnValue = folderPanel.getDefaultProfile(); 226 227 return returnValue; 228 229 } 230 231 public UserProfile getCurrentUser() { 232 return currentUser; 233 } 234 235 238 public void exitPooka(boolean exitToIcon) { 239 if (! processUnsentMessages()) 240 return; 241 242 if (contentPanel instanceof MessagePanel && 243 ((MessagePanel)contentPanel).isSavingWindowLocations()) { 244 ((MessagePanel)contentPanel).saveWindowLocations(); 245 } 246 247 Pooka.setProperty("Pooka.hsize", Integer.toString(this.getParentFrame().getWidth())); 248 Pooka.setProperty("Pooka.vsize", Integer.toString(this.getParentFrame().getHeight())); 249 Pooka.setProperty("Pooka.folderPanel.hsize", Integer.toString(folderPanel.getWidth())); 250 Pooka.setProperty("Pooka.folderPanel.vsize", Integer.toString(folderPanel.getHeight())); 251 Pooka.setProperty("Pooka.lastX", Integer.toString(this.getParentFrame().getX())); 252 Pooka.setProperty("Pooka.lastY", Integer.toString(this.getParentFrame().getY())); 253 contentPanel.savePanelSize(); 254 255 if (contentPanel.isSavingOpenFolders()) { 256 contentPanel.saveOpenFolders(); 257 } 258 259 if (exitToIcon && Pooka.getProperty("Pooka.exitToIcon", "false").equalsIgnoreCase("true") && Pooka.getUIFactory().getMessageNotificationManager().getTrayIcon() != null) { 260 Pooka.sStartupManager.stopPookaToTray(this); 261 } else { 262 Pooka.exitPooka(0, this); 263 } 264 } 265 266 274 public boolean processUnsentMessages() { 275 Vector unsentMessages = NewMessageProxy.getUnsentProxies(); 276 boolean cancel = false; 277 Vector unsentCopy = new Vector(unsentMessages); 278 for (int i = 0; !cancel && i < unsentCopy.size(); i++) { 279 NewMessageProxy current = (NewMessageProxy)unsentCopy.get(i); 280 if (current.promptForClose()) { 281 NewMessageUI nmui = current.getNewMessageUI(); 282 if (nmui != null) { 284 nmui.openMessageUI(); 285 int saveDraft = nmui.promptSaveDraft(); 286 switch (saveDraft) { 287 case JOptionPane.YES_OPTION: 288 current.saveDraft(); 289 break; 290 case JOptionPane.NO_OPTION: 291 nmui.setModified(false); 292 nmui.closeMessageUI(); 293 break; 294 case JOptionPane.CANCEL_OPTION: 295 cancel = true; 296 } 297 } 298 } 299 } 300 301 return ! cancel; 302 } 303 304 307 public ConfigurableMenuBar getMainMenu() { 308 return mainMenu; 309 } 310 311 public InfoPanel getInfoPanel() { 312 return infoPanel; 313 } 314 315 public void setMainMenu(ConfigurableMenuBar newMainMenu) { 316 mainMenu=newMainMenu; 317 } 318 319 public ConfigurableToolbar getMainToolbar() { 320 return mainToolbar; 321 } 322 323 public ConfigurableKeyBinding getKeyBindings() { 324 return keyBindings; 325 } 326 327 public void setKeyBindings(ConfigurableKeyBinding newKeyBindings) { 328 keyBindings = newKeyBindings; 329 } 330 331 332 public void setMainToolbar(ConfigurableToolbar newMainToolbar) { 333 if (mainToolbar != null) 334 this.remove(mainToolbar); 335 336 mainToolbar = newMainToolbar; 337 338 if (mainToolbar != null) 339 this.add("North", mainToolbar); 340 341 } 342 343 public ContentPanel getContentPanel() { 344 return contentPanel; 345 } 346 347 public void setContentPanel(ContentPanel newCp) { 348 contentPanel = newCp; 349 splitPane.setRightComponent(newCp.getUIComponent()); 350 this.repaint(); 351 } 352 353 public FolderPanel getFolderPanel() { 354 return folderPanel; 355 } 356 357 public Session getSession() { 358 return session; 359 } 360 361 public MailQueue getMailQueue() { 362 return mailQueue; 363 } 364 365 public Action[] getDefaultActions() { 366 return defaultActions; 367 } 368 369 public PookaFocusManager getFocusManager() { 370 return focusManager; 371 } 372 373 376 public JFrame getParentFrame() { 377 return (JFrame) getTopLevelAncestor(); 378 } 379 380 384 private Action[] defaultActions = { 385 new ExitAction(), 386 new EditUserConfigAction(), 387 new EditStoreConfigAction(), 388 new EditPreferencesAction(), 389 new EditAddressBookAction(), 390 new EditOutgoingServerAction(), 391 new EditConnectionAction(), 392 new EditInterfaceAction(), 393 new EditCryptoAction(), 394 new EditAllPreferencesAction(), 395 new HelpAboutAction(), 396 new HelpLicenseAction(), 397 new HelpAction(), 398 new HelpKeyBindingsAction(), 399 new SelectMessagePanelAction(), 400 new SelectFolderPanelAction(), 401 new NewMessageAction(), 402 new ExportConfigAction() 403 }; 404 405 406 411 class ExitAction extends AbstractAction { 412 413 ExitAction() { 414 super("file-exit"); 415 } 416 417 public void actionPerformed(ActionEvent e) { 418 exitPooka(false); 419 } 420 } 421 422 class ActivateWindowAction extends AbstractAction { 423 424 ActivateWindowAction() { 425 super("activate-window"); 426 } 427 428 public void actionPerformed(ActionEvent e) { 429 try { 430 ((JInternalFrame)(((MessagePanel)contentPanel).getComponent(Integer.parseInt(e.getActionCommand())))).setSelected(true); 431 } catch (java.beans.PropertyVetoException pve) { 432 } catch (NumberFormatException nfe) { 433 } 434 } 435 } 436 437 class EditUserConfigAction extends AbstractAction { 438 439 EditUserConfigAction() { 440 super("cfg-users"); 441 } 442 443 public void actionPerformed(ActionEvent e) { 444 Pooka.getUIFactory().showEditorWindow(Pooka.getProperty("title.userConfig", "Edit User Information"), "UserProfile.editor"); 445 } 446 } 447 448 449 class EditStoreConfigAction extends AbstractAction { 450 451 EditStoreConfigAction() { 452 super("cfg-stores"); 453 } 454 455 public void actionPerformed(ActionEvent e) { 456 457 Pooka.getUIFactory().showEditorWindow(Pooka.getProperty("title.storeConfig", "Edit Mailbox Information"), "Store"); 458 } 459 } 460 461 class EditPreferencesAction extends AbstractAction { 462 463 EditPreferencesAction() { 464 super("cfg-prefs"); 465 } 466 467 public void actionPerformed(ActionEvent e) { 468 Pooka.getUIFactory().showEditorWindow(Pooka.getProperty("title.preferences", "Edit Preferences"), "Preferences"); 469 } 470 } 471 472 class EditAddressBookAction extends AbstractAction { 473 474 EditAddressBookAction() { 475 super("cfg-address-book"); 476 } 477 478 public void actionPerformed(ActionEvent e) { 479 Pooka.getUIFactory().showEditorWindow(Pooka.getProperty("title.addressBook", "Address Book Editor"), "AddressBook.editor"); 480 } 481 } 482 483 class EditOutgoingServerAction extends AbstractAction { 484 485 EditOutgoingServerAction() { 486 super("cfg-outgoing"); 487 } 488 489 public void actionPerformed(ActionEvent e) { 490 Pooka.getUIFactory().showEditorWindow(Pooka.getProperty("title.outgoingServer", "Outgoing Mail Editor"), "OutgoingServer.editor"); 491 } 492 } 493 494 class EditConnectionAction extends AbstractAction { 495 496 EditConnectionAction() { 497 super("cfg-connection"); 498 } 499 500 public void actionPerformed(ActionEvent e) { 501 Pooka.getUIFactory().showEditorWindow(Pooka.getProperty("title.connectionEditor", "Connection Editor"), "Connection.editor"); 502 } 503 } 504 505 class EditCryptoAction extends AbstractAction { 506 507 EditCryptoAction() { 508 super("cfg-crypto"); 509 } 510 511 public void actionPerformed(ActionEvent e) { 512 Pooka.getUIFactory().showEditorWindow(Pooka.getProperty("title.cryptoEditor", "Encryption Editor"), "EncryptionManager"); 513 } 514 } 515 516 class EditInterfaceAction extends AbstractAction { 517 518 EditInterfaceAction() { 519 super("cfg-interface-style"); 520 } 521 522 public void actionPerformed(ActionEvent e) { 523 Pooka.getUIFactory().showEditorWindow(Pooka.getProperty("title.interfaceEditor", "User Interface Editor"), "Pooka.interface"); 524 } 525 } 526 527 class EditAllPreferencesAction extends AbstractAction { 528 529 EditAllPreferencesAction() { 530 super("cfg-all-prefs"); 531 } 532 533 public void actionPerformed(ActionEvent e) { 534 Pooka.getUIFactory().showEditorWindow(Pooka.getProperty("title.preferences", "Edit Preferences"), "Pooka.allPreferences"); 535 } 536 } 537 538 class HelpAboutAction extends AbstractAction { 539 540 HelpAboutAction() { 541 super("help-about"); 542 } 543 544 public void actionPerformed(ActionEvent e) { 545 String fileName="About.html"; 546 String dir="/net/suberic/pooka/doc"; 547 contentPanel.showHelpScreen(Pooka.getProperty("MenuBar.Help.About.Label", "About Pooka"), this.getClass().getResource(dir + "/" + java.util.Locale.getDefault().getLanguage() + "/" + fileName)); 548 549 } 550 } 551 552 class HelpLicenseAction extends AbstractAction { 553 554 HelpLicenseAction() { 555 super("help-license"); 556 } 557 558 public void actionPerformed(ActionEvent e) { 559 String fileName="COPYING"; 560 String dir="/net/suberic/pooka"; 561 contentPanel.showHelpScreen(Pooka.getProperty("MenuBar.Help.License.Label", "License"), this.getClass().getResource(dir + "/" + fileName)); 562 } 563 } 564 565 class HelpAction extends AbstractAction { 566 567 HelpAction() { 568 super("help"); 569 } 570 571 public void actionPerformed(ActionEvent e) { 572 new CSH.DisplayHelpFromSource(Pooka.getHelpBroker()).actionPerformed(e); 573 } 574 } 575 576 class HelpKeyBindingsAction extends AbstractAction { 577 578 HelpKeyBindingsAction() { 579 super("help-keybindings"); 580 } 581 582 public void actionPerformed(ActionEvent e) { 583 String fileName="KeyBindings.html"; 584 String dir="/net/suberic/pooka/doc"; 585 contentPanel.showHelpScreen(Pooka.getProperty("MenuBar.Help.KeyBindings.Label", "Pooka KeyBindings"), this.getClass().getResource(dir + "/" + java.util.Locale.getDefault().getLanguage() + "/" + fileName)); 586 } 587 } 588 589 class SelectMessagePanelAction extends AbstractAction { 590 591 SelectMessagePanelAction() { 592 super("select-message-panel"); 593 } 594 595 public void actionPerformed(ActionEvent e) { 596 contentPanel.getUIComponent().requestFocusInWindow(); 597 } 598 } 599 600 class SelectFolderPanelAction extends AbstractAction { 601 602 SelectFolderPanelAction() { 603 super("select-folder-panel"); 604 } 605 606 public void actionPerformed(ActionEvent e) { 607 folderPanel.requestFocusInWindow(); 608 } 609 } 610 611 public class NewMessageAction extends AbstractAction { 612 NewMessageAction() { 613 super("message-new"); 614 } 615 616 public void actionPerformed(ActionEvent e) { 617 try { 618 MessageUI nmu = Pooka.getUIFactory().createMessageUI(new NewMessageProxy(new net.suberic.pooka.NewMessageInfo(new javax.mail.internet.MimeMessage (getSession())))); 619 nmu.openMessageUI(); 620 } catch (MessagingException me) { 621 Pooka.getUIFactory().showError(Pooka.getProperty("error.NewMessage.errorLoadingMessage", "Error creating new message: ") + "\n" + me.getMessage(), Pooka.getProperty("error.NewMessage.errorLoadingMessage.title", "Error creating new message."), me); 622 } 623 624 } 625 626 } 627 628 public class ExportConfigAction extends AbstractAction { 629 ExportConfigAction() { 630 super("cfg-export"); 631 } 632 633 public void actionPerformed(ActionEvent e) { 634 JFileChooser jfc; 635 String currentDirectoryPath = Pooka.getProperty("Pooka.tmp.currentDirectory", ""); 636 if (currentDirectoryPath == "") 637 jfc = new JFileChooser(); 638 else 639 jfc = new JFileChooser(currentDirectoryPath); 640 641 jfc.setDialogTitle("Choose Export File"); 642 jfc.setFileSelectionMode(JFileChooser.FILES_ONLY); 643 jfc.setMultiSelectionEnabled(false); 644 int a = jfc.showDialog(MainPanel.this, "Save"); 645 646 Pooka.getResources().setProperty("Pooka.tmp.currentDirectory", jfc.getCurrentDirectory().getPath(), true); 647 648 if (a == JFileChooser.APPROVE_OPTION) { 649 File f = jfc.getSelectedFile(); 650 try { 651 net.suberic.pooka.resource.DisklessResourceManager.exportResources(f, false); 652 Pooka.getUIFactory().showMessage("Resources exported successfully", "Export complete"); 653 } catch (Exception exc) { 654 Pooka.getUIFactory().showError("Error exporting resources", exc); 655 } 656 657 } 658 } 659 660 } 661 662 663 667 public class PookaFocusManager implements PropertyChangeListener { 668 669 int lastStatus = CONTENT_LAST; 670 671 674 public PookaFocusManager() { 675 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); 676 kfm.addPropertyChangeListener("permanentFocusOwner", this); 677 } 678 679 682 public void propertyChange(java.beans.PropertyChangeEvent pce) { 683 Object newValue = pce.getNewValue(); 686 Object oldValue = pce.getOldValue(); 687 if ((newValue == null && oldValue == null) || newValue instanceof JFrame) { 689 passFocus(); 690 } else { 691 if (newValue != null && newValue instanceof Component) { 693 Window parentWindow = SwingUtilities.getWindowAncestor(MainPanel.this); 694 Window componentParentWindow = SwingUtilities.getWindowAncestor((Component) newValue); 695 if (parentWindow == componentParentWindow || componentParentWindow == null) { 696 refreshActiveMenus(); 697 refreshCurrentUser(); 698 } else { 699 700 java.util.logging.Logger.getLogger("Pooka.debug.gui.focus").fine("component " + newValue + " got focus, but it's not part of the main window. Ignoring."); 701 702 703 java.util.logging.Logger.getLogger("Pooka.debug.gui.focus").fine("main window = " + parentWindow + "; component's parent = " + componentParentWindow); 704 } 705 } 706 } 707 } 708 709 712 public void passFocus() { 713 java.util.logging.Logger.getLogger("Pooka.debug.gui.focus").fine("passing focus to subcomponent."); 714 if (lastStatus == CONTENT_LAST && contentPanel != null) { 715 if (contentPanel instanceof JComponent) 716 ((JComponent)contentPanel).requestFocusInWindow(); 717 else 718 contentPanel.getUIComponent().requestFocusInWindow(); 719 } else if (lastStatus == FOLDER_LAST && folderPanel != null) { 720 folderPanel.requestFocusInWindow(); 721 } 722 } 723 724 727 public int getLastStatus() { 728 return lastStatus; 729 } 730 731 734 public void setLastStatus(int newStatus) { 735 lastStatus = newStatus; 736 } 737 } 738 } 739 | Popular Tags |