blob: a690c31fd2cd62108752a74b7c95e8f4d0f6f0d2 [file] [log] [blame]
/*******************************************************************************
* <copyright>
*
* Copyright (c) 2005, 2016 SAP AG.
* 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:
* SAP AG - initial API, implementation and documentation
* Bug 336488 - DiagramEditor API
* mgorning - Bug 347262 - DirectEditingFeature with TYPE_DIALOG type
* mgorning - Bug 377419 - Hide text in underlying GA while DirectEditing is enabled
* pjpaulin - Bug 352120 - Now uses IDiagramContainerUI interface
* mwenz - Bug 492362 - Error when calling Help (F1) while direct edit is active
*
* </copyright>
*
*******************************************************************************/
package org.eclipse.graphiti.ui.internal.parts.directedit;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.gef.editparts.ZoomListener;
import org.eclipse.gef.editparts.ZoomManager;
import org.eclipse.gef.requests.DirectEditRequest;
import org.eclipse.gef.tools.DirectEditManager;
import org.eclipse.graphiti.features.IDirectEditingFeature;
import org.eclipse.graphiti.features.context.IDirectEditingContext;
import org.eclipse.graphiti.func.IDirectEditing;
import org.eclipse.graphiti.func.IProposal;
import org.eclipse.graphiti.func.Proposal;
import org.eclipse.graphiti.ui.editor.DiagramBehavior;
import org.eclipse.graphiti.ui.internal.figures.GFMultilineText;
import org.eclipse.graphiti.ui.internal.figures.GFText;
import org.eclipse.graphiti.ui.internal.parts.ShapeEditPart;
import org.eclipse.graphiti.ui.internal.requests.GFDirectEditRequest;
import org.eclipse.graphiti.ui.internal.services.GraphitiUiInternal;
import org.eclipse.graphiti.ui.platform.ICellEditorProvider;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.IContentProposalProvider;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.part.CellEditorActionHandler;
/**
* @noinstantiate This class is not intended to be instantiated by clients.
* @noextend This class is not intended to be subclassed by clients.
*/
public class GFDirectEditManager extends DirectEditManager implements IDirectEditHolder {
private IDirectEditingContext directEditingContext;
private IDirectEditingFeature directEditingFeature;
private DiagramBehavior diagramBehavior;
private Font cellEditorFont = null;
private IActionBars actionBars;
private CellEditorActionHandler actionHandler;
private IAction copy, cut, paste, undo, redo, find, selectAll, delete;
private double cachedZoom = -1.0;
private ZoomListener zoomListener = new ZoomListener() {
public void zoomChanged(double newZoom) {
updateScaledFont();
}
};
public GFDirectEditManager(ShapeEditPart part, TextCellLocator cellEditorLocator) {
super(part, null, cellEditorLocator);
diagramBehavior = part.getConfigurationProvider().getDiagramBehavior();
}
public IDirectEditingContext getDirectEditingContext() {
return directEditingContext;
}
public IDirectEditingFeature getDirectEditingFeature() {
return directEditingFeature;
}
public void setDirectEditingContext(IDirectEditingContext directEditingContext) {
this.directEditingContext = directEditingContext;
}
public void setDirectEditingFeature(IDirectEditingFeature directEditingFeature) {
this.directEditingFeature = directEditingFeature;
}
public boolean isSimpleMode() {
boolean ret = true;
if (getDirectEditingFeature() != null) {
if (getDirectEditingFeature().getProposalSupport() != null) {
ret = false;
}
}
return ret;
}
@Override
protected CellEditor createCellEditorOn(Composite composite) {
CellEditor ret = null;
IFigure locatorFigure = getTextLocatorFigure();
int editingType = directEditingFeature.getEditingType();
if (editingType == IDirectEditing.TYPE_MULTILINETEXT) {
int horizontalAlignment = SWT.LEFT;
if (locatorFigure instanceof GFMultilineText) {
int textAlignment = ((GFMultilineText) locatorFigure).getHorizontalAligment();
if (textAlignment == PositionConstants.CENTER) {
horizontalAlignment = SWT.CENTER;
} else if (textAlignment == PositionConstants.RIGHT) {
horizontalAlignment = SWT.RIGHT;
}
}
ret = new TextCellEditor(composite, SWT.MULTI | SWT.WRAP | horizontalAlignment);
} else if (editingType == IDirectEditing.TYPE_TEXT) {
int horizontalAlignment = SWT.LEFT;
if (locatorFigure instanceof GFText) {
int textAlignment = ((GFText) locatorFigure).getLabelAlignment();
if (textAlignment == PositionConstants.CENTER) {
horizontalAlignment = SWT.CENTER;
} else if (textAlignment == PositionConstants.RIGHT) {
horizontalAlignment = SWT.RIGHT;
}
}
ret = new TextCellEditor(composite, horizontalAlignment);
} else if (directEditingFeature.getEditingType() == IDirectEditing.TYPE_DROPDOWN
|| directEditingFeature.getEditingType() == IDirectEditing.TYPE_DROPDOWN_READ_ONLY) {
String[] possibleValues = getPossibleValues();
ret = new ComboBoxCellEditor(composite, possibleValues);
} else if (editingType == IDirectEditing.TYPE_CUSTOM) {
if (directEditingFeature instanceof ICellEditorProvider) {
ret = ((ICellEditorProvider) directEditingFeature).createCellEditor(composite);
} else {
throw new UnsupportedOperationException("if custom type the feature must implement ICellEditorProvider"); //$NON-NLS-1$
}
}
if (ret != null && editingType != IDirectEditing.TYPE_CUSTOM) {
ret.setValidator(new GFCellEditorValidator(this, ret));
}
return ret;
}
private String[] getPossibleValues() {
String[] possibleValues;
if (isSimpleMode()) {
possibleValues = directEditingFeature.getPossibleValues(directEditingContext);
} else {
IProposal[] proposals = directEditingFeature.getProposalSupport().getPossibleValues(directEditingContext);
possibleValues = Proposal.proposalsToTexts(proposals);
}
return possibleValues;
}
private void disposeCellEditorFont() {
if (cellEditorFont != null) {
cellEditorFont.dispose();
cellEditorFont = null;
}
}
private void updateScaledFont() {
if (getCellEditor().getControl() instanceof Text) {
double zoom = 1.0;
ZoomManager zoomMgr = (ZoomManager) getEditPart().getViewer().getProperty(ZoomManager.class.toString());
if (zoomMgr != null) {
zoom = zoomMgr.getZoom();
}
if (cachedZoom == zoom)
return;
cachedZoom = zoom;
disposeCellEditorFont();
Font lf = getTextLocatorFigure().getFont();
FontData fd = lf.getFontData()[0];
fd.setHeight((int) (fd.getHeight() * zoom));
cellEditorFont = new Font(lf.getDevice(), fd);
Text text = (Text) getCellEditor().getControl();
text.setForeground(getTextLocatorFigure().getForegroundColor());
text.setFont(cellEditorFont);
}
}
@Override
protected DirectEditRequest createDirectEditRequest() {
GFDirectEditRequest req = new GFDirectEditRequest();
req.setCellEditor(getCellEditor());
req.setDirectEditingContext(this);
return req;
}
@Override
protected void initCellEditor() {
String initialValue = directEditingFeature.getInitialValue(directEditingContext);
if (directEditingFeature.getEditingType() == IDirectEditing.TYPE_MULTILINETEXT) {
if (initialValue != null) {
getCellEditor().setValue(initialValue);
}
} else if (directEditingFeature.getEditingType() == IDirectEditing.TYPE_DROPDOWN
|| directEditingFeature.getEditingType() == IDirectEditing.TYPE_DROPDOWN_READ_ONLY) {
ComboBoxCellEditor comboBoxCellEditor = (ComboBoxCellEditor) getCellEditor();
setDirty(true);
if (directEditingFeature.getEditingType() == IDirectEditing.TYPE_DROPDOWN_READ_ONLY) {
CCombo cc = (CCombo) comboBoxCellEditor.getControl();
cc.setEditable(false);
}
String[] possibleValues = getPossibleValues();
comboBoxCellEditor.setValue(0);
for (int x = 0; x < possibleValues.length; x++) {
if (possibleValues[x].equals(initialValue))
comboBoxCellEditor.setValue(x);
}
} else if (directEditingFeature.getEditingType() == IDirectEditing.TYPE_TEXT) {
if (initialValue != null) {
getCellEditor().setValue(initialValue);
}
if (directEditingFeature.isCompletionAvailable()) {
String value = (String) getCellEditor().getValue();
if (value == null)
value = ""; //$NON-NLS-1$
TextContentAdapter controlContentAdapter = new TextContentAdapter();
IContentProposalProvider contentProposalProvider = new ContentProposalProvider(this);
// if auto code completion disabled then open code completion on
// CTRL+Space
KeyStroke keyStroke = directEditingFeature.isAutoCompletionEnabled() ? null : KeyStroke.getInstance(
SWT.CTRL, 32);
ContentProposalAdapter contentProposalAdapter = new ContentProposalAdapter(
getCellEditor().getControl(), controlContentAdapter, contentProposalProvider, keyStroke, null);
contentProposalAdapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
contentProposalAdapter.addContentProposalListener(new ContentProposalListener(
(TextCellEditor) getCellEditor()));
}
} else if (directEditingFeature.getEditingType() == IDirectEditing.TYPE_CUSTOM) {
setDirty(true);
getCellEditor().setValue(initialValue);
}
// this will force the font to be set
cachedZoom = -1.0;
updateScaledFont();
ZoomManager zoomMgr = (ZoomManager) getEditPart().getViewer().getProperty(ZoomManager.class.toString());
if (zoomMgr != null) {
zoomMgr.addZoomListener(zoomListener);
}
getLocator().relocate(getCellEditor());
// Hook the cell editor's copy/paste actions to the actionBars so that
// they can
// be invoked via keyboard shortcuts.
IEditorPart activeEditor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
.getActiveEditor();
if (activeEditor != null) {
actionBars = activeEditor.getEditorSite().getActionBars();
saveCurrentActions(actionBars);
actionHandler = new CellEditorActionHandler(actionBars);
actionHandler.addCellEditor(getCellEditor());
actionBars.updateActionBars();
}
}
@Override
protected void bringDown() {
GFMultilineText mt = getMultilineText();
if (mt != null) {
mt.setSuppressText(false);
}
diagramBehavior.setDirectEditingActive(false);
ZoomManager zoomMgr = (ZoomManager) getEditPart().getViewer().getProperty(ZoomManager.class.toString());
if (zoomMgr != null) {
zoomMgr.removeZoomListener(zoomListener);
}
if (actionHandler != null) {
actionHandler.dispose();
actionHandler = null;
}
if (actionBars != null) {
restoreSavedActions(actionBars);
actionBars.updateActionBars();
actionBars = null;
}
if (diagramBehavior.isAlive()) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
GFDirectEditManager.super.bringDown();
disposeCellEditorFont();
GraphitiUiInternal.getWorkbenchService().getActiveStatusLineManager().setErrorMessage(null);
}
});
}
((ShapeEditPart) getEditPart()).delayDirectEditing();
}
@Override
public void show() {
GFMultilineText mt = getMultilineText();
if (mt != null) {
mt.setSuppressText(true);
}
diagramBehavior.setDirectEditingActive(true);
// this is a bugfix
// celleditor not shown initially when figure has insets
// or mouse is not directly over control
super.show();
getLocator().relocate(getCellEditor());
}
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);
}
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 GFMultilineText getMultilineText() {
GFMultilineText mt = null;
if (getTextLocatorFigure() instanceof GFMultilineText) {
mt = (GFMultilineText) getTextLocatorFigure();
}
return mt;
}
private IFigure getTextLocatorFigure() {
return ((TextCellLocator) getLocator()).getFigure();
}
}