|
@@ -0,0 +1,683 @@
|
|
|
+/******************************************************************************
|
|
|
+ * Copyright (c) 2002, 2010 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
|
|
|
+ * Dmitry Stadnik (Borland) - contribution for bugzilla 135694
|
|
|
+ ****************************************************************************/
|
|
|
+
|
|
|
+package de.itemis.xtext.utils.gmf.directedit;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Iterator;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+import org.eclipse.core.runtime.Assert;
|
|
|
+import org.eclipse.draw2d.AncestorListener;
|
|
|
+import org.eclipse.draw2d.IFigure;
|
|
|
+import org.eclipse.draw2d.PositionConstants;
|
|
|
+import org.eclipse.draw2d.TextUtilities;
|
|
|
+import org.eclipse.draw2d.geometry.Dimension;
|
|
|
+import org.eclipse.draw2d.geometry.Rectangle;
|
|
|
+import org.eclipse.gef.GraphicalEditPart;
|
|
|
+import org.eclipse.gef.editparts.ZoomManager;
|
|
|
+import org.eclipse.gef.tools.CellEditorLocator;
|
|
|
+import org.eclipse.gef.tools.DirectEditManager;
|
|
|
+import org.eclipse.gmf.runtime.common.core.util.Log;
|
|
|
+import org.eclipse.gmf.runtime.common.core.util.Trace;
|
|
|
+import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIDebugOptions;
|
|
|
+import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIPlugin;
|
|
|
+import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIStatusCodes;
|
|
|
+import org.eclipse.gmf.runtime.diagram.ui.label.ILabelDelegate;
|
|
|
+import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramGraphicalViewer;
|
|
|
+import org.eclipse.gmf.runtime.draw2d.ui.figures.FigureUtilities;
|
|
|
+import org.eclipse.gmf.runtime.draw2d.ui.figures.WrappingLabel;
|
|
|
+import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil;
|
|
|
+import org.eclipse.gmf.runtime.gef.ui.internal.parts.TextCellEditorEx;
|
|
|
+import org.eclipse.jface.action.IAction;
|
|
|
+import org.eclipse.jface.resource.DeviceResourceException;
|
|
|
+import org.eclipse.jface.resource.FontDescriptor;
|
|
|
+import org.eclipse.jface.resource.JFaceResources;
|
|
|
+import org.eclipse.jface.resource.ResourceManager;
|
|
|
+import org.eclipse.jface.viewers.CellEditor;
|
|
|
+import org.eclipse.swt.SWT;
|
|
|
+import org.eclipse.swt.custom.StyledText;
|
|
|
+import org.eclipse.swt.graphics.Color;
|
|
|
+import org.eclipse.swt.graphics.Font;
|
|
|
+import org.eclipse.swt.graphics.FontData;
|
|
|
+import org.eclipse.swt.graphics.Point;
|
|
|
+import org.eclipse.swt.widgets.Composite;
|
|
|
+import org.eclipse.swt.widgets.Control;
|
|
|
+import org.eclipse.swt.widgets.Display;
|
|
|
+import org.eclipse.swt.widgets.Event;
|
|
|
+import org.eclipse.swt.widgets.Shell;
|
|
|
+import org.eclipse.swt.widgets.Table;
|
|
|
+import org.eclipse.ui.IActionBars;
|
|
|
+import org.eclipse.ui.PlatformUI;
|
|
|
+import org.eclipse.ui.actions.ActionFactory;
|
|
|
+import org.eclipse.ui.part.CellEditorActionHandler;
|
|
|
+
|
|
|
+import com.google.inject.Injector;
|
|
|
+
|
|
|
+import de.itemis.xtext.utils.gmf.viewers.XtextCellEditorEx;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author melaasar
|
|
|
+ */
|
|
|
+@SuppressWarnings("restriction")
|
|
|
+public class XtextDirectEditManager extends DirectEditManager {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * content assist background color
|
|
|
+ */
|
|
|
+ private Color proposalPopupBackgroundColor = null;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * content assist foreground color
|
|
|
+ */
|
|
|
+ private Color proposalPopupForegroundColor = null;
|
|
|
+
|
|
|
+ private boolean committed = false;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * flag used to avoid unhooking listeners twice if the UI thread is blocked
|
|
|
+ */
|
|
|
+ private boolean listenersAttached = true;
|
|
|
+
|
|
|
+ /** String buffer to hold initial characters * */
|
|
|
+ private StringBuffer initialString = new StringBuffer();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Cache the font descriptor when a font is created so that it can be
|
|
|
+ * disposed later.
|
|
|
+ */
|
|
|
+ private List<FontDescriptor> cachedFontDescriptors = new ArrayList<FontDescriptor>();
|
|
|
+
|
|
|
+ private IActionBars actionBars;
|
|
|
+
|
|
|
+ private CellEditorActionHandler actionHandler;
|
|
|
+
|
|
|
+ private IAction copy, cut, paste, undo, redo, find, selectAll, delete;
|
|
|
+
|
|
|
+ private Font zoomLevelFont = null;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The superclass only relocates the cell editor when the location of the
|
|
|
+ * editpart's figure moves, but we need to also relocate the cell editor
|
|
|
+ * when the text figure's location changes.
|
|
|
+ */
|
|
|
+ private AncestorListener textFigureListener;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Cache locally so we can check if the user specified an editorType.
|
|
|
+ */
|
|
|
+ private Class<?> editorType;
|
|
|
+
|
|
|
+ private final Injector injector;
|
|
|
+ private final int style;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * constructor
|
|
|
+ *
|
|
|
+ * @param source
|
|
|
+ * <code>GraphicalEditPart</code> to support direct edit of. The
|
|
|
+ * figure of the <code>source</code> edit part must be of type
|
|
|
+ * <code>WrapLabel</code>.
|
|
|
+ */
|
|
|
+ public XtextDirectEditManager(IXtextAwareEditPart source, Injector injector, int style) {
|
|
|
+ this(source, null, getTextCellEditorLocator(source), injector, style);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param source
|
|
|
+ * @param editorType
|
|
|
+ * @param locator
|
|
|
+ */
|
|
|
+ public XtextDirectEditManager(GraphicalEditPart source,
|
|
|
+ Class<?> editorType, CellEditorLocator locator, Injector injector,
|
|
|
+ int style) {
|
|
|
+ super(source, editorType, locator);
|
|
|
+ this.editorType = editorType;
|
|
|
+ this.injector = injector;
|
|
|
+ this.style = style;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param source
|
|
|
+ * the <code>ITextAwareEditPart</code> to determine the cell
|
|
|
+ * editor for
|
|
|
+ * @return the <code>CellEditorLocator</code> that is appropriate for the
|
|
|
+ * source <code>EditPart</code>
|
|
|
+ */
|
|
|
+ public static CellEditorLocator getTextCellEditorLocator(
|
|
|
+ final IXtextAwareEditPart source) {
|
|
|
+
|
|
|
+ final ILabelDelegate label = (ILabelDelegate) source
|
|
|
+ .getAdapter(ILabelDelegate.class);
|
|
|
+ if (label != null) {
|
|
|
+ return new CellEditorLocator() {
|
|
|
+
|
|
|
+ public void relocate(CellEditor celleditor) {
|
|
|
+ StyledText text = (StyledText) celleditor.getControl();
|
|
|
+
|
|
|
+ Rectangle rect = label.getTextBounds().getCopy();
|
|
|
+ if (label.getText().length() <= 0) {
|
|
|
+ // if there is no text, let's assume a default size
|
|
|
+ // of one character because it looks silly when the cell
|
|
|
+ // editor is tiny.
|
|
|
+ rect.setSize(TextUtilities.INSTANCE.getTextExtents(
|
|
|
+ "a", text.getFont())); //$NON-NLS-1$
|
|
|
+
|
|
|
+ if (label.isTextWrapOn()) {
|
|
|
+ // adjust the location of the cell editor based on
|
|
|
+ // text
|
|
|
+ // justification (i.e. where the cursor will be
|
|
|
+ if (label.getTextJustification() == PositionConstants.RIGHT) {
|
|
|
+ rect.translate(-rect.width, 0);
|
|
|
+ } else if (label.getTextJustification() == PositionConstants.CENTER) {
|
|
|
+ rect.translate(-rect.width / 2, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!text.getFont().isDisposed()) {
|
|
|
+ // Font may be disposed if the locator is called while
|
|
|
+ // this manager is being brought down in which case the
|
|
|
+ // calls below that use the font will result in an
|
|
|
+ // exception.
|
|
|
+ if (label.isTextWrapOn()) {
|
|
|
+ // When zoomed in, the height of this rectangle is
|
|
|
+ // not
|
|
|
+ // sufficient because the text is shifted downwards
|
|
|
+ // a
|
|
|
+ // little bit. Add some to the height to compensate
|
|
|
+ // for
|
|
|
+ // this. I'm not sure why this is happening, but I
|
|
|
+ // can
|
|
|
+ // see the text shifting down even in a label on a
|
|
|
+ // GEF
|
|
|
+ // logic diagram when zoomed into 400%.
|
|
|
+ int charHeight = FigureUtilities.getFontMetrics(
|
|
|
+ text.getFont()).getHeight();
|
|
|
+ rect.resize(0, charHeight / 2);
|
|
|
+ } else {
|
|
|
+
|
|
|
+ rect.setSize(new Dimension(text.computeSize(
|
|
|
+ SWT.DEFAULT, SWT.DEFAULT)));
|
|
|
+
|
|
|
+ // If SWT.WRAP is not passed in as a style of the
|
|
|
+ // TextCellEditor, then for some reason the first
|
|
|
+ // character disappears upon entering the second
|
|
|
+ // character. This should be investigated and an
|
|
|
+ // SWT bug logged.
|
|
|
+ int avr = FigureUtilities.getFontMetrics(
|
|
|
+ text.getFont()).getAverageCharWidth();
|
|
|
+ rect.setSize(new Dimension(text.computeSize(
|
|
|
+ SWT.DEFAULT, SWT.DEFAULT)).expand(avr * 2,
|
|
|
+ 0));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ org.eclipse.swt.graphics.Rectangle newRect = text
|
|
|
+ .computeTrim(rect.x, rect.y, rect.width,
|
|
|
+ rect.height);
|
|
|
+ if (!newRect.equals(text.getBounds())) {
|
|
|
+ text.setBounds(newRect.x, newRect.y, newRect.width,
|
|
|
+ newRect.height);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ // return a default figure locator
|
|
|
+ return new CellEditorLocator() {
|
|
|
+ public void relocate(CellEditor celleditor) {
|
|
|
+ StyledText text = (StyledText) celleditor.getControl();
|
|
|
+ Rectangle rect = source.getFigure().getBounds().getCopy();
|
|
|
+ source.getFigure().translateToAbsolute(rect);
|
|
|
+ if (!rect.equals(new Rectangle(text.getBounds()))) {
|
|
|
+ text.setBounds(rect.x, rect.y, rect.width, rect.height);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * This method is overridden so that the editor class can have a style as
|
|
|
+ * the style needs to be passed into the editor class when it is created. It
|
|
|
+ * will default to the super behavior if an <code>editorType</code> was
|
|
|
+ * passed into the constructor.
|
|
|
+ *
|
|
|
+ * @since 2.1
|
|
|
+ */
|
|
|
+ protected CellEditor createCellEditorOn(Composite composite) {
|
|
|
+
|
|
|
+ // if the client has overridden this class and provided their own editor
|
|
|
+ // type, then we should use that
|
|
|
+ if (editorType != null) {
|
|
|
+ return super.createCellEditorOn(composite);
|
|
|
+ }
|
|
|
+
|
|
|
+ XtextCellEditorEx editor = new XtextCellEditorEx(style);
|
|
|
+ injector.injectMembers(editor);
|
|
|
+ editor.create(composite);
|
|
|
+ return editor;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Given a label figure object, this will calculate the correct Font needed
|
|
|
+ * to display into screen coordinates, taking into account the current
|
|
|
+ * mapmode. This will typically be used by direct edit cell editors that
|
|
|
+ * need to display independent of the zoom or any coordinate mapping that is
|
|
|
+ * taking place on the drawing surface.
|
|
|
+ *
|
|
|
+ * @param label
|
|
|
+ * the label to use for the font calculation
|
|
|
+ * @return the <code>Font</code> that is scaled to the screen coordinates.
|
|
|
+ * Note: the returned <code>Font</code> should not be disposed since
|
|
|
+ * it is cached by a common resource manager.
|
|
|
+ */
|
|
|
+ protected Font getScaledFont(IFigure label) {
|
|
|
+ Font scaledFont = label.getFont();
|
|
|
+ FontData data = scaledFont.getFontData()[0];
|
|
|
+ Dimension fontSize = new Dimension(0, MapModeUtil.getMapMode(label)
|
|
|
+ .DPtoLP(data.getHeight()));
|
|
|
+ label.translateToAbsolute(fontSize);
|
|
|
+
|
|
|
+ if (Math.abs(data.getHeight() - fontSize.height) < 2)
|
|
|
+ fontSize.height = data.getHeight();
|
|
|
+
|
|
|
+ try {
|
|
|
+ FontDescriptor fontDescriptor = FontDescriptor.createFrom(data);
|
|
|
+ cachedFontDescriptors.add(fontDescriptor);
|
|
|
+ return getResourceManager().createFont(fontDescriptor);
|
|
|
+ } catch (DeviceResourceException e) {
|
|
|
+ Trace.catching(DiagramUIPlugin.getInstance(),
|
|
|
+ DiagramUIDebugOptions.EXCEPTIONS_CATCHING, getClass(),
|
|
|
+ "getScaledFont", e); //$NON-NLS-1$
|
|
|
+ Log.error(DiagramUIPlugin.getInstance(),
|
|
|
+ DiagramUIStatusCodes.IGNORED_EXCEPTION_WARNING,
|
|
|
+ "getScaledFont", e); //$NON-NLS-1$
|
|
|
+ }
|
|
|
+ return JFaceResources.getDefaultFont();
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void initCellEditor() {
|
|
|
+ committed = false;
|
|
|
+
|
|
|
+ // Get the Text Compartments Edit Part
|
|
|
+
|
|
|
+ setEditText(getEditPart().getEditText());
|
|
|
+
|
|
|
+ IFigure label = getEditPart().getFigure();
|
|
|
+ Assert.isNotNull(label);
|
|
|
+ StyledText text = (StyledText) getCellEditor().getControl();
|
|
|
+ // scale the font accordingly to the zoom level
|
|
|
+ text.setFont(getScaledFont(label));
|
|
|
+
|
|
|
+ // Hook the cell editor's copy/paste actions to the actionBars so that
|
|
|
+ // they can
|
|
|
+ // be invoked via keyboard shortcuts.
|
|
|
+ actionBars = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
|
|
|
+ .getActivePage().getActiveEditor().getEditorSite()
|
|
|
+ .getActionBars();
|
|
|
+ saveCurrentActions(actionBars);
|
|
|
+ actionHandler = new CellEditorActionHandler(actionBars);
|
|
|
+ actionHandler.addCellEditor(getCellEditor());
|
|
|
+ actionBars.updateActionBars();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @see org.eclipse.gef.tools.DirectEditManager#commit()
|
|
|
+ */
|
|
|
+ protected void commit() {
|
|
|
+ Shell activeShell = Display.getCurrent().getActiveShell();
|
|
|
+ if (activeShell != null
|
|
|
+ && getCellEditor().getControl().getShell()
|
|
|
+ .equals(activeShell.getParent())) {
|
|
|
+ Control[] children = activeShell.getChildren();
|
|
|
+ if (children.length == 1 && children[0] instanceof Table) {
|
|
|
+ /*
|
|
|
+ * CONTENT ASSIST: focus is lost to the content assist pop up -
|
|
|
+ * stay in focus
|
|
|
+ */
|
|
|
+ getCellEditor().getControl().setVisible(true);
|
|
|
+ ((XtextCellEditorEx) getCellEditor()).setDeactivationLock(true);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // content assist hacks
|
|
|
+ if (committed) {
|
|
|
+ bringDown();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ committed = true;
|
|
|
+ super.commit();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @see org.eclipse.gef.tools.DirectEditManager#bringDown()
|
|
|
+ */
|
|
|
+ protected void bringDown() {
|
|
|
+ if (proposalPopupForegroundColor != null) {
|
|
|
+ proposalPopupForegroundColor.dispose();
|
|
|
+ proposalPopupForegroundColor = null;
|
|
|
+ }
|
|
|
+ if (proposalPopupBackgroundColor != null) {
|
|
|
+ proposalPopupBackgroundColor.dispose();
|
|
|
+ proposalPopupBackgroundColor = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // myee - RATLC00523014: crashes when queued in asyncExec()
|
|
|
+ eraseFeedback();
|
|
|
+
|
|
|
+ initialString = new StringBuffer();
|
|
|
+
|
|
|
+ Display.getCurrent().asyncExec(new Runnable() {
|
|
|
+
|
|
|
+ public void run() {
|
|
|
+ // Content Assist hack - allow proper cleanup on childen
|
|
|
+ // controls
|
|
|
+ XtextDirectEditManager.super.bringDown();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ for (Iterator<FontDescriptor> iter = cachedFontDescriptors.iterator(); iter
|
|
|
+ .hasNext();) {
|
|
|
+ getResourceManager().destroyFont((FontDescriptor) iter.next());
|
|
|
+ }
|
|
|
+ cachedFontDescriptors.clear();
|
|
|
+
|
|
|
+ if (actionHandler != null) {
|
|
|
+ actionHandler.dispose();
|
|
|
+ actionHandler = null;
|
|
|
+ }
|
|
|
+ if (actionBars != null) {
|
|
|
+ restoreSavedActions(actionBars);
|
|
|
+ actionBars.updateActionBars();
|
|
|
+ actionBars = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * This method is used to set the cell editors text
|
|
|
+ *
|
|
|
+ * @param toEdit
|
|
|
+ * String to be set in the cell editor
|
|
|
+ */
|
|
|
+ public void setEditText(String toEdit) {
|
|
|
+
|
|
|
+ // Get the cell editor
|
|
|
+ CellEditor cellEditor = getCellEditor();
|
|
|
+
|
|
|
+ // IF the cell editor doesn't exist yet...
|
|
|
+ if (cellEditor == null) {
|
|
|
+ // Do nothing
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the Text Compartment Edit Part
|
|
|
+ IXtextAwareEditPart textEP = (IXtextAwareEditPart) getEditPart();
|
|
|
+
|
|
|
+ // Get the Text control
|
|
|
+ StyledText textControl = (StyledText) cellEditor.getControl();
|
|
|
+
|
|
|
+ // Set the Figures text
|
|
|
+ textEP.setLabelText(toEdit);
|
|
|
+
|
|
|
+ // See RATLC00522324
|
|
|
+ if (cellEditor instanceof TextCellEditorEx) {
|
|
|
+ ((TextCellEditorEx) cellEditor)
|
|
|
+ .setValueAndProcessEditOccured(toEdit);
|
|
|
+ } else {
|
|
|
+ cellEditor.setValue(toEdit);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Set the controls text and position the caret at the end of the text
|
|
|
+ textControl.setSelection(toEdit.length());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Performs show and sets the edit string to be the initial character or
|
|
|
+ * string
|
|
|
+ *
|
|
|
+ * @param initialChar
|
|
|
+ */
|
|
|
+ public void show(char initialChar) {
|
|
|
+ initialString = initialString.append(initialChar);
|
|
|
+ show();
|
|
|
+ if (SWT.getPlatform() != "carbon") { //$NON-NLS-1$
|
|
|
+ // Set the cell editor text to the initial character
|
|
|
+ setEditText(initialString.toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * This method obtains the fonts that are being used by the figure at its
|
|
|
+ * zoom level.
|
|
|
+ *
|
|
|
+ * @param gep
|
|
|
+ * the associated <code>GraphicalEditPart</code> of the figure
|
|
|
+ * @param actualFont
|
|
|
+ * font being used by the figure
|
|
|
+ * @param display
|
|
|
+ * @return <code>actualFont</code> if zoom level is 1.0 (or when there's an
|
|
|
+ * error), new Font otherwise.
|
|
|
+ */
|
|
|
+ private Font getZoomLevelFont(Font actualFont, Display display) {
|
|
|
+ Object zoom = getEditPart().getViewer().getProperty(
|
|
|
+ ZoomManager.class.toString());
|
|
|
+
|
|
|
+ if (zoom != null) {
|
|
|
+ double zoomLevel = ((ZoomManager) zoom).getZoom();
|
|
|
+
|
|
|
+ if (zoomLevel == 1.0f)
|
|
|
+ return actualFont;
|
|
|
+
|
|
|
+ FontData[] fd = new FontData[actualFont.getFontData().length];
|
|
|
+ FontData tempFD = null;
|
|
|
+
|
|
|
+ for (int i = 0; i < fd.length; i++) {
|
|
|
+ tempFD = actualFont.getFontData()[i];
|
|
|
+
|
|
|
+ fd[i] = new FontData(tempFD.getName(),
|
|
|
+ (int) (zoomLevel * tempFD.getHeight()),
|
|
|
+ tempFD.getStyle());
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ FontDescriptor fontDescriptor = FontDescriptor.createFrom(fd);
|
|
|
+ cachedFontDescriptors.add(fontDescriptor);
|
|
|
+ return getResourceManager().createFont(fontDescriptor);
|
|
|
+ } catch (DeviceResourceException e) {
|
|
|
+ Trace.catching(DiagramUIPlugin.getInstance(),
|
|
|
+ DiagramUIDebugOptions.EXCEPTIONS_CATCHING, getClass(),
|
|
|
+ "getZoomLevelFonts", e); //$NON-NLS-1$
|
|
|
+ Log.error(DiagramUIPlugin.getInstance(),
|
|
|
+ DiagramUIStatusCodes.IGNORED_EXCEPTION_WARNING,
|
|
|
+ "getZoomLevelFonts", e); //$NON-NLS-1$
|
|
|
+
|
|
|
+ return actualFont;
|
|
|
+ }
|
|
|
+ } else
|
|
|
+ return actualFont;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void show() {
|
|
|
+ super.show();
|
|
|
+
|
|
|
+ IFigure fig = getEditPart().getFigure();
|
|
|
+
|
|
|
+ Control control = getCellEditor().getControl();
|
|
|
+ this.zoomLevelFont = getZoomLevelFont(fig.getFont(),
|
|
|
+ control.getDisplay());
|
|
|
+
|
|
|
+ control.setFont(this.zoomLevelFont);
|
|
|
+
|
|
|
+ // since the font's have been resized, we need to resize the Text
|
|
|
+ // control...
|
|
|
+ getLocator().relocate(getCellEditor());
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * Performs show and sends an extra mouse click to the point location so
|
|
|
+ * that cursor appears at the mouse click point
|
|
|
+ *
|
|
|
+ * The Text control does not allow for the cursor to appear at point
|
|
|
+ * location but at a character location
|
|
|
+ *
|
|
|
+ * @param location
|
|
|
+ */
|
|
|
+ public void show(Point location) {
|
|
|
+ show();
|
|
|
+ sendClickToCellEditor(location);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void sendClickToCellEditor(final Point location) {
|
|
|
+ // make sure the diagram doesn't receive the click event..
|
|
|
+ getCellEditor().getControl().setCapture(true);
|
|
|
+
|
|
|
+ if (getCellEditor() != null
|
|
|
+ && getCellEditor().getControl().getBounds().contains(location))
|
|
|
+ sendMouseClick(location);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * Sends a SWT MouseUp and MouseDown event to the point location to the
|
|
|
+ * current Display
|
|
|
+ *
|
|
|
+ * @param location
|
|
|
+ */
|
|
|
+ private void sendMouseClick(final Point location) {
|
|
|
+
|
|
|
+ final Display currDisplay = Display.getCurrent();
|
|
|
+ currDisplay.asyncExec(new Runnable() {
|
|
|
+ public void run() {
|
|
|
+ Event event;
|
|
|
+ event = new Event();
|
|
|
+ event.type = SWT.MouseDown;
|
|
|
+ event.button = 1;
|
|
|
+ event.x = location.x;
|
|
|
+ event.y = location.y;
|
|
|
+ currDisplay.post(event);
|
|
|
+ event.type = SWT.MouseUp;
|
|
|
+ currDisplay.post(event);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void hookListeners() {
|
|
|
+ super.hookListeners();
|
|
|
+
|
|
|
+ // TODO: This gets around the problem of the cell editor not growing big
|
|
|
+ // enough when in autosize mode because it doesn't listen to textflow
|
|
|
+ // size changes. The superclass should be modified to not assume we want
|
|
|
+ // to listen to the editpart's figure.
|
|
|
+ ILabelDelegate label = (ILabelDelegate) getEditPart().getAdapter(
|
|
|
+ ILabelDelegate.class);
|
|
|
+ if (label != null && getEditPart().getFigure() instanceof WrappingLabel) {
|
|
|
+
|
|
|
+ textFigureListener = new AncestorListener.Stub() {
|
|
|
+
|
|
|
+ public void ancestorMoved(IFigure ancestor) {
|
|
|
+ getLocator().relocate(getCellEditor());
|
|
|
+ }
|
|
|
+ };
|
|
|
+ ((IFigure) ((WrappingLabel) getEditPart().getFigure())
|
|
|
+ .getTextFigure().getChildren().get(0))
|
|
|
+ .addAncestorListener(textFigureListener);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Overrides super unhookListeners to set listeners attached flag This
|
|
|
+ * method prevents unhooking listeners twice if the UI thread is blocked.
|
|
|
+ * For example, a validation dialog may block the thread
|
|
|
+ */
|
|
|
+ protected void unhookListeners() {
|
|
|
+ if (listenersAttached) {
|
|
|
+ listenersAttached = false;
|
|
|
+ super.unhookListeners();
|
|
|
+
|
|
|
+ ILabelDelegate label = (ILabelDelegate) getEditPart().getAdapter(
|
|
|
+ ILabelDelegate.class);
|
|
|
+ if (label != null && textFigureListener != null) {
|
|
|
+ ((IFigure) ((WrappingLabel) getEditPart().getFigure())
|
|
|
+ .getTextFigure().getChildren().get(0))
|
|
|
+ .removeAncestorListener(textFigureListener);
|
|
|
+ textFigureListener = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Sets the listeners attached flag if the cell editor exists
|
|
|
+ */
|
|
|
+ protected void setCellEditor(CellEditor editor) {
|
|
|
+ super.setCellEditor(editor);
|
|
|
+ if (editor != null) {
|
|
|
+ listenersAttached = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void showFeedback() {
|
|
|
+ try {
|
|
|
+ getEditPart().getRoot();
|
|
|
+ super.showFeedback();
|
|
|
+ } catch (Exception e) {
|
|
|
+ // TODO: handle exception
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected IXtextAwareEditPart getEditPart() {
|
|
|
+ return (IXtextAwareEditPart)super.getEditPart();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Gets the resource manager to remember the resources allocated for this
|
|
|
+ * graphical viewer. All resources will be disposed when the graphical
|
|
|
+ * viewer is closed if they have not already been disposed.
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ protected ResourceManager getResourceManager() {
|
|
|
+ return ((DiagramGraphicalViewer) getEditPart().getViewer())
|
|
|
+ .getResourceManager();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void saveCurrentActions(IActionBars _actionBars) {
|
|
|
+ copy = _actionBars.getGlobalActionHandler(ActionFactory.COPY.getId());
|
|
|
+ paste = _actionBars.getGlobalActionHandler(ActionFactory.PASTE.getId());
|
|
|
+ delete = _actionBars.getGlobalActionHandler(ActionFactory.DELETE
|
|
|
+ .getId());
|
|
|
+ selectAll = _actionBars.getGlobalActionHandler(ActionFactory.SELECT_ALL
|
|
|
+ .getId());
|
|
|
+ cut = _actionBars.getGlobalActionHandler(ActionFactory.CUT.getId());
|
|
|
+ find = _actionBars.getGlobalActionHandler(ActionFactory.FIND.getId());
|
|
|
+ undo = _actionBars.getGlobalActionHandler(ActionFactory.UNDO.getId());
|
|
|
+ redo = _actionBars.getGlobalActionHandler(ActionFactory.REDO.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+ private void restoreSavedActions(IActionBars _actionBars) {
|
|
|
+ _actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), copy);
|
|
|
+ _actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), paste);
|
|
|
+ _actionBars
|
|
|
+ .setGlobalActionHandler(ActionFactory.DELETE.getId(), delete);
|
|
|
+ _actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(),
|
|
|
+ selectAll);
|
|
|
+ _actionBars.setGlobalActionHandler(ActionFactory.CUT.getId(), cut);
|
|
|
+ _actionBars.setGlobalActionHandler(ActionFactory.FIND.getId(), find);
|
|
|
+ _actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), undo);
|
|
|
+ _actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(), redo);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|