Package net.suberic.pooka.gui

Source Code of net.suberic.pooka.gui.FolderDisplayPanel

package net.suberic.pooka.gui;
import net.suberic.pooka.*;
import javax.mail.*;
import javax.mail.internet.MimeMessage;
import javax.mail.event.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.text.TextAction;
import java.util.*;
import net.suberic.util.gui.*;
import net.suberic.util.event.*;
import net.suberic.util.thread.*;
import net.suberic.util.swing.*;
import net.suberic.pooka.gui.dnd.FolderTransferHandler;

/**
* This is a JPanel which contains a JTable which displays the messages in
* the table.
*
* Note that this class does not actually do any real work.  It does have
* Actions, but those are just passed on from the MessageProxy object in
* the table.  You will need to have another component which implements
* FolderDisplayUI to use as the actual UI object for the Folder.  That
* component can then use the FolderDisplayPanel to display the messages.
*
*/

public class FolderDisplayPanel extends JPanel {
  JTable messageTable = null;
  JScrollPane scrollPane = null;
  FolderInfo folderInfo = null;
  boolean enabled = true;

  boolean validated = false;
  boolean useFolderColumnSizes = true;

  public static String GLOBAL_COLUMN_PROPERTY_ROOT="PreviewFolderTable";

  /**
   * Creates an empty FolderDisplayPanel.
   */
  public FolderDisplayPanel() {
    initWindow();
    enabled=false;
  }

  /**
   * Creates a FolderDisplayPanel for the given FolderInfo.
   */
  public FolderDisplayPanel(FolderInfo newFolderInfo) {
    this(newFolderInfo, true);
  }

  /**
   * Creates a FolderDisplayPanel for the given FolderInfo.
   */
  public FolderDisplayPanel(FolderInfo newFolderInfo, boolean pUseFolderColumnSizes) {
    initWindow();
    setFolderInfo(newFolderInfo);
    addMessageTable();
    useFolderColumnSizes = pUseFolderColumnSizes;
  }

  /**
   * Initializes the window.
   */

  public void initWindow() {
    scrollPane = new JScrollPane();
    this.setLayout(new BorderLayout());
    this.add("Center", scrollPane);

    this.setPreferredSize(new Dimension(Integer.parseInt(Pooka.getProperty("folderWindow.height", "570")), Integer.parseInt(Pooka.getProperty("folderWindow.width","380"))));

    // if the FolderDisplayPanel itself gets the focus, pass it on to
    // the messageTable
    this.addFocusListener(new FocusAdapter() {
        public void focusGained(FocusEvent e) {
          java.util.logging.Logger.getLogger("Pooka.debug.gui.focus").fine("folder display panel:  gained focus.");

          if (messageTable != null) {
            messageTable.requestFocusInWindow();
          }
          Pooka.getMainPanel().refreshActiveMenus();
          if (getFolderInfo() != null && getFolderInfo().hasNewMessages()) {
            getFolderInfo().setNewMessages(false);
            FolderNode fn = getFolderInfo().getFolderNode();
            if (fn != null)
              fn.getParentContainer().repaint();
          }
        }
      });

    JScrollBar jsb = scrollPane.getVerticalScrollBar();
    if (jsb != null) {
      jsb.addAdjustmentListener(new AdjustmentListener() {
          public void adjustmentValueChanged(AdjustmentEvent e) {
            if (getFolderInfo() != null && getFolderInfo().hasNewMessages()) {
              getFolderInfo().setNewMessages(false);
              FolderNode fn = getFolderInfo().getFolderNode();
              if (fn != null)
                fn.getParentContainer().repaint();
            }
          }

        });
    }

    Pooka.getHelpBroker().enableHelpKey(this, "ui.folderWindow", Pooka.getHelpBroker().getHelpSet());

    setTransferHandler(new FolderTransferHandler());

  }

  /**
   * Creates the JTable for the FolderInfo and adds it to the component.
   */
  public void addMessageTable() {
    if (folderInfo != null) {
      createMessageTable();
      scrollPane.getViewport().add(messageTable);
    }

  }

  /**
   * This creates the messageTable.
   */
  public void createMessageTable() {
    messageTable=new JTable(getFolderInfo().getFolderTableModel()) {
        public String getToolTipText(MouseEvent event) {
          int rowIndex = rowAtPoint(event.getPoint());
          int columnIndex = columnAtPoint(event.getPoint());
          Object value = getValueAt(rowIndex, columnIndex);
          if (value != null) {
            return value.toString();
          } else {
            return null;
          }
        }
      };

    if (!Pooka.getProperty("FolderTable.showLines", "true").equals("true")) {
      messageTable.setShowVerticalLines(false);
      messageTable.setShowHorizontalLines(false);
    }

    FolderTableModel ftm = getFolderInfo().getFolderTableModel();
    for (int i = 0; i < messageTable.getColumnCount(); i++) {
      if (useFolderColumnSizes) {
        messageTable.getColumnModel().getColumn(i).setPreferredWidth(ftm.getColumnSize(i));
      } else {
        int colSize = 10;
        try {
          colSize = Integer.parseInt(Pooka.getProperty(GLOBAL_COLUMN_PROPERTY_ROOT + "." + ftm.getColumnId(i) + ".size", "10"));
        } catch (Exception e) {
          // just use the default.
        }
        messageTable.getColumnModel().getColumn(i).setPreferredWidth(colSize);
      }
    }

    messageTable.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);

    messageTable.setDefaultRenderer(Object.class, new FilterFolderCellRenderer());
    messageTable.setDefaultRenderer(Number.class, new FilterFolderCellRenderer());

    messageTable.setCellSelectionEnabled(false);
    messageTable.setColumnSelectionAllowed(false);
    messageTable.setRowSelectionAllowed(true);
    addListeners();

    messageTable.setTransferHandler(new FolderTransferHandler());

    messageTable.setDragEnabled(true);

  }

  /**
   * This removes the current message table.
   */
  public void removeMessageTable() {
    if (messageTable != null) {
      scrollPane.getViewport().remove(messageTable);
      if (getFolderInfo() != null)
        getFolderInfo().getFolderTableModel().removeTableModelListener(messageTable);
      messageTable = null;
    }
  }

  /**
   * This removes rows from the FolderTableModel.  This is the preferred
   * way to remove rows from the FolderTableModel.
   *
   * Called from within the FolderThread.
   */
  public void removeRows(java.util.List removedProxies) {
    //This is here so that we can select the next row and remove the
    //removed rows together in one call to the AWTEventThread.
    final java.util.List removedProxiesTmp = removedProxies;

    try {
      SwingUtilities.invokeAndWait(new Runnable() {
          public void run() {
            moveSelectionOnRemoval(removedProxiesTmp);

            getFolderTableModel().removeRows(removedProxiesTmp);
          }
        });
    } catch (Exception e) {
    }
  }

  /**
   * This checks to see if the message which has been removed is
   * currently selected.  If so, we unselect it and select the next
   * row.
   */
  public void moveSelectionOnRemoval(MessageChangedEvent e) {
    try {
      // don't bother if we're just going to autoexpunge it...
      if ((!Pooka.getProperty("Pooka.autoExpunge", "true").equalsIgnoreCase("true")) && e.getMessageChangeType() == MessageChangedEvent.FLAGS_CHANGED && (e.getMessage().isExpunged() || e.getMessage().getFlags().contains(Flags.Flag.DELETED))) {
        final Message changedMessage = e.getMessage();
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
              MessageProxy selectedProxy = getSelectedMessage();

              if ( selectedProxy != null && (! (selectedProxy instanceof MultiMessageProxy)) && selectedProxy.getMessageInfo().getMessage().equals(changedMessage)) {
                selectNextMessage();
              }
            }
          });
      }
    } catch (MessagingException me) {
    }
  }

  /**
   * This checks to see if the message which has been removed is
   * currently selected.  If so, we unselect it and select the next
   * row.
   */
  public void moveSelectionOnRemoval(MessageCountEvent e) {
    final Message[] removedMsgs = e.getMessages();

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          MessageProxy selectedProxy = getSelectedMessage();
          if (selectedProxy != null)  {
            boolean found = false;
            Message currentMsg = selectedProxy.getMessageInfo().getMessage();
            for (int i = 0; (currentMsg != null && found == false && i < removedMsgs.length); i++) {
              if (currentMsg.equals(removedMsgs[i])) {
                found = true;
              }
            }

            if (found) {
              selectNextMessage();
            }
          }
        }
      });

  }

  /**
   * This checks to see if the message which has been removed is
   * currently selected.  If so, we unselect it and select the next
   * row.
   *
   * Should be called on the AWTEventThread while the FolderThread
   * is locked.
   */
  void moveSelectionOnRemoval(java.util.List removedProxies) {
    MessageProxy selectedProxy = getSelectedMessage();
    if (selectedProxy != null)  {
      boolean selectNextMessage = false;
      if (selectedProxy instanceof MultiMessageProxy) {
        MultiMessageInfo mmi = (MultiMessageInfo) selectedProxy.getMessageInfo();
        int messageCount = mmi.getMessageCount();
        selectNextMessage = true;
        for (int i = 0; selectNextMessage && i < messageCount; i++) {
          MessageProxy currentProxy = mmi.getMessageInfo(i).getMessageProxy();
          if (! removedProxies.contains(currentProxy))
            selectNextMessage=false;
        }

      } else {
        if (removedProxies.contains(selectedProxy)) {
          selectNextMessage = true;
        }

      }

      if (selectNextMessage) {
        int currentlySelected = messageTable.getSelectedRow();
        int nextValue = getNextSelectableMessage(currentlySelected, removedProxies);
        if (nextValue >= messageTable.getRowCount()) {
          // in that case, check for a selectable message before this one.
          nextValue = getPreviousSelectableMessage(nextValue, removedProxies);
        }

        if (nextValue < 0) {
          // if we're removing all of the messages, then we should just
          // be able to unselect everything.
          int[] rowSelection = messageTable.getSelectedRows();
          messageTable.removeRowSelectionInterval(rowSelection[0], rowSelection[rowSelection.length - 1]);
        } else {
          selectMessage(nextValue);
        }
      }
    }
  }

  /**
   * This recreates the message table with a new FolderTableModel.
   */
  public void resetFolderTableModel(FolderTableModel newModel) {
    if (messageTable != null) {
      FolderTableModel oldFtm = (FolderTableModel) messageTable.getModel();
      oldFtm.removeTableModelListener(messageTable);
      //newModel.addTableModelListener(messageTable);
      messageTable.setModel(newModel);
    }
  }

  /**
   * This adds all the listeners to the current FolderDisplayPanel.
   */
  public void addListeners() {
    // add a mouse listener

    messageTable.addMouseListener(new MouseAdapter() {
        public void mouseClicked(MouseEvent e) {
          if (e.getClickCount() == 2) {
            int rowIndex = getMessageTable().rowAtPoint(e.getPoint());
            if (rowIndex != -1) {
              getMessageTable().setRowSelectionInterval(rowIndex, rowIndex);
              MessageProxy selectedMessage = getSelectedMessage();
              String actionCommand = Pooka.getProperty("MessagePanel.2xClickAction", "file-open");
              if (selectedMessage != null) {
                Action clickAction = selectedMessage.getAction(actionCommand);
                if (clickAction != null && isEnabled()) {
                  clickAction.actionPerformed (new ActionEvent(this, ActionEvent.ACTION_PERFORMED, actionCommand));

                }
              }
            }
          }
        }

        public void mousePressed(MouseEvent e) {
          if (e.isPopupTrigger()) {
            // see if anything is selected
            int rowIndex = getMessageTable().rowAtPoint(e.getPoint());
            int columnIndex = getMessageTable().columnAtPoint(e.getPoint());
            if (rowIndex == -1 || !getMessageTable().isRowSelected(rowIndex) ) {
              getMessageTable().setRowSelectionInterval(rowIndex, rowIndex);
            }

            MessageProxy selectedMessage = getSelectedMessage();
            if (selectedMessage != null && isEnabled()) {
              Object o = getMessageTable().getValueAt(rowIndex, columnIndex);
              if (o != null && o instanceof BooleanIcon) {
                BooleanIcon bi = (BooleanIcon) o;
                if (bi.getIconId().equalsIgnoreCase("attachments") && bi.iconValue()) {
                  selectedMessage.showAttachmentPopupMenu(getMessageTable(), e);
                } else {
                  selectedMessage.showPopupMenu(getMessageTable(), e);

                }
              } else {
                selectedMessage.showPopupMenu(getMessageTable(), e);
              }
            }
          }
        }

        public void mouseReleased(MouseEvent e) {
          if (e.isPopupTrigger()) {
            // see if anything is selected
            int rowIndex = getMessageTable().rowAtPoint(e.getPoint());
            int columnIndex = getMessageTable().columnAtPoint(e.getPoint());
            if (rowIndex == -1 || !getMessageTable().isRowSelected(rowIndex) ) {
              getMessageTable().setRowSelectionInterval(rowIndex, rowIndex);
            }

            MessageProxy selectedMessage = getSelectedMessage();
            if (selectedMessage != null && isEnabled())
              if (columnIndex == 2)
                selectedMessage.showAttachmentPopupMenu(getMessageTable(), e);
              else
                selectedMessage.showPopupMenu(getMessageTable(), e);
          }
        }
      });

    messageTable.getSelectionModel().addListSelectionListener(new SelectionListener());

    // add sorting by header.

    messageTable.getTableHeader().addMouseListener(new MouseAdapter() {
        public void mousePressed(MouseEvent e) {
          // show a wait cursor if we're not done loading the messages yet.
          boolean allLoaded = true;
          java.util.List data = ((FolderTableModel)messageTable.getModel()).getAllProxies();
          java.util.Iterator it = data.iterator();
          while (allLoaded && it.hasNext()) {
            MessageProxy current = (MessageProxy) it.next();
            if (! current.isLoaded())
              allLoaded = false;
          }

          if (! allLoaded) {
            messageTable.getTableHeader().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
          }

        }

        public void mouseReleased(MouseEvent e) {
          // clear the wait cursor, if any.
          messageTable.getTableHeader().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        }

        public void mouseClicked(MouseEvent e) {
          TableColumnModel columnModel = messageTable.getColumnModel();
          int viewColumn = columnModel.getColumnIndexAtX(e.getX());
          int column = messageTable.convertColumnIndexToModel(viewColumn);
          if (e.getClickCount() == 1 && column != -1) {
            // check to make sure that all messages are loaded.
            boolean allLoaded = true;
            java.util.List data = ((FolderTableModel)messageTable.getModel()).getAllProxies();
            java.util.Iterator it = data.iterator();
            while (allLoaded && it.hasNext()) {
              MessageProxy current = (MessageProxy) it.next();
              if (! current.isLoaded())
                allLoaded = false;
            }

            if (allLoaded) {
              java.util.logging.Logger.getLogger("Pooka.debug").fine("Sorting ...");

              int shiftPressed = e.getModifiers()&InputEvent.SHIFT_MASK;
              boolean ascending = (shiftPressed == 0);

              MessageProxy selectedMessage = null;

              int rowsSelected = messageTable.getSelectedRowCount();

              if (rowsSelected == 1)
                selectedMessage = getFolderInfo().getMessageProxy(messageTable.getSelectedRow());
              else if (rowsSelected > 1)
                selectedMessage = getFolderInfo().getMessageProxy(messageTable.getSelectedRows()[0]);

              if (! ascending) {
                ((FolderTableModel)messageTable.getModel()).sortByColumn(column, ascending);
              } else {
                ((FolderTableModel)messageTable.getModel()).sortByColumn(column );
              }

              if (selectedMessage != null) {
                int selectedIndex = ((FolderTableModel)messageTable.getModel()).getRowForMessage(selectedMessage);
                messageTable.setRowSelectionInterval(selectedIndex, selectedIndex);
                makeSelectionVisible(selectedIndex);
              }
            }
          }
        }
      });

    messageTable.registerKeyboardAction(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          FolderDisplayUI fdui = getFolderInfo().getFolderDisplayUI();
          if (fdui != null) {
            fdui.selectNextMessage();
          }
        }
      }, KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_DOWN, 0),  JComponent.WHEN_FOCUSED);

    messageTable.registerKeyboardAction(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          FolderDisplayUI fdui = getFolderInfo().getFolderDisplayUI();
          if (fdui != null) {
            fdui.selectPreviousMessage();
          }
        }
      }, KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_UP, 0),  JComponent.WHEN_FOCUSED);

    messageTable.registerKeyboardAction(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          MessageProxy selectedMessage = getSelectedMessage();
          if (selectedMessage != null) {
            Action defaultOpenAction = selectedMessage.getAction("file-default-open");
            if (defaultOpenAction != null) {
              defaultOpenAction.actionPerformed(e);
            } else {
              Pooka.getUIFactory().doDefaultOpen(selectedMessage);
            }
          }
        }
      }, KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ENTER, 0),  JComponent.WHEN_FOCUSED);

    messageTable.registerKeyboardAction(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          MessageProxy selectedMessage = getSelectedMessage();
          if (selectedMessage != null) {
            Action defaultOpenAction = selectedMessage.getAction("file-default-open");
            if (defaultOpenAction != null) {
              defaultOpenAction.actionPerformed(e);
            } else {
              Pooka.getUIFactory().doDefaultOpen(selectedMessage);
            }
          }
        }
      }, KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_SPACE, 0),  JComponent.WHEN_FOCUSED);

    messageTable.registerKeyboardAction(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          selectNextUnreadMessage();
        }
      }, KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_TAB, 0),  JComponent.WHEN_FOCUSED);

    messageTable.registerKeyboardAction(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          selectPreviousUnreadMessage();
        }
      }, KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_TAB, java.awt.Event.SHIFT_MASK),  JComponent.WHEN_FOCUSED);

  }

  /**
   * This finds the first unread message (if any) and sets that message
   * to selected, and returns that index.
   */
  public void selectFirstUnread() {

    // sigh.
    getFolderInfo().getFolderThread().addToQueue(new javax.swing.AbstractAction() {
        public void actionPerformed(java.awt.event.ActionEvent ae) {
          final int firstUnread = getFolderInfo().getFirstUnreadMessage();
          SwingUtilities.invokeLater(new Runnable() {
              public void run() {
                int useFirstUnread = firstUnread;
                if (useFirstUnread < 0 || useFirstUnread > messageTable.getRowCount()) {
                  useFirstUnread = messageTable.getRowCount() - 1;
                } else {
                  messageTable.setRowSelectionInterval(useFirstUnread, useFirstUnread);
                }
                makeSelectionVisible(useFirstUnread);
              }
            });
        }
      }, new java.awt.event.ActionEvent(this, 0, "folder-select-first-unread"));

  }

  /**
   * This scrolls the given row number to visible.
   */
  public void makeSelectionVisible(int rowNumber) {
    messageTable.scrollRectToVisible(messageTable.getCellRect(rowNumber, 1, true));

  }


  /**
   * This selects the next message.  If no message is selected, then
   * the first message is selected.
   */
  public int selectNextMessage() {
    int selectedRow = messageTable.getSelectedRow();
    int nextSelectable = getNextSelectableMessage(selectedRow, null);
    return selectMessage(nextSelectable);
  }

  /**
   * This selects the next unread message.  If no message is selected, then
   * the first unread message is selected.  If no unread messages exist, this
   * does nothing.
   */
  public int selectNextUnreadMessage() {
    int selectedRow = messageTable.getSelectedRow();
    int nextSelectable = getNextSelectableMessage(selectedRow, null, true);
    return selectMessage(nextSelectable);
  }


  /**
   * Determines which message is the next selectable message.  If no
   * messages past this one are selectable (i.e. not deleted or about to
   * be deleted), returns messageTable.getRowCount() (i.e. an unused
   * row.
   *
   * Since we're polling flags on the Messages, this probably should be
   * called on the FolderThread.  The change of selection itself, of course,
   * should be done on the AWTEventThread.
   */
  public int getNextSelectableMessage(int selectedRow, java.util.List removedProxies) {
    return getNextSelectableMessage(selectedRow, removedProxies, false);
  }

  /**
   * Determines which message is the next selectable message.  If no
   * messages past this one are selectable (i.e. not deleted or about to
   * be deleted), returns messageTable.getRowCount() (i.e. an unused
   * row.
   *
   * Since we're polling flags on the Messages, this probably should be
   * called on the FolderThread.  The change of selection itself, of course,
   * should be done on the AWTEventThread.
   */
  public int getNextSelectableMessage(int selectedRow, java.util.List removedProxies, boolean unread) {
    int newRow = selectedRow + 1;
    boolean done = false;
    while (! done && newRow < messageTable.getRowCount() ) {
      MessageProxy mp = getFolderInfo().getMessageProxy(newRow);
      try {
        //if ((removedProxies != null && removedProxies.contains(mp)) || mp.getMessageInfo().getFlags().contains(Flags.Flag.DELETED) || (unread && mp.getMessageInfo().getFlags().contains(Flags.Flag.SEEN))) {
        if ((removedProxies != null && removedProxies.contains(mp)) || mp.isDeleted() || (unread && mp.isSeen())) {
          newRow ++;
        } else {
          done = true;
        }
      } catch (MessagingException me) {
        newRow ++;
      }
    }

    return newRow;
  }


  /**
   * This selects the previous message.  If no message is selected, then
   * the last message is selected.
   */
  public int selectPreviousMessage() {
    int[] rowsSelected = messageTable.getSelectedRows();
    int selectedRow = 0;
    if (rowsSelected.length > 0)
      selectedRow = rowsSelected[0];
    else
      selectedRow = messageTable.getRowCount();

    int previousSelectable = getPreviousSelectableMessage(selectedRow, null, false);
    return selectMessage(previousSelectable);
  }

  /**
   * This selects the previous unread message.  If no message is selected, then
   * the first message is selected.
   */
  public int selectPreviousUnreadMessage() {
    int[] rowsSelected = messageTable.getSelectedRows();
    int selectedRow = 0;
    if (rowsSelected.length > 0)
      selectedRow = rowsSelected[0];
    else
      selectedRow = messageTable.getRowCount();

    int previousSelectable = getPreviousSelectableMessage(selectedRow, null, true);
    return selectMessage(previousSelectable);
  }

  /**
   * Determines which message is the previous selectable message.  If no
   * messages before this one are selectable (i.e. not deleted or about to
   * be deleted), returns -1.
   *
   * Since we're polling flags on the Messages, this probably should be
   * called on the FolderThread.  The change of selection itself, of course,
   * should be done on the AWTEventThread.
   */
  public int getPreviousSelectableMessage(int selectedRow, java.util.List removedProxies) {
    return getPreviousSelectableMessage(selectedRow, removedProxies, false);
  }

  /**
   * Determines which message is the previous selectable message.  If no
   * messages before this one are selectable (i.e. not deleted or about to
   * be deleted), returns -1.
   *
   * Since we're polling flags on the Messages, this probably should be
   * called on the FolderThread.  The change of selection itself, of course,
   * should be done on the AWTEventThread.
   */
  public int getPreviousSelectableMessage(int selectedRow, java.util.List removedProxies, boolean unread) {
    int newRow = selectedRow - 1;
    boolean done = false;
    while (! done && newRow >= 0 ) {
      MessageProxy mp = getFolderInfo().getMessageProxy(newRow);
      try {
        //if ((removedProxies != null && removedProxies.contains(mp)) || mp.getMessageInfo().getFlags().contains(Flags.Flag.DELETED) || (unread && mp.getMessageInfo().getFlags().contains(Flags.Flag.SEEN))) {
        if ((removedProxies != null && removedProxies.contains(mp)) || mp.isDeleted() || (unread && mp.isSeen())) {
          newRow--;
        } else {
          done = true;
        }
      } catch (MessagingException me) {
        newRow--;
      }
    }

    return newRow;

  }

  /**
   * Selects all of the messages in the FolderTable.
   */
  public void selectAll() {
    messageTable.selectAll();
  }

  /**
   * This selects the message at the given row, and also scrolls the
   * MessageTable to make the given row visible.
   *
   * If the number entered is below the range of available messages, then
   * the first message is selected.  If the number entered is above that
   * range, then the last message is selected.  If the MessageTable
   * contains no messages, nothing happens.
   *
   * @return  the index of the newly selected row.
   */
  public int selectMessage(int messageNumber) {
    int rowCount = messageTable.getRowCount();

    if (rowCount > 0) {
      int numberToSet = messageNumber;

      if (messageNumber < 0) {
        numberToSet = 0;
      } else if (messageNumber >= rowCount) {
        numberToSet = rowCount - 1;
      }
      messageTable.setRowSelectionInterval(numberToSet, numberToSet);
      makeSelectionVisible(numberToSet);
      return numberToSet;
    } else {
      return -1;
    }
  }

  /**
   * This method takes the currently selected row(s) and returns the
   * appropriate MessageProxy object.
   *
   * If no rows are selected, null is returned.
   */
  public MessageProxy getSelectedMessage() {
    if (messageTable != null) {
      int rowsSelected = messageTable.getSelectedRowCount();

      if (rowsSelected == 1)
        return getFolderInfo().getMessageProxy(messageTable.getSelectedRow());
      else if (rowsSelected < 1)
        return null;
      else {
        int[] selectedRows = messageTable.getSelectedRows();
        MessageProxy[] msgSelected= new MessageProxy[selectedRows.length];
        for (int i = 0; i < selectedRows.length; i++)
          msgSelected[i] = getFolderInfo().getMessageProxy(selectedRows[i]);
        return new MultiMessageProxy(selectedRows, msgSelected, this.getFolderInfo());
      }
    } else {
      return null;
    }
  }

  /**
   * This updates the entry for the given message, if that message is
   * visible.
   */
  public void repaintMessage(MessageProxy mp) {
    int row = getFolderTableModel().getRowForMessage(mp);
    if (row >=0) {
      getFolderTableModel().fireTableRowsUpdated(row, row);
    }
  }

  /**
   * Saves state for this display panel.
   */
  public void saveTableSettings() {
    if (getFolderInfo() != null) {
      String key = getFolderInfo().getFolderProperty();
      // save the column information.
      FolderTableModel ftm = getFolderTableModel();
      for (int i = 0; i < ftm.getColumnCount(); i++) {
        Pooka.setProperty(key + ".columnsize." + ftm.getColumnId(i) + ".value", Integer.toString(messageTable.getColumnModel().getColumn(i).getWidth()));

      }
    }
  }

  /**
   * This resets the size to that of the parent component.
   */
  public void resize() {
    this.setSize(getParent().getSize());
  }

  // Accessor methods.

  public JTable getMessageTable() {
    return messageTable;
  }

  /**
   * This sets the FolderInfo.
   */
  public void setFolderInfo(FolderInfo newValue) {
    folderInfo=newValue;
  }

  public FolderInfo getFolderInfo() {
    return folderInfo;
  }

  /**
   * Returns the FolderTableModel for this FolderDisplayPanel.
   */
  public FolderTableModel getFolderTableModel() {
    if (getFolderInfo() != null)
      return getFolderInfo().getFolderTableModel();
    else
      return null;
  }

  /**
   * gets the actions handled both by the FolderDisplayPanel and the
   * selected Message(s).
   */

  public class SelectionListener implements javax.swing.event.ListSelectionListener {
    SelectionListener() {
    }

    public void valueChanged(javax.swing.event.ListSelectionEvent e) {
      Pooka.getMainPanel().refreshActiveMenus();
      getFolderInfo().setNewMessages(false);
      FolderNode fn = getFolderInfo().getFolderNode();
      if (fn != null)
        fn.getParentContainer().repaint();
    }
  }

  /**
   * This registers the Keyboard action not only for the FolderDisplayPanel
   * itself, but also for pretty much all of its children, also.  This
   * is to work around something which I think is a bug in jdk 1.2.
   * (this is not really necessary in jdk 1.3.)
   *
   * Overrides JComponent.registerKeyboardAction(ActionListener anAction,
   *            String aCommand, KeyStroke aKeyStroke, int aCondition)
   */

  public void registerKeyboardAction(ActionListener anAction,
                                     String aCommand, KeyStroke aKeyStroke,
                                     int aCondition) {
    super.registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition);

    if (messageTable != null)
      messageTable.registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition);
  }

  /**
   * This unregisters the Keyboard action not only for the FolderDisplayPanel
   * itself, but also for pretty much all of its children, also.  This
   * is to work around something which I think is a bug in jdk 1.2.
   * (this is not really necessary in jdk 1.3.)
   *
   * Overrides JComponent.unregisterKeyboardAction(KeyStroke aKeyStroke)
   */

  public void unregisterKeyboardAction(KeyStroke aKeyStroke) {
    super.unregisterKeyboardAction(aKeyStroke);

    messageTable.unregisterKeyboardAction(aKeyStroke);
  }

  /**
   * Returns whether or not this window is enabled.  This should be true
   * just about all of the time.  The only time it won't be true is if
   * the Folder is closed or disconnected, and the mail store isn't set
   * up to work in disconnected mode.
   */
  public boolean isEnabled() {
    return enabled;
  }

  /**
   * This sets whether or not the window is enabled.  This should only
   * be set to false when the Folder is no longer available.
   */
  public void setEnabled(boolean newValue) {
    enabled = newValue;
  }

  public Action[] getActions() {
    if (isEnabled()) {
      Action[] returnValue = null;
      MessageProxy m = getSelectedMessage();

      if (m != null)
        returnValue = m.getActions();

      if (folderInfo.getActions() != null) {
        if (returnValue != null) {
          returnValue = TextAction.augmentList(folderInfo.getActions(), returnValue);
        } else {
          returnValue = folderInfo.getActions();
        }
      }

      if (messageTable != null) {
        Action[] defaultActions = new Action[] {
          FolderTransferHandler.getCutAction(messageTable),
          FolderTransferHandler.getCopyAction(messageTable),
          FolderTransferHandler.getPasteAction(messageTable)
        };
        if (returnValue != null) {
          returnValue = TextAction.augmentList(defaultActions, returnValue);
        } else {
          returnValue = defaultActions;
        }
      }

      return returnValue;
    } else {
      return null;
    }
  }
}
TOP

Related Classes of net.suberic.pooka.gui.FolderDisplayPanel

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.