/******************************************************************************* * Copyright (c) 2004, 2005 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.gef.examples.text.tools; import org.eclipse.swt.graphics.Cursor; import org.eclipse.draw2d.Cursors; import org.eclipse.gef.EditPart; import org.eclipse.gef.tools.SimpleDragTracker; import org.eclipse.gef.tools.ToolUtilities; import org.eclipse.gef.examples.text.GraphicalTextViewer; import org.eclipse.gef.examples.text.SelectionRange; import org.eclipse.gef.examples.text.TextLocation; import org.eclipse.gef.examples.text.edit.TextEditPart; import org.eclipse.gef.examples.text.requests.CaretRequest; import org.eclipse.gef.examples.text.requests.SearchResult; /** * @since 3.1 */ public class SelectionRangeDragTracker extends SimpleDragTracker { private static final int STATE_START = SimpleDragTracker.MAX_STATE << 1; private static final int STATE_SWIPE = SimpleDragTracker.MAX_STATE << 2; private TextLocation beginDrag; private TextLocation endDrag; /** * This flag is set to true during a double-click-swipe. */ private boolean isWordSelection; private final TextEditPart textSource; /** * @since 3.1 */ public SelectionRangeDragTracker(TextEditPart part) { this.textSource = part; } protected Cursor calculateCursor() { return Cursors.IBEAM; } /** * * @since 3.1 */ private void doNormalSwipe() { SearchResult result = getCurrentTextLocation(); endDrag = result.location; if (endDrag != null) { //Previous EditPart end = endDrag.part; EditPart begin = beginDrag.part; boolean inverted = false; if (end == begin) inverted = endDrag.offset < beginDrag.offset; else { EditPart ancestor = ToolUtilities.findCommonAncestor(end, begin); while (end.getParent() != ancestor) end = end.getParent(); while (begin.getParent() != ancestor) begin = begin.getParent(); inverted = ancestor.getChildren().indexOf(end) < ancestor.getChildren().indexOf(begin); } GraphicalTextViewer viewer = (GraphicalTextViewer)getCurrentViewer(); if (!inverted) viewer.setSelectionRange(new SelectionRange(beginDrag, endDrag, true, result.trailing)); else viewer.setSelectionRange(new SelectionRange(endDrag, beginDrag, false, result.trailing)); } } /** * Selects the word at the current mouse location * @since 3.1 */ private void doWordSelect() { SearchResult result = new SearchResult(); CaretRequest locationRequest = new CaretRequest(); locationRequest.setType(CaretRequest.LOCATION); locationRequest.setLocation(getLocation()); locationRequest.isForward = true; getSource().getTextLocation(locationRequest, result); TextLocation exact = result.location; CaretRequest nextWord = new CaretRequest(); result = new SearchResult(); nextWord.setType(CaretRequest.WORD_BOUNDARY); nextWord.isForward = true; nextWord.where = exact; getSource().getTextLocation(nextWord, result); TextLocation wordEnd = result.location; boolean isAfter = result.trailing; result = new SearchResult(); nextWord.where = wordEnd; nextWord.isForward = false; getSource().getTextLocation(nextWord, result); TextLocation wordBegin = result.location; if (wordBegin != null && wordEnd != null) ((GraphicalTextViewer)getCurrentViewer()).setSelectionRange( new SelectionRange(wordBegin, wordEnd, true, isAfter)); } /** * @since 3.1 */ private void doWordSwipe() { } protected String getCommandName() { return "Drop Text Request"; } private SearchResult getCurrentTextLocation() { SearchResult result = new SearchResult(); EditPart part = getCurrentViewer().findObjectAt(getLocation()); if (part instanceof TextEditPart) { TextEditPart textPart = (TextEditPart)part; if (textPart.acceptsCaret()) { CaretRequest request = new CaretRequest(); request.setType(CaretRequest.LOCATION); request.setLocation(getLocation()); textPart.getTextLocation(request, result); } } return result; } /** * * @since 3.1 */ private TextEditPart getSource() { return textSource; } protected boolean handleButtonDown(int button) { if (button == 1) { SearchResult result = getCurrentTextLocation(); beginDrag = result.location; ((GraphicalTextViewer)getCurrentViewer()).setSelectionRange( new SelectionRange(beginDrag, beginDrag, true, result.trailing)); return stateTransition(STATE_INITIAL, STATE_START); } return super.handleButtonDown(button); } protected boolean handleDoubleClick(int button) { if (button == 1) { doWordSelect(); isWordSelection = true; return true; } return super.handleDoubleClick(button); } protected boolean handleDragInProgress() { //$TODO during a swipe, the viewer should not be firing selection changes the whole time. if (isInState(STATE_SWIPE)) { if (isWordSelection) doWordSwipe(); else doNormalSwipe(); } return super.handleDragInProgress(); } protected boolean handleDragStarted() { return stateTransition(STATE_START, STATE_SWIPE); } }