/*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 Association for Decentralized Information Management
* in Industry THTH ry.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
*
* Contributors:
* VTT Technical Research Centre of Finland - initial API and implementation
+ * Semantum Oy - gitlab #215
*******************************************************************************/
package org.simantics.modeling.ui.diagramEditor;
import java.awt.geom.Point2D;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Set;
+import java.util.stream.Collectors;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPartSite;
import org.simantics.Simantics;
import org.simantics.db.ReadGraph;
import org.simantics.db.RequestProcessor;
import org.simantics.db.Resource;
import org.simantics.db.Session;
-import org.simantics.db.WriteGraph;
import org.simantics.db.common.request.PossibleIndexRoot;
import org.simantics.db.common.request.ResourceRead2;
-import org.simantics.db.common.request.UniqueRead;
-import org.simantics.db.common.request.WriteRequest;
import org.simantics.db.common.utils.NameUtils;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.request.IsLinkedTo;
import org.simantics.db.layer0.util.Layer0Utils;
import org.simantics.db.layer0.variable.Variable;
import org.simantics.db.layer0.variable.Variables;
+import org.simantics.db.request.Read;
+import org.simantics.db.request.Write;
import org.simantics.db.service.SerialisationSupport;
import org.simantics.diagram.adapter.GraphToDiagramSynchronizer;
import org.simantics.diagram.content.Change;
import org.simantics.diagram.content.DiagramContentChanges;
import org.simantics.diagram.content.DiagramContentTracker;
import org.simantics.diagram.stubs.DiagramResource;
-import org.simantics.diagram.symbollibrary.ISymbolItem;
import org.simantics.diagram.synchronization.runtime.DiagramSelectionUpdater;
import org.simantics.diagram.ui.DiagramModelHints;
import org.simantics.diagram.ui.ElementClassTransferable;
import org.simantics.g2d.participant.TransformUtil;
import org.simantics.modeling.ModelingResources;
import org.simantics.modeling.ui.Activator;
+import org.simantics.modeling.ui.diagramEditor.dnd.DropSuggestion;
+import org.simantics.modeling.ui.diagramEditor.dnd.DropSuggestions;
import org.simantics.scenegraph.g2d.snap.ISnapAdvisor;
import org.simantics.structural.stubs.StructuralResource2;
import org.simantics.ui.dnd.LocalObjectTransfer;
import org.simantics.ui.dnd.LocalObjectTransferable;
import org.simantics.ui.selection.WorkbenchSelectionElement;
+import org.simantics.utils.datastructures.hints.IHintContext;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
import org.simantics.utils.logging.TimeLogger;
+import org.simantics.utils.strings.EString;
+import org.simantics.utils.ui.SWTUtils;
+import org.simantics.utils.ui.dialogs.ShowError;
import org.simantics.utils.ui.workbench.WorkbenchUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* This participant populates Elements from ElementClass-resources drops
*/
public class PopulateElementDropParticipant extends AbstractDiagramParticipant implements IDropTargetParticipant {
+ private static final Logger LOGGER = LoggerFactory.getLogger(PopulateElementDropParticipant.class);
+
+ /**
+ * List of {@link DropSuggestion} instances that need to be applied to be model
+ * before the drop can commence. Used with the hint context from
+ * {@link IDnDContext#getHints()}.
+ */
+ private static final Key KEY_SUGGESTIONS = new IHintContext.KeyOf(List.class);
+
@Dependency PickContext pickContext;
@Dependency TransformUtil transformUtil;
-
+
protected GraphToDiagramSynchronizer synchronizer;
protected IWorkbenchPartSite partSite;
Transferable tr = dtde.getTransferable();
if (tr.isDataFlavorSupported(LocalObjectTransferable.FLAVOR)) {
- // System.out.println("joo");
Object obj = null;
// This must be done to have SWT transfer set the source data
try {
obj = tr.getTransferData(LocalObjectTransferable.FLAVOR);
// System.out.println("GOT FROM AWT: " + obj);
- } catch (UnsupportedFlavorException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ } catch (UnsupportedFlavorException | IOException e) {
+ LOGGER.error("Could not get AWT transferable data", e); //$NON-NLS-1$
}
// Check SWT
} else {
Resource r = (Resource) ((IAdaptable) elm).getAdapter(Resource.class);
if (r != null) {
- if (elm instanceof ISymbolItem) {
- /* FIXME fix this check
- ISymbolItem symbol = (ISymbolItem) elm;
- Resource dia = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE);
- try {
- if (!DiagramTypeUtils.symbolAllowedOnDiagram(synchronizer.getSession(), symbol, dia)) {
- // Deny dragging of this symbol
- continue;
- }
- } catch (DatabaseException e) {
- e.printStackTrace();
- continue;
- }*/
- }
-
try {
- Object errorOrSymbolResource = validateDrop(synchronizer.getSession(), r,
- diagram.<Resource> getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE));
+ Object errorOrSymbolResource = validateDrag(synchronizer.getSession(), r,
+ diagram.<Resource> getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE),
+ dp.getHints());
if (errorOrSymbolResource instanceof Resource) {
- ElementClassDragItem item = new ElementClassDragItem(synchronizer.getNodeClass((Resource)errorOrSymbolResource));
+ Resource symbol = (Resource) errorOrSymbolResource;
+ ElementClassDragItem item = new ElementClassDragItem(synchronizer.getNodeClass(symbol));
item.getHintContext().setHint(ElementHints.KEY_TRANSFORM, AffineTransform.getScaleInstance(1, 1));
+ item.getHintContext().setHint(ElementHints.KEY_OBJECT, symbol);
dp.add(item);
}
} catch (DatabaseException e) {
- // Ignore node-class retrieval failures.
- //System.out.println("error: " + e.getMessage());
+ // Ignore node-class retrieval failures, so only log as debug
+ LOGGER.debug("Could not retrieve node class for dropped symbol", e); //$NON-NLS-1$
}
}
}
}
}
- private Object validateDrop(RequestProcessor processor, final Resource draggedResource, final Resource dropTarget) throws DatabaseException {
- return processor.syncRequest(new UniqueRead<Object>() {
- @Override
- public Object perform(ReadGraph graph) throws DatabaseException {
-// System.out.println("dragged resource: " + draggedResource);
-// System.out.println("drop target resource: " + dropTarget);
- Resource sourceModel = graph.syncRequest(new PossibleIndexRoot(draggedResource));
- Resource targetModel = graph.syncRequest(new PossibleIndexRoot(dropTarget));
-// System.out.println("source model: " + sourceModel);
-// System.out.println("target model: " + targetModel);
-
- // Prevent dragging data from one source model to another.
- // If source is not part of any model, everything is okay.
- if (sourceModel != null && !graph.syncRequest(new IsLinkedTo(targetModel, sourceModel))) {
- // Prevent a symbol instantiating within its own configuration.
- // NOTE: this doesn't handle transitive cycles.
- return "Cannot instantiate " + NameUtils.getSafeName(graph, draggedResource) + " into model "
- + NameUtils.getURIOrSafeNameInternal(graph, targetModel) + ". The source namespace ("
- + NameUtils.getURIOrSafeNameInternal(graph, sourceModel) + ") is not linked to the target model.";
- }
-
- // Prevent dragging to published components
- ModelingResources MOD = ModelingResources.getInstance(graph);
- StructuralResource2 STR = StructuralResource2.getInstance(graph);
- Resource configuration = graph.getPossibleObject(dropTarget, MOD.DiagramToComposite);
- if (configuration != null) {
- Resource componentTypeFromDiagram = graph.getPossibleObject(configuration, STR.Defines);
- if(componentTypeFromDiagram != null) {
- if(Layer0Utils.isPublished(graph, componentTypeFromDiagram))
- return "Cannot create elements into a diagram that belongs to a published user component.";
- }
- }
+ private Object validateDrag(RequestProcessor processor, final Resource draggedResource, final Resource dropTarget, IHintContext dndHints) throws DatabaseException {
+ return processor.syncRequest((Read<Object>) graph -> {
+ List<DropSuggestion> suggestions = dndHints.getHint(KEY_SUGGESTIONS);
+ if (suggestions == null) {
+ suggestions = new ArrayList<>();
+ dndHints.setHint(KEY_SUGGESTIONS, suggestions);
+ }
- // Check if dragged object is symbol or component type and determine other
- Resource componentType;
- Resource symbol = graph.getPossibleObject(draggedResource, MOD.ComponentTypeToSymbol);
-
- if(symbol != null)
- componentType = draggedResource;
- else {
- componentType = graph.getPossibleObject(draggedResource, MOD.SymbolToComponentType);
- symbol = draggedResource;
- }
-
- // Prevent dragging a symbol of component type into its own configuration.
- if (componentType != null) {
- if (configuration != null) {
- Resource componentTypeFromDiagram = graph.getPossibleObject(configuration, STR.Defines);
- if (componentTypeFromDiagram != null && componentType.equals(componentTypeFromDiagram)) {
- return "Cannot instantiate user component within its own configuration.";
- }
- }
+ //System.out.println("dragged resource: " + draggedResource);
+ //System.out.println("drop target resource: " + dropTarget);
+ Resource sourceRoot = graph.syncRequest(new PossibleIndexRoot(draggedResource));
+ Resource targetRoot = graph.syncRequest(new PossibleIndexRoot(dropTarget));
+ //System.out.println("source model: " + sourceRoot);
+ //System.out.println("target model: " + targetRoot);
+
+ // Prevent dragging data from one source model to another.
+ // If source is not part of any model, everything is okay.
+ if (sourceRoot != null && !graph.syncRequest(new IsLinkedTo(targetRoot, sourceRoot))) {
+ // Prevent instantiation from source roots that are already dependent on the target root.
+ // This would form a dependency cycle.
+ if (graph.syncRequest(new IsLinkedTo(sourceRoot, targetRoot))) {
+ return NLS.bind("Cannot instantiate {0} into namespace {1}. The source namespace ({2}) is already linked to the target namespace. Linking the target to the source would form a dependency cycle.", //$NON-NLS-1$
+ new Object[] {
+ NameUtils.getSafeName(graph, draggedResource),
+ NameUtils.getURIOrSafeNameInternal(graph, targetRoot),
+ NameUtils.getURIOrSafeNameInternal(graph, sourceRoot)
+ });
}
- return symbol;
+ // It is OK to continue for now, even though the target root is not linked to the source root.
+ // The question of whether to link the target root to the source root will asked at drop time.
+ suggestions.add(DropSuggestions.linkToLibrary(graph, targetRoot, sourceRoot));
}
+
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+
+ Resource configurationComposite = graph.getPossibleObject(dropTarget, MOD.DiagramToComposite);
+ Resource componentTypeFromDiagram = configurationComposite != null ? graph.getPossibleObject(configurationComposite, STR.Defines) : null;
+
+ // Prevent dragging to published components
+ if (componentTypeFromDiagram != null && Layer0Utils.isPublished(graph, componentTypeFromDiagram))
+ return "Cannot create elements into a diagram that belongs to a published user component."; //$NON-NLS-1$
+
+ // Check if dragged object is symbol or component type and determine other
+ Resource componentType;
+ Resource symbol = graph.getPossibleObject(draggedResource, MOD.ComponentTypeToSymbol);
+ if (symbol != null)
+ componentType = draggedResource;
+ else {
+ componentType = graph.getPossibleObject(draggedResource, MOD.SymbolToComponentType);
+ symbol = draggedResource;
+ }
+
+ // Prevent dragging a symbol of component type into its own configuration.
+ if (componentType != null
+ && configurationComposite != null
+ && componentTypeFromDiagram != null
+ && componentType.equals(componentTypeFromDiagram)) {
+ return "Cannot instantiate user component within its own configuration."; //$NON-NLS-1$
+ }
+
+ return symbol;
});
}
}
private IElement tryPick(Point p) {
+ Point2D canvas = transformUtil.controlToCanvas(p, null);
- Point2D canvas = transformUtil.controlToCanvas(p, null);
-
assertDependencies();
PickRequest req = new PickRequest(canvas);
req.pickPolicy = PickRequest.PickPolicy.PICK_INTERSECTING_OBJECTS;
- List<IElement> picks = new ArrayList<IElement>();
+ List<IElement> picks = new ArrayList<>();
pickContext.pick(diagram, req, picks);
if(picks.size() == 1) return picks.iterator().next();
-
+
return null;
-
}
@Override
public void drop(DropTargetDropEvent dtde, final IDnDContext dp) {
- TimeLogger.resetTimeAndLog(getClass(), "drop");
+ TimeLogger.resetTimeAndLog(getClass(), "drop"); //$NON-NLS-1$
- final IDiagram d = getHint(DiagramHints.KEY_DIAGRAM);
+ final Point loc = dtde.getLocation();
+ final IDiagram d = diagram;
if (d == null)
return;
- IElement pick = tryPick(dtde.getLocation());
- if(pick != null) {
+ try {
+ validateDrop(d, dp, () -> performDrop(d, loc, dp));
+ } catch (DatabaseException e) {
+ LOGGER.error("Element drop validation failed", e); //$NON-NLS-1$
+ }
+ }
- final List<WorkbenchSelectionElement> wses = new ArrayList<WorkbenchSelectionElement>();
+ private void validateDrop(IDiagram diagram, IDnDContext dp, Runnable dropFunction)
+ throws DatabaseException {
+ List<DropSuggestion> reqs = dp.getHints().getHint(KEY_SUGGESTIONS);
+ if (reqs != null && !reqs.isEmpty()) {
+ // Ask user if suggestions should be ran before dropping.
+ // If not, cancel.
+ Shell parentShell = partSite.getWorkbenchWindow().getShell();
+ SWTUtils.asyncExec(parentShell, () -> {
+ if (parentShell.isDisposed())
+ return;
+ if (!DropSuggestions.askSuggestions(parentShell, reqs))
+ return;
- for(IDragItem i : dp.toArray())
- if(i instanceof WSEDragItem)
- wses.add(((WSEDragItem)i).getObject());
+ try {
+ Simantics.getSession().syncRequest(DropSuggestions.performSuggestionsRequest(reqs));
+
+ getThread().asyncExec(() -> {
+ if (isRemoved())
+ return;
+ dropFunction.run();
+ });
+ } catch (DatabaseException e) {
+ String format = Messages.PopulateElementDropParticipant_PreDropFixesFailed;
+ String formattedSuggestions = EString.implode(reqs);
+ LOGGER.error(format, formattedSuggestions, e);
+ ShowError.showError(Messages.PopulateElementDropParticipant_PreDropFixesFailed_Title, NLS.bind(format, formattedSuggestions), e);
+ }
+ });
+ } else {
+ dropFunction.run();
+ }
+ }
- final Resource element = (Resource)ElementUtils.getData(d, pick);
- if(element != null && !wses.isEmpty()) {
+ private void performDrop(IDiagram d, Point loc, IDnDContext dp) {
+ IElement pick = tryPick(loc);
+ if (pick != null) {
+ List<WorkbenchSelectionElement> wses = Arrays.stream(dp.toArray())
+ .filter(WSEDragItem.class::isInstance)
+ .map(di -> ((WSEDragItem) di).getObject())
+ .collect(Collectors.toList());
+ final Resource element = (Resource) ElementUtils.getData(d, pick);
+ if (element != null && !wses.isEmpty()) {
try {
Session db = Simantics.getSession();
DiagramResource DIA = DiagramResource.getInstance(db);
Variable function = db.syncRequest(new PossibleVariableProperty(element, DIA.symbolDropHandler));
if (function != null) {
- db.syncRequest(new WriteRequest() {
- @Override
- public void perform(WriteGraph graph) throws DatabaseException {
- Simantics.invokeSCLWrite(graph, function, wses);
- }
- });
+ db.syncRequest((Write) graph -> Simantics.invokeSCLWrite(graph, function, wses));
return;
}
} catch (DatabaseException e) {
Activator.getDefault().getLog()
.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
- "Invocation to custom symbolDropHandler for element "
- + element + " failed.",
+ "Invocation to custom symbolDropHandler for element " //$NON-NLS-1$
+ + element + " failed.", //$NON-NLS-1$
e));
return;
}
-
- }
-
-
+ }
}
-
- Runnable creator = new Runnable() {
- public void run() {
- DiagramUtils.mutateDiagram(d, m -> {
- IDragItem items[] = dp.toArray();
- for (IDragItem i : items) {
- if (!(i instanceof ElementClassDragItem))
- continue;
+ Runnable creator = () -> {
+ DiagramUtils.mutateDiagram(d, m -> {
+ IDragItem items[] = dp.toArray();
- ElementClassDragItem res = (ElementClassDragItem) i;
- ElementClass ec = res.getElementClass();
+ for (IDragItem i : items) {
+ if (!(i instanceof ElementClassDragItem))
+ continue;
- Point2D pos = dp.getItemPosition(i);
- // System.out.println(pos);
- assert (pos != null);
+ ElementClassDragItem res = (ElementClassDragItem) i;
+ ElementClass ec = res.getElementClass();
- IElement element = m.newElement(ec);
- element.setHints(res.getHintContext().getHints());
+ Point2D pos = dp.getItemPosition(i);
+ // System.out.println(pos);
+ assert (pos != null);
- setupDroppedElement(element, pos);
+ IElement element = m.newElement(ec);
+ element.setHints(res.getHintContext().getHints());
- // Remove only the drag items we've processed.
- dp.remove(i);
- }
- });
- }
+ setupDroppedElement(element, pos);
+
+ // Remove only the drag items we've processed.
+ dp.remove(i);
+ }
+ });
};
selectNewDiagramContentAfter(d, partSite, creator);
}
}
} catch (DatabaseException e) {
- Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Diagram content change tracking failed.", e));
+ Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Diagram content change tracking failed.", e)); //$NON-NLS-1$
}
}
public int getAllowedOps() {
return DnDConstants.ACTION_COPY;
}
-
+
@Override
public double getPriority() {
return 10.0;
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2018 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * 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:
+ * Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.modeling.ui.diagramEditor.dnd;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Shell;
+import org.simantics.NameLabelMode;
+import org.simantics.NameLabelUtil;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.ValidationException;
+import org.simantics.db.layer0.request.IsLinkedTo;
+import org.simantics.db.request.Write;
+import org.simantics.layer0.Layer0;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.37.0
+ */
+public class DropSuggestions {
+
+ public static boolean askSuggestions(Shell parent, List<DropSuggestion> suggestions) {
+ return Dialog.OK == MarkupDialog.open(parent,
+ "diagram.dropSuggestionDialog", //$NON-NLS-1$
+ Messages.DropSuggestions_ApplySuggestions_DialogTitle,
+ Messages.DropSuggestions_ApplySuggestions_DialogMsg,
+ formatSuggestions(suggestions),
+ SWT.ICON_QUESTION,
+ SWT.NONE,
+ SWT.BORDER | SWT.WRAP | SWT.V_SCROLL);
+ }
+
+ private static String formatSuggestions(List<DropSuggestion> suggestions) {
+ return suggestions.stream()
+ .map(DropSuggestion::toString)
+ .collect(Collectors.joining("\n", "- ", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ public static Write performSuggestionsRequest(List<DropSuggestion> suggestions) {
+ return (Write) graph -> {
+ for (DropSuggestion s : suggestions) {
+ s.fix(graph);
+ }
+ };
+ }
+
+ public static DropSuggestion linkToLibrary(ReadGraph graph, Resource linkSource, Resource linkTarget) throws DatabaseException {
+ return new LinkToLibrary(
+ NLS.bind(Messages.DropSuggestions_Description_LinkToLibrary,
+ NameLabelUtil.modalName(graph, linkSource, NameLabelMode.NAME_AND_LABEL),
+ NameLabelUtil.modalName(graph, linkTarget, NameLabelMode.NAME_AND_LABEL))
+ , linkSource, linkTarget);
+ }
+
+ public static class LinkToLibrary implements DropSuggestion {
+
+ private final String desc;
+ private final Resource linkFrom;
+ private final Resource linkTo;
+
+ public LinkToLibrary(String desc, Resource linkFrom, Resource linkTo) {
+ this.desc = desc;
+ this.linkFrom = linkFrom;
+ this.linkTo = linkTo;
+ }
+
+ @Override
+ public void fix(WriteGraph graph) throws DatabaseException {
+ // Ensure that there is no reverse link between the namespaces
+ if (graph.syncRequest(new IsLinkedTo(linkFrom, linkTo))) {
+ throw new ValidationException(
+ NLS.bind(Messages.DropSuggestions_Problem_CyclicDependency
+ , NameUtils.getURIOrSafeNameInternal(graph, linkTo)
+ , NameUtils.getURIOrSafeNameInternal(graph, linkFrom)));
+ }
+ Layer0 L0 = Layer0.getInstance(graph);
+ graph.claim(linkFrom, L0.IsLinkedTo, L0.IsLinkedTo_Inverse, linkTo);
+ }
+
+ @Override
+ public String toString() {
+ return desc;
+ }
+
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2018 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * 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:
+ * Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.modeling.ui.diagramEditor.dnd;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.text.Document;
+import org.eclipse.mylyn.wikitext.markdown.MarkdownLanguage;
+import org.eclipse.mylyn.wikitext.ui.viewer.MarkupViewer;
+import org.eclipse.mylyn.wikitext.ui.viewer.MarkupViewerConfiguration;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.simantics.modeling.ui.Activator;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.37.0
+ */
+class MarkupDialog extends Dialog {
+
+ private String title;
+ private String topText;
+ private String message;
+ private int dialogIconType;
+ private int viewerStyle;
+ private MarkupViewer viewer;
+
+ private IDialogSettings dialogBoundsSettings;
+
+ protected MarkupDialog(Shell parentShell, String dialogId, String title, String topText, String message, int dialogIconType, int viewerStyle) {
+ super(parentShell);
+ this.title = title;
+ this.topText = topText;
+ this.message = message;
+ this.dialogIconType = dialogIconType;
+ this.viewerStyle = viewerStyle;
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+
+ IDialogSettings settings = Activator.getDefault().getDialogSettings();
+ dialogBoundsSettings = settings.getSection(dialogId);
+ if (dialogBoundsSettings == null)
+ dialogBoundsSettings = settings.addNewSection(dialogId);
+ }
+
+ @Override
+ protected IDialogSettings getDialogBoundsSettings() {
+ return dialogBoundsSettings;
+ }
+
+ @Override
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ newShell.setText(title);
+ newShell.setImage(newShell.getDisplay().getSystemImage(dialogIconType));
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite) super.createDialogArea(parent);
+
+ Text text = new Text(composite, SWT.READ_ONLY | SWT.MULTI | SWT.WRAP);
+ text.setEditable(false);
+ text.setText(topText);
+ GridDataFactory.fillDefaults()
+ .grab(true, false)
+ .hint(convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH), SWT.DEFAULT)
+ .applyTo(text);
+
+ viewer = new MarkupViewer(composite, null, viewerStyle);
+ viewer.setMarkupLanguage(new MarkdownLanguage());
+ viewer.setEditable(false);
+ MarkupViewerConfiguration configuration = new MarkupViewerConfiguration(viewer, Activator.getDefault().getPreferenceStore());
+ viewer.configure(configuration);
+ viewer.setDocument(new Document(message));
+ GridDataFactory.fillDefaults()
+ .grab(true, true)
+ .hint(convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH), SWT.DEFAULT)
+ .applyTo(viewer.getControl());
+
+ return composite;
+ }
+
+ protected void createButtonsForButtonBar(Composite parent) {
+ createButton(parent, IDialogConstants.PROCEED_ID, IDialogConstants.PROCEED_LABEL, true);
+ createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+ }
+
+ @Override
+ protected void buttonPressed(int buttonId) {
+ if (IDialogConstants.PROCEED_ID == buttonId) {
+ okPressed();
+ } else if (IDialogConstants.CANCEL_ID == buttonId) {
+ cancelPressed();
+ }
+ }
+
+ public static int open(Shell parent, String dialogId, String title, String topText, String message, int dialogIconType, int dialogStyle, int sourceViewerStyle) {
+ MarkupDialog dialog = new MarkupDialog(parent, dialogId, title, topText, message, dialogIconType, sourceViewerStyle);
+ dialogStyle &= SWT.SHEET;
+ dialog.setShellStyle(dialog.getShellStyle() | dialogStyle);
+ return dialog.open();
+ }
+
+}
\ No newline at end of file