/* GraphWrap/PDF Analyser Beta 1
*
* The code in this module is based on the file WikiNavigateUI.java
* from the TouchGraph WikiBrowser application. These module is published
* under the TouchGraph Apache-style licence, which is printed below.
*
* --------------------------------------------------------------------
*
* TouchGraph LLC. Apache-Style Software License
*
*
* Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of soursce code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* TouchGraph LLC (http://www.touchgraph.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse
* or promote products derived from this software without prior written
* permission. For written permission, please contact
* alex@touchgraph.com
*
* 5. Products derived from this software may not be called "TouchGraph",
* nor may "TouchGraph" appear in their name, without prior written
* permission of alex@touchgraph.com.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
*/
/**
* Generic user interface for moving around the graph and wrapping. Based on
* WikiNavigateUI.java from TouchGraph WikiBrowser by TouchGraph LLC/
* Alexander Shapiro
*
* @author Tamir Hassan, hassan@dbai.tuwien.ac.at
* @version GraphWrap Beta 1
*/
package at.ac.tuwien.dbai.pdfwrap.gui.graphbrowser;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import at.ac.tuwien.dbai.pdfwrap.model.graph.DocEdge;
import at.ac.tuwien.dbai.pdfwrap.model.graph.DocNode;
import at.ac.tuwien.dbai.pdfwrap.model.document.*;
import com.touchgraph.graphlayout.TGPanel;
import com.touchgraph.graphlayout.interaction.DragNodeUI;
import com.touchgraph.graphlayout.interaction.TGAbstractClickUI;
import com.touchgraph.graphlayout.interaction.TGAbstractDragUI;
import com.touchgraph.graphlayout.interaction.TGUserInterface;
/**
* DocWrapperUI
*
* @author Tamir Hassan, pdfanalyser@tamirhassan.com
* @version PDF Analyser GUI 0.9
*/
public class DocWrapperUI extends TGUserInterface {
TGPanel tgPanel;
DocGBPanel docGBPanel;
DocNavigateMouseListener ml;
DocNavigateMouseMotionListener mml;
TGAbstractDragUI hvDragUI;
TGAbstractClickUI hvScrollToCenterUI;
DragNodeUI dragNodeUI;
// determines whether the "Enter Edit Mode" menu item is enabled
private boolean editMode;
JPopupMenu nodePopup;
JPopupMenu edgePopup;
JPopupMenu backPopup;
//DocNode popupNode;
DocNode popupNode; // 28.12.08 differing treatment of Gen- & TextSegments?
DocEdge popupEdge;
//DocPopupListener popupListenerObject;
public DocWrapperUI(DocGBPanel docGBPanel) {
// rename both these variables!
this.docGBPanel = docGBPanel;
tgPanel = docGBPanel.getTGPanel();
//localityScroll=tgWikiBrowser.localityScroll;
editMode = false;
hvDragUI = docGBPanel.hvScroll.getHVDragUI();
hvScrollToCenterUI = docGBPanel.hvScroll.getHVScrollToCenterUI();
dragNodeUI = new DragNodeUI(tgPanel);
ml = new DocNavigateMouseListener();
mml = new DocNavigateMouseMotionListener();
}
public void activate() {
tgPanel.addMouseListener(ml);
tgPanel.addMouseMotionListener(mml);
}
public void deactivate() {
tgPanel.removeMouseListener(ml);
tgPanel.removeMouseMotionListener(mml);
}
class DocNavigateMouseListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
if (e.isPopupTrigger()) {
triggerPopup(e);
}
else {
DocNode mouseOverN = (DocNode) tgPanel.getMouseOverN();
if (e.getModifiers() == MouseEvent.BUTTON1_MASK) {
if (mouseOverN == null)
hvDragUI.activate(e);
else
dragNodeUI.activate(e);
}
}
}
public void mouseClicked(MouseEvent e) {
DocNode mouseOverN = (DocNode) tgPanel.getMouseOverN();
DocEdge mouseOverE = (DocEdge) tgPanel.getMouseOverE();
//DocNode select = (DocNode) tgPanel.getSelect();
if ((e.getModifiers() & MouseEvent.BUTTON1_MASK)!=0) {
if (mouseOverN != null) {
if (e.getClickCount()==1) {
// docGBPanel.setSelect(mouseOverN);
tgPanel.setSelect(mouseOverN);
}
else {
tgPanel.setSelect(mouseOverN);
docGBPanel.setLocale(mouseOverN);
}
}
else if (mouseOverE != null)
{
tgPanel.setSelect(mouseOverE);
}
}
}
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger()) {
triggerPopup(e);
}
}
public void triggerPopup(MouseEvent e) {
popupNode = (DocNode) tgPanel.getMouseOverN();
popupEdge = (DocEdge) tgPanel.getMouseOverE();
if (popupNode != null) {
tgPanel.setMaintainMouseOver(true);
setUpNodePopup();
nodePopup.show(e.getComponent(), e.getX(), e.getY());
}
else if (popupEdge != null)
{
tgPanel.setMaintainMouseOver(true);
setUpEdgePopup();
edgePopup.show(e.getComponent(), e.getX(), e.getY());
}
else {
if (backPopup == null)
setUpBackPopup();
//if (backPopup != null)
backPopup.show(e.getComponent(), e.getX(), e.getY());
}
}
}
class DocNavigateMouseMotionListener extends MouseMotionAdapter {
public void mouseMoved( MouseEvent e ) {
DocNode mouseOverN = (DocNode) tgPanel.getMouseOverN();
if(mouseOverN!=null) {
tgPanel.setCursor(new Cursor(Cursor.HAND_CURSOR));
docGBPanel.setStatusBarText("[Node under pointer] " + mouseOverN.toSBText());
}
else {
/*
tgPanel.setCursor(null);
DocNode currentNode = (DocNode) docGBPanel.getTGPanel().getSelect();
String SBText = "Ready";
if (currentNode != null) SBText = "[Selected node] " + currentNode.toSBText();
docGBPanel.setStatusBarText(SBText);
*/
tgPanel.setCursor(null);
// DocNode currentNode = (DocNode) docGBPanel.getTGPanel().getSelect();
Object currentNode = docGBPanel.getTGPanel().getSelect();
String SBText = "Ready";
if (currentNode != null)
{
if (currentNode instanceof DocNode)
SBText = "[Selected node] " + ((DocNode)currentNode).toSBText();
else if (currentNode instanceof DocEdge)
SBText = "[Selected edge] " + ((DocEdge)currentNode).toSBText();
}
docGBPanel.setStatusBarText(SBText);
}
docGBPanel.statusBar.repaint();
}
public void mouseDragged( MouseEvent e ) {
DocNode mouseOverN = (DocNode) tgPanel.getMouseOverN();
if(mouseOverN!=null) {
tgPanel.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
docGBPanel.setStatusBarText("[Node under pointer] " + mouseOverN.toSBText());
}
else {
tgPanel.setCursor(new Cursor(Cursor.MOVE_CURSOR));
}
}
}
private void setUpNodePopup() {
nodePopup = new JPopupMenu();
JMenuItem menuItem;
menuItem = new JMenuItem("Expand node");
ActionListener expandAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(popupNode!=null) {
tgPanel.expandNode(popupNode);
}
}
};
menuItem.addActionListener(expandAction);
nodePopup.add(menuItem);
menuItem = new JMenuItem("Collapse node");
ActionListener collapseAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(popupNode!=null) {
tgPanel.collapseNode(popupNode );
}
}
};
menuItem.addActionListener(collapseAction);
nodePopup.add(menuItem);
menuItem = new JMenuItem("Hide node");
ActionListener hideAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(popupNode!=null) {
tgPanel.hideNode(popupNode);
}
}
};
menuItem.addActionListener(hideAction);
nodePopup.add(menuItem);
nodePopup.addSeparator();
//nodePopup.add(new JSeparator());
ActionListener sendAction = null;
// all the node types are listed here but the only types of interest to us
// are the Group Node and Genre Node. The others are included here for
// for completeness, e.g. if TVAeNavigateUI were to be used for additional,
// new visualizations
String itemText;
itemText = "Match font size";
menuItem = new JCheckBoxMenuItem(itemText, popupNode.isMatchFontSize());
ActionListener matchTypographyAction = new ActionListener() {
public void actionPerformed(ActionEvent e)
{
if (popupNode.isMatchFontSize())
popupNode.setMatchFontSize(false);
//docGBPanel.getGraphEltSet().setMatchTypography(popupNode, false);
else
popupNode.setMatchFontSize(true);
//docGBPanel.getGraphEltSet().setMatchTypography(popupNode, true);
}
};
menuItem.addActionListener(matchTypographyAction);
nodePopup.add(menuItem);
nodePopup.addSeparator();
itemText = "Remove from instance";
menuItem = new JCheckBoxMenuItem(itemText, popupNode.isRemoveFromInstance());
ActionListener removeFromInstanceAction = new ActionListener() {
public void actionPerformed(ActionEvent e)
{
if (popupNode.isRemoveFromInstance())
popupNode.setRemoveFromInstance(false);
//docGBPanel.getGraphEltSet().setRemoveFromInstance(popupNode, false);
else
popupNode.setRemoveFromInstance(true);
//docGBPanel.getGraphEltSet().setRemoveFromInstance(popupNode, true);
docGBPanel.getGraphEltSet().enableDisableEdges();
}
};
menuItem.addActionListener(removeFromInstanceAction);
nodePopup.add(menuItem);
nodePopup.addSeparator();
// TODO: doesn't clear all edits anymore -- what now?
itemText = "Clear all edits";
menuItem = new JMenuItem(itemText);
ActionListener clearAllAction = new ActionListener() {
public void actionPerformed(ActionEvent e)
{
docGBPanel.completeEltSet.clearWrapperEdits();
}
};
menuItem.addActionListener(clearAllAction);
nodePopup.add(menuItem);
if (editMode)
{
nodePopup.addSeparator();
menuItem = new JMenuItem("Enter Edit Mode");//, TVAeImageCache.getImage("icon.vis.edit"));
ActionListener editAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
deactivate();
docGBPanel.tgUIManager.activate("Edit");
}
};
menuItem.addActionListener(editAction);
nodePopup.add(menuItem);
}
nodePopup.addPopupMenuListener(new PopupMenuListener() {
public void popupMenuCanceled(PopupMenuEvent e) {}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
tgPanel.setMaintainMouseOver(false);
tgPanel.setMouseOverN(null);
tgPanel.repaint();
}
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
});
//addHelpMenuItem(nodePopup);
}
private void setUpEdgePopup() {
edgePopup = new JPopupMenu();
JMenuItem menuItem;
menuItem = new JMenuItem("Hide edge");
ActionListener hideAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(popupEdge!=null) {
tgPanel.hideEdge(popupEdge);
}
}
};
menuItem.addActionListener(hideAction);
edgePopup.add(menuItem);
edgePopup.addSeparator();
ButtonGroup group = new ButtonGroup();
menuItem = new JRadioButtonMenuItem("Match one occurrence");
if (popupEdge.getMultipleMatch() == DocEdge.MATCH_ONE)
menuItem.setSelected(true);
else
menuItem.setSelected(false);
group.add(menuItem);
ActionListener matchOneAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(popupEdge!=null) {
popupEdge.setMultipleMatch(DocEdge.MATCH_ONE);
//popupEdge.setMatchN(false);
//docGBPanel.completeEltSet.setMatchN(popupEdge, false);
}
}
};
menuItem.addActionListener(matchOneAction);
edgePopup.add(menuItem);
menuItem = new JRadioButtonMenuItem("Match n occurrences until first");
if (popupEdge.getMultipleMatch() == DocEdge.MATCH_N_TIL_FIRST)
menuItem.setSelected(true);
else
menuItem.setSelected(false);
group.add(menuItem);
ActionListener matchNFirstAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(popupEdge!=null) {
popupEdge.setMultipleMatch(DocEdge.MATCH_N_TIL_FIRST);
//popupEdge.setMatchN(true);
//docGBPanel.completeEltSet.setMatchN(popupEdge, true);
}
}
};
menuItem.addActionListener(matchNFirstAction);
edgePopup.add(menuItem);
menuItem = new JRadioButtonMenuItem("Match n occurrences until last");
if (popupEdge.getMultipleMatch() == DocEdge.MATCH_N_TIL_LAST)
menuItem.setSelected(true);
else
menuItem.setSelected(false);
group.add(menuItem);
ActionListener matchNLastAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(popupEdge!=null) {
popupEdge.setMultipleMatch(DocEdge.MATCH_N_TIL_LAST);
//popupEdge.setMatchN(true);
//docGBPanel.completeEltSet.setMatchN(popupEdge, true);
}
}
};
menuItem.addActionListener(matchNLastAction);
edgePopup.add(menuItem);
edgePopup.addSeparator();
String itemText = "Remove from instance";
menuItem = new JCheckBoxMenuItem(itemText, popupEdge.isRemoveFromInstance());
ActionListener removeFromInstanceAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(popupEdge!=null) {
if (popupEdge.isRemoveFromInstance())
popupEdge.setRemoveFromInstance(false);
//docGBPanel.completeEltSet.setRemoveFromInstance(popupEdge, false);
else
popupEdge.setRemoveFromInstance(true);
//docGBPanel.completeEltSet.setRemoveFromInstance(popupEdge, true);
}
System.out.println("2popupEdge.isRemoveFromInstance()" +popupEdge.isRemoveFromInstance());
}
};
menuItem.addActionListener(removeFromInstanceAction);
edgePopup.add(menuItem);
edgePopup.addSeparator();
menuItem = new JMenuItem("Clear all edits");
ActionListener clearAllAction = new ActionListener() {
public void actionPerformed(ActionEvent e)
{
docGBPanel.completeEltSet.clearWrapperEdits();
}
};
menuItem.addActionListener(clearAllAction);
edgePopup.add(menuItem);
//addHelpMenuItem(edgePopup);
edgePopup.addPopupMenuListener(new PopupMenuListener() {
public void popupMenuCanceled(PopupMenuEvent e) {}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
tgPanel.setMaintainMouseOver(false);
tgPanel.setMouseOverE(null);
tgPanel.repaint();
}
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
});
}
private void setUpBackPopup() {
if (editMode)
{
backPopup = new JPopupMenu();
JMenuItem menuItem;
menuItem = new JMenuItem("Enter Edit Mode");
//menuItem = new JMenuItem("Enter Edit Mode");
ActionListener editAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
deactivate();
docGBPanel.tgUIManager.activate("Edit");
// tvaePVPanel.editUI.activate();
}
};
menuItem.addActionListener(editAction);
backPopup.add(menuItem);
//addHelpMenuItem(backPopup);
backPopup.addPopupMenuListener(new PopupMenuListener() {
public void popupMenuCanceled(PopupMenuEvent e) {}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
tgPanel.setMaintainMouseOver(false);
tgPanel.setMouseOverE(null);
tgPanel.repaint();
}
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
});
}
else
{
backPopup = new JPopupMenu();
JMenuItem menuItem = new JMenuItem("Clear all edits");
ActionListener clearAllAction = new ActionListener() {
public void actionPerformed(ActionEvent e)
{
docGBPanel.completeEltSet.clearWrapperEdits();
}
};
menuItem.addActionListener(clearAllAction);
backPopup.add(menuItem);
}
}
public void setEditMode(boolean b)
{
editMode = b;
setUpBackPopup();
}
public boolean getEditMode()
{
return editMode;
}
}