package com.limegroup.gnutella.gui.search;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.swing.Action;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import com.limegroup.gnutella.gui.actions.SearchWhatsNewMediaTypeAction;
import com.limegroup.gnutella.gui.actions.SearchXMLFieldAction;
import com.limegroup.gnutella.gui.tables.DefaultMouseListener;
import com.limegroup.gnutella.gui.tables.MouseObserver;
import com.limegroup.gnutella.util.NameValue;
/**
* If added to a {@link FilterPanel} watches for popup events in all three
* filter boxes and displays a popup menu offering more detailed searches
* depending on the selected items in the filter boxes.
*/
class FilterPopupMenuHandler {
private FilterPanel filterPanel;
private FilterPopupMenuHandler(FilterPanel panel) {
filterPanel = panel;
FilterBox[] boxes = filterPanel.getBoxes();
for (int i = 0; i < boxes.length; i++) {
boxes[i].getList().addMouseListener
(new DefaultMouseListener(new MouseHandler(boxes[i])));
}
}
public static void install(FilterPanel panel) {
new FilterPopupMenuHandler(panel);
}
private void createAndShowPopup(FilterBox box, MouseEvent e) {
JList list = box.getList();
int index = list.locationToIndex(e.getPoint());
if (index != -1) {
list.setSelectedIndex(index);
}
LinkedHashMap map = new LinkedHashMap();
addData(box, map);
FilterBox[] boxes = filterPanel.getBoxes();
for (int i = 0; i < boxes.length; i++) {
addData(boxes[i], map);
}
Action[] actions = createActions(map);
if (actions.length > 0) {
JPopupMenu menu = new JPopupMenu();
for (int i = 0; i < actions.length; i++) {
menu.add(new JMenuItem(actions[i]));
}
menu.show(box.getList(), e.getX(), e.getY());
}
}
private void addData(FilterBox box, Map map) {
if (!box.getSelector().isPropertySelector()) {
Object o = box.getSelectedValue();
if (o != null && !MetadataModel.isAll(o)) {
map.put(box.getSelector(), o);
}
}
}
private Action[] createActions(Map map) {
if (map.isEmpty()) {
return new Action[0];
}
ArrayList actions = new ArrayList();
for (Iterator i = map.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry)i.next();
Selector sel = (Selector)entry.getKey();
if (sel.isSchemaSelector()) {
actions.add(new SearchWhatsNewMediaTypeAction
((NamedMediaType)entry.getValue()));
}
else if (sel.isFieldSelector()) {
actions.add(new SearchXMLFieldAction
(new NameValue(sel.getTitle(), entry.getValue()),
sel.getValue(), entry.getValue().toString(),
NamedMediaType.getFromDescription(sel.getSchema())));
}
}
return (Action[])actions.toArray(new Action[0]);
}
private class MouseHandler implements MouseObserver {
private FilterBox box;
public MouseHandler(FilterBox box) {
this.box = box;
}
public void handlePopupMenu(MouseEvent e) {
createAndShowPopup(box, e);
}
public void handleMouseDoubleClick(MouseEvent e) {
}
public void handleRightMouseClick(MouseEvent e) {
}
}
}