Package net.suberic.pooka.gui

Source Code of net.suberic.pooka.gui.FolderNode$OpenAction

package net.suberic.pooka.gui;
import javax.swing.*;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import javax.swing.tree.*;
import javax.mail.Store;
import javax.mail.Folder;
import javax.mail.MessagingException;
import java.util.*;
import net.suberic.pooka.*;
import net.suberic.util.thread.*;
import javax.mail.FolderNotFoundException;
import net.suberic.pooka.FolderInfo;
import javax.mail.event.*;

public class FolderNode extends MailTreeNode implements MessageChangedListener, UserProfileContainer, ConnectionListener {

  protected FolderInfo folderInfo = null;
  protected boolean hasLoaded = false;

  /**
   * creates a tree node that points to a folder
   *
   * @param newFolderthe store for this node
   * @param newParent the parent component
   */
  public FolderNode(FolderInfo newFolderInfo, JComponent newParent) {
    super(newFolderInfo, newParent);
    folderInfo = newFolderInfo;

    folderInfo.setFolderNode(this);

    commands = new Hashtable();

    defaultActions = new Action[] {
      new ActionWrapper(new OpenAction(), folderInfo.getFolderThread()),
      new ActionWrapper(new ReconnectAction(), folderInfo.getFolderThread()),
      new ActionWrapper(new CloseAction(), folderInfo.getFolderThread()),
      new UnsubscribeAction(),
      new NewFolderAction(),
      new DeleteAction()
    };

    Action[] actions = defaultActions;

    if (actions != null) {
      for (int i = 0; i < actions.length; i++) {
        Action a = actions[i];
        commands.put(a.getValue(Action.NAME), a);
      }
    }

    folderInfo.addMessageCountListener(new MessageCountAdapter() {
        public void messagesAdded(MessageCountEvent e) {
          if ( folderInfo.notifyNewMessagesMain()) {
            Pooka.getUIFactory().getMessageNotificationManager().notifyNewMessagesReceived(e, getFolderInfo().getFolderID());
          }
          updateNode();
        }

        public void messagesRemoved(MessageCountEvent e) {
          updateNode();

        }
      });

    folderInfo.addMessageChangedListener(this);
    folderInfo.addConnectionListener(this);
    loadChildren();

  }


  /**
   * a Folder is a leaf if it cannot contain sub folders
   */
  public boolean isLeaf() {
    if (getChildCount() < 1)
      return true;
    else
      return false;
  }

  /**
   * returns the folder for this node
   */
  public Folder getFolder() {
    return folderInfo.getFolder();
  }

  /**
   * This loads (or reloads) the children of the FolderNode from
   * the list of Children on the FolderInfo.
   *
   * Runs on the event dispatch thread, but is safe to be called from anywhere.
   */
  public void loadChildren() {
    Runnable runMe = new Runnable() {
        public void run() {
          doLoadChildren();
        }
      };

    if (SwingUtilities.isEventDispatchThread())
      doLoadChildren();
    else {
      try {
        SwingUtilities.invokeAndWait(runMe);
      } catch (Exception ie) {
      }
    }
  }

  /**
   * Does the actual work for loading the children.  performed on the swing
   * gui thread.
   */
  private void doLoadChildren() {
    Enumeration origChildren = children();
    Vector origChildrenVector = new Vector();
    while (origChildren.hasMoreElements()) {
      Object origChild = origChildren.nextElement();
      origChildrenVector.add(origChild);
    }
    Vector folderChildren = getFolderInfo().getChildren();

    boolean changed=false;

    if (folderChildren != null) {
      for (int i = 0; i < folderChildren.size(); i++) {
        FolderNode node = popChild(((FolderInfo)folderChildren.elementAt(i)).getFolderName(), origChildrenVector);
        if (node == null) {
          node = new FolderNode((FolderInfo)folderChildren.elementAt(i), getParentContainer());
          // we used insert here, since add() would mak
          // another recursive call to getChildCount();
          insert(node, 0);
        }
      }

    }

    if (origChildrenVector.size() > 0) {
      removeChildren(origChildrenVector);
    }

    hasLoaded=true;

  }

  /**
   * This goes through the Vector of FolderNodes provided and
   * returns the FolderNode for the given childName, if one exists.
   * It will also remove the Found FolderNode from the childrenList
   * Vector.
   *
   * If a FolderNode that corresponds with the given childName does
   * not exist, this returns null.
   *
   */
  public FolderNode popChild(String childName, Vector childrenList) {
    if (children != null) {
      for (int i = 0; i < childrenList.size(); i++)
        if (((FolderNode)childrenList.elementAt(i)).getFolderInfo().getFolderName().equals(childName)) {
          FolderNode fn = (FolderNode)childrenList.elementAt(i);
          childrenList.remove(fn);
          return fn;
        }
    }

    // no match.
    return null;
  }

  /**
   * This  creates the current PopupMenu if there is not one.  It then
   * will configure the PopupMenu with the current actions.
   *
   * Overrides MailTreeNode.configurePopupMenu();
   */

  public void configurePopupMenu() {
    if (popupMenu == null) {
      popupMenu = new net.suberic.util.gui.ConfigurablePopupMenu();
      if (getFolderInfo().isTrashFolder())
        popupMenu.configureComponent("TrashFolderNode.popupMenu", Pooka.getResources());
      else if (getFolderInfo().isOutboxFolder())
        popupMenu.configureComponent("OutboxFolderNode.popupMenu", Pooka.getResources());
      else if (getFolderInfo() instanceof net.suberic.pooka.cache.CachingFolderInfo && ! ((net.suberic.pooka.cache.CachingFolderInfo) getFolderInfo()).getCacheHeadersOnly())
        popupMenu.configureComponent("CachingFolderNode.popupMenu", Pooka.getResources());
      else
        popupMenu.configureComponent("FolderNode.popupMenu", Pooka.getResources());

      updatePopupTheme();

    }

    popupMenu.setActive(getActions());
  }

  /**
   * This removes all the items in removeList from the list of this
   * node's children.
   */
  public void removeChildren(Vector removeList) {
    for (int i = 0; i < removeList.size(); i++) {
      if (removeList.elementAt(i) instanceof javax.swing.tree.MutableTreeNode)
        this.remove((javax.swing.tree.MutableTreeNode)removeList.elementAt(i));
    }
  }

  /**
   * This makes the FolderNode visible in its parent JTree.
   */
  public void makeVisible() {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          javax.swing.JTree folderTree = ((FolderPanel)getParentContainer()).getFolderTree();
          TreeNode[] nodeList = ((DefaultTreeModel)folderTree.getModel()).getPathToRoot(FolderNode.this);
          TreePath path = new TreePath(nodeList);
          folderTree.makeVisible(path);
        }
      });
  }

  public void messageChanged(MessageChangedEvent mce) {
    updateNode();
  }

  public void closed(ConnectionEvent e) {
    updateNode();
  }

  public void opened(ConnectionEvent e) {
    updateNode();
  }

  public void disconnected(ConnectionEvent e) {
    updateNode();
  }


  int lastFolderStatus = -1;
  boolean lastUnread = false;
  boolean lastNewMessages = false;

  /**
   * Checks to see if the Folder's status has changed from the last time
   * we redrew this node.  If it has, then we redraw the node.
   */
  public void updateNode() {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          FolderInfo fi = getFolderInfo();
          if (fi != null) {
            int currentStatus = fi.getStatus();
            boolean hasUnread = fi.hasUnread();
            boolean hasNewMessages = fi.hasNewMessages();

            lastFolderStatus = currentStatus;
            lastUnread = hasUnread;
            lastNewMessages = hasNewMessages;
            javax.swing.JTree folderTree = ((FolderPanel)getParentContainer()).getFolderTree();
            ((DefaultTreeModel)folderTree.getModel()).nodeChanged(FolderNode.this);
          }
        }
      });
  }

  /**
   * This opens up a dialog asking if the user wants to unsubsribe to
   * the current Folder.  If the user chooses 'yes', then
   * getFolderInfo().unsubscribe() is called.
   */
  public void unsubscribeFolder() {
    String message;
    if (isLeaf())
      message = Pooka.getProperty("Folder.unsubscribeConfirm", "Do you really want to unsubscribe from the following folder?");
    else
      message = Pooka.getProperty("Folder.unsubscribeConfirm.notLeaf", "Do you really want to unsubscribe from \nthis folder and all its children?");

    int response = Pooka.getUIFactory().showConfirmDialog(message + "\n" + getFolderInfo().getFolderName(), Pooka.getProperty("Folder.unsubscribeConfirm.title", "Unsubscribe from Folder"), JOptionPane.YES_NO_OPTION);

    if (response == JOptionPane.YES_OPTION) {
      getFolderInfo().getFolderThread().addToQueue(new javax.swing.AbstractAction() {
          public void actionPerformed(java.awt.event.ActionEvent e) {
            getFolderInfo().unsubscribe();
          }
        } , new java.awt.event.ActionEvent(this, 0, "folder-unsubscribe"));
    }
  }

  /**
   * This opens up a dialog asking if the user wants to delete
   * the current Folder.  If the user chooses 'yes', then
   * getFolderInfo().delete() is called.
   */
  public void deleteFolder() {
    String message;
    if (isLeaf())
      message = Pooka.getProperty("Folder.deleteConfirm", "Do you really want to delete from the following folder?");
    else
      message = Pooka.getProperty("Folder.deleteConfirm.notLeaf", "Do you really want to delete \nthis folder and all its children?");

    int response = Pooka.getUIFactory().showConfirmDialog(message + "\n" + getFolderInfo().getFolderName(), Pooka.getProperty("Folder.deleteConfirm.title", "Delete Folder"), JOptionPane.YES_NO_OPTION);

    if (response == JOptionPane.YES_OPTION) {
      message = Pooka.getProperty("Folder.deleteConfirm.secondMessage", "Are you sure?  This will permanently remove the folder and all of its messages");
      int responseTwo = Pooka.getUIFactory().showConfirmDialog(message, Pooka.getProperty("Folder.deleteConfirm.secondMessage.title", "Are you sure?"), JOptionPane.YES_NO_OPTION);
      if (responseTwo == JOptionPane.YES_OPTION) {

        getFolderInfo().getFolderThread().addToQueue(new javax.swing.AbstractAction() {
            public void actionPerformed(java.awt.event.ActionEvent e) {
              try {
                getFolderInfo().delete();
              } catch (OperationCancelledException oce) {
                // don't show a message if we cancel.
              } catch(MessagingException me) {
                final Exception fme = me;
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                      Pooka.getUIFactory().showError("Error deleting folder:  ", fme);
                    }
                  });
              }
            }
          } , new java.awt.event.ActionEvent(this, 0, "folder-delete"));
      }
    }
  }

  /**
   * This opens up a dialog asking if the user wants to subscribe to a
   * subfolder.
   */
  public void newFolder() {
    if ((getFolderInfo().getType() & Folder.HOLDS_FOLDERS) != 0) {
      String message = Pooka.getProperty("Folder.newFolder", "Subscribe/create new subfolder of") + " " + getFolderInfo().getFolderName();

      JLabel messageLabel = new JLabel(message);

      JPanel typePanel = new JPanel();
      typePanel.setBorder(BorderFactory.createEtchedBorder());

      JRadioButton messagesButton = new JRadioButton(Pooka.getProperty("Folder.new.messages.label", "Contains Messages"), true);
      JRadioButton foldersButton = new JRadioButton(Pooka.getProperty("Folder.new.folders.label", "Contains Folders"));

      ButtonGroup bg = new ButtonGroup();
      bg.add(messagesButton);
      bg.add(foldersButton);

      typePanel.add(messagesButton);
      typePanel.add(foldersButton);

      Object[] inputPanels = new Object[] {
        messageLabel,
        typePanel
      };

      final String response = Pooka.getUIFactory().showInputDialog(inputPanels, Pooka.getProperty("Folder.new.title", "Create new Folder"));

      int type = javax.mail.Folder.HOLDS_MESSAGES;
      if (foldersButton.isSelected()) {
        type = javax.mail.Folder.HOLDS_FOLDERS;
      }

      final int finalType = type;

      if (response != null && response.length() > 0) {
        getFolderInfo().getFolderThread().addToQueue(new javax.swing.AbstractAction() {
            public void actionPerformed(java.awt.event.ActionEvent e) {
              try {
                getFolderInfo().createSubFolder(response, finalType);
              } catch (OperationCancelledException oce) {
                // don't show a message if we cancel.
              } catch (MessagingException me) {
                final Exception fme = me;
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                      Pooka.getUIFactory().showError(fme.getMessage());
                    }
                  });

                me.printStackTrace();
              }
            }
          } , new java.awt.event.ActionEvent(this, 0, "folder-new"));
      }
    }
  }

  /**
   * Opens the folder.
   */
  public void openFolder(boolean pReconnect) {
    openFolder(pReconnect, true);
  }

  /**
   * Opens the folder.
   */
  public void openFolder(boolean pReconnect, boolean pSelectFolder) {
    try {
      if (pReconnect) {
        // in case we've not connected in the past, set the store to open.
        StoreInfo si = getFolderInfo().getParentStore();
        si.setPreferredStatus(FolderInfo.CONNECTED);
      }

      getFolderInfo().loadAllMessages();

      if (! getFolderInfo().isSortaOpen() || (pReconnect && ! getFolderInfo().isConnected())) {
        getFolderInfo().openFolder(javax.mail.Folder.READ_WRITE, pReconnect);
      }

      int firstUnread = -1;
      int messageCount = -1;

      final int folderType = getFolderInfo().getType();

      if (getFolderInfo().isSortaOpen() && (folderType & Folder.HOLDS_MESSAGES) != 0 && getFolderInfo().getFolderDisplayUI() == null) {
        firstUnread = getFolderInfo().getFirstUnreadMessage();
        messageCount = getFolderInfo().getMessageCount();
      }

      final int finalFirstUnread = firstUnread;
      final int finalMessageCount = messageCount;
      final boolean fSelectFolder = pSelectFolder;

      SwingUtilities.invokeLater(new Runnable() {
          public void run() {

            if ((folderType & Folder.HOLDS_MESSAGES) != 0) {
              if (getFolderInfo().getFolderDisplayUI() != null) {
                getFolderInfo().getFolderDisplayUI().openFolderDisplay(fSelectFolder);
              } else {
                getFolderInfo().setFolderDisplayUI(Pooka.getUIFactory().createFolderDisplayUI(getFolderInfo()));
                if (Pooka.getProperty("Pooka.autoSelectFirstUnread", "true").equalsIgnoreCase("true")) {
                  if (finalFirstUnread >= 0)
                    getFolderInfo().getFolderDisplayUI().selectMessage(finalFirstUnread);
                  else
                    getFolderInfo().getFolderDisplayUI().selectMessage(finalMessageCount);
                } else {
                  if (finalFirstUnread >= 0)
                    getFolderInfo().getFolderDisplayUI().makeSelectionVisible(finalFirstUnread);
                  else
                    getFolderInfo().getFolderDisplayUI().makeSelectionVisible(finalMessageCount);

                }
                getFolderInfo().getFolderDisplayUI().openFolderDisplay(fSelectFolder);
              }

            }
            if ((folderType & Folder.HOLDS_FOLDERS) != 0) {
              javax.swing.JTree folderTree = ((FolderPanel)getParentContainer()).getFolderTree();
              folderTree.expandPath(folderTree.getSelectionPath());
            }
          }
        });
    } catch (OperationCancelledException oce) {
      // if we cancelled out, ignore.
    } catch (MessagingException me) {
      final MessagingException newMe = me;
      SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            Pooka.getUIFactory().showError(Pooka.getProperty("error.Folder.openFailed", "Failed to open folder") + " " + getFolderInfo().getFolderID(), newMe);
          }
        });
    }

  }

  /**
   * Returns the FolderID of the FolderInfo that's defining this FolderNode.
   */
  public String getFolderID() {
    return getFolderInfo().getFolderID();
  }

  /**
   * Returns the FolderInfo that's defining this FolderNode.
   */
  public FolderInfo getFolderInfo() {
    return folderInfo;
  }

  /**
   * override toString() since we only want to display a folder's
   * name, and not the full path of the folder
   */
  public String toString() {
    if (getFolderInfo() != null) {
      String folderName = getFolderInfo().getFolderName();
      if (getFolderInfo().hasUnread()) {
        return folderName + " (" + getFolderInfo().getUnreadCount() + ")";
      } else {
        return folderName;
      }
    } else {
      return "no folder name";
    }
  }


  //As specified by interface net.suberic.pooka.UserProfileContainer
  public UserProfile getDefaultProfile() {
    if (getFolderInfo() != null)
      return getFolderInfo().getDefaultProfile();
    else
      return null;
  }

  public Action[] getActions() {
    if (getFolderInfo().getActions() != null)
      return javax.swing.text.TextAction.augmentList(getFolderInfo().getActions(), defaultActions);
    else
      return defaultActions;
  }

  public Action[] defaultActions;

  class OpenAction extends AbstractAction {

    OpenAction() {
      super("file-open");
    }

    OpenAction(String nm) {
      super(nm);
    }

    public void actionPerformed(ActionEvent e) {
      SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            ((FolderPanel)getParentContainer()).getMainPanel().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
          }
        });

      openFolder(false);

      SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            ((FolderPanel)getParentContainer()).getMainPanel().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
          }
        });
    }

  }

  class ReconnectAction extends AbstractAction {

    ReconnectAction() {
      super("folder-connect");
    }

    ReconnectAction(String nm) {
      super(nm);
    }

    public void actionPerformed(ActionEvent e) {
      SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            ((FolderPanel)getParentContainer()).getMainPanel().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
          }
        });

      openFolder(true);

      SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            ((FolderPanel)getParentContainer()).getMainPanel().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
          }
        });
    }

  }

  class UnsubscribeAction extends AbstractAction {

    UnsubscribeAction() {
      super("folder-unsubscribe");
    }

    public void actionPerformed(ActionEvent e) {
      unsubscribeFolder();
    }

  }

  class DeleteAction extends AbstractAction {

    DeleteAction() {
      super("folder-delete");
    }

    public void actionPerformed(ActionEvent e) {
      deleteFolder();
    }

  }

  class NewFolderAction extends AbstractAction {

    NewFolderAction() {
      super("folder-new");
    }

    public void actionPerformed(ActionEvent e) {
      newFolder();
    }

  }

  class CloseAction extends AbstractAction {

    CloseAction() {
      super("folder-close");
    }

    public void actionPerformed(ActionEvent e) {
      try {
        getFolderInfo().closeFolder(false);
      } catch (Exception ex) {
        System.out.println("caught exception:  " + ex.getMessage());
      }
    }

  }
}
TOP

Related Classes of net.suberic.pooka.gui.FolderNode$OpenAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.