/******************************************************************************* * 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; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.eclipse.swt.widgets.Caret; import org.eclipse.jface.util.Assert; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.draw2d.LightweightSystem; import org.eclipse.draw2d.Viewport; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gef.EditDomain; import org.eclipse.gef.EditPart; import org.eclipse.gef.commands.CommandStack; import org.eclipse.gef.commands.CommandStackEvent; import org.eclipse.gef.commands.CommandStackEventListener; import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer; /** * @since 3.1 */ public class GraphicalTextViewer extends ScrollingGraphicalViewer { private SelectionModel selectionModel; /** * Returns the viewers selection range by <em>reference</em>. The range should not be * modified directly. * @since 3.1 * @return the current selection by reference * @deprecated in 3.2. @TODO:Pratik remove this method and all references to it. Use * getSelectionModel() instead. */ public SelectionRange getSelectionRange() { if (selectionModel != null) return selectionModel.getSelectionRange(); return null; } public void revealCaret() { Assert.isNotNull(getControl(), "The control has not been created yet."); Caret caret = getFigureCanvas().getCaret(); if (caret == null || !caret.isVisible()) return; // @TODO:Pratik you should expose the text location first (it might not be visible) Viewport port = getFigureCanvas().getViewport(); Rectangle view = new Rectangle(port.getViewLocation(), port.getClientArea().getSize()); Rectangle exposeRegion = new Rectangle(caret.getBounds()); port.getContents().translateToRelative(exposeRegion); if (!view.contains(exposeRegion)) { int x = view.x, y = view.y; if (exposeRegion.x < view.x) x = exposeRegion.x; else if (exposeRegion.right() > view.right()) x = view.x + exposeRegion.right() - view.right(); if (exposeRegion.y < view.y) y = exposeRegion.y; else if (exposeRegion.bottom() > view.bottom()) y = view.y + exposeRegion.bottom() - view.bottom(); getFigureCanvas().scrollTo(x, y); } } /** * Sets the selection range to the given value. Updates any editparts which had or will * have textual selection. Fires selection changed. Place the caret in the appropriate * location. * * @since 3.1 * @param newRange the new selection range * @deprecated in 3.2. @TODO:Pratik remove this method and all references to it. Use * setSelectionModel() instead. */ public void setSelectionRange(SelectionRange newRange) { // @TODO:Pratik change all these setSelection() methods so that they don't affect // any other selection. So, setting selectionRange to null would not clear the // selected editparts. SelectionModel newModel = null; if (newRange != null) newModel = createSelectionModel(null, newRange, selectionModel == null ? null : selectionModel.getSelectedEditParts(), null); setSelectionModel(newModel); } public SelectionModel getSelectionModel() { return selectionModel; } public void setSelectionModel(SelectionModel selection) { if (selection != null) { // setFocus(selection.getFocusPart()); selection.applySelection(selectionModel); } else if (selectionModel != null) { setFocus(null); selectionModel.deselect(); } selectionModel = selection; fireSelectionChanged(); } public void appendSelection(EditPart editpart) { if (focusPart != editpart) setFocus(null); if (selectionModel != null) setSelectionModel(selectionModel.getAppendedSelection(editpart)); else select(editpart); } public void deselect(EditPart editpart) { if (selectionModel != null) setSelectionModel(selectionModel.getExcludedSelection(editpart)); } public void deselectAll() { setSelectionModel(null); } public void select(EditPart editpart) { if (focusPart != editpart) setFocus(null); ArrayList list = new ArrayList(); list.add(editpart); setSelectionModel(createSelectionModel(null, null, list, null)); } // @TODO:Pratik Hack. This shouldn't be here. CommandStack should be doing this automatically. // You can make that change once you remove the GraphicalTextViewer class. public void setEditDomain(EditDomain domain) { super.setEditDomain(domain); getEditDomain().getCommandStack().addCommandStackEventListener(new CommandStackEventListener() { public void stackChanged(CommandStackEvent event) { if (!(event.getCommand() instanceof TextCommand) || getSelectionRange() == null) return; TextCommand command = (TextCommand)event.getCommand(); if (command != null) { if (event.getDetail() == CommandStack.POST_EXECUTE) setSelectionRange( command.getExecuteSelectionRange(GraphicalTextViewer.this)); else if (event.getDetail() == CommandStack.POST_REDO) setSelectionRange( command.getRedoSelectionRange(GraphicalTextViewer.this)); else if (event.getDetail() == CommandStack.POST_UNDO) setSelectionRange( command.getUndoSelectionRange(GraphicalTextViewer.this)); } } }); } public void setSelection(ISelection newSelection) { if (newSelection != null) setSelectionModel(createSelectionModel(newSelection, null, null, null)); else setSelectionModel(null); } public ISelection getSelection() { if (selectionModel != null) return selectionModel.getSelection(); return new StructuredSelection(getContents()); } protected SelectionModel createSelectionModel(ISelection selection, SelectionRange range, List parts, EditPart container) { if (selection instanceof IStructuredSelection) return new SelectionModel(selection); return new SelectionModel(range, parts, container); } /** * @see org.eclipse.gef.ui.parts.AbstractEditPartViewer#getSelectedEditParts() */ public List getSelectedEditParts() { return primGetSelectedEditParts(); } /** * The method returns the same list as getSelectedEditParts(). The list is unmodifiable. * @deprecated * @see org.eclipse.gef.ui.parts.AbstractEditPartViewer#primGetSelectedEditParts() */ protected List primGetSelectedEditParts() { if (selectionModel != null) return selectionModel.getSelectedEditParts(); return Collections.EMPTY_LIST; } public boolean isTextSelected() { return selectionModel != null && selectionModel.isTextSelected(); } protected LightweightSystem getLightweightSystem() { return super.getLightweightSystem(); } }