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 net.suberic.util.gui.ConfigurableToolbar; 7 import java.awt.*; 8 import java.awt.dnd.*; 9 import java.awt.event.*; 10 import javax.mail.*; 11 import javax.swing.*; 12 import javax.swing.event.*; 13 import javax.swing.table.*; 14 import javax.swing.tree.*; 15 import javax.swing.text.TextAction ; 16 import javax.swing.plaf.metal.MetalTheme ; 17 import net.suberic.pooka.gui.*; 18 import java.util.Vector ; 19 import java.util.LinkedList ; 20 21 22 25 public class FolderPanel extends JPanel implements ItemListChangeListener, UserProfileContainer, ThemeSupporter, ThemeListener { 26 MainPanel mainPanel=null; 27 JTree folderTree; 28 DefaultTreeModel folderModel; 29 Session session; 30 ConfigurableKeyBinding keyBindings; 31 ConfigurableToolbar folderPanelToolbar; 32 MetalTheme currentTheme = null; 33 DropTarget mDropTarget = null; 34 TransferHandler mTransferHandler = null; 35 36 private Action [] defaultActions = { 37 new NewMessageAction() 38 }; 39 40 43 public FolderPanel(MainPanel newMainPanel) { 44 45 this.setLayout(new BorderLayout()); 46 47 mainPanel=newMainPanel; 48 49 setPreferredSize(new Dimension(Integer.parseInt(Pooka.getProperty("Pooka.folderPanel.hsize", "200")), Integer.parseInt(Pooka.getProperty("Pooka.folderPanel.vsize", Pooka.getProperty("Pooka.vsize","570"))))); 50 51 folderModel = new DefaultTreeModel(createTreeRoot()); 52 folderTree = new JTree(folderModel); 53 54 JScrollPane jsp = new JScrollPane(folderTree); 55 57 folderPanelToolbar = Pooka.getUIFactory().createFolderPanelToolbar(); 58 if (folderPanelToolbar != null) { 60 folderPanelToolbar.setActive(getActions()); 61 this.add("North", folderPanelToolbar); 62 } 63 64 this.add("Center", jsp); 65 66 folderTree.addMouseListener(new MouseAdapter() { 67 68 public void mouseClicked(MouseEvent e) { 69 if (e.getClickCount() == 2) { 70 MailTreeNode tmpNode = getSelectedNode(); 71 if (tmpNode != null) { 72 String actionCommand = Pooka.getProperty("FolderPanel.2xClickAction", "file-open"); 73 Action clickAction = getSelectedNode().getAction(actionCommand); 74 if (clickAction != null ) { 75 clickAction.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, actionCommand)); 76 } 77 78 } 79 } 80 } 81 82 public void mousePressed(MouseEvent e) { 83 if (e.isPopupTrigger()) { 84 TreePath path = folderTree.getClosestPathForLocation(e.getX(), e.getY()); 86 if (folderTree.getPathBounds(path).contains(e.getX(), e.getY())) { 87 90 if (!folderTree.isPathSelected(path)) 91 folderTree.setSelectionPath(path); 92 } 93 94 MailTreeNode tmpNode = getSelectedNode(); 95 if (tmpNode != null) { 96 tmpNode.showPopupMenu(folderTree, e); 97 98 } 99 } 100 } 101 102 public void mouseReleased(MouseEvent e) { 103 if (e.isPopupTrigger()) { 104 TreePath path = folderTree.getClosestPathForLocation(e.getX(), e.getY()); 106 if (folderTree.getPathBounds(path).contains(e.getX(), e.getY())) { 107 110 if (!folderTree.isPathSelected(path)) 111 folderTree.setSelectionPath(path); 112 } 113 114 MailTreeNode tmpNode = getSelectedNode(); 115 if (tmpNode != null) { 116 tmpNode.showPopupMenu(folderTree, e); 117 118 } 119 } 120 } 121 }); 122 123 folderTree.addTreeSelectionListener(new TreeSelectionListener() { 124 public void valueChanged(javax.swing.event.TreeSelectionEvent e) { 125 getMainPanel().refreshActiveMenus(); 126 getMainPanel().refreshCurrentUser(); 127 refreshActiveMenus(); 128 keyBindings.setActive(getActions()); 129 } 130 }); 131 132 folderTree.setCellRenderer(new EnhancedFolderTreeCellRenderer()); 133 134 mDropTarget = new FolderTreeDropTarget(); 135 mTransferHandler = new net.suberic.pooka.gui.dnd.FolderTransferHandler(); 136 folderTree.setDropTarget(mDropTarget); 137 138 folderTree.setTransferHandler(mTransferHandler); 139 140 keyBindings = new ConfigurableKeyBinding(this, "FolderPanel.keyBindings", Pooka.getResources()); 141 keyBindings.setActive(getActions()); 142 143 this.addFocusListener(new FocusAdapter() { 146 public void focusGained(FocusEvent e) { 147 folderTree.requestFocusInWindow(); 148 } 149 }); 150 151 Pooka.getHelpBroker().enableHelpKey(this, "ui.folderPanel", Pooka.getHelpBroker().getHelpSet()); 152 153 this.configureInterfaceStyle(); 154 155 } 156 157 160 public void configureInterfaceStyle() { 161 configureInterfaceStyle(false); 162 } 163 164 private void configureInterfaceStyle(boolean pForce) { 165 final boolean force = pForce; 166 Runnable runMe = new Runnable () { 167 public void run() { 168 try { 169 Pooka.getUIFactory().getPookaThemeManager().updateUI(FolderPanel.this, FolderPanel.this, force); 170 LinkedList allNodes = getAllNodes(); 171 for (int i = 0; i < allNodes.size(); i++) { 172 Object currentNode = allNodes.get(i); 173 if (currentNode instanceof MailTreeNode) { 174 ((MailTreeNode) currentNode).updatePopupTheme(); 175 } 176 } 177 } catch (Exception e) { 178 179 } 180 } 181 }; 182 183 if (! SwingUtilities.isEventDispatchThread()) { 184 SwingUtilities.invokeLater(runMe); 185 } else { 186 runMe.run(); 187 } 188 189 } 190 191 195 public MetalTheme getTheme(ThemeManager tm) { 196 String id = Pooka.getProperty("Pooka.folderPanel.theme", ""); 197 if (id != null && ! id.equals("")) { 198 return tm.getTheme(id); 199 } 200 201 return tm.getDefaultTheme(); 202 } 203 204 207 public MetalTheme getCurrentTheme() { 208 return currentTheme; 209 } 210 211 214 public void setCurrentTheme(MetalTheme newTheme) { 215 if (currentTheme != null && currentTheme instanceof ConfigurableMetalTheme) { 216 ((ConfigurableMetalTheme)currentTheme).removeThemeListener(this); 217 } 218 currentTheme = newTheme; 219 220 if (currentTheme != null && currentTheme instanceof ConfigurableMetalTheme) { 221 ((ConfigurableMetalTheme)currentTheme).addThemeListener(this); 222 } 223 } 224 225 228 public void themeChanged(ConfigurableMetalTheme theme) { 229 if (currentTheme != null && currentTheme == theme) { 232 SwingUtilities.invokeLater(new Runnable () { 233 public void run() { 234 configureInterfaceStyle(true); 235 } 236 }); 237 } 238 } 239 240 243 public MailTreeNode getSelectedNode() { 244 TreePath tp = folderTree.getSelectionPath(); 245 246 if (tp != null) { 247 return (MailTreeNode)tp.getLastPathComponent(); 248 } else { 249 return null; 250 } 251 } 252 253 256 private MailTreeNode createTreeRoot() { 257 MailTreeNode root = new MailTreeNode("Pooka", this); 258 259 synchronized(root) { 260 String storeID = null; 262 263 Vector allStoreInfos = Pooka.getStoreManager().getStoreList(); 264 for (int i = 0; i < allStoreInfos.size(); i++) { 265 StoreNode storenode = new StoreNode((StoreInfo)allStoreInfos.elementAt(i), this); 266 root.add(storenode); 267 } 268 269 Pooka.getStoreManager().addItemListChangeListener(this); 270 } 271 return root; 272 } 273 274 287 public void refreshStores(ItemListChangeEvent ilce) { 288 final ItemListChangeEvent e = ilce; 289 SwingUtilities.invokeLater(new Runnable () { 290 public void run() { 291 Item[] removed = e.getRemoved(); 292 Item[] added = e.getAdded(); 293 MailTreeNode root = (MailTreeNode)getFolderTree().getModel().getRoot(); 294 synchronized(root) { 295 if (removed != null && removed.length > 0) { 296 int[] removedIndices = new int[removed.length]; 297 Object [] removedObjects = new Object [removed.length]; 298 for (int i = 0; removed != null && i < removed.length; i++) { 299 300 StoreInfo currentStore = (StoreInfo) removed[i]; 301 302 if (currentStore != null) { 303 StoreNode sn = currentStore.getStoreNode(); 304 if (sn != null) { 305 removedObjects[i] = sn; 306 removedIndices[i] = root.getIndex(sn); 307 root.remove(sn); 308 } 309 } 310 } 311 java.util.Arrays.sort(removedIndices); 312 ((DefaultTreeModel)getFolderTree().getModel()).nodesWereRemoved(root, removedIndices, removedObjects); 313 } 314 315 if (added != null && added.length > 0) { 316 int[] addedIndices = new int[added.length]; 317 for (int i = 0; added != null && i < added.length ; i++) { 318 StoreNode storenode = new StoreNode((StoreInfo)added[i], FolderPanel.this); 319 root.add(storenode); 320 addedIndices[i] = root.getIndex(storenode); 321 } 323 ((DefaultTreeModel)getFolderTree().getModel()).nodesWereInserted(root, addedIndices); 324 } 325 326 currentTheme = null; 327 configureInterfaceStyle(); 328 } 329 } 330 }); 331 } 332 333 334 338 346 347 public MainPanel getMainPanel() { 348 return mainPanel; 349 } 350 351 public JTree getFolderTree() { 352 return folderTree; 353 } 354 355 359 public void itemListChanged(ItemListChangeEvent e) { 360 refreshStores(e); 361 } 362 363 366 public LinkedList getAllNodes() { 367 Object root = folderModel.getRoot(); 368 return parseTree(folderModel, root); 369 } 370 371 374 public LinkedList parseTree(TreeModel tm, Object root) { 375 LinkedList returnValue = new LinkedList (); 376 if (! tm.isLeaf(root)) { 377 int numChild = tm.getChildCount(root); 378 for (int i = 0; i < numChild; i++) { 379 Object child = tm.getChild(root, i); 380 returnValue.addAll(parseTree(tm, child)); 381 } 382 } 383 384 returnValue.add(root); 385 return returnValue; 386 } 387 388 391 public UserProfile getDefaultProfile() { 392 MailTreeNode selectedNode = getSelectedNode(); 393 394 if (selectedNode != null && selectedNode instanceof UserProfileContainer) 395 return ((UserProfileContainer)selectedNode).getDefaultProfile(); 396 else 397 return null; 398 } 399 400 403 public ConfigurableToolbar getFolderPanelToolbar() { 404 return folderPanelToolbar; 405 } 406 407 410 public void setFolderPanelToolbar(ConfigurableToolbar newFolderPanelToolbar) { 411 if (folderPanelToolbar != null) 412 this.remove(folderPanelToolbar); 413 414 folderPanelToolbar = newFolderPanelToolbar; 415 416 if (folderPanelToolbar != null) 417 this.add("North", folderPanelToolbar); 418 419 } 420 421 424 public void refreshActiveMenus() { 425 if (folderPanelToolbar != null) 426 folderPanelToolbar.setActive(getActions()); 427 } 428 429 public Action [] getActions() { 430 if (getSelectedNode() != null) { 431 Action [] nodeActions = getSelectedNode().getActions(); 432 if (nodeActions != null) 433 return TextAction.augmentList(nodeActions, defaultActions); 434 } 435 436 return defaultActions; 437 } 438 439 442 class FolderTreeDropTarget extends DropTarget { 443 public void dragOver(DropTargetDragEvent dtde) { 444 if (mTransferHandler.canImport(folderTree, dtde.getCurrentDataFlavors())) { 446 447 Point e = dtde.getLocation(); 448 449 TreePath path = folderTree.getClosestPathForLocation(e.x, e.y); 450 451 if (folderTree.getPathBounds(path).contains(e.x, e.y)) { 452 if (path.getLastPathComponent() instanceof FolderNode) { 455 if (!folderTree.isPathSelected(path)) 457 folderTree.setSelectionPath(path); 458 459 462 463 } 464 } 465 } 466 } 467 468 public void drop(DropTargetDropEvent dtde) { 469 boolean accept = false; 470 if (mTransferHandler.canImport(folderTree, dtde.getCurrentDataFlavors())) { 472 473 Point e = dtde.getLocation(); 474 475 TreePath path = folderTree.getClosestPathForLocation(e.x, e.y); 476 477 if (folderTree.getPathBounds(path).contains(e.x, e.y)) { 478 if (path.getLastPathComponent() instanceof FolderNode) { 481 if (!folderTree.isPathSelected(path)) 483 folderTree.setSelectionPath(path); 484 485 accept = true; 487 488 dtde.acceptDrop(dtde.getDropAction()); 489 490 try { 491 java.awt.datatransfer.Transferable trans = dtde.getTransferable(); 492 boolean returnValue = mTransferHandler.importData(folderTree, trans); 493 dtde.dropComplete(returnValue); 494 } catch (RuntimeException re) { 495 dtde.dropComplete(false); 496 } 497 } 498 } 499 } 500 501 if (! accept) { 502 dtde.rejectDrop(); 503 } 504 } 505 } 506 507 public class NewMessageAction extends AbstractAction { 508 NewMessageAction() { 509 super("message-new"); 510 } 511 512 public void actionPerformed(ActionEvent e) { 513 try { 514 MessageUI nmu = Pooka.getUIFactory().createMessageUI(new NewMessageProxy(new net.suberic.pooka.NewMessageInfo(new javax.mail.internet.MimeMessage (mainPanel.getSession())))); 515 nmu.openMessageUI(); 516 } catch (MessagingException me) { 517 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); 518 } 519 520 } 521 522 } 523 524 525 } 526 527 528 529 530 531 | Popular Tags |