Skip to main content
summaryrefslogtreecommitdiffstats
blob: cc65393e55f81221c23034f2d62d04b7cda3fe47 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
/*****************************************************************************
 * Copyright (c) 2009 CEA LIST.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *  Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
 *  Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Bug 496905
 *
 *****************************************************************************/
package org.eclipse.papyrus.uml.diagram.common.editpolicies;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.draw2d.FigureUtilities;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.transaction.RunnableWithResult;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.requests.DirectEditRequest;
import org.eclipse.gef.tools.CellEditorLocator;
import org.eclipse.gef.tools.DirectEditManager;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.LabelDirectEditPolicy;
import org.eclipse.gmf.runtime.diagram.ui.tools.TextDirectEditManager;
import org.eclipse.gmf.runtime.draw2d.ui.figures.WrappingLabel;
import org.eclipse.gmf.runtime.gef.ui.internal.parts.TextCellEditorEx;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.window.Window;
import org.eclipse.papyrus.extensionpoints.editors.Activator;
import org.eclipse.papyrus.extensionpoints.editors.configuration.IDirectEditorConfiguration;
import org.eclipse.papyrus.extensionpoints.editors.ui.ExtendedDirectEditionDialog;
import org.eclipse.papyrus.extensionpoints.editors.utils.DirectEditorsUtil;
import org.eclipse.papyrus.extensionpoints.editors.utils.IDirectEditorsIds;
import org.eclipse.papyrus.uml.diagram.common.directedit.FigureControler;
import org.eclipse.papyrus.uml.diagram.common.directedit.ILabelControler;
import org.eclipse.papyrus.uml.diagram.common.directedit.PropertyAccessor;
import org.eclipse.papyrus.uml.internationalization.utils.utils.UMLLabelInternationalization;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.ElementImport;
import org.eclipse.uml2.uml.NamedElement;

/**
 * Extended edit policy for direct edit. this policy checks if an editor is
 * available in the editor registry for the given edited element
 */
public class ExtendedDirectEditPolicy extends LabelDirectEditPolicy {

	/** direct edition mode (default, undefined, registered editor, etc.) */
	protected int directEditionMode = IDirectEdition.UNDEFINED_DIRECT_EDITOR;

	/** configuration from a registered edit dialog */
	private IDirectEditorConfiguration configuration;

	/** Manager for editing class name */
	protected DirectEditManager manager;

	@Override
	protected Command getDirectEditCommand(DirectEditRequest request) {
		return performDirectEdit(request);
	}

	/**
	 * The direct edit mechanism requires the edit part to handle the direct
	 * edit request.
	 *
	 * @param req
	 *            the request that called the direct edit.
	 */
	public Command performDirectEdit(DirectEditRequest req) {
		if (IDirectEdition.UNDEFINED_DIRECT_EDITOR == directEditionMode) {
			directEditionMode = getDirectEditionType();
		}
		switch (directEditionMode) {
		case IDirectEdition.NO_DIRECT_EDITION:
			// no direct edition mode => does nothing
			return null;
		case IDirectEdition.EXTENDED_DIRECT_EDITOR:
			// opens a dialog using specific configuration
			configuration.preEditAction(getUMLElement());
			final ExtendedDirectEditionDialog dialog = new ExtendedDirectEditionDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), getUMLElement(), configuration.getTextToEdit(getUMLElement()), configuration);
			if (Window.OK == dialog.open()) {
				TransactionalEditingDomain domain = getEditingDomain();
				try {
					domain.runExclusive(new RunnableWithResult<Object>() {

						private Object result = null;

						private IStatus status = Status.OK_STATUS;

						@Override
						public Object getResult() {
							return result;
						}

						@Override
						public IStatus getStatus() {
							return status;
						}

						@Override
						public void setStatus(IStatus status) {
							this.status = status;
						}

						@Override
						public void run() {
							result = configuration.postEditAction(getUMLElement(), dialog.getValue());
						}

					});
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			return null;
		case IDirectEdition.DEFAULT_DIRECT_EDITOR:
			return super.getDirectEditCommand(req);
		default:
			return null;
		}

	}

	/**
	 * Returns the view controlled by the host edit part
	 *
	 * @return the view controlled by the host edit part
	 */
	protected View getView() {
		return (View) getHost().getModel();
	}

	/**
	 * Returns the {@link Element} managed by this edit part.
	 *
	 * @return the {@link Element} managed by this edit part.
	 */
	protected Element getUMLElement() {
		return (Element) getView().getElement();
	}

	/**
	 * Returns the style of direct edition.
	 * <p>
	 * Note: This method should never be overridden. Override sub-methods instead.
	 * </p>
	 *
	 * @return the style of direct edition
	 */
	public int getDirectEditionType() {
		if (checkExtendedEditor()) {
			initExtendedEditorConfiguration();
			return IDirectEdition.EXTENDED_DIRECT_EDITOR;
		}
		if (checkDefaultEdition()) {
			return IDirectEdition.DEFAULT_DIRECT_EDITOR;
		}

		// not a named element. no specific editor => do nothing
		return IDirectEdition.NO_DIRECT_EDITION;
	}

	/**
	 * Checks if an extended editor is present.
	 *
	 * @return <code>true</code> if an extended editor is present.
	 */
	protected boolean checkExtendedEditor() {
		if (getUMLElement() != null) {
			return DirectEditorsUtil.hasSpecificEditorConfiguration(IDirectEditorsIds.UML_LANGUAGE, getUMLElement());
		}
		return false;
	}

	/**
	 * Checks if a default direct edition is available
	 *
	 * @return <code>true</code> if a default direct edition is available
	 */
	protected boolean checkDefaultEdition() {
		return (getUMLElement() instanceof NamedElement);
	}

	/**
	 * Initializes the extended editor configuration
	 */
	protected void initExtendedEditorConfiguration() {
		if (configuration == null) {
			configuration = DirectEditorsUtil.findEditorConfiguration(IDirectEditorsIds.UML_LANGUAGE, getUMLElement());
		}
	}

	/**
	 * Init the label direct edit manager. This method should be called when a
	 * Direct Edit request is performed.
	 */
	// @unused
	protected void initLabelEditManager() {
		if (manager == null) {
			// locator for the cell editor (on the name label)
			CellEditorLocator locator = getTextCellEditorLocator();

			// defining how properties are modified in the model
			PropertyAccessor accessor = new PropertyAccessor() {

				@Override
				public String getPropertyName() {
					return "Name";
				}

				@Override
				public String getValue() {
					if (isElementImport()) {
						return getElementImport().getAlias();
					} else if (getUMLElement() instanceof NamedElement) {
						return UMLLabelInternationalization.getInstance().getLabel(((NamedElement) getUMLElement()));
					}
					return "";

				}

				@Override
				public void setValue(String value) {
					if (isElementImport()) {
						getElementImport().setAlias(value);
					} else if (getUMLElement() instanceof NamedElement) {
						((NamedElement) getUMLElement()).setName(value);
					}
				}
			};
			// defines the controller: link between model and view
			ILabelControler labelControler = new FigureControler(getHostFigure(), accessor);

			// creates the editing manager.
			manager = new TextDirectEditManager((GraphicalEditPart) getHost(), TextCellEditorEx.class, locator);
		}
	}

	private CellEditorLocator getTextCellEditorLocator() {
		if (getHostFigure() instanceof WrappingLabel) {
			return new TextCellEditorLocator((WrappingLabel) getHostFigure());
		} else if (getHostFigure() instanceof WrappingLabel) {
			return new LabelCellEditorLocator((Label) getHostFigure());
		} else {
			Activator.log("Problem to locate the direct edit editor. Figure is neither a label nor a wrapping label");
			return null;
		}
	}

	/**
	 * Returns <code>true</code> if the uml element is an element import
	 *
	 * @return <code>true</code> if the uml element is an element import
	 */
	public boolean isElementImport() {
		return (getUMLElement() instanceof ElementImport);
	}

	/**
	 * Returns the element associated to the edit part hosting this edit policy
	 *
	 * @return the element associated to the edit part hosting this edit policy
	 *         or <code>null</code> if the element is not an element import
	 */
	public ElementImport getElementImport() {
		if (isElementImport()) {
			return (ElementImport) getUMLElement();
		}
		return null;
	}

	private class TextCellEditorLocator implements CellEditorLocator {

		/**
		 * @generated
		 */
		private final WrappingLabel wrapLabel;

		/**
		 * @generated
		 */
		public TextCellEditorLocator(WrappingLabel wrapLabel) {
			this.wrapLabel = wrapLabel;
		}

		/**
		 * @generated
		 */
		public WrappingLabel getWrapLabel() {
			return wrapLabel;
		}

		/**
		 * @generated
		 */
		@Override
		public void relocate(CellEditor celleditor) {
			Text text = (Text) celleditor.getControl();
			Rectangle rect = getWrapLabel().getTextBounds().getCopy();
			getWrapLabel().translateToAbsolute(rect);
			if (getWrapLabel().isTextWrapOn() && getWrapLabel().getText().length() > 0) {
				rect.setSize(new Dimension(text.computeSize(rect.width, SWT.DEFAULT)));
			} else {
				int avr = FigureUtilities.getFontMetrics(text.getFont()).getAverageCharWidth();
				rect.setSize(new Dimension(text.computeSize(SWT.DEFAULT, SWT.DEFAULT)).expand(avr * 2, 0));
			}
			if (!rect.equals(new Rectangle(text.getBounds()))) {
				text.setBounds(rect.x, rect.y, rect.width, rect.height);
			}
		}
	}

	private class LabelCellEditorLocator implements CellEditorLocator {

		/**
		 * @generated
		 */
		private final Label label;

		/**
		 * @generated
		 */
		public LabelCellEditorLocator(Label label) {
			this.label = label;
		}

		/**
		 * @generated
		 */
		public Label getLabel() {
			return label;
		}

		/**
		 * @generated
		 */
		@Override
		public void relocate(CellEditor celleditor) {
			Text text = (Text) celleditor.getControl();
			Rectangle rect = getLabel().getTextBounds().getCopy();
			getLabel().translateToAbsolute(rect);
			int avr = FigureUtilities.getFontMetrics(text.getFont()).getAverageCharWidth();
			rect.setSize(new Dimension(text.computeSize(SWT.DEFAULT, SWT.DEFAULT)).expand(avr * 2, 0));
			if (!rect.equals(new Rectangle(text.getBounds()))) {
				text.setBounds(rect.x, rect.y, rect.width, rect.height);
			}
		}
	}

	/**
	 * retrieves the host editing domain
	 *
	 * @return the {@link TransactionalEditingDomain} of the host edit part.
	 */
	protected TransactionalEditingDomain getEditingDomain() {
		return ((IGraphicalEditPart) getHost()).getEditingDomain();
	}

}

Back to the top