1 package net.suberic.pooka.gui; 2 3 import javax.swing.tree.DefaultMutableTreeNode ; 4 import javax.swing.JComponent ; 5 import javax.mail.*; 6 import net.suberic.pooka.Pooka; 7 import net.suberic.pooka.FolderInfo; 8 import net.suberic.pooka.StoreInfo; 9 import net.suberic.util.thread.ActionWrapper; 10 import net.suberic.pooka.gui.search.*; 11 import net.suberic.pooka.gui.filechooser.*; 12 import java.util.StringTokenizer ; 13 import java.util.Vector ; 14 import java.util.Enumeration ; 15 import java.util.logging.Logger ; 16 import javax.swing.*; 17 import java.awt.Cursor ; 18 import javax.mail.event.*; 19 20 23 public class StoreNode extends MailTreeNode { 24 25 protected StoreInfo store = null; 26 protected String displayName = null; 27 protected boolean hasLoaded = false; 28 29 public StoreNode(StoreInfo newStore, JComponent parent) { 30 super(newStore, parent); 31 store = newStore; 32 newStore.setStoreNode(this); 33 displayName=Pooka.getProperty("Store." + store.getStoreID() + ".displayName", store.getStoreID()); 34 setCommands(); 35 loadChildren(); 36 defaultActions = new Action[] { 37 new ActionWrapper(new OpenAction(), getStoreInfo().getStoreThread()), 38 new ActionWrapper(new SubscribeAction(), getStoreInfo().getStoreThread()), 39 new TestAction(), 40 new NewFolderAction(), 41 new ActionWrapper(new DisconnectAction(), getStoreInfo().getStoreThread()), 42 new EditAction(), 43 new StatusAction() 44 }; 45 46 } 47 48 51 public boolean isLeaf() { 52 return false; 53 } 54 55 56 59 public void loadChildren() { 60 Runnable runMe = new Runnable () { 61 public void run() { 62 doLoadChildren(); 63 } 64 }; 65 66 if (SwingUtilities.isEventDispatchThread()) 67 doLoadChildren(); 68 else { 69 try { 70 SwingUtilities.invokeAndWait(runMe); 71 } catch (Exception ie) { 72 } 73 } 74 } 75 76 80 private void doLoadChildren() { 81 Logger logger = Logger.getLogger("Store." + getStoreInfo().getStoreID()); 82 logger.fine("calling loadChildren() for " + getStoreInfo().getStoreID()); 83 84 Enumeration origChildren = super.children(); 85 Vector origChildrenVector = new Vector (); 86 while (origChildren.hasMoreElements()) 87 origChildrenVector.add(origChildren.nextElement()); 88 89 logger.fine(getStoreInfo().getStoreID() + ": origChildrenVector.size() = " + origChildrenVector.size()); 90 91 Vector storeChildren = getStoreInfo().getChildren(); 92 93 logger.fine(getStoreInfo().getStoreID() + ": storeChildren.size() = " + storeChildren.size()); 94 95 if (storeChildren != null) { 96 for (int i = 0; i < storeChildren.size(); i++) { 97 FolderNode node = popChild(((FolderInfo)storeChildren.elementAt(i)).getFolderName(), origChildrenVector); 98 if (node == null) { 99 node = new FolderNode((FolderInfo)storeChildren.elementAt(i), getParentContainer()); 100 insert(node, 0); 103 } 104 } 105 106 } 107 108 removeChildren(origChildrenVector); 109 110 hasLoaded=true; 111 112 113 javax.swing.JTree folderTree = ((FolderPanel)getParentContainer()).getFolderTree(); 114 if (folderTree != null && folderTree.getModel() instanceof javax.swing.tree.DefaultTreeModel ) { 115 ((javax.swing.tree.DefaultTreeModel )folderTree.getModel()).nodeStructureChanged(this); 116 } 117 118 } 119 120 130 public FolderNode popChild(String childName, Vector childrenList) { 131 if (children != null) { 132 for (int i = 0; i < childrenList.size(); i++) 133 if (((FolderNode)childrenList.elementAt(i)).getFolderInfo().getFolderName().equals(childName)) { 134 FolderNode fn = (FolderNode)childrenList.elementAt(i); 135 childrenList.remove(fn); 136 return fn; 137 } 138 } 139 140 return null; 142 } 143 144 148 public void removeChildren(Vector removeList) { 149 for (int i = 0; i < removeList.size(); i++) { 150 if (removeList.elementAt(i) instanceof javax.swing.tree.MutableTreeNode ) 151 this.remove((javax.swing.tree.MutableTreeNode )removeList.elementAt(i)); 152 } 153 } 154 155 161 162 public void configurePopupMenu() { 163 if (popupMenu == null) { 164 popupMenu = new net.suberic.util.gui.ConfigurablePopupMenu(); 165 popupMenu.configureComponent("StoreNode.popupMenu", Pooka.getResources()); 166 updatePopupTheme(); 167 } 168 169 popupMenu.setActive(getActions()); 170 171 } 172 173 177 public void newFolder() { 178 String message = Pooka.getProperty("Folder.newFolder", "Subscribe/create new subfolder of") + " " + getStoreInfo().getStoreID(); 179 180 JLabel messageLabel = new JLabel(message); 181 182 JPanel typePanel = new JPanel(); 183 typePanel.setBorder(BorderFactory.createEtchedBorder()); 184 185 JRadioButton messagesButton = new JRadioButton(Pooka.getProperty("Folder.new.messages.label", "Contains Messages"), true); 186 JRadioButton foldersButton = new JRadioButton(Pooka.getProperty("Folder.new.folders.label", "Contains Folders")); 187 188 ButtonGroup bg = new ButtonGroup(); 189 bg.add(messagesButton); 190 bg.add(foldersButton); 191 192 typePanel.add(messagesButton); 193 typePanel.add(foldersButton); 194 195 Object [] inputPanels = new Object [] { 196 messageLabel, 197 typePanel 198 }; 199 200 final String response = Pooka.getUIFactory().showInputDialog(inputPanels, Pooka.getProperty("Folder.new.title", "Create new Folder")); 201 202 int type = javax.mail.Folder.HOLDS_MESSAGES; 203 if (foldersButton.isSelected()) { 204 type = javax.mail.Folder.HOLDS_FOLDERS; 205 } 206 207 final int finalType = type; 208 209 if (response != null && response.length() > 0) { 210 getStoreInfo().getStoreThread().addToQueue(new javax.swing.AbstractAction () { 211 public void actionPerformed(java.awt.event.ActionEvent e) { 212 try { 213 getStoreInfo().createSubFolder(response, finalType); 214 } catch (MessagingException me) { 215 final Exception fme = me; 216 SwingUtilities.invokeLater(new Runnable () { 217 public void run() { 218 Pooka.getUIFactory().showError(fme.getMessage()); 219 } 220 }); 221 222 me.printStackTrace(); 223 } 224 } 225 } , new java.awt.event.ActionEvent (this, 0, "folder-new")); 226 } 227 } 228 229 232 public void setBusy(boolean newBusy) { 233 final boolean newValue = newBusy; 234 235 Runnable runMe = new Runnable () { 236 public void run() { 237 if (newValue) 238 getParentContainer().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 239 else 240 getParentContainer().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); 241 } 242 }; 243 244 if (SwingUtilities.isEventDispatchThread()) 245 runMe.run(); 246 else 247 SwingUtilities.invokeLater(runMe); 248 249 } 250 251 255 public String getStoreID() { 256 if (store != null) 257 return store.getStoreID(); 258 else 259 return null; 260 } 261 262 266 public StoreInfo getStoreInfo() { 267 return store; 268 } 269 270 274 public String toString() { 275 return displayName; 276 } 277 278 public boolean isConnected() { 279 if (store != null) { 280 return store.isConnected(); 281 } else 282 return false; 283 } 284 285 public Action[] defaultActions; 286 287 public Action[] getDefaultActions() { 288 return defaultActions; 289 } 290 291 class OpenAction extends AbstractAction { 292 293 OpenAction() { 294 super("file-open"); 295 this.putValue(Action.SHORT_DESCRIPTION, "file-open on Store " + getStoreID()); 296 } 297 298 OpenAction(String nm) { 299 super(nm); 300 } 301 302 public void actionPerformed(java.awt.event.ActionEvent e) { 303 if (!store.isConnected()) 304 try { 305 store.connectStore(); 306 } catch (MessagingException me) { 307 Pooka.getUIFactory().showError(Pooka.getProperty("error.Store.connectionFailed", "Failed to open connection to Mail Store."), me); 309 } 310 javax.swing.JTree folderTree = ((FolderPanel)getParentContainer()).getFolderTree(); 311 folderTree.expandPath(folderTree.getSelectionPath()); 312 } 313 } 314 315 class SubscribeAction extends AbstractAction { 316 317 SubscribeAction() { 318 super("folder-subscribe"); 319 320 } 321 322 public void actionPerformed(java.awt.event.ActionEvent e) { 323 SwingUtilities.invokeLater(new Runnable () { 324 public void run() { 325 Pooka.getUIFactory().showStatusMessage("Connecting to " + getStoreInfo().getStoreID() + " to get list of folders..."); 326 setBusy(true); 327 } 328 }); 329 330 final MailFileSystemView mfsv = new MailFileSystemView(getStoreInfo()); 332 333 SwingUtilities.invokeLater(new Runnable () { 334 public void run() { 335 final Logger storeLogger = Logger.getLogger("Store." + getStoreInfo().getStoreID()); 336 final Logger guiLogger = Logger.getLogger("Pooka.debug.gui.filechooser"); 337 338 JFileChooser jfc = 339 new JFileChooser(getStoreInfo().getStoreID(), mfsv); 340 jfc.setMultiSelectionEnabled(true); 341 jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); 342 int returnValue = 343 jfc.showDialog(getParentContainer(), 344 Pooka.getProperty("FolderEditorPane.Select", 345 "Select")); 346 if (returnValue == JFileChooser.APPROVE_OPTION) { 347 guiLogger.fine("got " + jfc.getSelectedFile() + " as a return value."); 348 349 final java.io.File [] selectedFiles = jfc.getSelectedFiles(); 350 351 getStoreInfo().getStoreThread().addToQueue(new javax.swing.AbstractAction () { 352 public void actionPerformed(java.awt.event.ActionEvent ae) { 353 for (int i = 0 ; selectedFiles != null && i < selectedFiles.length; i++) { 354 net.suberic.pooka.gui.filechooser.FolderFileWrapper wrapper = (net.suberic.pooka.gui.filechooser.FolderFileWrapper) selectedFiles[i]; 355 try { 356 if (! wrapper.exists()) { 358 wrapper.getFolder().create(Folder.HOLDS_MESSAGES); 359 } 360 String absFileName = wrapper.getAbsolutePath(); 361 int firstSlash = absFileName.indexOf('/'); 362 String normalizedFileName = absFileName; 363 if (firstSlash >= 0) 364 normalizedFileName = absFileName.substring(firstSlash); 365 366 guiLogger.fine("adding folder " + normalizedFileName + "; absFileName = " + absFileName); 367 storeLogger.fine("adding folder " + normalizedFileName); 368 369 getStoreInfo().subscribeFolder(normalizedFileName); 370 } catch (MessagingException me) { 371 final String folderName = wrapper.getName(); 372 SwingUtilities.invokeLater(new Runnable () { 373 public void run() { 374 Pooka.getUIFactory().showError(Pooka.getProperty("error.creatingFolder", "Error creating folder ") + folderName); 375 } 376 }); 377 } 378 } 379 } 380 }, new java.awt.event.ActionEvent (this, 0, "folder-subscribe")); 381 } 382 383 Pooka.getUIFactory().clearStatus(); 384 setBusy(false); 385 } 386 }); 387 } 388 } 389 390 class TestAction extends AbstractAction { 391 392 TestAction() { 393 super("file-test"); 394 } 395 396 public void actionPerformed(java.awt.event.ActionEvent e) { 397 398 } 399 400 } 401 402 class DisconnectAction extends AbstractAction { 403 404 DisconnectAction() { 405 super("file-close"); 406 } 407 408 public void actionPerformed(java.awt.event.ActionEvent e) { 409 try { 410 getStoreInfo().disconnectStore(); 411 } catch (Exception ex) { 412 System.out.println("caught exception: " + ex.getMessage()); 413 } 414 } 415 } 416 417 class NewFolderAction extends AbstractAction { 418 419 NewFolderAction() { 420 super("folder-new"); 421 } 422 423 public void actionPerformed(java.awt.event.ActionEvent e) { 424 newFolder(); 425 } 426 427 } 428 429 class EditAction extends AbstractAction { 430 431 EditAction() { 432 super("file-edit"); 433 } 434 435 EditAction(String nm) { 436 super(nm); 437 } 438 439 public void actionPerformed(java.awt.event.ActionEvent e) { 440 Pooka.getUIFactory().showEditorWindow(getStoreInfo().getStoreProperty(), getStoreInfo().getStoreProperty(), "Store.editor"); 441 } 442 } 443 444 class StatusAction extends AbstractAction { 445 446 StatusAction() { 447 super("store-status"); 448 } 449 450 public void actionPerformed(java.awt.event.ActionEvent e) { 451 getStoreInfo().showStatus(); 452 } 453 } 454 } 455 456 | Popular Tags |