/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.gef.tool; import static org.xmind.gef.GEF.ST_ACTIVE; import static org.xmind.gef.GEF.ST_ALT_PRESSED; import static org.xmind.gef.GEF.ST_CONTROL_PRESSED; import static org.xmind.gef.GEF.ST_SHIFT_PRESSED; import java.util.List; import org.eclipse.swt.SWT; import org.xmind.gef.EditDomain; import org.xmind.gef.IViewer; import org.xmind.gef.Request; import org.xmind.gef.event.DragDropEvent; import org.xmind.gef.event.KeyEvent; import org.xmind.gef.event.MouseDragEvent; import org.xmind.gef.event.MouseEvent; import org.xmind.gef.event.MouseWheelEvent; import org.xmind.gef.part.IPart; import org.xmind.gef.part.IRootPart; import org.xmind.gef.status.IStatusMachine; import org.xmind.gef.status.StatusMachine2; /** * @author Brian Sun */ public abstract class AbstractTool implements ITool, IDragDropHandler { // private String type; private EditDomain domain = null; private IStatusMachine statusMachine = null; private String contextId = null; // private IViewer targetViewer = null; // private List<Request> requestQueue = new ArrayList<Request>(5); // // private boolean handlingQueue = false; // public void setType(String type) { // this.type = type; // } // // public String getType() { // return type; // } /** * @return the contextId */ public String getContextId() { return contextId; } /** * @param contextId * the contextId to set */ public void setContextId(String contextId) { this.contextId = contextId; } public EditDomain getDomain() { return domain; } public void setDomain(EditDomain domain) { this.domain = domain; } public IViewer getTargetViewer() { // if (targetViewer == null) { // targetViewer = getDomain().getViewer(); // } return getDomain().getTargetViewer(); } public void setTargetViewer(IViewer viewer) { getDomain().setTargetViewer(viewer); } /** * <b>IMPORTANT: </b> this method is not intended to be subclassed and * should only be called by EditDomain. Clients may extend the protected * method {@link #onActivated(ITool)} instead. * * @see org.xmind.gef.tool.ITool#activate(ITool) */ public final void activate(ITool prevTool) { if (getStatus().isStatus(ST_ACTIVE)) return; getStatus().setStatus(ST_ACTIVE, true); onActivated(prevTool); } /** * <b>IMPORTANT: </b> this method is not intended to be subclassed and * should only be called by EditDomain. Clients may extend the protected * method {@link #onDeactivated(ITool)} instead. * * @see org.xmind.gef.tool.ITool#deactivate(ITool) */ public final void deactivate(ITool nextTool) { if (!getStatus().isStatus(ST_ACTIVE)) return; getStatus().setStatus(ST_ACTIVE, false); onDeactivated(nextTool); } /** * This method is called after the activation of this tool and may by * extended clients. * * @param prevTool */ protected void onActivated(ITool prevTool) { } /** * This method is called after the deactivation of this tool and may by * extended by clients. * * @param nextTool */ protected void onDeactivated(ITool nextTool) { if (nextTool != null) { copyStatus(nextTool); } } /** * @param next */ protected ITool copyStatus(ITool next) { if (next instanceof AbstractTool) { IStatusMachine nextStatus = ((AbstractTool) next).getStatus(); IStatusMachine status = getStatus(); copyStatus(ST_CONTROL_PRESSED, status, nextStatus); copyStatus(ST_SHIFT_PRESSED, status, nextStatus); copyStatus(ST_ALT_PRESSED, status, nextStatus); ((AbstractTool) next).setTargetViewer(getTargetViewer()); } return next; } /** * @return the statusMachine */ public IStatusMachine getStatus() { if (statusMachine == null) { statusMachine = new StatusMachine2(); } return statusMachine; } /** * @param key * @param fromStatus * @param toStatus */ private void copyStatus(int key, IStatusMachine fromStatus, IStatusMachine toStatus) { toStatus.setStatus(key, fromStatus.isStatus(key)); } public ITool changeActiveTool(String toolType) { domain.setActiveTool(toolType); return domain.getActiveTool(); } protected ITool getTool(String toolType) { return domain.getTool(toolType); } /** * @see org.xmind.gef.tool.ITool#focusGained() */ public void focusGained(IViewer viewer) { setTargetViewer(viewer); handleFocusGained(); } protected boolean handleFocusGained() { return false; } /** * @see org.xmind.gef.tool.ITool#focusLost() */ public void focusLost(IViewer viewer) { setTargetViewer(viewer); handleFocusLost(); } protected boolean handleFocusLost() { return false; } /** * @see org.xmind.gef.tool.ITool#keyDown(org.xmind.gef.event.KeyEvent) */ public void keyDown(KeyEvent ke, IViewer viewer) { setTargetViewer(viewer); captureModifier(ke, true); handleKeyDown(ke); } protected boolean handleKeyDown(KeyEvent ke) { return false; } /** * @see org.xmind.gef.tool.ITool#keyUp(org.xmind.gef.event.KeyEvent) */ public void keyUp(KeyEvent ke, IViewer viewer) { setTargetViewer(viewer); captureModifier(ke, false); handleKeyUp(ke); } protected boolean handleKeyUp(KeyEvent ke) { return false; } protected void captureModifier(KeyEvent ke, boolean pressed) { if ((ke.keyCode & SWT.MOD1) != 0) getStatus().setStatus(ST_CONTROL_PRESSED, pressed); if ((ke.keyCode & SWT.MOD2) != 0) getStatus().setStatus(ST_SHIFT_PRESSED, pressed); if ((ke.keyCode & SWT.MOD3) != 0) getStatus().setStatus(ST_ALT_PRESSED, pressed); } protected void captureModifier(MouseEvent me) { getStatus().setStatus(ST_CONTROL_PRESSED, me.isState(SWT.MOD1)); getStatus().setStatus(ST_SHIFT_PRESSED, me.isState(SWT.MOD2)); getStatus().setStatus(ST_ALT_PRESSED, me.isState(SWT.MOD3)); } /** * @see org.xmind.gef.tool.ITool#keyTraversed(org.xmind.gef.event.KeyEvent) */ public void keyTraversed(KeyEvent ke, IViewer viewer) { setTargetViewer(viewer); handleKeyTraversed(ke); } protected boolean handleKeyTraversed(KeyEvent ke) { return false; } /** * @see org.xmind.gef.tool.ITool#mouseDoubleClick(org.xmind.gef.event.MouseEvent) */ public void mouseDoubleClick(MouseEvent me, IViewer viewer) { setTargetViewer(viewer); captureModifier(me); handleMouseDoubleClick(me); } protected boolean handleMouseDoubleClick(MouseEvent me) { return false; } /** * @see org.xmind.gef.tool.ITool#mouseDown(org.xmind.gef.event.MouseEvent) */ public void mouseDown(MouseEvent me, IViewer viewer) { setTargetViewer(viewer); captureModifier(me); handleMouseDown(me); } protected boolean handleMouseDown(MouseEvent me) { return false; } /** * @see org.xmind.gef.tool.ITool#mouseLongPressed(org.xmind.gef.event.MouseEvent) */ public void mouseLongPressed(MouseEvent me, IViewer viewer) { setTargetViewer(viewer); captureModifier(me); handleLongPressed(me); } protected boolean handleLongPressed(MouseEvent me) { return false; } /** * @see org.xmind.gef.tool.ITool#mouseDrag(org.xmind.gef.event.MouseEvent) */ public void mouseDrag(MouseDragEvent me, IViewer viewer) { setTargetViewer(viewer); captureModifier(me); handleMouseDrag(me); } protected boolean handleMouseDrag(MouseDragEvent me) { return false; } /** * @see org.xmind.gef.tool.ITool#mouseHover(org.xmind.gef.event.MouseEvent) */ public void mouseHover(MouseEvent me, IViewer viewer) { setTargetViewer(viewer); captureModifier(me); handleMouseHover(me); } protected boolean handleMouseHover(MouseEvent me) { return false; } /** * @see org.xmind.gef.tool.ITool#mouseMove(org.xmind.gef.event.MouseEvent) */ public void mouseMove(MouseEvent me, IViewer viewer) { setTargetViewer(viewer); captureModifier(me); handleMouseMove(me); } protected boolean handleMouseMove(MouseEvent me) { return false; } /** * @see org.xmind.gef.tool.ITool#mouseUp(org.xmind.gef.event.MouseEvent) */ public void mouseUp(MouseEvent me, IViewer viewer) { setTargetViewer(viewer); captureModifier(me); handleMouseUp(me); } protected boolean handleMouseUp(MouseEvent me) { return false; } /** * @see org.xmind.gef.tool.ITool#mouseEntered(org.xmind.gef.event.MouseEvent) */ public void mouseEntered(MouseEvent me, IViewer viewer) { setTargetViewer(viewer); captureModifier(me); handleMouseEntered(me); } protected boolean handleMouseEntered(MouseEvent me) { return false; } /** * @see org.xmind.gef.tool.ITool#mouseExited(org.xmind.gef.event.MouseEvent) */ public void mouseExited(MouseEvent me, IViewer viewer) { setTargetViewer(viewer); captureModifier(me); handleMouseExited(me); } protected boolean handleMouseExited(MouseEvent me) { return false; } /** * @see org.xmind.gef.tool.ITool#mouseWheelScrolled(org.xmind.gef.event.MouseWheelEvent) */ public void mouseWheelScrolled(MouseWheelEvent me, IViewer viewer) { setTargetViewer(viewer); captureModifier(me); handleWheelScrolled(me); } protected boolean handleWheelScrolled(MouseWheelEvent me) { return false; } /** * @see org.xmind.gef.tool.IDragDropHandler#dragEntered(org.xmind.gef.event.DragDropEvent) */ public void dragEntered(DragDropEvent de, IViewer viewer) { setTargetViewer(viewer); handleDragEntered(de); } protected boolean handleDragEntered(DragDropEvent de) { return false; } /** * @see org.xmind.gef.tool.IDragDropHandler#dragExited(org.xmind.gef.event.DragDropEvent) */ public void dragExited(DragDropEvent de, IViewer viewer) { setTargetViewer(viewer); handleDragExited(de); } protected boolean handleDragExited(DragDropEvent de) { return false; } /** * @see org.xmind.gef.tool.IDragDropHandler#dragOver(org.xmind.gef.event.DragDropEvent) */ public void dragOver(DragDropEvent de, IViewer viewer) { setTargetViewer(viewer); handleDragOver(de); } protected boolean handleDragOver(DragDropEvent de) { return false; } /** * @see org.xmind.gef.tool.IDragDropHandler#dragOperationChanged(org.xmind.gef.event.DragDropEvent) */ public void dragOperationChanged(DragDropEvent de, IViewer viewer) { setTargetViewer(viewer); handleDragOperationChanged(de); } protected boolean handleDragOperationChanged(DragDropEvent de) { return false; } /** * @see org.xmind.gef.tool.IDragDropHandler#drop(org.xmind.gef.event.DragDropEvent) */ public void drop(DragDropEvent de, IViewer viewer) { setTargetViewer(viewer); handleDrop(de); } protected boolean handleDrop(DragDropEvent de) { return false; } /** * @see org.xmind.gef.tool.IDragDropHandler#dropAccept(org.xmind.gef.event.DragDropEvent) */ public void dropAccept(DragDropEvent de, IViewer viewer) { setTargetViewer(viewer); handleDropAccept(de); } protected boolean handleDropAccept(DragDropEvent de) { return false; } public void dragDismissed(DragDropEvent de, IViewer viewer) { setTargetViewer(viewer); handleDragDismissed(de); } protected boolean handleDragDismissed(DragDropEvent de) { return false; } public void dragStarted(DragDropEvent de, IViewer viewer) { setTargetViewer(viewer); handleDragStarted(de); } protected boolean handleDragStarted(DragDropEvent de) { return false; } /** * @deprecated see {@link ITool#handleRequest(String, IViewer)} */ public final void handleRequest(String requestType, IViewer targetViewer) { // setTargetViewer(targetViewer); // Request request = new Request(requestType); // request.setViewer(targetViewer); // handleRequest(request); getDomain().handleRequest(requestType, targetViewer); } /** * @see org.xmind.gef.tool.ITool#handleRequest(org.xmind.gef.Request) */ public final void handleRequest(Request request) { setTargetViewer(request.getTargetViewer()); internalHandleRequest(request); } protected void internalHandleRequest(Request request) { if (request.hasTargets()) { handleTargetedRequest(request); } else { handleNonTargetedRequest(request); } } // protected final void handleSingleRequest(Request request) { // if (request.getTargetViewer() == null) { // request.setViewer(getTargetViewer()); // } // if (request.getTargetDomain() == null) { // request.setDomain(getDomain()); // } // } protected void handleTargetedRequest(Request request) { IPart target = request.getPrimaryTarget(); String role = getDomain().getPartRoles().getRole(request.getType()); if (target == null || target instanceof IRootPart) { if (role != null) { target = findPartByRole(role, target == null ? request .getTargetViewer().getRootPart() : target); } } if (target != null) { target.handleRequest(request, role); } } protected void handleNonTargetedRequest(Request request) { String type = request.getType(); String role = getDomain().getPartRoles().getRole(type); if (role != null) { IPart part = findPartByRole(role, request.getTargetViewer() .getRootPart()); if (part != null && part.hasRole(role)) { part.handleRequest(request, role); } } } protected IPart findPartByRole(String role, IPart parent) { for (IPart p : parent.getChildren()) { if (p.hasRole(role)) return p; IPart child = findPartByRole(role, p); if (child != null) return child; } return null; } protected Request createTargetedRequest(String type, IViewer viewer, boolean includeRootPartIfEmpty) { return fillTargets( new Request(type).setViewer(viewer).setDomain(getDomain()), viewer, includeRootPartIfEmpty); } protected Request fillTargets(Request request, IViewer viewer, boolean includeRootPartIfEmpty) { List<IPart> parts = getSelectedParts(viewer); if (parts.isEmpty()) { if (includeRootPartIfEmpty) request.setPrimaryTarget(viewer.getRootPart()); } else { request.setTargets(parts); // IPart focusedPart = viewer.getFocusedPart(); // if (parts.contains(focusedPart)) // request.setPrimaryTarget(focusedPart); } return request; } protected List<IPart> getSelectedParts(IViewer viewer) { return viewer.getSelectionSupport().getPartSelection(); } }