00001 package cz.vutbr.fit.dudka.SGVis.Visual;
00002
00003 import java.awt.event.ActionEvent;
00004 import java.awt.event.ActionListener;
00005 import java.awt.event.MouseEvent;
00006 import java.net.MalformedURLException;
00007 import java.net.URL;
00008
00009 import javax.swing.JLabel;
00010 import javax.swing.JMenu;
00011 import javax.swing.JMenuItem;
00012 import javax.swing.JPopupMenu;
00013
00014 import prefuse.controls.Control;
00015 import prefuse.controls.ControlAdapter;
00016 import prefuse.util.FontLib;
00017 import prefuse.util.collections.IntIterator;
00018 import prefuse.visual.VisualItem;
00019 import cz.vutbr.fit.dudka.SGVis.Config;
00020 import cz.vutbr.fit.dudka.SGVis.Data.DataLib;
00021 import cz.vutbr.fit.dudka.SGVis.Data.RelationStorage;
00022 import edu.stanford.ejalbert.BrowserLauncher;
00023 import edu.stanford.ejalbert.exception.BrowserLaunchingInitializingException;
00024 import edu.stanford.ejalbert.exception.UnsupportedOperatingSystemException;
00025
00029 class GraphNodeContextMenu {
00030 private class ItemBrowseActionListener implements ActionListener {
00031 private URL url;
00032 public ItemBrowseActionListener(URL url) {
00033 this.url = url;
00034 }
00035 public void actionPerformed(ActionEvent e) {
00036 view.showStatus("Opening browser at "+url.toString());
00037 try {
00038 BrowserLauncher launcher = new BrowserLauncher();
00039 launcher.openURLinBrowser(this.url.toString());
00040 } catch (BrowserLaunchingInitializingException e1) {
00041
00042 e1.printStackTrace();
00043 } catch (UnsupportedOperatingSystemException e1) {
00044
00045 e1.printStackTrace();
00046 }
00047 }
00048 }
00049
00050 private class ItemDeleteActionListener implements ActionListener {
00051 private final GraphView view;
00052 private final int node;
00053 public ItemDeleteActionListener(GraphView view, int node) {
00054 this.view = view;
00055 this.node = node;
00056 }
00057 public void actionPerformed(ActionEvent e) {
00058 view.removeNode(node);
00059 }
00060 }
00061
00062 private class ItemLookupActionListener implements ActionListener {
00063 private GraphView view;
00064 private URL url;
00065 public ItemLookupActionListener(GraphView view, URL url) {
00066 this.view = view;
00067 this.url = url;
00068 }
00069 public void actionPerformed(ActionEvent e) {
00070 view.lookup(url);
00071 }
00072 }
00073
00074 private class ItemCollapseActionListener implements ActionListener {
00075 private GraphView view;
00076 private String host;
00077 public ItemCollapseActionListener(GraphView view, String host) {
00078 this.view = view;
00079 this.host = host;
00080 }
00081 public void actionPerformed(ActionEvent e) {
00082 view.collapseHost(host);
00083 }
00084 }
00085
00086 private class ItemExpandActionListener implements ActionListener {
00087 private GraphView view;
00088 private String host;
00089 public ItemExpandActionListener(GraphView view, String host) {
00090 this.view = view;
00091 this.host = host;
00092 }
00093 public void actionPerformed(ActionEvent e) {
00094 view.expandHost(host);
00095 }
00096 }
00097 GraphView view;
00098 public GraphNodeContextMenu(GraphView view) {
00099 this.view = view;
00100 }
00101 private JPopupMenu getContextMenu(VisualItem item) {
00102 JPopupMenu menu = new JPopupMenu();
00103 JLabel name = new JLabel(" "+item.getString("text"));
00104 name.setFont(FontLib.getFont("Tahoma", 18));
00105 menu.add(name);
00106 menu.addSeparator();
00107
00108 try {
00109 String text = item.getString("text");
00110 String type = item.getString("type");
00111 if (type == "G") {
00112
00113 JMenuItem itemExpand = new JMenuItem("Expand");
00114 itemExpand.addActionListener(
00115 new ItemExpandActionListener(view, text)
00116 );
00117 menu.add(itemExpand);
00118
00119 } else {
00120
00121 JMenuItem itemCollapse = new JMenuItem("Collapse");
00122 itemCollapse.addActionListener(
00123 new ItemCollapseActionListener(
00124 view,
00125 RelationStorage.urlToHost(new URL(text)))
00126 );
00127 menu.add(itemCollapse);
00128 }
00129
00130
00131 final int node = item.getRow();
00132 IntIterator iter = view.edgeRows(node);
00133 if (!DataLib.hasMinSize(iter, 2)) {
00134 JMenuItem delete = new JMenuItem("Delete");
00135 delete.addActionListener(
00136 new ItemDeleteActionListener(view, node)
00137 );
00138 menu.add(delete);
00139 }
00140
00141
00142 ListenerFactory lookupFactory = new ListenerFactory() {
00143 public ActionListener createListener(URL url) {
00144 return new ItemLookupActionListener(view, url);
00145 }
00146 };
00147 JMenuItem lookupMenu = createPerUrlEntry(item, "Lookup", lookupFactory);
00148 if (LookupWorker.getActiveCount()>=Config.MAX_CONCURRENT_LOOKUPS)
00149 lookupMenu.setEnabled(false);
00150 menu.add(lookupMenu);
00151
00152
00153 menu.addSeparator();
00154 ListenerFactory browseFactory = new ListenerFactory() {
00155 public ActionListener createListener(URL url) {
00156 return new ItemBrowseActionListener(url);
00157 }
00158 };
00159 menu.add(createPerUrlEntry(item, "Open in browser", browseFactory));
00160 }
00161 catch (MalformedURLException e) {
00162 throw new AssertionError("malformed URL");
00163 }
00164
00165 return menu;
00166 }
00167 private interface ListenerFactory {
00168 ActionListener createListener(URL url);
00169 }
00170 private JMenuItem createPerUrlEntry(
00171 VisualItem item,
00172 String itemText,
00173 ListenerFactory factory)
00174 {
00175 JMenuItem menuItem = null;
00176
00177 String text = item.getString("text");
00178 String type = item.getString("type");
00179 if (type == "G") {
00180 RelationStorage storage = view.getStorage();
00181 Iterable<URL> urls = storage.getUrls(text);
00182 if (DataLib.hasMinSize(urls, 2)) {
00183 menuItem = new JMenu(itemText);
00184 for (URL u: urls)
00185 menuItem.add(createItem(u.toString(), u, factory));
00186 } else if (urls.iterator().hasNext()) {
00187 URL url = urls.iterator().next();
00188 menuItem = createItem(itemText + " - " + url.toString(), url, factory);
00189 } else {
00190 throw new AssertionError("Group with no items");
00191 }
00192 } else {
00193 try {
00194 menuItem = createItem(itemText, new URL(text), factory);
00195 } catch (MalformedURLException e) {
00196
00197 e.printStackTrace();
00198 }
00199 }
00200
00201 return menuItem;
00202 }
00203 private JMenuItem createItem(
00204 String text,
00205 URL url,
00206 ListenerFactory factory)
00207 {
00208 JMenuItem item = new JMenuItem(text);
00209 item.addActionListener(factory.createListener(url));
00210 return item;
00211 }
00212 public void showContextMenu(VisualItem item, MouseEvent e) {
00213 JPopupMenu menu = this.getContextMenu(item);
00214 menu.show(e.getComponent(), e.getX(), e.getY());
00215 }
00216 public Control getControlListener() {
00217 final GraphNodeContextMenu obj = this;
00218 return new ControlAdapter() {
00219 public void itemClicked(VisualItem item, MouseEvent e) {
00220 if (e.getButton()!=3)
00221
00222 return;
00223
00224 obj.showContextMenu(item, e);
00225 }
00226 };
00227 }
00228
00229 }