package com.jbidwatcher.ui;
/*
* Copyright (c) 2000-2007, CyberFOX Software, Inc. All Rights Reserved.
*
* Developed by mrs (Morgan Schweers)
*/
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.jbidwatcher.ui.config.JConfigFrame;
import com.jbidwatcher.ui.util.*;
import com.jbidwatcher.ui.table.TableColumnController;
import com.jbidwatcher.util.config.JConfig;
import com.jbidwatcher.util.queue.MessageQueue;
import java.awt.event.*;
import java.awt.*;
import javax.annotation.Nullable;
import javax.swing.*;
import javax.swing.event.PopupMenuListener;
import javax.swing.event.PopupMenuEvent;
import java.util.*;
import java.util.List;
public class JTabPopupMenu extends JContext implements MessageQueue.Listener {
private JTabbedPane mTabs = null;
private JMenu customize = null;
private JMenuItem _print = null;
private JMenu _deleteSubmenu = null;
private Map<String, JCheckBoxMenuItem> menuItemMap = new TreeMap<String, JCheckBoxMenuItem>();
private FilterManager mFilter;
private final ListManager listManager;
/**
* @param inTabs - The tab display to act as a context menu for.
* @param popup - The popup to add the behavior to.
* @brief Construct a menu & listener to be used as a context menu
* on the tabbed display.
*/
@Inject
public JTabPopupMenu(ListManager listManager, FilterManager filters, @Assisted JTabbedPane inTabs, @Nullable @Assisted JPopupMenu popup) {
this.listManager = listManager;
mFilter = filters;
mTabs = inTabs;
if(popup != null) {
localPopup = popup;
makeTabMenu(localPopup);
} else {
localPopup = new JPopupMenu();
makeTabMenu(localPopup);
inTabs.addMouseListener(this);
}
}
/**
* @brief Make a small menu for tabs.
*
* @param myPopup - The pop-up menu to be displayed on 'context menu' at any of the tabs.
*
* @noinspection StringContatenationInLoop
*/
public void makeTabMenu(JPopupMenu myPopup) {
customize = new JMenu("Custom Columns");
customize.getPopupMenu().addPopupMenuListener(new PopupMenuListener() {
public void popupMenuWillBecomeVisible(PopupMenuEvent e) { prepCustomColumnMenu(null); }
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { customize.getPopupMenu().setInvoker(customize); }
public void popupMenuCanceled(PopupMenuEvent e) { }
});
myPopup.add(makeMenuItem("Add Tab")).addActionListener(this);
_deleteSubmenu = new JMenu("Delete");
_deleteSubmenu.add(makeMenuItem("Just Tab")).addActionListener(this);
_deleteSubmenu.add(makeMenuItem("Tab & All Entries")).addActionListener(this);
myPopup.add(_deleteSubmenu);
myPopup.add(customize).addActionListener(this);
//myPopup.add(makeMenuItem("+/- Comment")).addActionListener(this);
myPopup.add(_print = makeMenuItem("Print")).addActionListener(this);
myPopup.add(makeMenuItem("Export")).addActionListener(this);
myPopup.add(makeMenuItem("Properties")).addActionListener(this);
}
/**
* @brief If it's the bottom three tabs (current, completed, selling) we don't want to allow delete.
*
* @param inPopup - The pop-up menu that is going to be displayed.
* @param e - The event that occurred (a context-operation).
*/
protected void beforePopup(JPopupMenu inPopup, MouseEvent e) {
super.beforePopup(inPopup, e);
int curIndex = mTabs.indexAtLocation(e.getX(), e.getY());
if(curIndex == -1) {
int tabCount = mTabs.getTabCount();
for(int i=0; i<tabCount; i++) {
Rectangle tabBounds = mTabs.getBoundsAt(i);
if(tabBounds != null && tabBounds.contains(e.getPoint())) curIndex = i;
}
}
preparePopup(curIndex);
}
public void preparePopup(int curIndex) {
if (curIndex == -1) {
customize.setEnabled(false);
_deleteSubmenu.setEnabled(false);
_print.setEnabled(false);
JConfig.log().logDebug("Whoops! Click-point not found!");
} else {
_print.setEnabled(true);
prepCustomColumnMenu(curIndex);
if (curIndex < 3) {
_deleteSubmenu.setEnabled(false);
} else {
_deleteSubmenu.setEnabled(true);
}
}
}
public void prepCustomColumnMenu(Integer tabIndex) {
customize.removeAll();
Collection<String> nameCollection = TableColumnController.getInstance().getColumnNames();
ArrayList<String> sortedNames = new ArrayList<String>(nameCollection);
Collections.sort(sortedNames);
for (String s : sortedNames) {
JCheckBoxMenuItem colMenuItem = new JCheckBoxMenuItem(s);
colMenuItem.setActionCommand('~' + s);
customize.add(colMenuItem).addActionListener(this);
menuItemMap.put(s, colMenuItem);
}
if(tabIndex == null) tabIndex = mTabs.getSelectedIndex();
customize.setEnabled(true);
String tabName = mTabs.getTitleAt(tabIndex);
uncheckAll();
setColumnChecks(tabName);
}
public JMenu getCustomizeMenu() {
return customize;
}
private void setColumnChecks(String tabName) {
List<String> columns = listManager.getColumns(tabName);
for (String colName : columns) {
JCheckBoxMenuItem jch = menuItemMap.get(colName);
jch.setState(true);
}
}
private void uncheckAll() {
for (JCheckBoxMenuItem jch : menuItemMap.values()) {
jch.setState(false);
}
}
public void actionPerformed(ActionEvent ae) {
super.actionPerformed(ae);
DoAction(ae.getActionCommand(), mTabs.getSelectedIndex());
}
protected JFrame propFrame = null;
private TreeMap<String, JTabProperties> tabToProperties = null;
protected JFrame getFrame(String tabName) {
if(propFrame == null) propFrame = new JBidFrame("Tab Properties");
if(tabToProperties == null) tabToProperties = new TreeMap<String, JTabProperties>();
JTabProperties properties = tabToProperties.get(tabName);
if(properties == null) {
properties = new JTabProperties(listManager, tabName);
tabToProperties.put(tabName, properties);
}
properties.updateValues();
Container content = propFrame.getContentPane();
content.removeAll();
content.setLayout(new BorderLayout());
content.add(properties, BorderLayout.CENTER);
JPanel tmp = new JPanel();
JButton ok = new JButton("OK");
ok.addActionListener(properties);
tmp.add(ok, BorderLayout.CENTER);
content.add(tmp, BorderLayout.SOUTH);
propFrame.addWindowListener(new JConfigFrame.IconifyingWindowAdapter(propFrame));
propFrame.pack();
propFrame.setResizable(false);
properties.setFrame(propFrame);
return propFrame;
}
public void messageAction(Object deQ) {
DoAction(deQ.toString(), -1);
}
/**
* @brief Execute a given action, based on the string form of the action name.
*
* @param actionString - The command to do.
* @param tabIndex - The tab to perform the action on.
*/
protected void DoAction(String actionString, int tabIndex) {
if(actionString.equals("Add Tab")) {
OptionUI oui = new OptionUI();
String result = oui.promptString(mTabs.getComponentAt(tabIndex>=0?tabIndex:0), "Enter the name of the tab to add. Prefer brevity.", "Add New Tab", "");
if(result == null) return;
result = result.trim();
if(result.length() == 0) return;
mFilter.addTab(result);
return;
}
String tabName = mTabs.getTitleAt(tabIndex);
if(actionString.charAt(0) == '~') {
boolean result = listManager.toggleField(tabName, actionString.substring(1));
if(tabToProperties != null) {
JTabProperties properties = tabToProperties.get(tabName);
if(properties != null) {
properties.setColumnStatus(actionString.substring(1), result);
}
}
}
if(actionString.equals("Properties")) {
JFrame jf = getFrame(tabName);
jf.setState(Frame.NORMAL);
jf.setVisible(true);
}
if(actionString.equals("Export")) {
JFileChooser jfc = new JFileChooser();
jfc.setApproveButtonText("Export");
int result = jfc.showSaveDialog(null);
switch(result) {
case JFileChooser.APPROVE_OPTION:
String fname = jfc.getSelectedFile().getAbsolutePath();
if(!listManager.exportTab(tabName, fname)) {
JOptionPane.showMessageDialog(null, "Could not export tab [" + tabName + "].", "Export error", JOptionPane.PLAIN_MESSAGE);
}
return;
case JFileChooser.ERROR_OPTION:
case JFileChooser.CANCEL_OPTION:
default:
return;
}
}
if(actionString.equals("Print")) {
if(tabIndex == -1) {
JConfig.log().logDebug("Can't print unknown tab, must prompt...");
} else {
if(!listManager.printTab(tabName)) {
JOptionPane.showMessageDialog(null, "Could not print tab [" + tabName + "].", "Print error", JOptionPane.PLAIN_MESSAGE);
}
}
}
boolean eraseEntries = false;
if(actionString.equals("Tab & All Entries")) {
eraseEntries = true;
actionString = "Just Tab";
}
if(actionString.equals("Just Tab")) {
// If we couldn't have figured out which tab, prompt for delete.
if(tabIndex == -1) {
JConfig.log().logDebug("Prompting for Delete...\n");
} else {
JConfig.log().logDebug("Deleting tab [" + tabName + "]...\n");
Component removed = listManager.deleteTab(tabName, eraseEntries);
if(removed == null) {
JOptionPane.showMessageDialog(null, "Could not delete tab [" + tabName + "].", "Tab deletion error", JOptionPane.PLAIN_MESSAGE);
} else {
mTabs.remove(removed);
}
}
}
}
}