|
@@ -13,14 +13,24 @@ package org.yakindu.sct.ui.editor.editor;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Optional;
|
|
|
|
|
|
+import org.eclipse.core.databinding.UpdateValueStrategy;
|
|
|
+import org.eclipse.core.databinding.observable.value.IObservableValue;
|
|
|
import org.eclipse.core.resources.IMarker;
|
|
|
import org.eclipse.core.resources.IProject;
|
|
|
import org.eclipse.core.resources.IProjectDescription;
|
|
|
import org.eclipse.core.runtime.CoreException;
|
|
|
import org.eclipse.core.runtime.IStatus;
|
|
|
import org.eclipse.core.runtime.Status;
|
|
|
+import org.eclipse.draw2d.ColorConstants;
|
|
|
+import org.eclipse.draw2d.geometry.Rectangle;
|
|
|
+import org.eclipse.emf.databinding.IEMFValueProperty;
|
|
|
+import org.eclipse.emf.databinding.edit.EMFEditProperties;
|
|
|
import org.eclipse.emf.ecore.EObject;
|
|
|
+import org.eclipse.emf.ecore.util.EcoreUtil;
|
|
|
+import org.eclipse.emf.edit.command.AddCommand;
|
|
|
+import org.eclipse.emf.edit.command.SetCommand;
|
|
|
import org.eclipse.emf.transaction.TransactionalEditingDomain;
|
|
|
+import org.eclipse.emf.transaction.util.TransactionUtil;
|
|
|
import org.eclipse.gef.KeyHandler;
|
|
|
import org.eclipse.gef.KeyStroke;
|
|
|
import org.eclipse.gef.editparts.ZoomManager;
|
|
@@ -31,32 +41,84 @@ import org.eclipse.gmf.runtime.common.ui.services.marker.MarkerNavigationService
|
|
|
import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
|
|
|
import org.eclipse.gmf.runtime.diagram.ui.internal.parts.DiagramGraphicalViewerKeyHandler;
|
|
|
import org.eclipse.gmf.runtime.gef.ui.internal.editparts.AnimatableZoomManager;
|
|
|
+import org.eclipse.gmf.runtime.notation.BooleanValueStyle;
|
|
|
+import org.eclipse.gmf.runtime.notation.NotationPackage;
|
|
|
+import org.eclipse.gmf.runtime.notation.View;
|
|
|
import org.eclipse.jface.action.Action;
|
|
|
import org.eclipse.jface.action.IAction;
|
|
|
+import org.eclipse.jface.action.MenuManager;
|
|
|
+import org.eclipse.jface.databinding.swt.ISWTObservableValue;
|
|
|
+import org.eclipse.jface.databinding.swt.WidgetProperties;
|
|
|
import org.eclipse.jface.layout.GridDataFactory;
|
|
|
+import org.eclipse.jface.layout.GridLayoutFactory;
|
|
|
+import org.eclipse.jface.util.IPropertyChangeListener;
|
|
|
+import org.eclipse.jface.util.PropertyChangeEvent;
|
|
|
import org.eclipse.swt.SWT;
|
|
|
+import org.eclipse.swt.custom.SashForm;
|
|
|
+import org.eclipse.swt.custom.StyledText;
|
|
|
+import org.eclipse.swt.events.ControlAdapter;
|
|
|
+import org.eclipse.swt.events.ControlEvent;
|
|
|
+import org.eclipse.swt.events.KeyEvent;
|
|
|
+import org.eclipse.swt.events.KeyListener;
|
|
|
+import org.eclipse.swt.events.ModifyEvent;
|
|
|
+import org.eclipse.swt.events.ModifyListener;
|
|
|
+import org.eclipse.swt.events.MouseAdapter;
|
|
|
+import org.eclipse.swt.events.MouseEvent;
|
|
|
+import org.eclipse.swt.events.MouseTrackAdapter;
|
|
|
+import org.eclipse.swt.events.PaintEvent;
|
|
|
+import org.eclipse.swt.events.PaintListener;
|
|
|
+import org.eclipse.swt.events.SelectionAdapter;
|
|
|
+import org.eclipse.swt.events.SelectionEvent;
|
|
|
+import org.eclipse.swt.graphics.Cursor;
|
|
|
+import org.eclipse.swt.graphics.Font;
|
|
|
+import org.eclipse.swt.graphics.GC;
|
|
|
+import org.eclipse.swt.graphics.Image;
|
|
|
+import org.eclipse.swt.graphics.Transform;
|
|
|
+import org.eclipse.swt.widgets.Button;
|
|
|
+import org.eclipse.swt.widgets.Canvas;
|
|
|
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.Label;
|
|
|
+import org.eclipse.swt.widgets.Listener;
|
|
|
+import org.eclipse.swt.widgets.Menu;
|
|
|
+import org.eclipse.swt.widgets.Text;
|
|
|
import org.eclipse.ui.IEditorInput;
|
|
|
import org.eclipse.ui.IEditorPart;
|
|
|
import org.eclipse.ui.IEditorReference;
|
|
|
import org.eclipse.ui.IEditorSite;
|
|
|
import org.eclipse.ui.IFileEditorInput;
|
|
|
+import org.eclipse.ui.IMemento;
|
|
|
+import org.eclipse.ui.IWorkbenchPartSite;
|
|
|
import org.eclipse.ui.PartInitException;
|
|
|
import org.eclipse.ui.PlatformUI;
|
|
|
+import org.eclipse.ui.XMLMemento;
|
|
|
import org.eclipse.ui.help.IWorkbenchHelpSystem;
|
|
|
import org.eclipse.ui.ide.IGotoMarker;
|
|
|
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
|
|
|
import org.eclipse.xtext.EcoreUtil2;
|
|
|
import org.eclipse.xtext.ui.XtextProjectHelper;
|
|
|
+import org.yakindu.base.base.BasePackage;
|
|
|
import org.yakindu.base.base.DomainElement;
|
|
|
import org.yakindu.base.xtext.utils.gmf.resource.DirtyStateListener;
|
|
|
+import org.yakindu.base.xtext.utils.jface.fieldassist.CompletionProposalAdapter;
|
|
|
+import org.yakindu.base.xtext.utils.jface.viewers.FilteringMenuManager;
|
|
|
+import org.yakindu.base.xtext.utils.jface.viewers.StyledTextXtextAdapter;
|
|
|
import org.yakindu.sct.domain.extension.DomainRegistry;
|
|
|
import org.yakindu.sct.domain.extension.DomainStatus;
|
|
|
import org.yakindu.sct.domain.extension.DomainStatus.Severity;
|
|
|
import org.yakindu.sct.domain.extension.IDomain;
|
|
|
+import org.yakindu.sct.model.sgraph.SGraphPackage;
|
|
|
+import org.yakindu.sct.model.sgraph.Statechart;
|
|
|
+import org.yakindu.sct.model.sgraph.util.ContextElementAdapter;
|
|
|
+import org.yakindu.sct.model.sgraph.util.ContextElementAdapter.IContextElementProvider;
|
|
|
import org.yakindu.sct.ui.editor.DiagramActivator;
|
|
|
+import org.yakindu.sct.ui.editor.StatechartImages;
|
|
|
import org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningEditor;
|
|
|
import org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningUtil;
|
|
|
+import org.yakindu.sct.ui.editor.preferences.StatechartPreferenceConstants;
|
|
|
+import org.yakindu.sct.ui.editor.propertysheets.ValidatingEMFDatabindingContext;
|
|
|
import org.yakindu.sct.ui.editor.proposals.ContentProposalViewerKeyHandler;
|
|
|
import org.yakindu.sct.ui.editor.providers.ISCTOutlineFactory;
|
|
|
import org.yakindu.sct.ui.editor.utils.HelpContextIds;
|
|
@@ -70,18 +132,42 @@ import com.google.inject.Key;
|
|
|
/**
|
|
|
* @author andreas muelder - Initial contribution and API
|
|
|
* @author martin esser
|
|
|
+ * @author robert rudi
|
|
|
*/
|
|
|
@SuppressWarnings("restriction")
|
|
|
-public class StatechartDiagramEditor extends DiagramPartitioningEditor implements IGotoMarker {
|
|
|
+public class StatechartDiagramEditor extends DiagramPartitioningEditor implements IGotoMarker, IContextElementProvider, IPropertyChangeListener {
|
|
|
|
|
|
- private static final int INITIAL_PALETTE_SIZE = 175;
|
|
|
public static final String ID = "org.yakindu.sct.ui.editor.editor.StatechartDiagramEditor";
|
|
|
|
|
|
- private KeyHandler keyHandler;
|
|
|
+ protected static final String ROTATED_LABEL_TEXT = "Definition section";
|
|
|
+ protected static final String CANNOT_INLINE_SECTION_TOOLTIP = "Cannot be inlined for subdiagrams";
|
|
|
+ protected static final String INLINE_SECTION_TOOLTIP = "Inline statechart definition section";
|
|
|
+ protected static final String EXPAND_TOOLTIP = "Show statechart definition section";
|
|
|
+ protected static final String COLLAPSE_TOOLTIP = "Hide statechart definition section";
|
|
|
+ protected final Image EXPAND_IMAGE = StatechartImages.EXPAND.image();
|
|
|
+ protected final Image COLLAPSE_IMAGE = StatechartImages.COLLAPSE.image();
|
|
|
+
|
|
|
+ protected static final int TEXT_CONTROL_HORIZONTAL_MARGIN = 10;
|
|
|
+ protected static final int INITIAL_PALETTE_SIZE = 175;
|
|
|
+ protected static final int[] MIN_CONTROL_SIZE = {11, 21};
|
|
|
+ protected static final int BORDERWIDTH = 2;
|
|
|
+ protected static boolean imageLabelHasFocus = false;
|
|
|
+ protected int[] previousWidths = DEFAULT_WEIGHTS;
|
|
|
|
|
|
+ private KeyHandler keyHandler;
|
|
|
private DirtyStateListener domainAdapter;
|
|
|
private LiveValidationListener validationListener;
|
|
|
private IValidationIssueStore issueStore;
|
|
|
+ private SwitchListener switchListener;
|
|
|
+ private ResizeListener resizeListener;
|
|
|
+ private boolean isDefinitionSectionExpanded = true;
|
|
|
+
|
|
|
+ private ImageLabelMouseListener imageLabelMouseListener;
|
|
|
+ private ImageLabelMouseTrackListener imageLabelMouseTrackListener;
|
|
|
+ private ImageLabelPaintListener imageLabelPaintListener;
|
|
|
+
|
|
|
+ private StyledText xtextControl;
|
|
|
+ private Button switchControl;
|
|
|
|
|
|
public StatechartDiagramEditor() {
|
|
|
super(true);
|
|
@@ -103,7 +189,7 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
|
|
|
return domainStatus;
|
|
|
}
|
|
|
return null;
|
|
|
- };
|
|
|
+ }
|
|
|
|
|
|
@Override
|
|
|
protected void createBreadcrumbViewer(Composite parent) {
|
|
@@ -136,6 +222,11 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
|
|
|
super.init(site, input);
|
|
|
checkXtextNature();
|
|
|
registerValidationListener();
|
|
|
+ registerPropertyChangeListener();
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void registerPropertyChangeListener() {
|
|
|
+ DiagramActivator.getDefault().getPreferenceStore().addPropertyChangeListener(this);
|
|
|
}
|
|
|
|
|
|
protected void registerValidationListener() {
|
|
@@ -150,8 +241,7 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
|
|
|
protected IValidationIssueStore getIssueStore() {
|
|
|
Optional<IEditorPart> editorWithSameResource = getEditorWithSameResource();
|
|
|
if (editorWithSameResource.isPresent()) {
|
|
|
- IValidationIssueStore sharedStore = editorWithSameResource.get()
|
|
|
- .getAdapter(IValidationIssueStore.class);
|
|
|
+ IValidationIssueStore sharedStore = editorWithSameResource.get().getAdapter(IValidationIssueStore.class);
|
|
|
return sharedStore;
|
|
|
} else {
|
|
|
IValidationIssueStore newStore = getEditorInjector().getInstance(IValidationIssueStore.class);
|
|
@@ -185,6 +275,11 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
|
|
|
return injector;
|
|
|
}
|
|
|
|
|
|
+ protected Injector getEmbeddedStatechartSpecificationInjector() {
|
|
|
+ IDomain domain = DomainRegistry.getDomain(getDiagram().getElement());
|
|
|
+ return domain.getInjector(IDomain.FEATURE_EDITOR, Statechart.class.getName());
|
|
|
+ }
|
|
|
+
|
|
|
protected void checkXtextNature() {
|
|
|
IFileEditorInput editorInput = (IFileEditorInput) getEditorInput();
|
|
|
IProject project = editorInput.getFile().getProject();
|
|
@@ -230,7 +325,6 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
|
|
|
super.createGraphicalViewer(parent);
|
|
|
IWorkbenchHelpSystem helpSystem = PlatformUI.getWorkbench().getHelpSystem();
|
|
|
helpSystem.setHelp(getGraphicalViewer().getControl(), HelpContextIds.SC_EDITOR_GRAPHICAL_VIEWER);
|
|
|
-
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -238,6 +332,7 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
|
|
|
super.configureGraphicalViewer();
|
|
|
disableAnimatedZoom();
|
|
|
createContentProposalViewerKeyHandler();
|
|
|
+ super.constructPaletteViewer();
|
|
|
}
|
|
|
|
|
|
// Disable the animated zoom, it is too slow for bigger models
|
|
@@ -326,8 +421,16 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
|
|
|
return ID;
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public String getFactoryId() {
|
|
|
+ return getEditorInput().getPersistable().getFactoryId();
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public void dispose() {
|
|
|
+ saveState(getMemento());
|
|
|
+
|
|
|
+ removepropertyChangeListener();
|
|
|
if (validationListener != null) {
|
|
|
validationListener.dispose();
|
|
|
}
|
|
@@ -338,9 +441,42 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
|
|
|
getEditingDomain().removeResourceSetListener(domainAdapter);
|
|
|
if (domainAdapter != null)
|
|
|
domainAdapter.dispose();
|
|
|
+
|
|
|
+ disposeDefinitionSectionControls();
|
|
|
+
|
|
|
super.dispose();
|
|
|
}
|
|
|
|
|
|
+ protected void removepropertyChangeListener() {
|
|
|
+ DiagramActivator.getDefault().getPreferenceStore().removePropertyChangeListener(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void disposeDefinitionSectionControls() {
|
|
|
+ if (switchListener != null && switchControl != null && !switchControl.isDisposed())
|
|
|
+ switchControl.removeSelectionListener(switchListener);
|
|
|
+
|
|
|
+ if (resizeListener != null && getSash() != null && !getSash().isDisposed())
|
|
|
+ getSash().removeControlListener(resizeListener);
|
|
|
+
|
|
|
+ if (resizeListener != null && xtextControl != null && !xtextControl.isDisposed())
|
|
|
+ xtextControl.removeControlListener(resizeListener);
|
|
|
+
|
|
|
+ if (xtextControl != null && !xtextControl.isDisposed()) {
|
|
|
+ xtextControl.dispose();
|
|
|
+ xtextControl = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (switchControl != null && !switchControl.isDisposed()) {
|
|
|
+ switchControl.dispose();
|
|
|
+ switchControl = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ switchListener = null;
|
|
|
+ resizeListener = null;
|
|
|
+ imageLabelMouseListener = null;
|
|
|
+ imageLabelMouseTrackListener = null;
|
|
|
+ imageLabelPaintListener = null;
|
|
|
+ }
|
|
|
|
|
|
@Override
|
|
|
protected int getInitialPaletteSize() {
|
|
@@ -353,7 +489,483 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
|
|
|
return createOutline(type);
|
|
|
} else if (IValidationIssueStore.class.equals(type)) {
|
|
|
return issueStore;
|
|
|
+ } else if (DiagramPartitioningEditor.class.equals(type)) {
|
|
|
+ return super.getAdapter(type);
|
|
|
}
|
|
|
return super.getAdapter(type);
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void createTextEditor(Composite parent) {
|
|
|
+ Composite definitionSection = new Composite(parent, SWT.BORDER);
|
|
|
+ GridLayoutFactory.fillDefaults().numColumns(2).spacing(0, 0).applyTo(definitionSection);
|
|
|
+
|
|
|
+ switchControl = createExpandControl(definitionSection);
|
|
|
+ createDefinitionSectionLabels(definitionSection);
|
|
|
+ xtextControl = createXtextControl(definitionSection);
|
|
|
+
|
|
|
+ switchListener = new SwitchListener(parent);
|
|
|
+ resizeListener = new ResizeListener(parent, definitionSection);
|
|
|
+
|
|
|
+ parent.addControlListener(resizeListener);
|
|
|
+ switchControl.addSelectionListener(switchListener);
|
|
|
+ xtextControl.addControlListener(resizeListener);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Need hook into part creation lifecycle because the Xtext controls depends on
|
|
|
+ * the selection provider of IWorkbenchPartSite, so the Xtext enabling cannot be
|
|
|
+ * done before or while the part is created.
|
|
|
+ *
|
|
|
+ * @see org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningEditor#
|
|
|
+ * createPartControl(org.eclipse.swt.widgets.Composite)
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void createPartControl(Composite parent) {
|
|
|
+ super.createPartControl(parent);
|
|
|
+ toggleDefinitionSection();
|
|
|
+ restoreSashWidths(getSash(), getMemento());
|
|
|
+ enableXtext(xtextControl);
|
|
|
+ reloadFromPreferences();
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void reloadFromPreferences() {
|
|
|
+ boolean pinningActivated = DiagramActivator.getDefault().getPreferenceStore()
|
|
|
+ .getBoolean(StatechartPreferenceConstants.PREF_DEFINITION_SECTION);
|
|
|
+ if (!isDefinitionSectionInlined() && !pinningActivated) {
|
|
|
+ // set the new value for the boolean value style
|
|
|
+ TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(getDiagram());
|
|
|
+ BooleanValueStyle inlineStyle = DiagramPartitioningUtil.getInlineDefinitionSectionStyle(getDiagram());
|
|
|
+
|
|
|
+ SetCommand command = setBooleanValueStyle(inlineStyle, domain);
|
|
|
+ domain.getCommandStack().execute(command);
|
|
|
+
|
|
|
+ toggleDefinitionSection();
|
|
|
+ refreshDiagramEditPartChildren();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void enableXtext(StyledText xtextControl) {
|
|
|
+ final StyledTextXtextAdapter xtextAdapter = new StyledTextXtextAdapter(
|
|
|
+ getEmbeddedStatechartSpecificationInjector(), getSite());
|
|
|
+ xtextAdapter.getFakeResourceContext().getFakeResource().eAdapters().add(new ContextElementAdapter(this));
|
|
|
+ xtextAdapter.adapt((StyledText) xtextControl);
|
|
|
+ initContextMenu(xtextControl);
|
|
|
+ CompletionProposalAdapter adapter = new CompletionProposalAdapter(xtextControl,
|
|
|
+ xtextAdapter.getContentAssistant(),
|
|
|
+ org.eclipse.jface.bindings.keys.KeyStroke.getInstance(SWT.CTRL, SWT.SPACE), null);
|
|
|
+ IEMFValueProperty modelProperty = EMFEditProperties.value(getEditingDomain(),
|
|
|
+ SGraphPackage.Literals.SPECIFICATION_ELEMENT__SPECIFICATION);
|
|
|
+
|
|
|
+ ISWTObservableValue uiProperty = WidgetProperties.text(new int[]{SWT.FocusOut, SWT.Modify})
|
|
|
+ .observe(xtextControl);
|
|
|
+ ValidatingEMFDatabindingContext context = new ValidatingEMFDatabindingContext(this, getSite().getShell());
|
|
|
+ context.bindValue(uiProperty, modelProperty.observe(
|
|
|
+ EcoreUtil.getObjectByType(getDiagram().eResource().getContents(), SGraphPackage.Literals.STATECHART)),
|
|
|
+ null, new UpdateValueStrategy() {
|
|
|
+ @Override
|
|
|
+ protected IStatus doSet(IObservableValue observableValue, Object value) {
|
|
|
+ if (adapter != null && !adapter.isProposalPopupOpen())
|
|
|
+ return super.doSet(observableValue, value);
|
|
|
+ return Status.OK_STATUS;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ protected StyledText createXtextControl(Composite definitionSection) {
|
|
|
+ StyledText textControl = new StyledText(definitionSection, SWT.MULTI | SWT.V_SCROLL | SWT.WRAP);
|
|
|
+ GridDataFactory.fillDefaults().grab(true, true).indent(TEXT_CONTROL_HORIZONTAL_MARGIN, 0).applyTo(textControl);
|
|
|
+ textControl.setAlwaysShowScrollBars(false);
|
|
|
+ textControl.setBackground(ColorConstants.white);
|
|
|
+ textControl.addKeyListener(new KeyListener() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void keyReleased(KeyEvent e) {
|
|
|
+ if (e.stateMask == SWT.CTRL && e.keyCode == 'a') {
|
|
|
+ textControl.selectAll();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void keyPressed(KeyEvent e) {
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return textControl;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected Composite createDefinitionSectionLabels(Composite definitionSection) {
|
|
|
+ Composite labelComposite = new Composite(definitionSection, SWT.NONE);
|
|
|
+ GridLayoutFactory.fillDefaults().numColumns(2).spacing(0, 0).applyTo(labelComposite);
|
|
|
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(labelComposite);
|
|
|
+ createDefinitionSectionNameLabel(labelComposite);
|
|
|
+ createDefinitionSectionImageLabel(labelComposite);
|
|
|
+ createSeparator(definitionSection);
|
|
|
+ createRotatedLabel(definitionSection);
|
|
|
+ return labelComposite;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void createDefinitionSectionImageLabel(Composite labelComposite) {
|
|
|
+ Label statechartImageLabel = new Label(labelComposite, SWT.FILL);
|
|
|
+ statechartImageLabel.setImage(StatechartImages.PIN.image());
|
|
|
+ statechartImageLabel.setToolTipText(INLINE_SECTION_TOOLTIP);
|
|
|
+ statechartImageLabel.setEnabled(getContextObject() instanceof Statechart);
|
|
|
+ labelComposite.setToolTipText(getTooltipText());
|
|
|
+ GridDataFactory.fillDefaults().applyTo(statechartImageLabel);
|
|
|
+ imageLabelMouseListener = new ImageLabelMouseListener();
|
|
|
+ imageLabelMouseTrackListener = new ImageLabelMouseTrackListener(statechartImageLabel);
|
|
|
+ imageLabelPaintListener = new ImageLabelPaintListener(statechartImageLabel);
|
|
|
+ statechartImageLabel.addMouseListener(imageLabelMouseListener);
|
|
|
+ statechartImageLabel.addMouseTrackListener(imageLabelMouseTrackListener);
|
|
|
+ statechartImageLabel.addPaintListener(imageLabelPaintListener);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected String getTooltipText() {
|
|
|
+ return (getContextObject() instanceof Statechart) ? INLINE_SECTION_TOOLTIP : CANNOT_INLINE_SECTION_TOOLTIP;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected SetCommand setBooleanValueStyle(BooleanValueStyle inlineStyle, TransactionalEditingDomain domain) {
|
|
|
+ SetCommand command = new SetCommand(domain, inlineStyle,
|
|
|
+ NotationPackage.Literals.BOOLEAN_VALUE_STYLE__BOOLEAN_VALUE, !inlineStyle.isBooleanValue());
|
|
|
+ return command;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected AddCommand addBooleanValueStyle(View view, BooleanValueStyle inlineStyle,
|
|
|
+ TransactionalEditingDomain domain) {
|
|
|
+ AddCommand command = new AddCommand(domain, view, NotationPackage.Literals.VIEW__STYLES, inlineStyle);
|
|
|
+ return command;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void createDefinitionSectionNameLabel(Composite labelComposite) {
|
|
|
+ Text statechartNameLabel = new Text(labelComposite, SWT.SINGLE | SWT.NORMAL);
|
|
|
+ GridDataFactory.fillDefaults().indent(5, 1).grab(true, false).align(SWT.FILL, SWT.CENTER)
|
|
|
+ .applyTo(statechartNameLabel);
|
|
|
+ statechartNameLabel.setText(this.getTitle());
|
|
|
+ statechartNameLabel.addModifyListener(new ModifyListener() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void modifyText(ModifyEvent e) {
|
|
|
+ statechartNameLabel.update();
|
|
|
+ statechartNameLabel.redraw();
|
|
|
+ statechartNameLabel.getParent().layout();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ observeStatechartName(statechartNameLabel);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void observeStatechartName(Text statechartNameLabel) {
|
|
|
+ ValidatingEMFDatabindingContext context = new ValidatingEMFDatabindingContext(this, this.getSite().getShell());
|
|
|
+ IEMFValueProperty property = EMFEditProperties.value(TransactionUtil.getEditingDomain(getContextObject()),
|
|
|
+ BasePackage.Literals.NAMED_ELEMENT__NAME);
|
|
|
+ ISWTObservableValue observe = WidgetProperties.text(new int[]{SWT.FocusOut, SWT.DefaultSelection})
|
|
|
+ .observe(statechartNameLabel);
|
|
|
+ context.bindValue(observe, property.observe(this.getContextObject()));
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void createSeparator(Composite definitionSection) {
|
|
|
+ Label separator = new Label(definitionSection, SWT.SEPARATOR | SWT.HORIZONTAL);
|
|
|
+ GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(separator);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void createRotatedLabel(Composite definitionSection) {
|
|
|
+ RotatedLabel rotatedLabel = new RotatedLabel(definitionSection, SWT.NONE);
|
|
|
+ rotatedLabel.setText(ROTATED_LABEL_TEXT, new Font(Display.getDefault(), "Segoe UI", 8, SWT.NORMAL));
|
|
|
+ rotatedLabel.addMouseListener(new MouseAdapter() {
|
|
|
+ @Override
|
|
|
+ public void mouseUp(MouseEvent e) {
|
|
|
+ if (!isDefinitionSectionExpanded)
|
|
|
+ switchListener.handleSelection();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ rotatedLabel.addMouseTrackListener(new MouseTrackAdapter() {
|
|
|
+ @Override
|
|
|
+ public void mouseEnter(MouseEvent e) {
|
|
|
+ rotatedLabel.setCursor(new Cursor(Display.getDefault(),
|
|
|
+ (!isDefinitionSectionExpanded) ? SWT.CURSOR_HAND : SWT.CURSOR_ARROW));
|
|
|
+ rotatedLabel.setToolTipText((!isDefinitionSectionExpanded) ? EXPAND_TOOLTIP : null);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ GridDataFactory.fillDefaults().grab(false, false)
|
|
|
+ .hint(MIN_CONTROL_SIZE[0], definitionSection.getBounds().height).applyTo(rotatedLabel);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected Button createExpandControl(Composite definitionSection) {
|
|
|
+ Button expandButton = new Button(definitionSection, SWT.PUSH | SWT.BORDER_SOLID);
|
|
|
+ expandButton.setToolTipText(COLLAPSE_TOOLTIP);
|
|
|
+ expandButton.setImage(
|
|
|
+ isDefinitionSectionExpanded ? StatechartImages.COLLAPSE.image() : StatechartImages.EXPAND.image());
|
|
|
+ expandButton.setCursor(new Cursor(Display.getDefault(), SWT.CURSOR_HAND));
|
|
|
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).indent(-1, 0)
|
|
|
+ .hint(MIN_CONTROL_SIZE[0], MIN_CONTROL_SIZE[1]).applyTo(expandButton);
|
|
|
+ return expandButton;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public EObject getContextObject() {
|
|
|
+ return getDiagram().getElement();
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void initContextMenu(Control control) {
|
|
|
+ MenuManager menuManager = new FilteringMenuManager();
|
|
|
+ Menu contextMenu = menuManager.createContextMenu(control);
|
|
|
+ control.setMenu(contextMenu);
|
|
|
+ IWorkbenchPartSite site = getSite();
|
|
|
+ if (site != null)
|
|
|
+ site.registerContextMenu("org.yakindu.base.xtext.utils.jface.viewers.StyledTextXtextAdapterContextMenu",
|
|
|
+ menuManager, site.getSelectionProvider());
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void collapseDefinitionSection(Composite parent) {
|
|
|
+ int width = parent.getBounds().width;
|
|
|
+ ((SashForm) parent).setWeights(new int[]{switchControl.getBounds().width + BORDERWIDTH, width});
|
|
|
+ updateSwitchControl(EXPAND_TOOLTIP, EXPAND_IMAGE);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void expandDefinitionSection(Composite parent) {
|
|
|
+ ((SashForm) parent).setWeights(previousWidths);
|
|
|
+ updateSwitchControl(COLLAPSE_TOOLTIP, COLLAPSE_IMAGE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Updates the tooltip text and the image for the prominent switchControl.
|
|
|
+ *
|
|
|
+ * @param tooltipText
|
|
|
+ * The tooltip text for the switchControl
|
|
|
+ * @param image
|
|
|
+ * The image for the controls
|
|
|
+ */
|
|
|
+ protected void updateSwitchControl(String tooltipText, Image image) {
|
|
|
+ switchControl.setToolTipText(tooltipText);
|
|
|
+ switchControl.setImage(image);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected class ImageLabelMouseListener extends MouseAdapter {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mouseUp(MouseEvent e) {
|
|
|
+ TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(getDiagram());
|
|
|
+ BooleanValueStyle inlineStyle = DiagramPartitioningUtil.getInlineDefinitionSectionStyle(getDiagram());
|
|
|
+ if (inlineStyle == null) {
|
|
|
+ inlineStyle = DiagramPartitioningUtil.createInlineDefinitionSectionStyle();
|
|
|
+ AddCommand command = addBooleanValueStyle(getDiagram(), inlineStyle, domain);
|
|
|
+ domain.getCommandStack().execute(command);
|
|
|
+ }
|
|
|
+ // set the new value for the boolean value style
|
|
|
+ SetCommand command = setBooleanValueStyle(inlineStyle, domain);
|
|
|
+ domain.getCommandStack().execute(command);
|
|
|
+
|
|
|
+ toggleDefinitionSection();
|
|
|
+ refreshDiagramEditPartChildren();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ protected class ImageLabelMouseTrackListener extends MouseTrackAdapter {
|
|
|
+ private final Label statechartImageLabel;
|
|
|
+ protected ImageLabelMouseTrackListener(Label statechartImageLabel) {
|
|
|
+ this.statechartImageLabel = statechartImageLabel;
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public void mouseEnter(MouseEvent e) {
|
|
|
+ statechartImageLabel.setCursor(new Cursor(Display.getDefault(), SWT.CURSOR_HAND));
|
|
|
+ imageLabelHasFocus = true;
|
|
|
+ statechartImageLabel.redraw();
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public void mouseExit(MouseEvent e) {
|
|
|
+ imageLabelHasFocus = false;
|
|
|
+ statechartImageLabel.redraw();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ protected class ImageLabelPaintListener implements PaintListener {
|
|
|
+ private final Label statechartImageLabel;
|
|
|
+
|
|
|
+ protected ImageLabelPaintListener(Label statechartImageLabel) {
|
|
|
+ this.statechartImageLabel = statechartImageLabel;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void paintControl(PaintEvent e) {
|
|
|
+ if (imageLabelHasFocus) {
|
|
|
+ drawIconBorder(statechartImageLabel, e.gc);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ protected void drawIconBorder(Label statechartImageLabel, GC gc) {
|
|
|
+ Rectangle rect = new Rectangle(0, 0, statechartImageLabel.getBounds().width - 1,
|
|
|
+ statechartImageLabel.getBounds().height - 1);
|
|
|
+ Transform t = new Transform(Display.getDefault());
|
|
|
+ gc.setTransform(t);
|
|
|
+ gc.setForeground(ColorConstants.lightGray);
|
|
|
+ gc.drawRectangle(0, 0, rect.width, rect.height);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @author robert rudi - Initial contribution and API
|
|
|
+ *
|
|
|
+ */
|
|
|
+ protected class ResizeListener extends ControlAdapter {
|
|
|
+
|
|
|
+ private final Composite parent;
|
|
|
+ private final Composite definitionSection;
|
|
|
+
|
|
|
+ protected ResizeListener(Composite parent, Composite definitionSection) {
|
|
|
+ this.parent = parent;
|
|
|
+ this.definitionSection = definitionSection;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void controlResized(ControlEvent e) {
|
|
|
+ handleControlChanged();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void controlMoved(ControlEvent e) {
|
|
|
+ handleControlChanged();
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void handleControlChanged() {
|
|
|
+ if (isDefinitionSectionExpanded) {
|
|
|
+ previousWidths = ((SashForm) parent).getWeights();
|
|
|
+ } else {
|
|
|
+ if (definitionSection.getBounds().width != switchControl.getBounds().width) {
|
|
|
+ collapseDefinitionSection(parent);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @author robert rudi - Initial contribution and API
|
|
|
+ *
|
|
|
+ */
|
|
|
+ protected class SwitchListener extends SelectionAdapter {
|
|
|
+
|
|
|
+ protected final Composite parent;
|
|
|
+
|
|
|
+ protected SwitchListener(Composite parent) {
|
|
|
+ this.parent = parent;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void widgetSelected(SelectionEvent e) {
|
|
|
+ handleSelection();
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void handleSelection() {
|
|
|
+ parent.setRedraw(false);
|
|
|
+ xtextControl.setVisible(!xtextControl.isVisible());
|
|
|
+ isDefinitionSectionExpanded = !isDefinitionSectionExpanded;
|
|
|
+ if (xtextControl.isVisible()) {
|
|
|
+ expandDefinitionSection(parent);
|
|
|
+ } else {
|
|
|
+ if (isDefinitionSectionExpanded) {
|
|
|
+ // needed to restore previous widths of sashcontrols if definition section is
|
|
|
+ // collapsed and editor has been reopened
|
|
|
+ xtextControl.setVisible(!xtextControl.isVisible());
|
|
|
+ expandDefinitionSection(parent);
|
|
|
+ } else {
|
|
|
+ collapseDefinitionSection(parent);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ parent.setRedraw(true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected boolean isDefinitionSectionInlined() {
|
|
|
+ BooleanValueStyle style = DiagramPartitioningUtil.getInlineDefinitionSectionStyle(getDiagram());
|
|
|
+ return style != null ? style.isBooleanValue() : true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @author robert rudi - Initial contribution and API
|
|
|
+ *
|
|
|
+ */
|
|
|
+ protected class RotatedLabel extends Canvas {
|
|
|
+
|
|
|
+ private String text;
|
|
|
+ float rotatingAngle = -90f;
|
|
|
+
|
|
|
+ public RotatedLabel(Composite parent, int style) {
|
|
|
+ super(parent, style);
|
|
|
+
|
|
|
+ this.addPaintListener(new PaintListener() {
|
|
|
+ public void paintControl(PaintEvent e) {
|
|
|
+ paint(e);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ this.addListener(SWT.MouseDown, new Listener() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void handleEvent(Event event) {
|
|
|
+ if (switchListener != null && !isDefinitionSectionExpanded)
|
|
|
+ switchListener.handleSelection();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setText(String string, Font font) {
|
|
|
+ this.text = string;
|
|
|
+ setFont(font);
|
|
|
+ redraw();
|
|
|
+ update();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setText(String string) {
|
|
|
+ this.text = string;
|
|
|
+ redraw();
|
|
|
+ update();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void paint(PaintEvent e) {
|
|
|
+ Transform tr = null;
|
|
|
+ tr = new Transform(e.display);
|
|
|
+ int w = e.width;
|
|
|
+ int h = e.height;
|
|
|
+ tr.translate(w / 2, h / 3);
|
|
|
+ tr.rotate(rotatingAngle);
|
|
|
+ e.gc.setTransform(tr);
|
|
|
+ int drawHeight = -((w / 3) * 2);
|
|
|
+ e.gc.drawString(isDefinitionSectionExpanded ? "" : text, 0,
|
|
|
+ (drawHeight % 2) != 0 ? drawHeight - 1 : drawHeight);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void saveState(IMemento memento) {
|
|
|
+ if (memento == null) {
|
|
|
+ memento = XMLMemento.createWriteRoot(getFactoryId());
|
|
|
+ }
|
|
|
+
|
|
|
+ memento.putInteger(FIRST_SASH_CONTROL_WEIGHT, previousWidths[0]);
|
|
|
+ memento.putInteger(SECOND_SASH_CONTROL_WEIGHT, previousWidths[1]);
|
|
|
+ rememberExpandState(memento);
|
|
|
+
|
|
|
+ super.setMemento(memento);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void restoreState(IMemento memento) {
|
|
|
+ if (getSash() != null && memento != null && memento.getInteger(FIRST_SASH_CONTROL_WEIGHT) != null
|
|
|
+ && memento.getInteger(SECOND_SASH_CONTROL_WEIGHT) != null) {
|
|
|
+ getSash().setWeights(new int[]{memento.getInteger(FIRST_SASH_CONTROL_WEIGHT),
|
|
|
+ memento.getInteger(SECOND_SASH_CONTROL_WEIGHT)});
|
|
|
+ previousWidths = getSash().getWeights();
|
|
|
+ isDefinitionSectionExpanded = getExpandState(memento);
|
|
|
+ }
|
|
|
+ super.setMemento(memento);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void propertyChange(PropertyChangeEvent event) {
|
|
|
+ if(StatechartPreferenceConstants.PREF_DEFINITION_SECTION.equals(event.getProperty())) {
|
|
|
+ reloadFromPreferences();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
}
|