package thaw.plugins.miniFrost;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import java.util.Vector;
import java.util.Iterator;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import thaw.gui.IconBox;
import thaw.core.I18n;
import thaw.core.Logger;
import thaw.plugins.signatures.Identity;
import thaw.plugins.miniFrost.interfaces.Message;
import thaw.plugins.miniFrost.interfaces.SubMessage;
import thaw.plugins.miniFrost.interfaces.Attachment;
import thaw.plugins.miniFrost.interfaces.Draft;
import thaw.fcp.*;
import thaw.plugins.IndexBrowser;
import thaw.plugins.index.IndexManagementHelper;
import thaw.core.ThawThread;
import thaw.core.ThawRunnable;
public class MessagePanel
implements ActionListener {
public final static String[] ACTIONS = {
I18n.getMessage("thaw.plugin.miniFrost.actions"),
I18n.getMessage("thaw.plugin.miniFrost.reply"),
I18n.getMessage("thaw.plugin.miniFrost.archivate"),
I18n.getMessage("thaw.plugin.miniFrost.unarchivate"),
I18n.getMessage("thaw.plugin.miniFrost.unfoldAll"),
I18n.getMessage("thaw.plugin.miniFrost.foldAll")
};
public final static int DEFAULT_UNFOLDED = 2;
private MiniFrostPanel mainPanel;
private JPanel panel;
private JPanel insidePanel;
private JPanel msgsPanel;
private Message msg;
private Vector subMsgs;
private Vector attachments;
private JScrollPane scrollPane;
private JComboBox actions;
private JButton back;
private JButton nextUnread;
private JButton reply;
private Vector subPanels;
private JLabel subject;
private KeyActionMenu keyActionMenu;
public MessagePanel(MiniFrostPanel mainPanel) {
this.mainPanel = mainPanel;
/* keyActionMenu == Right click menu when you click on an highlighted key
*/
keyActionMenu = new KeyActionMenu(chkActions, indexActions);
insidePanel = null;
panel = new JPanel(new BorderLayout(15, 15));
/* messages Panel */
msgsPanel = new JPanel(new BorderLayout(0, 20));
msgsPanel.add(new JLabel(""), BorderLayout.CENTER);
/* actions */
actions = new JComboBox(ACTIONS);
actions.addActionListener(this);
JPanel buttonPanel = new JPanel(new GridLayout(1, 3));
back = new JButton("", IconBox.minLeft);
back.setToolTipText(I18n.getMessage("thaw.plugin.miniFrost.goBack"));
back.addActionListener(this);
if (mainPanel.isInGmailView())
buttonPanel.add(back);
nextUnread = new JButton("", IconBox.minNextUnread);
nextUnread.setToolTipText(I18n.getMessage("thaw.plugin.miniFrost.nextUnread"));
nextUnread.addActionListener(this);
if (mainPanel.isInGmailView())
buttonPanel.add(nextUnread);
reply = new JButton("", IconBox.minMsgReply);
reply.setToolTipText(I18n.getMessage("thaw.plugin.miniFrost.reply"));
reply.addActionListener(this);
buttonPanel.add(reply);
subject = new JLabel("");
subject.setIcon(IconBox.minMail);
subject.setIconTextGap(15);
JPanel northPanel = new JPanel(new BorderLayout(5, 5));
JPanel northNorthPanel = new JPanel(new BorderLayout(5,5));
boolean gmailView = mainPanel.isInGmailView();
if (gmailView) {
northNorthPanel.add(new JLabel(""), BorderLayout.CENTER);
northNorthPanel.add(actions, BorderLayout.EAST);
northNorthPanel.add(buttonPanel, BorderLayout.WEST);
northPanel.add(northNorthPanel, BorderLayout.CENTER);
northPanel.add(new JScrollPane(subject), BorderLayout.SOUTH);
panel.add(northPanel, BorderLayout.NORTH);
scrollPane = new JScrollPane(msgsPanel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
} else { /* => if outlook layout */
JPanel globalPanel = new JPanel(new BorderLayout(10, 10));
globalPanel.add(subject, BorderLayout.NORTH);
globalPanel.add(msgsPanel, BorderLayout.CENTER);
scrollPane = new JScrollPane(globalPanel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
panel.add(scrollPane, BorderLayout.CENTER);
}
public MiniFrostPanel getMiniFrostPanel() {
return mainPanel;
}
public void revalidate() {
panel.revalidate();
}
public void hided() {
nextUnread.setMnemonic(KeyEvent.VK_Z);
}
public void redisplayed() {
nextUnread.setMnemonic(KeyEvent.VK_N);
nextUnread.requestFocus();
}
public void setMessage(Message msg) {
this.msg = msg;
subMsgs = msg.getSubMessages();
attachments = msg.getAttachments();
refresh();
}
public Message getMessage() {
return msg;
}
protected class AttachmentAction extends JMenuItem
implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 3518533179205885687L;
private Attachment a;
private String action;
public AttachmentAction(Attachment a, String action) {
super(action);
this.a = a;
this.action = action;
super.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
a.apply(mainPanel.getDb(),
mainPanel.getPluginCore().getCore().getQueueManager(),
action);
}
}
protected class AttachmentPanel extends JPanel
implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 367756847110840408L;
private JButton button;
private Vector attachments;
public AttachmentPanel(Vector attachments) {
super();
this.attachments = attachments;
button = new JButton(IconBox.attachment);
button.setToolTipText(I18n.getMessage("thaw.plugin.miniFrost.attachments"));
button.addActionListener(this);
super.add(button);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
JPopupMenu menu = new JPopupMenu();
/* make the menu */
for(Iterator it = attachments.iterator();
it.hasNext();) {
Attachment a = (Attachment)it.next();
JMenu subMenu = new JMenu(a.getPrintableType() + " : "+a.toString());
String[] actions = a.getActions();
for (int i = 0 ; i < actions.length ; i++) {
subMenu.add(new AttachmentAction(a, actions[i]));
}
menu.add(subMenu);
}
/* and next display it */
menu.show(this,
this.getWidth()/2,
this.getHeight()/2);
}
}
}
public JPanel getEncryptedForPanel(Identity id) {
JPanel panel = new JPanel(new GridLayout(1, 1));
panel.add(new JLabel(I18n.getMessage("thaw.plugin.miniFrost.encryptedBody").replaceAll("X", id.toString())));
return panel;
}
public void refresh() {
subPanels = new Vector();
/* will imbricate BorderLayout */
/* it's dirty, but it should work */
JPanel iPanel = null;
String rev = "";
if (msg.getRev() >= 0)
rev = " [r"+Integer.toString(msg.getRev())+"]";
subject.setText(I18n.getMessage("thaw.plugin.miniFrost.subject")+": "+msg.getSubject()+
rev);
Logger.info(this, "Displaying "+Integer.toString(subMsgs.size())+" sub-msgs");
if (msg.encryptedFor() != null) {
iPanel = getEncryptedForPanel(msg.encryptedFor());
Logger.info(this, "(Encrypted message)");
}
int i = 0;
/* sub messages */
for (Iterator it = subMsgs.iterator();
it.hasNext();) {
SubMessage subMsg = (SubMessage)it.next();
//SubMessagePanel panel = new SubMessagePanel(subMsg,
// (i + DEFAULT_UNFOLDED) < subMsgs.size());
SubMessagePanel panel = new SubMessagePanel(this, subMsg, false);
subPanels.add(panel);
if (iPanel == null) {
iPanel = panel;
} else {
JPanel newPanel = new JPanel(new BorderLayout(0, 20));
newPanel.add(iPanel, BorderLayout.NORTH);
newPanel.add(panel, BorderLayout.CENTER);
iPanel = newPanel;
}
i++;
}
if (msg.encryptedFor() != null) {
if (iPanel == null) {
iPanel = getEncryptedForPanel(msg.encryptedFor());
} else {
JPanel newPanel = new JPanel(new BorderLayout(0, 20));
newPanel.add(iPanel, BorderLayout.NORTH);
newPanel.add(getEncryptedForPanel(msg.encryptedFor()), BorderLayout.CENTER);
iPanel = newPanel;
}
}
/* attachments */
if (attachments != null) {
AttachmentPanel panel = new AttachmentPanel(attachments);
if (iPanel == null) {
iPanel = panel;
} else {
JPanel newPanel = new JPanel(new BorderLayout(0, 20));
newPanel.add(iPanel, BorderLayout.NORTH);
newPanel.add(panel, BorderLayout.CENTER);
iPanel = newPanel;
}
}
if (insidePanel != null) {
msgsPanel.remove(insidePanel);
}
if (iPanel != null) {
msgsPanel.add(iPanel, BorderLayout.NORTH);
msgsPanel.add(new JLabel(""), BorderLayout.CENTER);
}
insidePanel = iPanel;
revalidate();
putScrollBarAtBottom();
}
public JScrollPane getScrollPane() {
return scrollPane;
}
private class ScrollBarSetter implements ThawRunnable {
public ScrollBarSetter() { }
public void run() {
try {
/* dirty way to have the expected result */
Thread.sleep(100);
} catch(InterruptedException e) {
}
scrollPane.getVerticalScrollBar().setUnitIncrement(15);
int max = scrollPane.getVerticalScrollBar().getMaximum();
int extent = scrollPane.getVerticalScrollBar().getVisibleAmount();
int min = scrollPane.getVerticalScrollBar().getMinimum();
int value = scrollPane.getVerticalScrollBar().getValue();
Logger.debug(this, "ScrollBar: "
+"min : "+Integer.toString(min)
+" ; max : "+Integer.toString(max)
+" ; extent : "+Integer.toString(extent)
+" ; value : "+Integer.toString(value));
scrollPane.getVerticalScrollBar().setValue(max);
}
public void stop() {
/* \_o< */
}
}
private void putScrollBarAtBottom() {
int max = scrollPane.getVerticalScrollBar().getMaximum();
scrollPane.getVerticalScrollBar().setValue(max);
Runnable doScroll = new Runnable() {
public void run() {
Thread th = new ThawThread(new ScrollBarSetter(),
"Scrollbar setter", this);
th.start();
}
};
javax.swing.SwingUtilities.invokeLater(doScroll);
}
public JPanel getPanel() {
return panel;
}
private boolean nextUnread() {
/**
* because it knows the filter rules
*/
return mainPanel.getMessageTreeTable().nextUnread();
}
protected void reply() {
Draft draft = msg.getBoard().getDraft(msg);
mainPanel.getDraftPanel().setDraft(draft);
mainPanel.displayDraftPanel();
}
public void actionPerformed(ActionEvent e) {
if (msg == null)
return;
if (e.getSource() == back) {
mainPanel.displayMessageTable();
} else if (e.getSource() == nextUnread) {
if (!nextUnread())
mainPanel.displayMessageTable();
} else if (e.getSource() == reply) {
reply();
} else if (e.getSource() == actions) {
int sel = actions.getSelectedIndex();
if (sel == 2 || sel == 3) { /* (un)archive */
boolean archive = (sel == 2);
msg.setArchived(archive);
mainPanel.getMessageTreeTable().refresh();
if (archive && !nextUnread())
mainPanel.displayMessageTable();
} else if (sel == 1) { /* reply */
reply();
} else if (sel == 4 || sel == 5) { /* (un)fold */
boolean retracted = (sel == 5);
for (Iterator it = subPanels.iterator();
it.hasNext();) {
((SubMessagePanel)it.next()).setRetracted(retracted);
}
}
actions.setSelectedIndex(0);
}
}
public final static JMenuItem[] chkActions = {
new JMenuItem(I18n.getMessage("thaw.plugin.miniFrost.downloadThisKey")),
new JMenuItem(I18n.getMessage("thaw.plugin.miniFrost.downloadAllKeys")),
null,
new JMenuItem(I18n.getMessage("thaw.plugin.miniFrost.copyThisKey")),
new JMenuItem(I18n.getMessage("thaw.plugin.miniFrost.copyAllKeys"))
};
public final static JMenuItem[] indexActions = {
new JMenuItem(I18n.getMessage("thaw.plugin.miniFrost.addThisIndex")),
new JMenuItem(I18n.getMessage("thaw.plugin.miniFrost.addAllIndexes")),
null,
new JMenuItem(I18n.getMessage("thaw.plugin.miniFrost.copyThisKey")),
new JMenuItem(I18n.getMessage("thaw.plugin.miniFrost.copyAllKeys"))
};
protected MiniFrostPanel getMainPanel() {
return mainPanel;
}
public Vector getAllKeys() {
Vector v = new Vector();
for (Iterator it = subPanels.iterator();
it.hasNext();) {
v.addAll( ((SubMessagePanel)it.next()).getKeys() );
}
return v;
}
public Vector getCHKKeys() {
Vector v = new Vector();
Vector keys = getAllKeys();
for (Iterator it = keys.iterator();
it.hasNext();) {
String key = (String)it.next();
if (key.startsWith("CHK@"))
v.add(key);
}
return v;
}
public Vector getIndexKeys() {
Vector v = new Vector();
Vector keys = getAllKeys();
for (Iterator it = keys.iterator();
it.hasNext();) {
String key = (String)it.next();
if (key.endsWith(".frdx"))
v.add(key);
}
return v;
}
protected class KeyActionMenu extends JPopupMenu implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 7604690757405586814L;
private String key;
private JMenuItem[] chkActions;
private JMenuItem[] indexActions;
private MessagePanel messagePanel;
public KeyActionMenu(JMenuItem[] chkActions, JMenuItem[] indexActions) {
super();
this.chkActions = chkActions;
this.indexActions = indexActions;
for (int i = 0 ; i < indexActions.length;i++) {
if (indexActions[i] != null)
indexActions[i].addActionListener(this);
}
for (int i = 0 ; i < indexActions.length;i++) {
if (chkActions[i] != null)
chkActions[i].addActionListener(this);
}
}
public void setKeys(MessagePanel panel, String key) {
this.key = key;
this.messagePanel = panel;
removeAll();
boolean index = key.endsWith(".frdx");
JMenuItem[] items = (index ? indexActions : chkActions);
for (int i = 0 ; i < items.length ;i++) {
if (items[i] != null)
add(items[i]);
else
addSeparator();
}
}
public void download(String key, java.io.File destDir) {
FCPQueueManager queueManager = messagePanel.getMainPanel().getPluginCore().getCore().getQueueManager();
FCPClientGet get = new FCPClientGet(key, FCPClientGet.DEFAULT_PRIORITY,
FCPClientGet.PERSISTENCE_FOREVER,
true /* global queue */,
FCPClientGet.DEFAULT_MAX_RETRIES /* max retries */,
destDir.getPath());
queueManager.addQueryToThePendingQueue(get);
}
public void addIndex(String key) {
FCPQueueManager queueManager = messagePanel.getMainPanel().getPluginCore().getCore().getQueueManager();
IndexBrowser browser = (IndexBrowser)messagePanel.getMainPanel().getPluginCore().getCore().getPluginManager().getPlugin("thaw.plugins.IndexBrowser");
if (browser == null) {
Logger.error(this, "The index browser is not running. Can't add an index");
return;
}
IndexManagementHelper.addIndex(queueManager,
browser.getIndexBrowserPanel(),
null,
key,
true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == chkActions[3]
|| e.getSource() == indexActions[3]) { /* copy this key */
thaw.gui.GUIHelper.copyToClipboard(key);
} else if (e.getSource() == chkActions[4]
|| e.getSource() == indexActions[4]) { /* copy all keys */
Vector v = ( (e.getSource() == indexActions[4]) ?
messagePanel.getIndexKeys() :
messagePanel.getCHKKeys() );
String str = "";
for (Iterator it = v.iterator();
it.hasNext();) {
str += ((String)it.next())+"\n";
}
thaw.gui.GUIHelper.copyToClipboard(str);
} else if (e.getSource() == chkActions[0]) { /* download this key */
String lastPath = mainPanel.getConfig().getValue("lastDestinationDirectory");
thaw.gui.FileChooser chooser = (lastPath != null ?
new thaw.gui.FileChooser(lastPath) :
new thaw.gui.FileChooser());
chooser.setTitle(I18n.getMessage("thaw.plugin.fetch.chooseDestination"));
chooser.setDirectoryOnly(true);
chooser.setDialogType(javax.swing.JFileChooser.SAVE_DIALOG);
java.io.File file = chooser.askOneFile();
if (file == null)
return;
mainPanel.getConfig().setValue("lastDestinationDirectory", file.getPath());
download(key, file);
} else if (e.getSource() == chkActions[1]) { /* download all the keys */
String lastPath = mainPanel.getConfig().getValue("lastDestinationDirectory");
thaw.gui.FileChooser chooser = (lastPath != null ?
new thaw.gui.FileChooser(lastPath) :
new thaw.gui.FileChooser());
chooser.setTitle(I18n.getMessage("thaw.plugin.fetch.chooseDestination"));
chooser.setDirectoryOnly(true);
chooser.setDialogType(javax.swing.JFileChooser.SAVE_DIALOG);
java.io.File file = chooser.askOneFile();
if (file == null)
return;
mainPanel.getConfig().setValue("lastDestinationDirectory", file.getPath());
Vector v = messagePanel.getCHKKeys();
for (Iterator it = v.iterator();
it.hasNext();) {
download((String)it.next(), file);
}
} else if (e.getSource() == indexActions[0]) { /* add this index */
addIndex(key);
} else if (e.getSource() == indexActions[1]) { /* add all the indexes */
Vector v = messagePanel.getIndexKeys();
for (Iterator it = v.iterator();
it.hasNext();) {
addIndex((String)it.next());
}
}
}
}
public void popMenuOnKey(MouseEvent e, String key) {
keyActionMenu.setKeys(this, key);
keyActionMenu.show(e.getComponent(), e.getX(), e.getY());
}
}