1 package org.columba.mail.gui.frame; 19 20 import java.awt.BorderLayout ; 21 import java.awt.Point ; 22 import java.awt.event.KeyEvent ; 23 import java.awt.event.MouseAdapter ; 24 import java.awt.event.MouseEvent ; 25 import java.io.File ; 26 import java.io.FileInputStream ; 27 import java.io.IOException ; 28 import java.io.InputStream ; 29 30 import javax.swing.BorderFactory ; 31 import javax.swing.JPanel ; 32 import javax.swing.JPopupMenu ; 33 import javax.swing.JScrollPane ; 34 import javax.swing.JSplitPane ; 35 import javax.swing.JTable ; 36 import javax.swing.KeyStroke ; 37 import javax.swing.SwingUtilities ; 38 import javax.swing.tree.TreePath ; 39 40 import org.columba.api.gui.frame.IContainer; 41 import org.columba.api.gui.frame.IDock; 42 import org.columba.api.gui.frame.IDockable; 43 import org.columba.api.selection.ISelectionListener; 44 import org.columba.api.selection.SelectionChangedEvent; 45 import org.columba.core.config.ViewItem; 46 import org.columba.core.gui.base.UIFSplitPane; 47 import org.columba.core.gui.menu.MenuXMLDecoder; 48 import org.columba.core.gui.tagging.TagList; 49 import org.columba.core.gui.tagging.TagPopupMenu; 50 import org.columba.core.io.DiskIO; 51 import org.columba.mail.command.IMailFolderCommandReference; 52 import org.columba.mail.config.MailConfig; 53 import org.columba.mail.folder.IMailFolder; 54 import org.columba.mail.folder.IMailbox; 55 import org.columba.mail.folder.IMailboxInfo; 56 import org.columba.mail.folder.event.IFolderEvent; 57 import org.columba.mail.folder.event.IFolderListener; 58 import org.columba.mail.gui.composer.HeaderController; 59 import org.columba.mail.gui.filtertoolbar.FilterToolbar; 60 import org.columba.mail.gui.message.action.ViewMessageAction; 61 import org.columba.mail.gui.table.ITableController; 62 import org.columba.mail.gui.table.TableController; 63 import org.columba.mail.gui.table.action.DeleteAction; 64 import org.columba.mail.gui.table.action.OpenMessageWithComposerAction; 65 import org.columba.mail.gui.table.action.OpenMessageWithMessageFrameAction; 66 import org.columba.mail.gui.table.action.ViewHeaderListAction; 67 import org.columba.mail.gui.table.model.HeaderTableModel; 68 import org.columba.mail.gui.table.model.MessageNode; 69 import org.columba.mail.gui.table.selection.TableSelectionChangedEvent; 70 import org.columba.mail.gui.table.selection.TableSelectionHandler; 71 import org.columba.mail.gui.tagging.MailTagList; 72 import org.columba.mail.gui.tree.FolderTreeModel; 73 import org.columba.mail.gui.tree.ITreeController; 74 import org.columba.mail.gui.tree.TreeController; 75 import org.columba.mail.gui.tree.action.MoveDownAction; 76 import org.columba.mail.gui.tree.action.MoveUpAction; 77 import org.columba.mail.gui.tree.action.RenameFolderAction; 78 import org.columba.mail.gui.tree.action.SortFoldersMenu; 79 import org.columba.mail.gui.tree.selection.TreeSelectionChangedEvent; 80 import org.columba.mail.gui.tree.selection.TreeSelectionHandler; 81 import org.columba.mail.util.MailResourceLoader; 82 83 86 public class ThreePaneMailFrameController extends AbstractMailFrameController 87 implements TreeViewOwner, TableViewOwner, ISelectionListener, 88 IFolderListener { 89 90 public TreeController treeController; 91 92 public TableController tableController; 93 94 public HeaderController headerController; 95 96 public FilterToolbar filterToolbar; 97 98 public JSplitPane mainSplitPane; 99 100 public JSplitPane rightSplitPane; 101 102 private JPanel tablePanel; 103 104 private JPanel messagePanel; 105 106 private IMailFolder currentFolder; 107 108 112 public boolean isTablePopupEvent; 113 114 118 public boolean isTreePopupEvent; 119 120 private IDockable folderTreeDockable; 121 122 private IDockable messageListDockable; 123 124 private IDockable messageViewerDockable; 125 126 private IDockable tagListDockable; 127 128 131 public ThreePaneMailFrameController(ViewItem viewItem) { 132 super(viewItem); 133 134 treeController = new TreeController(this, FolderTreeModel.getInstance()); 135 tableController = new TableController(this); 136 137 TableSelectionHandler tableHandler = new TableSelectionHandler( 139 tableController); 140 getSelectionManager().addSelectionHandler(tableHandler); 141 tableHandler.addSelectionListener(this); 142 143 TreeSelectionHandler treeHandler = new TreeSelectionHandler( 144 treeController.getView()); 145 getSelectionManager().addSelectionHandler(treeHandler); 146 147 tableController.getView().addMouseListener(new TableMouseListener()); 149 150 treeController.getView().addMouseListener(new TreeMouseListener()); 151 152 treeHandler.addSelectionListener(tableHandler); 154 155 treeHandler.addSelectionListener(this); 158 159 filterToolbar = new FilterToolbar(this); 160 161 RenameFolderAction renameFolderAction = new RenameFolderAction(this); 162 163 tableController.getView().getActionMap().put("F2", renameFolderAction); 166 tableController.getView().getInputMap().put( 167 KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0), "F2"); 168 169 treeController.getView().getActionMap().put("F2", renameFolderAction); 172 treeController.getView().getInputMap().put( 173 KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0), "F2"); 174 175 MoveUpAction moveUpAction = new MoveUpAction(this); 178 tableController.getView().getActionMap().put("ALT_UP", moveUpAction); 179 tableController.getView().getInputMap().put( 180 KeyStroke.getKeyStroke(KeyEvent.VK_UP, KeyEvent.ALT_MASK), 181 "ALT_UP"); 182 183 treeController.getView().getActionMap().put("ALT_UP", moveUpAction); 184 treeController.getView().getInputMap().put( 185 KeyStroke.getKeyStroke(KeyEvent.VK_UP, KeyEvent.ALT_MASK), 186 "ALT_UP"); 187 188 MoveDownAction moveDownAction = new MoveDownAction(this); 191 tableController.getView().getActionMap() 192 .put("ALT_DOWN", moveDownAction); 193 tableController.getView().getInputMap().put( 194 KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.ALT_MASK), 195 "ALT_DOWN"); 196 197 treeController.getView().getActionMap().put("ALT_DOWN", moveDownAction); 198 treeController.getView().getInputMap().put( 199 KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.ALT_MASK), 200 "ALT_DOWN"); 201 202 DeleteAction deleteAction = new DeleteAction(this); 203 tableController.getView().getActionMap().put("DEL", deleteAction); 204 tableController.getView().getInputMap().put( 205 KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "DEL"); 206 207 208 OpenMessageWithMessageFrameAction openAction = new OpenMessageWithMessageFrameAction(this); 209 tableController.getView().getActionMap().put("ENTER", openAction); 210 tableController.getView().getInputMap().put( 211 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "ENTER"); 212 213 registerDockables(); 214 215 tableController.createPopupMenu(); 216 treeController.createPopupMenu(); 217 219 } 220 221 public void enableMessagePreview(boolean enable) { 222 getViewItem().setBoolean("header_enabled", enable); 223 224 if (enable) { 225 rightSplitPane = new UIFSplitPane(); 226 rightSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT); 227 rightSplitPane.add(tablePanel, JSplitPane.LEFT); 228 rightSplitPane.add(messagePanel, JSplitPane.RIGHT); 229 230 mainSplitPane.add(rightSplitPane, JSplitPane.RIGHT); 231 } else { 232 rightSplitPane = null; 233 234 mainSplitPane.add(tablePanel, JSplitPane.RIGHT); 235 } 236 237 mainSplitPane.setDividerLocation(viewItem.getIntegerWithDefault( 238 "splitpanes", "main", 100)); 239 240 if (enable) 241 rightSplitPane.setDividerLocation(viewItem.getIntegerWithDefault( 242 "splitpanes", "header", 100)); 243 244 fireLayoutChanged(); 245 } 246 247 250 public FilterToolbar getFilterToolbar() { 251 return filterToolbar; 252 } 253 254 257 public ITreeController getTreeController() { 258 return treeController; 259 } 260 261 264 public ITableController getTableController() { 265 return tableController; 266 } 267 268 271 public void showFilterToolbar() { 279 tablePanel.add(filterToolbar, BorderLayout.NORTH); 280 tablePanel.validate(); 281 282 } 283 284 public void hideFilterToolbar() { 285 tablePanel.remove(filterToolbar); 286 tablePanel.validate(); 287 288 } 289 290 306 310 public String getString(String sPath, String sName, String sID) { 311 return MailResourceLoader.getString(sPath, sName, sID); 312 } 313 314 317 323 public void selectionChanged(SelectionChangedEvent e) { 324 325 if (e instanceof TreeSelectionChangedEvent) { 326 TreeSelectionChangedEvent event = (TreeSelectionChangedEvent) e; 328 329 IMailFolder[] selectedFolders = event.getSelected(); 330 331 if (isTreePopupEvent == false) { 332 new ViewHeaderListAction(this).actionPerformed(null); 334 335 if (currentFolder != null) { 337 currentFolder.removeFolderListener(this); 338 currentFolder = null; 339 } 340 if (selectedFolders.length == 1 && selectedFolders[0] != null) { 341 selectedFolders[0].addFolderListener(this); 342 currentFolder = selectedFolders[0]; 343 } 344 345 updateTreeDockableTitle(); 347 } 348 349 isTreePopupEvent = false; 350 351 } else if (e instanceof TableSelectionChangedEvent) { 352 if (isTablePopupEvent == false) 353 new ViewMessageAction(this).actionPerformed(null); 355 356 isTablePopupEvent = false; 357 } else 358 throw new IllegalArgumentException ( 359 "unknown selection changed event"); 360 } 361 362 private void updateTreeDockableTitle() { 363 if (currentFolder != null) { 364 fireTitleChanged(currentFolder.getName()); 365 366 messageListDockable.setTitle(currentFolder.getName()); 368 369 if (currentFolder instanceof IMailbox) { 371 IMailboxInfo info = ((IMailbox) currentFolder) 372 .getMessageFolderInfo(); 373 StringBuffer buf = new StringBuffer (); 374 buf.append("Total: " + info.getExists()); 375 buf.append(" Recent: " + info.getRecent()); 376 folderTreeDockable.setTitle(buf.toString()); 377 } else 378 folderTreeDockable.setTitle(currentFolder.getName()); 379 } else { 380 fireTitleChanged(""); 381 } 382 } 383 384 391 class TableMouseListener extends MouseAdapter { 392 393 396 public void mousePressed(MouseEvent event) { 397 if (event.isPopupTrigger()) { 398 processPopup(event); 399 } 400 } 401 402 405 public void mouseReleased(MouseEvent event) { 406 if (event.isPopupTrigger()) { 407 processPopup(event); 408 } 409 } 410 411 414 public void mouseClicked(MouseEvent event) { 415 if (event.getClickCount() == 2) { 417 int selectedRow = tableController.getView().getSelectedRow(); 419 420 MessageNode node = (MessageNode) ((HeaderTableModel) tableController 422 .getHeaderTableModel()) 423 .getMessageNodeAtRow(selectedRow); 424 425 boolean markedAsDraft = node.getHeader().getFlags().getDraft(); 427 428 if (markedAsDraft) { 429 new OpenMessageWithComposerAction( 431 ThreePaneMailFrameController.this) 432 .actionPerformed(null); 433 } else { 434 new OpenMessageWithMessageFrameAction( 436 ThreePaneMailFrameController.this) 437 .actionPerformed(null); 438 } 439 } 440 } 441 442 protected void processPopup(final MouseEvent event) { 443 444 isTablePopupEvent = true; 445 446 JTable table = tableController.getView(); 447 448 int selectedRows = table.getSelectedRowCount(); 449 450 if (selectedRows <= 1) { 451 int row = table 453 .rowAtPoint(new Point (event.getX(), event.getY())); 454 table.setRowSelectionInterval(row, row); 455 } 456 457 SwingUtilities.invokeLater(new Runnable () { 458 459 public void run() { 460 tableController.getPopupMenu().show(event.getComponent(), 461 event.getX(), event.getY()); 462 isTablePopupEvent = false; 463 } 464 }); 465 } 466 } 467 468 class TreeMouseListener extends MouseAdapter { 469 470 473 public void mousePressed(MouseEvent event) { 474 if (event.isPopupTrigger()) { 475 processPopup(event); 476 } 477 } 478 479 482 public void mouseReleased(MouseEvent event) { 483 if (event.isPopupTrigger()) { 484 processPopup(event); 485 } 486 } 487 488 491 public void mouseClicked(MouseEvent event) { 492 if (event.getClickCount() == 2) { 494 496 } 497 } 498 499 protected void processPopup(final MouseEvent event) { 500 501 isTreePopupEvent = true; 502 503 Point point = event.getPoint(); 504 TreePath path = treeController.getView().getClosestPathForLocation( 505 point.x, point.y); 506 treeController.getView().setSelectionPath(path); 507 508 SwingUtilities.invokeLater(new Runnable () { 509 510 public void run() { 511 treeController.getPopupMenu().show(event.getComponent(), 512 event.getX(), event.getY()); 513 isTreePopupEvent = false; 514 } 515 }); 516 } 517 } 518 519 522 public void close(IContainer container) { 523 super.close(container); 524 525 IMailFolderCommandReference r = getTreeSelection(); 526 527 if (r != null) { 528 IMailFolder folder = (IMailFolder) r.getSourceFolder(); 529 530 532 if (folder instanceof IMailbox) 533 getFolderOptionsController().save((IMailbox) folder); 534 } 535 } 536 537 540 public void loadDefaultPosition() { 541 542 super.dock(messageListDockable, IDock.REGION.CENTER); 543 544 super.dock(folderTreeDockable, messageListDockable, IDock.REGION.WEST, 545 0.3f); 546 547 super.dock(messageViewerDockable, messageListDockable, 548 IDock.REGION.SOUTH, 0.3f); 549 550 super.setSplitProportion(folderTreeDockable, 0.3f); 551 super.setSplitProportion(messageListDockable, 0.35f); 552 } 553 554 private void registerDockables() { 555 556 JPopupMenu popup = null; 557 558 JScrollPane treeScrollPane = new JScrollPane (treeController.getView()); 560 treeScrollPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); 561 562 571 folderTreeDockable = registerDockable("mail_foldertree", 572 MailResourceLoader.getString("global", "dockable_foldertree"), 573 treeScrollPane, new SortFoldersMenu(this)); 574 575 JPanel p = new JPanel (); 577 p.setLayout(new BorderLayout ()); 578 JScrollPane tableScrollPane = new JScrollPane (tableController.getView()); 579 tableScrollPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); 580 p.add(tableScrollPane, BorderLayout.CENTER); 581 p.add(filterToolbar, BorderLayout.NORTH); 582 583 popup = null; 584 try { 585 InputStream is = DiskIO 586 .getResourceStream("org/columba/mail/action/table_dockmenu.xml"); 587 popup = new MenuXMLDecoder(this).createPopupMenu(is); 588 } catch (IOException e1) { 589 e1.printStackTrace(); 590 } 591 592 messageListDockable = registerDockable("mail_messagelist", 593 MailResourceLoader.getString("global", "dockable_messagelist"), 594 p, popup); 595 596 popup = null; 597 try { 598 InputStream is = DiskIO 599 .getResourceStream("org/columba/mail/action/message_dockmenu.xml"); 600 popup = new MenuXMLDecoder(this).createPopupMenu(is); 601 } catch (IOException e1) { 602 e1.printStackTrace(); 603 } 604 605 messageViewerDockable = registerDockable("mail_messageviewer", 606 MailResourceLoader 607 .getString("global", "dockable_messageviewer"), 608 messageController, popup); 609 610 616 } 621 622 625 626 public void extendMenu(IContainer container) { 627 try { 628 InputStream is = DiskIO 629 .getResourceStream("org/columba/mail/action/menu.xml"); 630 container.extendMenu(this, is); 631 } catch (IOException e) { 632 e.printStackTrace(); 633 } 634 } 635 636 public void extendToolBar(IContainer container) { 637 try { 638 File configDirectory = MailConfig.getInstance() 639 .getConfigDirectory(); 640 InputStream is2 = new FileInputStream (new File (configDirectory, 641 "main_toolbar.xml")); 642 container.extendToolbar(this, is2); 643 } catch (IOException e) { 644 e.printStackTrace(); 645 } 646 } 647 648 651 public IDockable getMessageViewerDockable() { 652 return messageViewerDockable; 653 } 654 655 public void messageAdded(IFolderEvent e) { 656 } 657 658 public void messageRemoved(IFolderEvent e) { 659 } 660 661 public void messageFlagChanged(IFolderEvent e) { 662 } 663 664 public void folderPropertyChanged(IFolderEvent e) { 665 SwingUtilities.invokeLater(new Runnable () { 667 public void run() { 668 updateTreeDockableTitle(); 669 } 670 }); 671 } 672 673 public void folderAdded(IFolderEvent e) { 674 } 675 676 public void folderRemoved(IFolderEvent e) { 677 } 678 679 } | Popular Tags |