1 package net.suberic.pooka.gui; 2 import net.suberic.pooka.*; 3 import net.suberic.util.gui.*; 4 import net.suberic.util.swing.HyperlinkMouseHandler; 5 import javax.mail.*; 6 import javax.mail.internet.*; 7 import java.awt.*; 8 import java.awt.event.*; 9 import javax.swing.*; 10 import javax.swing.text.TextAction ; 11 import java.util.*; 12 import javax.swing.text.JTextComponent ; 13 import javax.swing.event.*; 14 import java.io.File ; 15 16 public class ReadMessageDisplayPanel extends MessageDisplayPanel { 17 18 private JTextPane otherEditorPane = null; 19 private JScrollPane otherScrollPane = null; 20 21 private Box attachmentSlot = null; 22 private Box cryptoSlot = null; 23 24 public boolean firstShow = true; 25 26 private static String WITH_ATTACHMENTS = "with"; 27 private static String WITHOUT_ATTACHMENTS = "without"; 28 29 private String editorStatus = WITHOUT_ATTACHMENTS; 30 31 private DisplayStyleComboBox displayCombo = null; 32 private DisplayStyleComboBox headerCombo = null; 33 private net.suberic.pooka.gui.crypto.CryptoStatusDisplay cryptoStatusDisplay = null; 34 35 Action [] defaultActions = new Action [] { 36 new AttachmentPanelAction(), 37 new FindAction(), 38 new FindNextAction() 39 }; 40 41 44 public ReadMessageDisplayPanel() { 45 super(); 46 47 this.setLayout(new CardLayout()); 48 49 this.addFocusListener(new FocusAdapter() { 50 public void focusGained(FocusEvent e) { 51 if (editorStatus == WITHOUT_ATTACHMENTS) { 52 if (editorPane != null) 53 editorPane.requestFocusInWindow(); 54 } else if (editorStatus == WITH_ATTACHMENTS) { 55 if (otherEditorPane != null) 56 otherEditorPane.requestFocusInWindow(); 57 } 58 } 59 }); 60 } 61 62 65 public ReadMessageDisplayPanel(MessageUI newMsgUI) { 66 super(newMsgUI); 67 68 this.setLayout(new CardLayout()); 69 70 this.addFocusListener(new FocusAdapter() { 71 public void focusGained(FocusEvent e) { 72 if (editorStatus == WITHOUT_ATTACHMENTS) { 73 if (editorPane != null) 74 editorPane.requestFocusInWindow(); 75 } else if (editorStatus == WITH_ATTACHMENTS) { 76 if (otherEditorPane != null) 77 otherEditorPane.requestFocusInWindow(); 78 } 79 } 80 }); 81 } 82 83 88 public void configureMessageDisplay() throws MessagingException { 89 editorPane = new JTextPane(); 90 editorPane.setEditable(false); 91 editorPane.addHyperlinkListener(new HyperlinkDispatcher()); 92 HyperlinkMouseHandler hmh = new HyperlinkMouseHandler(Integer.parseInt(Pooka.getProperty("Pooka.lineLength", "80"))); 93 editorPane.addMouseListener(hmh); 94 editorPane.addMouseMotionListener(hmh); 95 96 editorScrollPane = new JScrollPane(editorPane, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 97 98 100 otherEditorPane = new JTextPane(); 101 otherEditorPane.setEditable(false); 102 otherEditorPane.addHyperlinkListener(new HyperlinkDispatcher()); 103 otherEditorPane.addMouseListener(hmh); 104 otherEditorPane.addMouseMotionListener(hmh); 105 otherScrollPane = new JScrollPane(otherEditorPane, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 106 107 setDefaultFont(); 108 109 splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); 110 111 attachmentDisplayPanel = new JPanel(); 112 attachmentDisplayPanel.setLayout(new BoxLayout(attachmentDisplayPanel, BoxLayout.X_AXIS)); 113 attachmentSlot = new Box(BoxLayout.Y_AXIS); 114 cryptoSlot = new Box(BoxLayout.Y_AXIS); 115 116 attachmentDisplayPanel.add(Box.createHorizontalStrut(5)); 117 attachmentDisplayPanel.add(attachmentSlot); 118 attachmentDisplayPanel.add(Box.createHorizontalStrut(5)); 119 attachmentDisplayPanel.add(cryptoSlot); 120 attachmentDisplayPanel.add(Box.createHorizontalStrut(5)); 121 122 splitPane.setTopComponent(otherScrollPane); 123 splitPane.setBottomComponent(attachmentDisplayPanel); 124 125 this.add(WITH_ATTACHMENTS, splitPane); 126 this.add(WITHOUT_ATTACHMENTS, editorScrollPane); 127 128 keyBindings = new ConfigurableKeyBinding(this, "ReadMessageWindow.keyBindings", Pooka.getResources()); 129 keyBindings.setActive(getActions()); 130 131 KeyStroke upArrowStroke = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_UP, 0); 133 KeyStroke downArrowStroke = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_DOWN, 0); 134 KeyStroke leftArrowStroke = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_LEFT, 0); 135 KeyStroke rightArrowStroke = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_RIGHT, 0); 136 137 Action upArrowAction = new AbstractAction() { 138 public void actionPerformed(ActionEvent e) { 139 JScrollBar jsb = getCurrentScrollPane().getVerticalScrollBar(); 140 jsb.setValue(jsb.getValue() - jsb.getBlockIncrement()); 141 } 142 }; 143 144 Action downArrowAction = new AbstractAction() { 145 public void actionPerformed(ActionEvent e) { 146 JScrollBar jsb = getCurrentScrollPane().getVerticalScrollBar(); 147 jsb.setValue(jsb.getValue() + jsb.getBlockIncrement()); 148 } 149 }; 150 151 Action leftArrowAction = new AbstractAction() { 152 public void actionPerformed(ActionEvent e) { 153 JScrollBar jsb = getCurrentScrollPane().getHorizontalScrollBar(); 154 if (jsb != null) 155 jsb.setValue(jsb.getValue() - jsb.getBlockIncrement()); 156 } 157 }; 158 159 Action rightArrowAction = new AbstractAction() { 160 public void actionPerformed(ActionEvent e) { 161 JScrollBar jsb = getCurrentScrollPane().getHorizontalScrollBar(); 162 if (jsb != null) 163 jsb.setValue(jsb.getValue() + jsb.getBlockIncrement()); 164 } 165 }; 166 167 String upArrowKey = "message-scroll-up"; 168 String downArrowKey = "message-scroll-down"; 169 String leftArrowKey = "message-scroll-left"; 170 String rightArrowKey = "message-scroll-right"; 171 172 174 InputMap newInputMap = new InputMap(); 175 ActionMap newActionMap = new ActionMap(); 176 177 newInputMap.put(upArrowStroke, upArrowKey); 178 newActionMap.put(upArrowKey, upArrowAction); 179 180 newInputMap.put(downArrowStroke, downArrowKey); 181 newActionMap.put(downArrowKey, downArrowAction); 182 183 newInputMap.put(leftArrowStroke, leftArrowKey); 184 newActionMap.put(leftArrowKey, leftArrowAction); 185 186 newInputMap.put(rightArrowStroke, rightArrowKey); 187 newActionMap.put(rightArrowKey, rightArrowAction); 188 189 InputMap editorInputMap = editorPane.getInputMap(); 190 ActionMap editorActionMap = editorPane.getActionMap(); 191 192 newInputMap.setParent(editorInputMap); 193 newActionMap.setParent(editorActionMap); 194 195 editorPane.setInputMap(JComponent.WHEN_FOCUSED, newInputMap); 196 editorPane.setActionMap(newActionMap); 197 198 200 newInputMap = new InputMap(); 201 newActionMap = new ActionMap(); 202 203 newInputMap.put(upArrowStroke, upArrowKey); 204 newActionMap.put(upArrowKey, upArrowAction); 205 206 newInputMap.put(downArrowStroke, downArrowKey); 207 newActionMap.put(downArrowKey, downArrowAction); 208 209 newInputMap.put(leftArrowStroke, leftArrowKey); 210 newActionMap.put(leftArrowKey, leftArrowAction); 211 212 newInputMap.put(rightArrowStroke, rightArrowKey); 213 newActionMap.put(rightArrowKey, rightArrowAction); 214 215 InputMap otherEditorInputMap = otherEditorPane.getInputMap(); 216 ActionMap otherEditorActionMap = otherEditorPane.getActionMap(); 217 218 newInputMap.setParent(otherEditorInputMap); 219 newActionMap.setParent(otherEditorActionMap); 220 221 otherEditorPane.setInputMap(JComponent.WHEN_FOCUSED, newInputMap); 222 otherEditorPane.setActionMap(newActionMap); 223 224 226 editorPane.addMouseListener(new MouseAdapter() { 227 228 public void mousePressed(MouseEvent e) { 229 if (e.isPopupTrigger()) { 230 showPopupMenu(editorPane, e); 231 } 232 } 233 234 public void mouseReleased(MouseEvent e) { 235 if (e.isPopupTrigger()) { 236 showPopupMenu(editorPane, e); 237 } 238 } 239 }); 240 241 if (getMessageProxy() != null) { 242 resetEditorText(); 243 } else { 244 ((CardLayout)getLayout()).show(this, WITHOUT_ATTACHMENTS); 245 editorStatus = WITHOUT_ATTACHMENTS; 246 } 247 248 } 249 250 251 259 public void resetEditorText() throws MessagingException { 260 264 266 if (getMessageProxy() != null) { 267 StringBuffer messageText = new StringBuffer (); 268 269 String content = null; 270 271 String contentType = "text/plain"; 272 273 boolean displayHtml = false; 274 275 int msgDisplayMode = getMessageProxy().getDisplayMode(); 276 277 if (Pooka.getProperty("Pooka.displayHtml", "").equalsIgnoreCase("true")) { 279 if (getMessageProxy().getMessageInfo().isHtml()) { 280 if (msgDisplayMode > MessageProxy.TEXT_ONLY) 281 displayHtml = true; 282 283 } else if (getMessageProxy().getMessageInfo().containsHtml()) { 284 if (msgDisplayMode >= MessageProxy.HTML_PREFERRED) 285 displayHtml = true; 286 287 } else { 288 } 290 } 291 292 if (msgDisplayMode == MessageProxy.RFC_822) { 294 content = getMessageProxy().getMessageInfo().getRawText(); 295 } else { 296 if (displayHtml) { 297 contentType = "text/html"; 298 299 if (Pooka.getProperty("Pooka.displayTextAttachments", "").equalsIgnoreCase("true")) { 300 content = getMessageProxy().getMessageInfo().getHtmlAndTextInlines(true, showFullHeaders()); 301 } else { 302 content = getMessageProxy().getMessageInfo().getHtmlPart(true, showFullHeaders()); 303 } 304 } else { 305 if (Pooka.getProperty("Pooka.displayTextAttachments", "").equalsIgnoreCase("true")) { 306 if (getMessageProxy().getMessageInfo().isHtml()) 309 content = getMessageProxy().getMessageInfo().getHtmlAndTextInlines(true, showFullHeaders()); 310 else 311 content = getMessageProxy().getMessageInfo().getTextAndTextInlines(true, showFullHeaders()); 312 } else { 313 if (getMessageProxy().getMessageInfo().isHtml()) 316 content = getMessageProxy().getMessageInfo().getHtmlPart(true, showFullHeaders()); 317 else 318 content = getMessageProxy().getMessageInfo().getTextPart(true, showFullHeaders()); 319 } 320 } 321 } 322 323 if (content != null) 324 messageText.append(content); 325 326 final String finalMessageText = messageText.toString(); 327 final String finalContentType = contentType; 328 final boolean hasAttachments = getMessageProxy().hasAttachments(); 329 final boolean hasEncryption = (getMessageProxy().getMessageInfo() == null) ? false : getMessageProxy().getMessageInfo().hasEncryption(); 330 final boolean contentIsNull = (content == null); 331 332 SwingUtilities.invokeLater(new Runnable () { 333 public void run() { 334 if (getDisplayCombo() != null) 335 getDisplayCombo().styleUpdated(getMessageProxy().getDisplayMode(), getMessageProxy().getHeaderMode()); 336 337 if (getHeaderCombo() != null && getHeaderCombo() != getDisplayCombo()) { 338 getHeaderCombo().styleUpdated(getMessageProxy().getDisplayMode(), getMessageProxy().getHeaderMode()); 339 } 340 341 if (! contentIsNull) { 342 if (hasAttachments) { 343 try { 344 otherEditorPane.setContentType(finalContentType); 345 otherEditorPane.setEditable(false); 346 otherEditorPane.setText(finalMessageText); 347 otherEditorPane.setCaretPosition(0); 348 } catch (Exception e) { 349 otherEditorPane.setEditorKit(new javax.swing.text.StyledEditorKit ()); 351 352 otherEditorPane.setEditable(false); 353 otherEditorPane.setText(finalMessageText); 354 otherEditorPane.setCaretPosition(0); 355 } 356 } else { 357 try { 358 editorPane.setContentType(finalContentType); 359 editorPane.setEditable(false); 360 editorPane.setText(finalMessageText); 361 editorPane.setCaretPosition(0); 362 } catch (Exception e) { 363 366 editorPane.setEditorKit(new javax.swing.text.StyledEditorKit ()); 367 368 editorPane.setEditable(false); 369 editorPane.setText(finalMessageText); 370 editorPane.setCaretPosition(0); 371 372 } 373 } 374 } 375 376 if (hasAttachments) { 377 attachmentPanel = new AttachmentPane(getMessageProxy()); 378 fillAttachmentSlot(attachmentPanel); 379 380 ((CardLayout) getLayout()).show(ReadMessageDisplayPanel.this, WITH_ATTACHMENTS); 381 editorStatus = WITH_ATTACHMENTS; 382 383 if (splitPane != null && attachmentPanel != null) { 384 double paneHeight = splitPane.getSize().getHeight(); 385 if (paneHeight <= 0) 386 paneHeight = splitPane.getPreferredSize().getHeight(); 387 splitPane.setDividerLocation((int)(paneHeight - attachmentPanel.getPreferredSize().getHeight())); 388 } else { 389 splitPane.setDividerLocation(400); 390 } 391 392 MessageUI mui = getMessageUI(); 394 if (mui instanceof net.suberic.util.swing.ThemeSupporter) { 395 try { 396 Pooka.getUIFactory().getPookaThemeManager().updateUI((net.suberic.util.swing.ThemeSupporter) mui, attachmentPanel, true); 397 } catch (Exception etwo) { 398 if (Pooka.isDebug()) 399 System.out.println("error setting theme: " + etwo); 400 } 401 } 402 403 } else { 404 ((CardLayout) getLayout()).show(ReadMessageDisplayPanel.this, WITHOUT_ATTACHMENTS); 405 editorStatus = WITHOUT_ATTACHMENTS; 406 } 407 408 if (hasEncryption) { 409 net.suberic.pooka.gui.crypto.CryptoStatusDisplay csd = new net.suberic.pooka.gui.crypto.CryptoPanel(); 410 setCryptoStatusDisplay(csd); 411 MessageCryptoInfo cryptoInfo = getMessageProxy().getMessageInfo().getCryptoInfo(); 412 if (cryptoInfo != null) 413 csd.cryptoUpdated(cryptoInfo); 414 415 fillCryptoSlot((JComponent) csd); 416 } else { 417 fillCryptoSlot(null); 418 } 419 } 420 }); 421 422 } else { 423 424 SwingUtilities.invokeLater(new Runnable () { 425 public void run() { 426 editorPane.setEditable(false); 428 editorPane.setText(""); 429 editorPane.setCaretPosition(0); 430 431 otherEditorPane.setEditable(false); 432 otherEditorPane.setText(""); 433 otherEditorPane.setCaretPosition(0); 434 435 ((CardLayout) getLayout()).show(ReadMessageDisplayPanel.this, WITHOUT_ATTACHMENTS); 436 editorStatus = WITHOUT_ATTACHMENTS; 437 } 438 }); 439 } 440 441 keyBindings.setActive(getActions()); 442 443 SwingUtilities.invokeLater(new Runnable () { 444 public void run() { 445 ReadMessageDisplayPanel.this.repaint(); 446 } 447 }); 448 } 449 450 453 public boolean showFullHeaders() { 454 if (getMessageProxy() != null) 455 return (getMessageProxy().getHeaderMode() == MessageProxy.HEADERS_FULL); 456 else 457 return false; 458 } 459 460 463 public void fillAttachmentSlot(JComponent component) { 464 if (attachmentSlot != null) { 465 Component [] children = attachmentSlot.getComponents(); 466 for (int i = 0; children != null && i < children.length; i++) { 467 attachmentSlot.remove(children[i]); 468 } 469 470 if (component != null) 471 attachmentSlot.add(component); 472 } 473 474 } 475 476 479 public void fillCryptoSlot(JComponent component) { 480 if (cryptoSlot != null) { 481 Component [] children = cryptoSlot.getComponents(); 482 for (int i = 0; children != null && i < children.length; i++) { 483 cryptoSlot.remove(children[i]); 484 } 485 486 if (component != null) 487 cryptoSlot.add(component); 488 } 489 490 } 491 492 501 502 public void registerKeyboardAction(ActionListener anAction, 503 String aCommand, KeyStroke aKeyStroke, int aCondition) { 504 super.registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition); 505 506 if (attachmentPanel != null) 507 attachmentPanel.registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition); 508 editorPane.registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition); 509 editorScrollPane.registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition); 510 if (splitPane != null) 511 splitPane.registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition); 512 } 513 514 522 523 public void unregisterKeyboardAction(KeyStroke aKeyStroke) { 524 super.unregisterKeyboardAction(aKeyStroke); 525 526 if (attachmentPanel != null) 527 attachmentPanel.unregisterKeyboardAction(aKeyStroke); 528 editorPane.unregisterKeyboardAction(aKeyStroke); 529 editorScrollPane.unregisterKeyboardAction(aKeyStroke); 530 splitPane.unregisterKeyboardAction(aKeyStroke); 531 } 532 533 536 public void showPopupMenu(JComponent component, MouseEvent e) { 537 ConfigurablePopupMenu popupMenu = new ConfigurablePopupMenu(); 538 popupMenu.configureComponent("ReadMessageWindow.popupMenu", Pooka.getResources()); 539 popupMenu.setActive(getActions()); 540 MessageUI mui = getMessageUI(); 541 if (mui instanceof net.suberic.util.swing.ThemeSupporter) { 542 try { 543 Pooka.getUIFactory().getPookaThemeManager().updateUI((net.suberic.util.swing.ThemeSupporter) mui, popupMenu, true); 544 } catch (Exception etwo) { 545 if (Pooka.isDebug()) 546 System.out.println("error setting theme: " + e); 547 } 548 } 549 popupMenu.show(component, e.getX(), e.getY()); 550 551 } 552 553 557 public void sizeToDefault() { 558 Dimension prefSize = getDefaultEditorPaneSize(); 559 if (editorPane != null && editorScrollPane != null) { 560 JScrollBar vsb = editorScrollPane.getVerticalScrollBar(); 561 if (vsb != null) 562 prefSize.setSize(prefSize.getWidth() + vsb.getPreferredSize().getWidth(), prefSize.getHeight()); 563 editorScrollPane.setPreferredSize(prefSize); 564 if (otherScrollPane != null) { 565 otherScrollPane.setPreferredSize(prefSize); 566 } 567 this.setPreferredSize(prefSize); 568 if (splitPane != null && attachmentPanel != null) { 569 splitPane.setPreferredSize(prefSize); 570 double paneHeight = splitPane.getSize().getHeight(); 571 if (paneHeight <= 0) 572 paneHeight = splitPane.getPreferredSize().getHeight(); 573 splitPane.setDividerLocation((int)(paneHeight - attachmentPanel.getPreferredSize().getHeight())); 574 } 575 } else { 576 this.setSize(prefSize); 577 } 578 } 579 580 587 public void setDefaultFont() { 588 if (editorPane != null) 589 setDefaultFont(editorPane); 590 591 if (otherEditorPane != null) 592 setDefaultFont(otherEditorPane); 593 } 594 595 596 public void addNotify() { 597 super.addNotify(); 598 599 if (firstShow) { 600 sizeToDefault(); 601 firstShow = false; 602 } 603 604 } 605 606 public DisplayStyleComboBox getDisplayCombo() { 607 return displayCombo; 608 }; 609 public void setDisplayCombo(DisplayStyleComboBox dscb) { 610 displayCombo = dscb; 611 } 612 public DisplayStyleComboBox getHeaderCombo() { 613 return headerCombo; 614 }; 615 public void setHeaderCombo(DisplayStyleComboBox dscb) { 616 headerCombo = dscb; 617 } 618 619 622 public net.suberic.pooka.gui.crypto.CryptoStatusDisplay getCryptoStatusDisplay() { 623 return cryptoStatusDisplay; 624 } 625 626 629 public void setCryptoStatusDisplay( net.suberic.pooka.gui.crypto.CryptoStatusDisplay newDisplay) { 630 cryptoStatusDisplay = newDisplay; 631 } 632 633 636 public JTextPane getCurrentEditorPane() { 637 if (editorStatus == WITHOUT_ATTACHMENTS) { 638 return editorPane; 639 } else { 640 return otherEditorPane; 641 } 642 } 643 644 647 public JScrollPane getCurrentScrollPane() { 648 if (editorStatus == WITHOUT_ATTACHMENTS) { 649 return editorScrollPane; 650 } else { 651 return otherScrollPane; 652 } 653 } 654 655 656 657 659 662 public Action [] getActions() { 663 664 Action [] actionList = defaultActions; 665 666 if (getMessageProxy() != null) 667 actionList = TextAction.augmentList(actionList, getMessageProxy().getActions()); 668 669 Action [] subActions = null; 670 if (editorStatus == WITHOUT_ATTACHMENTS) { 671 if (editorPane != null) { 672 subActions = editorPane.getActions(); 673 } 674 } else { 675 678 Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); 679 if (focusOwner != null && attachmentPanel != null && SwingUtilities.isDescendingFrom(focusOwner, attachmentPanel)) { 680 subActions = attachmentPanel.getActions(); 681 } else { 682 if (otherEditorPane != null) { 683 subActions = otherEditorPane.getActions(); 684 } 685 } 686 687 } 688 689 if (subActions != null) 690 return TextAction.augmentList(actionList, subActions); 691 else 692 return actionList; 693 } 694 695 698 public class AttachmentPanelAction extends AbstractAction { 699 AttachmentPanelAction() { 700 super("message-select-attachment"); 701 } 702 703 public void actionPerformed(ActionEvent e) { 704 if (attachmentPanel != null) { 705 attachmentPanel.requestFocusInWindow(); 706 } 707 } 708 } 709 710 713 public class FindAction extends AbstractAction { 714 FindAction() { 715 super("message-find"); 716 } 717 718 public void actionPerformed(ActionEvent e) { 719 searchMessage(); 720 } 721 } 722 723 726 public class FindNextAction extends AbstractAction { 727 FindNextAction() { 728 super("message-find-next"); 729 } 730 731 public void actionPerformed(ActionEvent e) { 732 searchAgain(); 733 } 734 } 735 736 739 public class EditorPanelAction extends AbstractAction { 740 EditorPanelAction() { 741 super("message-select-editor"); 742 } 743 744 public void actionPerformed(ActionEvent e) { 745 if (editorStatus == WITHOUT_ATTACHMENTS) { 746 if (editorPane != null) 747 editorPane.requestFocusInWindow(); 748 } else if (editorStatus == WITH_ATTACHMENTS) { 749 if (otherEditorPane != null) 750 otherEditorPane.requestFocusInWindow(); 751 } 752 } 753 } 754 755 } 756 | Popular Tags |