1 package net.suberic.pooka.gui; 2 import net.suberic.pooka.*; 3 import net.suberic.util.*; 4 import net.suberic.util.swing.*; 5 import net.suberic.util.gui.ConfigurableKeyBinding; 6 import java.util.*; 7 import java.awt.*; 8 import java.awt.event.*; 9 import java.io.*; 10 import javax.mail.internet.MimeMessage ; 11 import javax.mail.Session ; 12 import javax.mail.MessagingException ; 13 import javax.swing.*; 14 import javax.swing.text.*; 15 import javax.swing.border.*; 16 import javax.swing.plaf.metal.MetalTheme ; 17 18 22 23 public class MessagePanel extends JDesktopPane implements ContentPanel, ThemeSupporter, ThemeListener { 24 31 class ExtendedDesktopManager extends net.suberic.util.swing.ScrollingDesktopManager { 32 33 public ExtendedDesktopManager(JDesktopPane pane, JScrollPane scrollPane) { 34 super(pane, scrollPane); 35 } 36 37 43 public void activateFrame(JInternalFrame f) { 44 super.activateFrame(f); 45 } 46 47 53 public void closeFrame(JInternalFrame f) { 54 super.closeFrame(f); 55 JInternalFrame allFrames[] = getAllFrames(); 56 if (allFrames.length > 0 && allFrames[0] != null) 57 try { 58 allFrames[0].setSelected(true); 59 } catch (java.beans.PropertyVetoException pve) { 60 } 61 } 62 63 } 64 65 67 JComponent UIComponent; 68 ConfigurableKeyBinding keyBindings; 69 boolean savingWindowLocations = false; 70 boolean savingOpenFolders = false; 71 MetalTheme currentTheme = null; 72 73 76 public MessagePanel() { 77 this.setSize(1000, 1000); 79 80 keyBindings = new ConfigurableKeyBinding(this, "ContentPanel.keyBindings", Pooka.getResources()); 81 keyBindings.setActive(getActions()); 83 84 Pooka.getHelpBroker().enableHelpKey(this, "ui.messagePanel", Pooka.getHelpBroker().getHelpSet()); 85 86 89 this.addFocusListener(new FocusAdapter() { 90 public void focusGained(FocusEvent e) { 91 JInternalFrame selectedFrame = getCurrentWindow(); 92 if (selectedFrame != null) { 93 java.util.logging.Logger.getLogger("Pooka.debug.gui.focus").fine("sending focus from MessagePanel to " + selectedFrame); 94 selectedFrame.requestFocusInWindow(); 95 } 96 } 97 }); 98 99 this.setSavingWindowLocations(Pooka.getProperty("Pooka.saveFolderWindowLocationsOnExit", "false").equalsIgnoreCase("true")); 100 this.setSavingOpenFolders(Pooka.getProperty("Pooka.saveOpenFoldersOnExit", "false").equalsIgnoreCase("true")); 101 102 configureInterfaceStyle(); 104 } 105 106 110 public MessagePanel(PreviewContentPanel pcp) { 111 this (); 112 113 115 java.util.HashMap cardTable = pcp.getCardTable(); 116 Set keys = cardTable.keySet(); 117 Iterator keyIt = keys.iterator(); 118 while (keyIt.hasNext()) { 119 String folderID = (String ) keyIt.next(); 120 PreviewFolderPanel pfp = (PreviewFolderPanel) cardTable.get(folderID); 121 FolderInternalFrame fif = new FolderInternalFrame(pfp, this); 122 pfp.getFolderInfo().setFolderDisplayUI(fif); 123 openFolderWindow(fif); 124 } 125 126 PreviewFolderPanel current = pcp.getCurrentPanel(); 127 if (current != null) { 128 current.getFolderDisplay().getMessageTable().getSelectionModel().removeListSelectionListener(pcp.getSelectionListener()); 129 } 130 } 131 132 135 public void savePanelSize() { 136 } 138 139 140 144 public void openFolderWindow(FolderInternalFrame f) { 145 openFolderWindow(f, true); 146 } 147 148 154 public void openFolderWindow(FolderInternalFrame newFolderWindow, boolean selectWindow) { 155 156 if (! SwingUtilities.isEventDispatchThread()) { 157 System.err.println("running openFolderWindow while not on EventDispatchThread."); 158 Thread.currentThread().dumpStack(); 159 } 160 if (newFolderWindow.getDesktopPane() != this) { 161 setLayer(newFolderWindow, JLayeredPane.DEFAULT_LAYER.intValue()); 162 String folderProperty = newFolderWindow.getFolderInfo().getFolderProperty(); 163 try { 164 int x = Integer.parseInt(Pooka.getProperty(folderProperty + ".windowLocation.x")); 165 int y = Integer.parseInt(Pooka.getProperty(folderProperty + ".windowLocation.y")); 166 167 newFolderWindow.setLocation(x, y); 168 } catch (Exception e) { 169 newFolderWindow.setLocation(getNewWindowLocation(newFolderWindow, false)); 170 } 171 172 if (!newFolderWindow.isVisible()) 173 newFolderWindow.setVisible(true); 174 175 if (getComponentCount() == 0) 176 selectWindow = true; 177 178 this.add(newFolderWindow); 179 } else { 180 if (!newFolderWindow.isVisible()) 181 newFolderWindow.setVisible(true); 182 } 183 184 if (newFolderWindow.isIcon()) { 185 try { 186 newFolderWindow.setIcon(false); 187 } catch (java.beans.PropertyVetoException e) { 188 } 189 } 190 191 if (selectWindow) { 192 try { 193 newFolderWindow.setSelected(true); 194 } catch (java.beans.PropertyVetoException e) { 195 } 196 } 197 } 198 199 200 206 public Point getNewWindowLocation(JComponent c, boolean center) { 207 int baseDelta = 20; 208 210 if (getUIComponent() != null) { 211 JViewport viewport = ((JScrollPane)getUIComponent()).getViewport(); 212 213 Point p = viewport.getViewPosition(); 214 215 217 Dimension componentSize = c.getSize(); 218 219 Dimension viewportSize = viewport.getViewSize(); 220 221 222 if (! center) { 223 int maxX = (Math.max(0, viewportSize.width - componentSize.width) + p.x); 224 int maxY = (Math.max(0, viewportSize.height - componentSize.height) + p.y); 225 226 if (maxX - p.x <= baseDelta && maxY - p.y <= baseDelta) 227 return p; 228 229 Point returnValue = new Point(p.x, p.y); 230 231 233 JInternalFrame[] allFrames = getAllFrames(); 234 235 if (allFrames.length > 0) { 236 ArrayList problemPoints = new ArrayList(); 237 238 for (int i = 0; i < allFrames.length; i++) { 239 if (allFrames[i] != c) { 240 Point currentLoc = allFrames[i].getLocation(); 241 242 if (currentLoc.x <= maxX + baseDelta && currentLoc.x > p.x - baseDelta && currentLoc.y <= maxY + baseDelta && currentLoc.y > p.y - baseDelta) { 243 problemPoints.add(currentLoc); 244 } 245 } 246 } 247 248 if (problemPoints.size() > 0) { 249 251 boolean spotfound = false; 252 for (int delta = 0; ! spotfound && p.x + delta <= maxX && p.y + delta <= maxY; delta += baseDelta) { 254 if (checkSpot(p.x + delta, p.y + delta, problemPoints)) { 255 spotfound = true; 256 returnValue = new Point(p.x + delta, p.y + delta); 257 } 258 } 259 260 263 if (!spotfound) { 264 for (int xdelta = 0; ! spotfound && p.x + xdelta <= maxX; xdelta += baseDelta) { 265 for (int ydelta = 0; ! spotfound && p.y + ydelta <= maxY; ydelta += baseDelta) { 266 if (checkSpot(p.x + xdelta, p.y + ydelta, problemPoints)) { 267 spotfound = true; 268 returnValue = new Point(p.x + xdelta, p.y + ydelta); 269 } 270 } 271 272 } 273 } 274 275 278 if (! spotfound) { 279 JInternalFrame jif = getSelectedFrame(); 280 if (jif != null) { 281 Point selectedPoint = jif.getLocation(); 282 if (selectedPoint.x >= p.x && selectedPoint.y >= p.y) { 284 int xdelta = selectedPoint.x - p.x; 286 int ydelta = selectedPoint.y - p.y; 287 int mindelta = Math.min(xdelta, ydelta); 288 Point basePoint = new Point(p.x + mindelta, p.y + mindelta); 289 if (basePoint.x + baseDelta <= maxX && basePoint.y + baseDelta <= maxY) { 290 returnValue = new Point(basePoint.x + baseDelta, basePoint.y + baseDelta); 291 } else if (basePoint.x + baseDelta <= maxX && basePoint.y <= maxY) { 292 returnValue = new Point(basePoint.x + baseDelta, basePoint.y); 293 } else if (basePoint.x <= maxX && basePoint.y + baseDelta <= maxY) { 294 returnValue = new Point(basePoint.x, basePoint.y + baseDelta); 295 } 296 297 299 } 300 } 301 } 302 } 303 } 304 return returnValue; 305 } else { 307 int diffWidth = Math.max(viewportSize.width - componentSize.width, 0); 308 int diffHeight = Math.max(viewportSize.height - componentSize.height, 0); 309 310 Point returnValue = new Point(p.x + (diffWidth / 2), p.y + (diffHeight / 2)); 311 312 return returnValue; 313 } 314 } else { 315 return new Point(0, 0); 316 } 317 } 318 319 322 private boolean checkSpot(int pX, int pY, java.util.List problemPoints) { 323 boolean ok = true; 324 int baseDelta = 20; 325 for (int i = 0; ok && i < problemPoints.size(); i++) { 326 Point currentPoint = (Point) problemPoints.get(i); 327 if (currentPoint.x > pX - baseDelta && currentPoint.x < pX + baseDelta && currentPoint.y > pY - baseDelta && currentPoint.y < pY + baseDelta) { 328 ok = false; 329 } 330 } 331 332 return ok; 333 } 334 335 343 public void openSavedFolders(Vector folderList) { 344 if (folderList != null) 345 for (int i = 0; i < folderList.size(); i++) { 346 FolderInfo fInfo = Pooka.getStoreManager().getFolderById((String )folderList.elementAt(i)); 347 if (fInfo != null && fInfo.getFolderNode() != null) { 348 349 final FolderNode fNode = fInfo.getFolderNode(); 350 fNode.makeVisible(); 351 fInfo.getFolderThread().addToQueue(new javax.swing.AbstractAction () { 354 public void actionPerformed(java.awt.event.ActionEvent ae) { 355 fNode.openFolder(false, false); 356 } 357 }, new java.awt.event.ActionEvent (this, 0, "message-send")); 358 } 359 } 360 } 361 362 370 public void openMessageWindow(MessageProxy m, boolean newMessage) { 371 JInternalFrame messageWindow = (JInternalFrame) m.getMessageUI(); 372 if (messageWindow == null) { 373 try { 374 MessageUI mui = Pooka.getUIFactory().createMessageUI(m); 375 m.setMessageUI(mui); 376 messageWindow = (JInternalFrame) mui; 377 newMessage = true; 378 } catch (MessagingException me) { 379 Pooka.getUIFactory().showError(Pooka.getProperty("error.MessageInternalFrame.errorLoadingMessage", "Error loading Message: ") + "\n" + me.getMessage(), Pooka.getProperty("error.MessageInternalFrame.errorLoadingMessage.title", "Error loading message."), me); 380 } 381 } 382 383 if (messageWindow != null) { 384 final JInternalFrame newMessageWindow = messageWindow; 385 final boolean isNew = newMessage; 386 387 Runnable openWindowCommand = new Runnable () { 388 public void run() { 389 if (isNew) { 390 391 MessagePanel.this.add(newMessageWindow); 392 Point p = getNewWindowLocation(newMessageWindow, false); 393 newMessageWindow.setLocation(p); 394 newMessageWindow.setVisible(true); 395 } else { 396 if (newMessageWindow.isIcon()) 397 try { 398 newMessageWindow.setIcon(false); 399 } catch (java.beans.PropertyVetoException e) { 400 } 401 } 402 403 try { 404 newMessageWindow.setSelected(true); 405 } catch (java.beans.PropertyVetoException e) { 406 } 407 } 408 }; 409 if (SwingUtilities.isEventDispatchThread()) 410 openWindowCommand.run(); 411 else 412 try { 413 SwingUtilities.invokeAndWait(openWindowCommand); 414 } catch (Exception e) { 415 } 417 } 418 } 419 420 423 public void createNewMessage() { 424 createNewMessage(new MimeMessage (Pooka.getMainPanel().getSession())); 425 } 426 427 432 public void createNewMessage(javax.mail.Message m) { 433 NewMessageProxy nmp = new NewMessageProxy(new NewMessageInfo(m)); 434 openMessageWindow(nmp, true); 435 } 436 437 441 442 public void saveWindowLocations() { 443 JInternalFrame[] allFrames = getAllFrames(); 444 445 for(int i = 0; i < allFrames.length; i++) { 446 if (allFrames[i] instanceof FolderInternalFrame) { 447 FolderInternalFrame fif = (FolderInternalFrame)allFrames[i]; 448 fif.saveWindowSettings(); 450 } 451 } 452 453 } 454 455 459 460 public void saveOpenFolders() { 461 JInternalFrame[] allFrames = getAllFrames(); 462 boolean isFirst = true; 463 464 StringBuffer savedFolderValues = new StringBuffer (); 465 for(int i = 0; i < allFrames.length; i++) { 466 if (allFrames[i] instanceof FolderDisplayUI) { 467 String folderID = ((FolderDisplayUI)allFrames[i]).getFolderInfo().getFolderID(); 468 if (! isFirst) 469 savedFolderValues.append(":"); 470 471 isFirst = false; 472 473 savedFolderValues.append(folderID); 474 } 475 } 476 477 Pooka.setProperty("Pooka.openFolderList", savedFolderValues.toString()); 478 479 } 480 481 484 public JInternalFrame getCurrentWindow() { 485 JInternalFrame[] allFrames = getAllFrames(); 486 487 for(int i = 0; i < allFrames.length; i++) { 488 if (allFrames[i].isSelected()) 489 return allFrames[i]; 490 } 491 492 return null; 493 } 494 495 498 public void selectNextWindow() { 499 JInternalFrame[] allFrames = getAllFrames(); 500 501 if (allFrames.length > 0) { 502 for(int i = 0; i < allFrames.length; i++) { 503 if (allFrames[i].isSelected()) { 504 JInternalFrame selected = allFrames[i]; 505 JInternalFrame newSelected = allFrames[i + 1 % allFrames.length]; 506 try { 507 setPosition(selected, allFrames.length -1); 508 newSelected.setSelected(true); 509 } catch (java.beans.PropertyVetoException e) { 510 } 511 512 return; 513 } 514 } 515 516 519 try { 520 allFrames[0].setSelected(true); 521 } catch (java.beans.PropertyVetoException e) { 522 } 523 } 524 } 525 526 529 public void selectPreviousWindow() { 530 JInternalFrame[] allFrames = getAllFrames(); 531 532 if (allFrames.length > 0) { 533 for(int i = 0; i < allFrames.length; i++) { 534 if (allFrames[i].isSelected()) { 535 int j; 536 if (i > 0) 537 j = i-1; 538 else 539 j = allFrames.length -1; 540 try { 541 allFrames[j].setSelected(true); 542 } catch (java.beans.PropertyVetoException e) { 543 } 544 545 return; 546 } 547 } 548 549 552 try { 553 allFrames[0].setSelected(true); 554 } catch (java.beans.PropertyVetoException e) { 555 } 556 } 557 } 558 559 563 564 public void moveWindow(int modifiers, String cmd) { 565 JInternalFrame current = getCurrentWindow(); 566 567 if (current != null) { 568 int x = current.getX(); 569 int y = current.getY(); 570 571 int moveValue = 1; 572 573 if ((modifiers & ActionEvent.SHIFT_MASK) != 0) 574 moveValue = 10; 575 576 if (cmd.equals("left")) 577 x = x - moveValue; 578 else if (cmd.equals("right")) 579 x = x + moveValue; 580 else if (cmd.equals("up")) 581 y = y - moveValue; 582 else if (cmd.equals("down")) 583 y = y + moveValue; 584 585 current.setLocation(x, y); 586 } 587 } 588 589 593 public void unselectAndMoveToBack(JInternalFrame pFrame) { 594 pFrame.moveToBack(); 595 if (pFrame.isSelected()) { 596 try { 597 pFrame.setSelected(false); 598 } catch (Exception e) { 599 java.util.logging.Logger.getLogger("Pooka.debug.gui").fine("error unselecting frame."); 600 } 601 int topLayer = highestLayer(); 602 JInternalFrame[] onTop = getAllFramesInLayer(topLayer); 603 for (int i = 0; onTop != null && i < onTop.length; i++) { 604 if (onTop[i] != null && onTop[i] != pFrame) { 605 try { 606 onTop[i].setSelected(true); 607 } catch (Exception e) { 608 java.util.logging.Logger.getLogger("Pooka.debug.gui").fine("selecting frame."); 609 } 610 break; 611 } 612 } 613 } 614 } 615 616 617 622 public void showHelpScreen(String title, java.net.URL url) { 623 JInternalFrame jif = new JInternalFrame(title, true, true, true); 624 JEditorPane jep = new JEditorPane(); 625 try { 626 jep.setPage(url); 627 } catch (IOException ioe) { 628 jep.setText(Pooka.getProperty("err.noHelpPage", "No help available.")); 629 } 630 jep.setEditable(false); 631 jif.setSize(500,500); 632 jif.getContentPane().add(new JScrollPane(jep)); 633 this.add(jif); 634 jif.setVisible(true); 635 try { 636 jif.setSelected(true); 637 } catch (java.beans.PropertyVetoException e) { 638 } 639 640 } 641 642 645 public void configureInterfaceStyle() { 646 Runnable runMe = new Runnable () { 647 public void run() { 648 try { 649 Pooka.getUIFactory().getPookaThemeManager().updateUI(MessagePanel.this, MessagePanel.this); 650 } catch (Exception e) { 651 } 652 } 653 }; 654 655 if (! SwingUtilities.isEventDispatchThread()) { 656 SwingUtilities.invokeLater(runMe); 657 } else { 658 runMe.run(); 659 } 660 } 661 662 666 public MetalTheme getTheme(ThemeManager tm) { 667 String id = Pooka.getProperty("Pooka.messagePanel.theme", ""); 668 if (id != null && ! id.equals("")) { 669 return tm.getTheme(id); 670 } 671 672 return tm.getDefaultTheme(); 673 } 674 675 678 public MetalTheme getCurrentTheme() { 679 return currentTheme; 680 } 681 682 685 public void setCurrentTheme(MetalTheme newTheme) { 686 if (currentTheme != null && currentTheme instanceof ConfigurableMetalTheme) { 687 ((ConfigurableMetalTheme)currentTheme).removeThemeListener(this); 688 } 689 currentTheme = newTheme; 690 691 if (currentTheme != null && currentTheme instanceof ConfigurableMetalTheme) { 692 ((ConfigurableMetalTheme)currentTheme).addThemeListener(this); 693 } 694 } 695 696 699 public void themeChanged(ConfigurableMetalTheme theme) { 700 if (currentTheme != null && currentTheme == theme) { 703 SwingUtilities.invokeLater(new Runnable () { 704 public void run() { 705 try { 706 Pooka.getUIFactory().getPookaThemeManager().updateUI(MessagePanel.this, MessagePanel.this); 707 } catch (Exception e) { 708 } 709 } 710 }); 711 } 712 } 713 714 717 public void refreshActiveMenus() { 718 719 } 720 721 724 public JComponent getUIComponent() { 725 return UIComponent; 726 } 727 728 731 public void setUIComponent(JComponent newComp) { 732 UIComponent = newComp; 733 } 734 735 738 739 public UserProfile getDefaultProfile() { 740 JInternalFrame cw = getCurrentWindow(); 741 if (cw != null && cw instanceof UserProfileContainer) 742 return ((UserProfileContainer)cw).getDefaultProfile(); 743 else 744 return null; 745 } 746 747 751 752 public boolean isSavingWindowLocations() { 753 return savingWindowLocations; 754 } 755 756 760 public void setSavingWindowLocations(boolean newValue) { 761 savingWindowLocations = newValue; 762 } 763 764 768 769 public boolean isSavingOpenFolders() { 770 return savingOpenFolders; 771 } 772 773 777 public void setSavingOpenFolders(boolean newValue) { 778 savingOpenFolders = newValue; 779 } 780 781 public Action[] defaultActions = { 782 new NextWindowAction(), 783 new PreviousWindowAction(), 784 new MoveWindowAction("move-window-left"), 785 new MoveWindowAction("move-window-right"), 786 new MoveWindowAction("move-window-up"), 787 new MoveWindowAction("move-window-down") 788 }; 789 790 public Action[] getDefaultActions() { 791 return defaultActions; 792 } 793 794 public Action[] getActions() { 795 JInternalFrame cw = getCurrentWindow(); 796 797 if (cw != null) { 798 Action[] windowActions = null; 799 if (cw instanceof ActionContainer) 800 windowActions = ((ActionContainer)cw).getActions(); 801 802 if (windowActions != null) 803 return TextAction.augmentList(windowActions, getDefaultActions()); 804 805 } 806 return getDefaultActions(); 807 } 808 809 public class NextWindowAction extends AbstractAction { 810 NextWindowAction() { 811 super("window-next"); 812 } 813 814 public void actionPerformed(ActionEvent e) { 815 selectNextWindow(); 816 } 817 } 818 819 public class PreviousWindowAction extends AbstractAction { 820 PreviousWindowAction() { 821 super("window-previous"); 822 } 823 824 public void actionPerformed(ActionEvent e) { 825 selectPreviousWindow(); 826 } 827 } 828 829 public class MoveWindowAction extends AbstractAction { 830 MoveWindowAction() { 831 super("move-window"); 832 } 833 834 MoveWindowAction(String cmdString) { 835 super(cmdString); 836 } 837 838 public void actionPerformed(ActionEvent e) { 839 String cmdString = e.getActionCommand(); 840 moveWindow(e.getModifiers(), cmdString.substring(cmdString.lastIndexOf("-") +1)); 841 } 842 } 843 844 } 845 846 847 848 849 850 851 | Popular Tags |