Package net.suberic.pooka.gui

Source Code of net.suberic.pooka.gui.NewMessageDisplayPanel$CustomHeaderTableModel

package net.suberic.pooka.gui;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.InternetHeaders;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextPane;
import javax.swing.JToggleButton;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.JTextComponent;
import javax.swing.text.TextAction;

import net.suberic.pooka.NewMessageInfo;
import net.suberic.pooka.Pooka;
import net.suberic.pooka.UserProfile;
import net.suberic.pooka.gui.crypto.CryptoStatusDisplay;
//import net.suberic.pooka.gui.crypto.NewMessageCryptoDisplay;
import net.suberic.util.gui.ConfigurableKeyBinding;
import net.suberic.util.gui.ConfigurablePopupMenu;
import net.suberic.util.gui.IconManager;
import net.suberic.util.swing.EntryTextArea;

/**
* A window for entering new messages.
*/
public class NewMessageDisplayPanel extends MessageDisplayPanel implements ItemListener {
  JTabbedPane tabbedPane = null;
  Container headerPanel = null;
  boolean modified = false;
  Hashtable inputTable;

  JScrollPane headerScrollPane;

  private Action[] defaultActions;

  CryptoStatusDisplay cryptoDisplay = null;
  Container cryptoPanel = null;

  Container customHeaderPane = null;
  JTable customHeaderTable = null;
  JToggleButton customHeaderButton = null;

  /**
   * Creates a NewMessageDisplayPanel from the given Message.
   */

  public NewMessageDisplayPanel(NewMessageUI newMsgUI) {
    super(newMsgUI);
  }

  /**
   * This configures the MessageDisplayPanel.  This means that here is
   * where we create the headerPanel and editorPane and add them to the
   * splitPane.
   */
  public void configureMessageDisplay() throws MessagingException {

    splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
    tabbedPane = new JTabbedPane();

    inputTable = new Hashtable();

    headerPanel = createHeaderInputPanel(getMessageProxy(), inputTable);
    editorPane = createMessagePanel(getMessageProxy());

    installTransferHandler();

    // workaround for java bug.
    editorPane.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
        public void propertyChange(java.beans.PropertyChangeEvent evt) {
          String propertyName = evt.getPropertyName();
          if (propertyName != null && propertyName.equalsIgnoreCase("ui")) {
            installTransferHandler();
          }
        }
      });


    headerScrollPane = new JScrollPane(headerPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    tabbedPane.add(Pooka.getProperty("MessageWindow.HeaderTab", "Headers"), headerScrollPane);

    if (getMessageProxy().getAttachments() != null && getMessageProxy().getAttachments().size() > 0) {
      addAttachmentPane();
    }

    editorScrollPane = new JScrollPane(editorPane, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

    splitPane.setTopComponent(tabbedPane);
    splitPane.setBottomComponent(editorScrollPane);

    this.add("Center", splitPane);

    editorPane.addMouseListener(new MouseAdapter() {

        public void mousePressed(MouseEvent e) {
          if (e.isPopupTrigger()) {
            showPopupMenu(editorPane, e);
          }
        }

        public void mouseReleased(MouseEvent e) {
          if (e.isPopupTrigger()) {
            showPopupMenu(editorPane, e);
          }
        }
      });

    editorPane.addKeyListener(new KeyAdapter() {
        public void keyTyped(KeyEvent e) {
          setModified(true);
        }
      });

    splitPane.resetToPreferredSizes();

    this.addFocusListener(new FocusAdapter() {
        public void focusGained(FocusEvent e) {
          // if we get focus, see what we want to select by default.
          // if there's no to: done, select to:.  if there's no
          // subject, select it.  if both of those are filled out,
          // select the message.

          Component subjectComponent = null;
          Component toComponent = null;

          boolean done = false;

          if (inputTable != null) {
            String key;
            Enumeration keys = inputTable.keys();
            while (keys.hasMoreElements()) {
              key = (String)(keys.nextElement());

              if (key.equalsIgnoreCase("subject")) {
                subjectComponent = (Component) inputTable.get(key);
              } else if (key.equalsIgnoreCase("to")) {
                toComponent = (Component) inputTable.get(key);
              }
            }

            if (toComponent != null && toComponent instanceof JTextComponent) {
              String toValue = ((JTextComponent) toComponent).getText();
              if (toValue == null || toValue.length() == 0) {
                done = true;
                toComponent.requestFocusInWindow();
              }
            }

            if (! done && subjectComponent != null && subjectComponent instanceof JTextComponent) {
              String subjectValue = ((JTextComponent) subjectComponent).getText();
              if (subjectValue == null || subjectValue.length() == 0) {
                done = true;
                subjectComponent.requestFocusInWindow();
              }
            }
          }

          if (! done) {
            if (editorPane != null)
              editorPane.requestFocusInWindow();
          }
        }
      });

    keyBindings = new ConfigurableKeyBinding(this, "NewMessageWindow.keyBindings", Pooka.getResources());
    //keyBindings.setCondition(JComponent.WHEN_IN_FOCUSED_WINDOW);

    keyBindings.setActive(getActions());

  }

  /**
   * Sets the window to its preferred size.
   */
  public void sizeToDefault() {
    Dimension prefSize = getDefaultEditorPaneSize();
    JScrollBar vsb = editorScrollPane.getVerticalScrollBar();
    if (vsb != null)
      prefSize.setSize(prefSize.getWidth() + vsb.getPreferredSize().getWidth(), prefSize.getHeight());
    editorScrollPane.setPreferredSize(prefSize);
    int width = prefSize.width;
    this.setPreferredSize(new Dimension(width, width));
    this.setSize(this.getPreferredSize());
  }

  /**
   * as defined in java.awt.event.ItemListener
   *
   * This implementation calls a refreshCurrentUser() on the MainPanel.
   *
   * It also updates the panel's interface style.
   */
  public void itemStateChanged(ItemEvent ie) {
    if (ie.getStateChange() == ItemEvent.SELECTED) {
      if (Pooka.getMainPanel() != null)
        Pooka.getMainPanel().refreshCurrentUser();
      SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            NewMessageUI nmui = getNewMessageUI();
            if (nmui instanceof net.suberic.util.swing.ThemeSupporter) {
              try {
                Pooka.getUIFactory().getPookaThemeManager().updateUI((net.suberic.util.swing.ThemeSupporter) nmui, (java.awt.Component) nmui);
                Font currentFont = editorPane.getFont();
                setDefaultFont(editorPane);
                Font newFont = editorPane.getFont();
                if (currentFont != newFont) {
                  sizeToDefault();
                }
                MessageUI mui = getMessageUI();
                if (mui instanceof MessageInternalFrame) {
                  ((MessageInternalFrame) mui).resizeByWidth();
                } else if (mui instanceof MessageFrame) {
                  ((MessageFrame) mui).resizeByWidth();
                }

              } catch (Exception e) {
                if (Pooka.isDebug())
                  System.out.println("error setting theme:  " + e);
              }
            }
          }
        });
    }

  }

  /**
   * Creates the panel in which the addressing will be done, such as
   * the To: field, Subject: field, etc.
   */
  public Container createHeaderInputPanel(MessageProxy pProxy, Hashtable proptDict) {

    Box inputPanel = new Box(BoxLayout.Y_AXIS);

    Box inputRow = new Box(BoxLayout.X_AXIS);

    // Create UserProfile DropDown
    JLabel userProfileLabel = new JLabel(Pooka.getProperty("UserProfile.label","User:"), SwingConstants.RIGHT);
    userProfileLabel.setPreferredSize(new Dimension(75,userProfileLabel.getPreferredSize().height));
    JComboBox profileCombo = new JComboBox(new Vector(Pooka.getPookaManager().getUserProfileManager().getUserProfileList()));


    IconManager iconManager = Pooka.getUIFactory().getIconManager();

    ImageIcon headerIcon = iconManager.getIcon(Pooka.getProperty("NewMessage.customHeader.button", "Hammer"));
    if (headerIcon != null) {
      java.awt.Image headerImage = headerIcon.getImage();
      headerImage = headerImage.getScaledInstance(15, 15, java.awt.Image.SCALE_SMOOTH);
      headerIcon.setImage(headerImage);
      customHeaderButton = new JToggleButton(headerIcon);
      customHeaderButton.setMargin(new java.awt.Insets(1,1,1,1));
      customHeaderButton.setSize(15,15);
    } else {
      customHeaderButton = new JToggleButton();
    }

    customHeaderButton.addChangeListener(new ChangeListener() {

        public void stateChanged(ChangeEvent e) {
          if (customHeaderButton.isSelected()) {
            selectCustomHeaderPane();
          } else {
            removeCustomHeaderPane();
          }
        }

      });

    customHeaderButton.setToolTipText(Pooka.getProperty("NewMessage.customHeaders.button.Tooltip", "Edit Headers"));

    inputRow.add(userProfileLabel);
    inputRow.add(profileCombo);
    inputRow.add(customHeaderButton);

    UserProfile selectedProfile = null;
    selectedProfile = pProxy.getDefaultProfile();
    if (selectedProfile == null)
      if (Pooka.getMainPanel() != null)
        selectedProfile = Pooka.getMainPanel().getCurrentUser();

    if (selectedProfile == null)
      selectedProfile = Pooka.getPookaManager().getUserProfileManager().getDefaultProfile();

    if (selectedProfile != null)
      profileCombo.setSelectedItem(selectedProfile);

    profileCombo.addItemListener(this);

    proptDict.put("UserProfile", profileCombo);

    inputPanel.add(inputRow);

    // Create Address panel

    StringTokenizer tokens = new StringTokenizer(Pooka.getProperty("MessageWindow.Input.DefaultFields", "To:CC:BCC:Subject"), ":");
    String currentHeader = null;
    JLabel hdrLabel = null;
    EntryTextArea inputField = null;

    while (tokens.hasMoreTokens()) {
      inputRow = new Box(BoxLayout.X_AXIS);
      currentHeader=tokens.nextToken();
      hdrLabel = new JLabel(Pooka.getProperty("MessageWindow.Input.." + currentHeader + ".label", currentHeader) + ":", SwingConstants.RIGHT);
      hdrLabel.setPreferredSize(new Dimension(75,hdrLabel.getPreferredSize().height));
      inputRow.add(hdrLabel);

      if (currentHeader.equalsIgnoreCase("To") || currentHeader.equalsIgnoreCase("CC") || currentHeader.equalsIgnoreCase("BCC") ) {
        try {
          inputField = new AddressEntryTextArea(getNewMessageUI(), getNewMessageProxy().getNewMessageInfo().getHeader(Pooka.getProperty("MessageWindow.Input." + currentHeader + ".MIMEHeader", "") , ","), 1, 30);
        } catch (MessagingException me) {
          inputField = new net.suberic.util.swing.EntryTextArea(1, 30);
        }
      } else {
        try {
          inputField = new net.suberic.util.swing.EntryTextArea(getNewMessageProxy().getNewMessageInfo().getHeader(Pooka.getProperty("MessageWindow.Input." + currentHeader + ".MIMEHeader", "") , ","), 1, 30);
        } catch (MessagingException me) {
          inputField = new net.suberic.util.swing.EntryTextArea(1, 30);
        }
      }

      inputField.setLineWrap(true);
      inputField.setWrapStyleWord(true);
      inputField.setBorder(BorderFactory.createEtchedBorder());
      inputField.addKeyListener(new KeyAdapter() {
          public void keyTyped(KeyEvent e) {
            setModified(true);
          }
        });


      inputRow.add(inputField);
      if (inputField instanceof AddressEntryTextArea) {
        //int height = inputField.getPreferredSize().height;
        JButton addressButton = ((AddressEntryTextArea)inputField).createAddressButton(10, 10);
        inputRow.add(Box.createHorizontalGlue());
        inputRow.add(addressButton);
      }
      inputPanel.add(inputRow);

      proptDict.put(Pooka.getProperty("MessageWindow.Input." + currentHeader + ".value", currentHeader), inputField);
    }

    return inputPanel;
  }

  /**
   * Extends a DefaultTableModel to make it so certain columns are not
   * editable.
   */
  class CustomHeaderTableModel extends javax.swing.table.DefaultTableModel {

    // Constructor
    public CustomHeaderTableModel(Vector headers, int rows) {
      super(headers,rows);
    }

    // the number of rows that have uneditable headers in it.
    int mUneditableRows = 0;

    /**
     * Sets the number of uneditable header rows we have.
     */
    public void setUneditableRows(int pRows) {
      mUneditableRows = pRows;
    }

    /**
     * Returns the number of uneditable header rows we have.
     */
    public int getUneditableRows() {
      return mUneditableRows;
    }

    /**
     * Returns whether or not this cell it editable.
     */
    public boolean isCellEditable(int row, int column) {
      if (column == 0 && row < mUneditableRows) {
        return false;
      } else {
        return true;
      }
    }

  }

  /**
   * This creates a new JTextPane for the main text part of the new
   * message.  It will also include the current text of the message.
   */
  public JTextPane createMessagePanel(MessageProxy pProxy) {
    JTextPane retval = new net.suberic.util.swing.ExtendedEditorPane();
    retval.setEditorKit(new MailEditorKit());

    setDefaultFont(retval);

    // see if this message already has a text part, and if so,
    // include it.

    String origText = ((NewMessageInfo)getMessageProxy().getMessageInfo()).getTextPart(false);
    if (origText != null && origText.length() > 0)
      retval.setText(origText);

    UserProfile profile = getSelectedProfile();
    if (profile.autoAddSignature) {
      retval.setCaretPosition(retval.getDocument().getLength());
      if (profile.signatureFirst) {

      }
      addSignature(retval);

    }

    return retval;

  }

  TransferHandler mTransferHandler = null;
  /**
   * Installs the TransferHandler for this component.
   */
  public void installTransferHandler() {
    if (editorPane != null && mTransferHandler == null) {
      TransferHandler defaultHandler = editorPane.getTransferHandler();

      net.suberic.pooka.gui.dnd.MultipleTransferHandler multiHandler = new net.suberic.pooka.gui.dnd.MultipleTransferHandler();
      multiHandler.addTransferHandler(defaultHandler);
      multiHandler.addTransferHandler(new net.suberic.pooka.gui.dnd.NewMessageTransferHandler());
      mTransferHandler = multiHandler;
    }

    if (editorPane != null)
      editorPane.setTransferHandler(mTransferHandler);
  }

  /**
   * This adds the current user's signature to the message at the current
   * location of the cursor.
   */
  public void addSignature(JEditorPane editor) {
    String sig = getSelectedProfile().getSignature();
    if (sig != null) {
      try {
        editor.getDocument().insertString(editor.getCaretPosition(), sig, null);
      } catch (javax.swing.text.BadLocationException ble) {
        ;
      }
    }
  }

  /**
   * This returns the values in the MesssageWindow as a set of
   * InternetHeaders.
   */
  public InternetHeaders getMessageHeaders() throws MessagingException {
    InternetHeaders returnValue = new InternetHeaders();
    String key;

    Enumeration keys = inputTable.keys();
    while (keys.hasMoreElements()) {
      key = (String)(keys.nextElement());

      if (! key.equals("UserProfile")) {
        String header = new String(Pooka.getProperty("MessageWindow.Header." + key + ".MIMEHeader", key));

        EntryTextArea inputField = (EntryTextArea) inputTable.get(key);
        String value = null;
        if (inputField instanceof AddressEntryTextArea) {
          value = ((AddressEntryTextArea) inputField).getParsedAddresses();
          value = ((NewMessageInfo)getMessageProxy().getMessageInfo()).convertAddressLine(value, getSelectedProfile());
        } else {
          value = ((EntryTextArea)(inputTable.get(key))).getText();
          value = value.replaceAll("\n", " ");
        }

        // don't set it if it's blank.
        if (value != null && value.length() > 0) {
          returnValue.setHeader(header, value);
        }
      }
    }

    if (customHeaderButton.isSelected()) {
      populateCustomHeaders(returnValue);
    } else {
      UserProfile p = getSelectedProfile();
      p.populateHeaders(returnValue);
      returnValue.setHeader(Pooka.getProperty("Pooka.userProfileProperty", "X-Pooka-UserProfile"), p.getName());
    }

    return returnValue;
  }

  /**
   * This notifies the MessageDisplayPanel that an attachment has been added
   * at the provided index.  This does not actually add an attachment,
   * but rather should be called by the MessageProxy when an attachment
   * has been added.
   *
   * If an AttachmentPane does not currently exist for this
   * MessageDisplayPanel, this method will call addAttachmentPane() to
   * create one.
   */
  public void attachmentAdded(int index) {
    if (getAttachmentPanel() == null)
      addAttachmentPane();
    else
      getAttachmentPanel().getTableModel().fireTableRowsInserted(index, index);
  }

  /**
   * This notifies the MessageDisplayPanel that the attachment at the
   * provided index has been removed.  This does not actually remove
   * the attachment, but rather should be called by the MessageProxy
   * when an attachment has been removed.
   *
   * If this removes the last attachment, the entire AttachmentPane
   * is removed from the MessageDisplayPanel.
   */
  public void attachmentRemoved(int index) {
    try {
      java.util.List attach = getNewMessageProxy().getAttachments();
      if (attach == null || attach.size() == 0) {
        removeAttachmentPane();
      } else {
        getAttachmentPanel().getTableModel().fireTableRowsDeleted(index, index);
      }
    } catch (MessagingException me) {
    }
  }

  /**
   * This creates the JComponent which shows the attachments, and then
   * adds it to the JTabbedPane.
   *
   */
  public void addAttachmentPane() {
    attachmentPanel = new AttachmentPane(getMessageProxy());
    attachmentDisplayPanel = new JPanel();
    attachmentDisplayPanel.add(attachmentPanel);

    NewMessageUI nmui = getNewMessageUI();
    if (nmui instanceof net.suberic.util.swing.ThemeSupporter) {
      try {
        Pooka.getUIFactory().getPookaThemeManager().updateUI((net.suberic.util.swing.ThemeSupporter) nmui, attachmentDisplayPanel, true);
      } catch (Exception e) {
        if (Pooka.isDebug())
          System.out.println("error setting theme:  " + e);
      }
    }
    tabbedPane.add(attachmentDisplayPanel, Pooka.getProperty("MessageWindow.AttachmentTab", "Attachments"), 1);
  }

  /**
   * This creates the JComponent which shows the encryption status, and then
   * adds it to the JTabbedPane.
   *
   */
  public void addEncryptionPane() {
    cryptoPanel = new JPanel();
//    NewMessageCryptoDisplay nmcd = new NewMessageCryptoDisplay(getNewMessageProxy());
//    cryptoDisplay = nmcd;

    cryptoPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    cryptoPanel.setSize(headerPanel.getSize());

    ((JPanel)cryptoPanel).setBorder(BorderFactory.createEtchedBorder());

//    cryptoPanel.add(nmcd);

    tabbedPane.add(Pooka.getProperty("MessageWindow.EncryptionTab", "Encryption"), cryptoPanel);
  }

  /**
   * Creates a new CustomHeaderPane.
   */
  public Container createCustomHeaderPane() {

    JPanel returnValue = new JPanel();
    returnValue.setLayout(new BorderLayout());

    Box customInputPanel = new Box(BoxLayout.Y_AXIS);

    Vector headerNames = new Vector();
    headerNames.add(Pooka.getProperty("NewMessage.customHeaders.header", "Header"));
    headerNames.add(Pooka.getProperty("NewMessage.customHeaders.value", "Value"));

    CustomHeaderTableModel dtm = new CustomHeaderTableModel(headerNames, 4);

    customHeaderTable = new JTable(dtm);

    // get the preconfigured properties

    Properties headers = new Properties();

    Properties mailProperties = getSelectedProfile().getMailProperties();
    Enumeration keys = mailProperties.propertyNames();

    String fromAddr = null, fromPersonal = null, replyAddr = null, replyPersonal = null;

    // we want to put From and Reply-To first.
    java.util.List otherProps = new ArrayList();

    while (keys.hasMoreElements()) {
      String key = (String)(keys.nextElement());

      if (key.equals("FromPersonal")) {
        fromPersonal = mailProperties.getProperty(key);
      } else if (key.equals("From")) {
        fromAddr = mailProperties.getProperty(key);
      } else if (key.equals("ReplyTo")) {
        replyAddr = mailProperties.getProperty(key);
      } else if (key.equals("ReplyToPersonal")) {
        replyPersonal = mailProperties.getProperty(key);
      } else {
        otherProps.add(key);
      }
    }

    try {
      if (fromAddr != null) {
        if (fromPersonal != null && !(fromPersonal.equals("")))
          headers.setProperty("From", new InternetAddress(fromAddr, fromPersonal).toString());
        else
          headers.setProperty("From", new InternetAddress(fromAddr).toString());
      } else {
        headers.setProperty("From", "");
      }

      if (replyAddr != null && !(replyAddr.equals(""))) {
        if (replyPersonal != null)
          headers.setProperty("Reply-To", new InternetAddress(replyAddr, replyPersonal).toString());
        else
          headers.setProperty("Reply-To", new InternetAddress(replyAddr).toString());
      } else {
        headers.setProperty("Reply-To", "");
      }
    } catch (java.io.UnsupportedEncodingException uee) {
      //don't bother
    } catch (javax.mail.MessagingException me) {
      //don't bother
    }

    String currentHeader = null;
    String currentValue = null;
    JLabel hdrLabel = null;

    javax.swing.table.DefaultTableModel model = (javax.swing.table.DefaultTableModel) customHeaderTable.getModel();

    model.setValueAt("From", 0, 0);
    model.setValueAt(headers.getProperty("From", ""), 0, 1);

    model.setValueAt("Reply-To", 1, 0);
    model.setValueAt(headers.getProperty("Reply-To", ""), 1, 1);

    int row = 2;
    Iterator it = otherProps.iterator();
    while(it.hasNext()) {
      currentHeader=(String) it.next();
      currentValue = (String) headers.get(currentHeader);
      if (currentValue == null)
        currentValue = "";

      if (model.getRowCount() <= row) {
        model.addRow(new Vector());
      }

      model.setValueAt(currentHeader, row, 0);
      model.setValueAt(currentValue, row, 1);

      row++;
    }

    dtm.setUneditableRows(2 + otherProps.size());

    customInputPanel.add(new JScrollPane(customHeaderTable));

    returnValue.add(customInputPanel, BorderLayout.CENTER);

    JPanel buttonPanel = new JPanel();
    buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));

    IconManager iconManager = Pooka.getUIFactory().getIconManager();

    ImageIcon headerIcon = iconManager.getIcon(Pooka.getProperty("NewMessage.customHeader.add.button", "Plus"));

    JButton headerButton = null;

    if (headerIcon != null) {
      headerButton = new JButton(headerIcon);
      headerButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
      headerButton.setSize(new java.awt.Dimension(10,10));
    } else {
      headerButton = new JButton();
    }

    headerButton.addActionListener(new AbstractAction() {
        public void actionPerformed(ActionEvent e) {
          javax.swing.table.DefaultTableModel model = (javax.swing.table.DefaultTableModel) customHeaderTable.getModel();
          model.addRow(new Vector());
        }
      });

    buttonPanel.add(new JLabel("Add Header"));
    buttonPanel.add(headerButton);
    buttonPanel.setBorder(BorderFactory.createEmptyBorder());

    buttonPanel.setSize(buttonPanel.getMinimumSize());
    returnValue.add(buttonPanel, BorderLayout.SOUTH);
    return returnValue;

  }

  /**
   * Populates an InternetHeaders object from the CustomHeaderPane.
   */
  public void populateCustomHeaders(InternetHeaders pHeaders) {
    if (customHeaderTable.isEditing()) {
      javax.swing.table.TableCellEditor tce = customHeaderTable.getCellEditor(customHeaderTable.getEditingRow(), customHeaderTable.getEditingColumn());
      if (tce != null) {
        tce.stopCellEditing();
      }
    }

    int rowCount = customHeaderTable.getRowCount();
    for (int i = 0; i < rowCount; i++) {
      String header = null;
      String value = null;
      try {
        header = (String) customHeaderTable.getValueAt(i, 0);
        value = (String) customHeaderTable.getValueAt(i, 1);
      } catch (ClassCastException cce) {
        // ignore the header.
      }

      if (header != null && value != null && header.length() > 0 && value.length() > 0) {
        pHeaders.setHeader(header, value);
      }
    }
  }

  /**
   * Selects the custom header pane.
   */
  public void selectCustomHeaderPane() {
    if (customHeaderPane == null) {
      customHeaderPane = createCustomHeaderPane();
      tabbedPane.add(Pooka.getProperty("MessageWindow.CustomHeaderTab", "Custom"), customHeaderPane);
    }
    tabbedPane.setSelectedComponent(customHeaderPane);
  }

  /**
   * Removes the custom header pane, if any.
   */
  public void removeCustomHeaderPane() {
    if (customHeaderPane != null) {
      tabbedPane.setSelectedComponent(headerScrollPane);

      tabbedPane.remove(customHeaderPane);
    }
    customHeaderPane = null;
  }

  /**
   * This removes the AttachmentPane from the JTabbedPane.
   */

  public void removeAttachmentPane() {
    if (attachmentPanel != null) {
      tabbedPane.setSelectedComponent(headerScrollPane);
      tabbedPane.remove(attachmentDisplayPanel);
    }
    attachmentPanel = null;
    attachmentDisplayPanel = null;
  }

  /**
   * This registers the Keyboard action not only for the FolderWindow
   * 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 (attachmentPanel != null)
      attachmentPanel.registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition);
    editorPane.registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition);
    editorScrollPane.registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition);

    splitPane.registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition);
  }

  /**
   * This unregisters the Keyboard action not only for the FolderWindow
   * 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);

    if (attachmentPanel != null)
      attachmentPanel.unregisterKeyboardAction(aKeyStroke);
    editorPane.unregisterKeyboardAction(aKeyStroke);
    editorScrollPane.unregisterKeyboardAction(aKeyStroke);
    splitPane.unregisterKeyboardAction(aKeyStroke);
  }

  /**
   * This creates and shows a PopupMenu for this component.
   */
  public void showPopupMenu(JComponent component, MouseEvent e) {
    ConfigurablePopupMenu popupMenu = new ConfigurablePopupMenu();
    popupMenu.configureComponent("NewMessageWindow.popupMenu", Pooka.getResources());
    popupMenu.setActive(getActions());
    NewMessageUI nmui = getNewMessageUI();
    if (nmui instanceof net.suberic.util.swing.ThemeSupporter) {
      try {
        Pooka.getUIFactory().getPookaThemeManager().updateUI((net.suberic.util.swing.ThemeSupporter) nmui, popupMenu, true);
      } catch (Exception etwo) {
        if (Pooka.isDebug())
          System.out.println("error setting theme:  " + e);
      }
    }
    popupMenu.show(component, e.getX(), e.getY());

  }

  /**
   * As specified by interface net.suberic.pooka.UserProfileContainer.
   *
   * This implementation returns the DefaultProfile of the associated
   * MessageProxy if the MessageDisplayPanel is not editable.  If the
   * MessageDisplayPanel is editable, it returns the currently selected
   * UserProfile object.
   */
  public UserProfile getDefaultProfile() {
    if (isEditable())
      return getSelectedProfile();
    else
      return getMessageProxy().getDefaultProfile();
  }


  /**
   * This method returns the UserProfile currently selected in the
   * drop-down menu.
   */

  public UserProfile getSelectedProfile() {
    return (UserProfile)(((JComboBox)(inputTable.get("UserProfile"))).getSelectedItem());
  }

  /**
   * sets the currently selected Profile.
   */
  public void setSelectedProfile(UserProfile newProfile) {
    if (newProfile != null) {
      ((JComboBox)(inputTable.get("UserProfile"))).setSelectedItem(newProfile);
    }
  }

  /**
   * Overrides JComponent.addNotify().
   *
   * We override addNotify() here to set the proper splitPane location.
   */

  public void addNotify() {
    super.addNotify();
    splitPane.setDividerLocation(Math.min(tabbedPane.getPreferredSize().height + 1, Integer.parseInt(Pooka.getProperty("MessageWindow.headerPanel.vsize", "500"))));
  }

  public boolean isEditable() {
    return true;
  }

  public boolean isModified() {
    return modified;
  }

  public void setModified(boolean mod) {
    if (isEditable())
      modified=mod;
  }

  /**
   * Returns the MessageProxy as a NewMessageProxy.
   */
  public NewMessageProxy getNewMessageProxy() {
    return (NewMessageProxy) getMessageProxy();
  }

  /**
   * Returns the MessageUI as a NewMessageUI.
   */
  public NewMessageUI getNewMessageUI() {
    return (NewMessageUI) getMessageUI();
  }

  /**
   * Shows the current display of the encryption status.
   */
  public net.suberic.pooka.gui.crypto.CryptoStatusDisplay getCryptoStatusDisplay() {
    if (cryptoDisplay == null) {
      addEncryptionPane();
    }

    return cryptoDisplay;
  }

  //------- Actions ----------//

  /**
   * performTextAction grabs the focused component on the MessageDisplayPanel
   * and, if it is a JTextComponent, tries to get it to perform the
   * appropriate ActionEvent.
   */
  public void performTextAction(String name, ActionEvent e) {
    Action[] textActions;

    Component focusedComponent = getFocusedComponent(this);

    // this is going to suck more.

    if (focusedComponent != null) {
      if (focusedComponent instanceof JTextComponent) {
        JTextComponent fTextComp = (JTextComponent) focusedComponent;
        textActions = fTextComp.getActions();
        Action selectedAction = null;
        for (int i = 0; (selectedAction == null) && i < textActions.length; i++) {
          if (textActions[i].getValue(Action.NAME).equals(name))
            selectedAction = textActions[i];
        }

        if (selectedAction != null) {
          selectedAction.actionPerformed(e);
        }
      }
    }
  }

  private Component getFocusedComponent(Container container) {
    Component[] componentList = container.getComponents();

    Component focusedComponent = null;

    // this is going to suck.

    for (int i = 0; (focusedComponent == null) && i < componentList.length; i++) {
      if (componentList[i].hasFocus())
        focusedComponent = componentList[i];
      else if (componentList[i] instanceof Container)
        focusedComponent=getFocusedComponent((Container)componentList[i]);

    }

    return focusedComponent;

  }

  public Hashtable getInputTable() {
    return inputTable;
  }

  public void setInputTable(Hashtable newInputTable) {
    inputTable = newInputTable;
  }

  public Action[] getActions() {
    Action[] returnValue = getDefaultActions();

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

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

    return returnValue;
  }

  /**
   * Sets this editor as enabled or disabled.
   */
  public void setEnabled(boolean enabled) {
    super.setEnabled(enabled);
    getEditorPane().setEnabled(enabled);
  }

  public Action[] getDefaultActions() {
    return defaultActions;
  }

  private void createDefaultActions() {
    // The actions supported by the window itself.

    /*defaultActions = new Action[] {
      new CloseAction(),
      new CutAction(),
      new CopyAction(),
      new PasteAction(),
      new TestAction()
      };*/

    defaultActions = new Action[] {
      new AddSignatureAction(),
      new EditorPanelAction(),
      new AttachmentPanelAction(),
      new TestAction()
    };
  }

  //-----------actions----------------

  class AddSignatureAction extends AbstractAction {

    AddSignatureAction() {
      super("message-add-signature");
    }

    public void actionPerformed(ActionEvent e) {
      addSignature(editorPane);
    }
  }

  class CutAction extends AbstractAction {

    CutAction() {
      super("cut-to-clipboard");
    }

    public void actionPerformed(ActionEvent e) {
      performTextAction((String)getValue(Action.NAME), e);
    }
  }

  class CopyAction extends AbstractAction {

    CopyAction() {
      super("copy-to-clipboard");
    }

    public void actionPerformed(ActionEvent e) {
      performTextAction((String)getValue(Action.NAME), e);
    }
  }

  class PasteAction extends AbstractAction {

    PasteAction() {
      super("paste-from-clipboard");
    }

    public void actionPerformed(ActionEvent e) {
      performTextAction((String)getValue(Action.NAME), e);
    }
  }

  class TestAction extends AbstractAction {

    TestAction() {
      super("test");
    }

    public void actionPerformed(ActionEvent e) {
      System.out.println(net.suberic.pooka.MailUtilities.wrapText(getMessageText()));
    }
  }

  /**
   * Selects the Attachment panel.
   */
  public class AttachmentPanelAction extends AbstractAction {
    AttachmentPanelAction() {
      super("message-select-attachment");
    }

    public void actionPerformed(ActionEvent e) {
      if (attachmentPanel != null) {
        tabbedPane.setSelectedComponent(attachmentDisplayPanel);
        attachmentPanel.requestFocusInWindow();
      }
    }
  }

  /**
   * Selects the Editor panel.
   */
  public class EditorPanelAction extends AbstractAction {
    EditorPanelAction() {
      super("message-select-editor");
    }

    public void actionPerformed(ActionEvent e) {
      tabbedPane.setSelectedComponent(headerScrollPane);
    }
  }

  /**
   * Creates a new CustomHeaderEditorPane if there is not one alrady, and
   * then selects it.
   */
  public class CustomHeaderPanelAction extends AbstractAction {
    CustomHeaderPanelAction() {
      super("message-custom-headers");
    }

    public void actionPerformed(ActionEvent e) {
      customHeaderButton.setSelected(true);
    }
  }

}




TOP

Related Classes of net.suberic.pooka.gui.NewMessageDisplayPanel$CustomHeaderTableModel

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.