package org.freeplane.plugin.workspace.mindmapmode; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.swing.JTree; import javax.swing.KeyStroke; import javax.swing.tree.TreePath; import org.freeplane.core.ui.AFreeplaneAction; import org.freeplane.core.util.LogUtils; import org.freeplane.plugin.workspace.WorkspaceController; import org.freeplane.plugin.workspace.actions.NodeCopyAction; import org.freeplane.plugin.workspace.actions.NodeCutAction; import org.freeplane.plugin.workspace.actions.NodePasteAction; import org.freeplane.plugin.workspace.actions.NodeRefreshAction; import org.freeplane.plugin.workspace.actions.NodeRemoveAction; import org.freeplane.plugin.workspace.actions.NodeRenameAction; import org.freeplane.plugin.workspace.components.TreeView; import org.freeplane.plugin.workspace.components.WorkspaceNodeRenderer; import org.freeplane.plugin.workspace.dnd.DnDController; import org.freeplane.plugin.workspace.event.IWorkspaceNodeActionListener; import org.freeplane.plugin.workspace.event.WorkspaceActionEvent; import org.freeplane.plugin.workspace.model.AWorkspaceTreeNode; public class InputController implements KeyListener, MouseListener, MouseMotionListener { // WORKSPACE - ToDo: implement gui for hot-key handling private Map<HotKeyIdentifier, String> actionKeyMap = new LinkedHashMap<InputController.HotKeyIdentifier, String>(); private TreePath lastSelection = null; /*********************************************************************************** * CONSTRUCTORS **********************************************************************************/ public InputController() { initActionKeyMap(); } /*********************************************************************************** * METHODS **********************************************************************************/ public final TreePath getLastSelectionPath() { return lastSelection; } /*********************************************************************************** * REQUIRED METHODS FOR INTERFACES **********************************************************************************/ public void mouseClicked(MouseEvent e) { if (e.isConsumed()) { return; } TreePath path = ((JTree) e.getSource()).getClosestPathForLocation(e.getX(), e.getY()); ((TreeView) WorkspaceController.getCurrentModeExtension().getView()).addSelectionPath(path); if (path != null) { AWorkspaceTreeNode node = (AWorkspaceTreeNode) path.getLastPathComponent(); // encode buttons int eventType = 0; if (e.getButton() == MouseEvent.BUTTON1) { eventType += WorkspaceActionEvent.MOUSE_LEFT; } if (e.getButton() == MouseEvent.BUTTON3) { eventType += WorkspaceActionEvent.MOUSE_RIGHT; } if (e.getClickCount() % 2 == 0) { eventType += WorkspaceActionEvent.MOUSE_DBLCLICK; } else { eventType += WorkspaceActionEvent.MOUSE_CLICK; } if (e.isPopupTrigger()) { eventType += WorkspaceActionEvent.POPUP_TRIGGER; } WorkspaceActionEvent event = new WorkspaceActionEvent(node, eventType, e.getX(), e.getY(), e.getComponent()); List<IWorkspaceNodeActionListener> nodeEventListeners = WorkspaceController.getCurrentModeExtension().getIOController() .getNodeActionListeners(node.getClass(), eventType); if (nodeEventListeners != null) { for (IWorkspaceNodeActionListener listener : nodeEventListeners) { if (event.isConsumed()) { break; } listener.handleAction(event); } } if (!event.isConsumed() && node instanceof IWorkspaceNodeActionListener) { ((IWorkspaceNodeActionListener) node).handleAction(event); } } else { if (e.getButton() == MouseEvent.BUTTON3) { // WorkspaceController.getController().getPopups().showWorkspacePopup(e.getComponent(), e.getX(), e.getY()); ((AWorkspaceTreeNode) WorkspaceController.getCurrentModel().getRoot()).showPopup(e.getComponent(), e.getX(), e.getY()); } } } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mouseDragged(MouseEvent e) { } public void mouseMoved(MouseEvent e) { JTree tree = ((JTree) e.getSource()); TreePath path = tree.getPathForLocation(e.getX(), e.getY()); if (path == getLastSelectionPath()) { return; } WorkspaceNodeRenderer renderer = (WorkspaceNodeRenderer) tree.getCellRenderer(); if (path != null && path != getLastSelectionPath()) { lastSelection = path; renderer.highlightRow(tree.getRowForLocation(e.getX(), e.getY())); tree.repaint(); } else if (getLastSelectionPath() != null) { lastSelection = null; renderer.highlightRow(-1); tree.repaint(); } } /********* * Keyboard events */ private void initActionKeyMap() { actionKeyMap.put(new HotKeyIdentifier("copy", KeyStroke.getKeyStroke(KeyEvent.VK_C, /*KeyEvent.CTRL_DOWN_MASK*/Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())), NodeCopyAction.KEY); actionKeyMap.put(new HotKeyIdentifier("cut", KeyStroke.getKeyStroke(KeyEvent.VK_X, /*KeyEvent.CTRL_DOWN_MASK*/Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())),NodeCutAction.KEY); actionKeyMap.put(new HotKeyIdentifier("paste", KeyStroke.getKeyStroke(KeyEvent.VK_V, /*KeyEvent.CTRL_DOWN_MASK*/Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),new KeyEventAcceptor() { public boolean accept(KeyEvent e) { TreePath path = ((JTree) e.getSource()).getSelectionPath(); if (path == null) { return false; } AWorkspaceTreeNode node = (AWorkspaceTreeNode) path.getLastPathComponent(); if(DnDController.isDropAllowed(node)) { return true; } return false; } }), NodePasteAction.KEY); actionKeyMap.put(new HotKeyIdentifier("delete", KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), new KeyEventAcceptor() { public boolean accept(KeyEvent e) { TreePath path = ((JTree) e.getSource()).getSelectionPath(); if (path == null) { return false; } AWorkspaceTreeNode node = (AWorkspaceTreeNode) path.getLastPathComponent(); if(!node.isSystem() && node.isTransferable()) { return true; } return false; } }), NodeRemoveAction.KEY); actionKeyMap.put(new HotKeyIdentifier("rename", KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0), new KeyEventAcceptor() { public boolean accept(KeyEvent event) { TreePath path = ((JTree) event.getSource()).getSelectionPath(); if (path == null) { return false; } AWorkspaceTreeNode node = (AWorkspaceTreeNode) path.getLastPathComponent(); if(!node.isSystem()) { return true; } return false; } }), NodeRenameAction.KEY); actionKeyMap.put(new HotKeyIdentifier("refresh", KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0)), NodeRefreshAction.KEY); } public void keyTyped(KeyEvent e) { } public void keyPressed(KeyEvent e) { KeyStroke currentStroke = KeyStroke.getKeyStrokeForEvent(e); if (e.getKeyCode() == KeyEvent.VK_ENTER) { TreePath path = ((JTree) e.getSource()).getSelectionPath(); if (path == null) { return; } AWorkspaceTreeNode node = (AWorkspaceTreeNode) path.getLastPathComponent(); if (node instanceof IWorkspaceNodeActionListener) { ((IWorkspaceNodeActionListener) node).handleAction(new WorkspaceActionEvent(node, WorkspaceActionEvent.WSNODE_OPEN_DOCUMENT, 0, 0, e .getComponent())); e.consume(); } } else { for(HotKeyIdentifier id : actionKeyMap.keySet()) { if(currentStroke.equals(id.getKeyStroke())) { if(id.accept(e)) { AFreeplaneAction action = WorkspaceController.getAction(actionKeyMap.get(id)); if(action != null) { action.actionPerformed(new ActionEvent(e.getSource(), 0, null)); } else { LogUtils.info("No action set for: "+ id.getKeyStroke()); } } e.consume(); break; } } } } public void keyReleased(KeyEvent e) { } class HotKeyIdentifier { private final KeyStroke stroke; private final String identifier; private final KeyEventAcceptor acceptor; public HotKeyIdentifier(String id, KeyStroke stroke) { this(id, stroke, null); } public HotKeyIdentifier(String id, KeyStroke stroke, KeyEventAcceptor acceptor) { this.identifier = id; this.stroke = stroke; this.acceptor = acceptor; } public boolean accept(KeyEvent e) { if(this.acceptor == null) { return true; } return this.acceptor.accept(e); } public KeyStroke getKeyStroke() { return this.stroke; } public String getIdentifier() { return this.identifier; } //WORKSPACE - ToDo: localization // public String getLocalizedIdentifier() { // return TextUtils.getText("workspace.key.action."+getIdentifier().toLowerCase(Locale.ENGLISH)); // } } interface KeyEventAcceptor { public boolean accept(KeyEvent event); } }