From: jsimomaa Date: Mon, 5 Nov 2018 14:07:02 +0000 (+0200) Subject: Add initial version of regions to source control X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=48d9ed8412b4a8dc45dcd9db351923046de7fead;p=simantics%2Fdistrict.git Add initial version of regions to source control gitlab #14 Change-Id: I57884758ed59938fa61ef6e4139d9771183a7e21 --- diff --git a/org.simantics.district.network.ontology/META-INF/MANIFEST.MF b/org.simantics.district.network.ontology/META-INF/MANIFEST.MF index 16df5e15..a4cb4e14 100644 --- a/org.simantics.district.network.ontology/META-INF/MANIFEST.MF +++ b/org.simantics.district.network.ontology/META-INF/MANIFEST.MF @@ -11,6 +11,7 @@ Require-Bundle: org.simantics.layer0, org.simantics.image2.ontology;bundle-version="1.2.0", org.simantics.selectionview.ontology;bundle-version="1.2.0", org.simantics.selectionview.ui.ontology;bundle-version="1.1.0", - org.simantics.g2d.ontology;bundle-version="1.1.0" + org.simantics.g2d.ontology;bundle-version="1.1.0", + org.simantics.layer0x.ontology;bundle-version="1.1.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Export-Package: org.simantics.district.network.ontology diff --git a/org.simantics.district.region.ontology/.classpath b/org.simantics.district.region.ontology/.classpath new file mode 100644 index 00000000..eca7bdba --- /dev/null +++ b/org.simantics.district.region.ontology/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.simantics.district.region.ontology/.project b/org.simantics.district.region.ontology/.project new file mode 100644 index 00000000..c549af01 --- /dev/null +++ b/org.simantics.district.region.ontology/.project @@ -0,0 +1,34 @@ + + + org.simantics.district.region.ontology + + + + + + org.simantics.graph.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.simantics.graph.nature + + diff --git a/org.simantics.district.region.ontology/META-INF/MANIFEST.MF b/org.simantics.district.region.ontology/META-INF/MANIFEST.MF new file mode 100644 index 00000000..2ec31d79 --- /dev/null +++ b/org.simantics.district.region.ontology/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Simantics Diagram Region Ontology +Bundle-SymbolicName: org.simantics.district.region.ontology +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.simantics.district.region.ontology.Activator +Bundle-Vendor: Semantum Oy +Require-Bundle: org.eclipse.core.runtime, + org.simantics.layer0, + org.simantics.diagram.ontology;bundle-version="2.2.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-ActivationPolicy: lazy +Export-Package: org.simantics.district.region.ontology diff --git a/org.simantics.district.region.ontology/build.properties b/org.simantics.district.region.ontology/build.properties new file mode 100644 index 00000000..e85b630a --- /dev/null +++ b/org.simantics.district.region.ontology/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + graph.tg diff --git a/org.simantics.district.region.ontology/graph.tg b/org.simantics.district.region.ontology/graph.tg new file mode 100644 index 00000000..2cc8f4c6 Binary files /dev/null and b/org.simantics.district.region.ontology/graph.tg differ diff --git a/org.simantics.district.region.ontology/graph/DiagramRegions.pgraph b/org.simantics.district.region.ontology/graph/DiagramRegions.pgraph new file mode 100644 index 00000000..c7774dba --- /dev/null +++ b/org.simantics.district.region.ontology/graph/DiagramRegions.pgraph @@ -0,0 +1,14 @@ +L0 = +DIA = + +DIARegions = : L0.Ontology + @L0.new + L0.HasResourceClass "org.simantics.district.region.ontology.DiagramRegionsResource" + +DIARegions.Region () { + public DiagramRegionsResource perform(ReadGraph graph) throws DatabaseException { + QueryControl qc = graph.getService(QueryControl.class); + return new DiagramRegionsResource(qc.getIndependentGraph(graph)); + } + }); + session.registerService(DiagramRegionsResource.class, ret); + } + return ret; + } + +} + diff --git a/org.simantics.district.region.ui/.classpath b/org.simantics.district.region.ui/.classpath new file mode 100644 index 00000000..eca7bdba --- /dev/null +++ b/org.simantics.district.region.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.simantics.district.region.ui/.project b/org.simantics.district.region.ui/.project new file mode 100644 index 00000000..2b5278c0 --- /dev/null +++ b/org.simantics.district.region.ui/.project @@ -0,0 +1,28 @@ + + + org.simantics.district.region.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.simantics.district.region.ui/META-INF/MANIFEST.MF b/org.simantics.district.region.ui/META-INF/MANIFEST.MF new file mode 100644 index 00000000..1d458788 --- /dev/null +++ b/org.simantics.district.region.ui/META-INF/MANIFEST.MF @@ -0,0 +1,23 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Simantics Diagram Region UI +Bundle-SymbolicName: org.simantics.district.region.ui;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.simantics.district.region.ui.Activator +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.e4.ui.di, + org.eclipse.e4.ui.model.workbench, + org.simantics, + org.simantics.district.region, + org.eclipse.e4.core.di.annotations, + org.simantics.ui, + org.eclipse.e4.ui.workbench, + org.slf4j.api, + org.simantics.g2d, + org.simantics.diagram, + org.simantics.modeling, + org.eclipse.e4.ui.services +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-ActivationPolicy: lazy +Export-Package: org.simantics.district.region.ui.handlers diff --git a/org.simantics.district.region.ui/build.properties b/org.simantics.district.region.ui/build.properties new file mode 100644 index 00000000..55c54efe --- /dev/null +++ b/org.simantics.district.region.ui/build.properties @@ -0,0 +1,6 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + fragment.e4xmi,\ + plugin.xml diff --git a/org.simantics.district.region.ui/fragment.e4xmi b/org.simantics.district.region.ui/fragment.e4xmi new file mode 100644 index 00000000..76544f9a --- /dev/null +++ b/org.simantics.district.region.ui/fragment.e4xmi @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.simantics.district.region.ui/plugin.xml b/org.simantics.district.region.ui/plugin.xml new file mode 100644 index 00000000..3fba72d3 --- /dev/null +++ b/org.simantics.district.region.ui/plugin.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/org.simantics.district.region.ui/src/org/simantics/district/region/ui/Activator.java b/org.simantics.district.region.ui/src/org/simantics/district/region/ui/Activator.java new file mode 100644 index 00000000..501e6dae --- /dev/null +++ b/org.simantics.district.region.ui/src/org/simantics/district/region/ui/Activator.java @@ -0,0 +1,50 @@ +package org.simantics.district.region.ui; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.simantics.district.region.ui"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/org.simantics.district.region.ui/src/org/simantics/district/region/ui/CreateRegionFromSelection.java b/org.simantics.district.region.ui/src/org/simantics/district/region/ui/CreateRegionFromSelection.java new file mode 100644 index 00000000..33759e2d --- /dev/null +++ b/org.simantics.district.region.ui/src/org/simantics/district/region/ui/CreateRegionFromSelection.java @@ -0,0 +1,84 @@ +package org.simantics.district.region.ui; + +import java.awt.geom.Rectangle2D; +import java.util.Set; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.workbench.modeling.ESelectionService; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.window.Window; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.progress.UIJob; +import org.simantics.Simantics; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.request.Write; +import org.simantics.diagram.ui.DiagramModelHints; +import org.simantics.district.region.DiagramRegions; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.diagram.participant.Selection; +import org.simantics.g2d.element.ElementUtils; +import org.simantics.g2d.element.IElement; +import org.simantics.utils.ui.workbench.WorkbenchUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CreateRegionFromSelection { + + private static final Logger LOGGER = LoggerFactory.getLogger(CreateRegionFromSelection.class); + + @CanExecute + public boolean canExecute(ESelectionService selectionService) { + return selectionService.getSelection() != null; + } + + @Execute + public void createRegionFromSelection() { + IEditorPart activeEditor = WorkbenchUtils.getActiveEditor(); + ICanvasContext context = activeEditor.getAdapter(ICanvasContext.class); + if (context != null) { + IDiagram diagram = activeEditor.getAdapter(IDiagram.class); + if (diagram != null) { + Resource diagramResource = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE); + Selection selection = context.getAtMostOneItemOfClass(Selection.class); + Set allSelections = selection.getAllSelections(); + Rectangle2D surroundingElementBoundsOnDiagram = ElementUtils.getSurroundingElementBoundsOnDiagram(allSelections); + double[] coordinates = DiagramRegions.shapeToCoordinates(surroundingElementBoundsOnDiagram); + + UIJob job = new UIJob("Creating new region for diagram") { + + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + InputDialog d = new InputDialog(getDisplay().getActiveShell(), "Enter label for region", "Enter region label", "", null); + int status = d.open(); + if (status == Window.OK) { + String label = d.getValue(); + Simantics.getSession().asyncRequest(new Write() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + DiagramRegions.createRegionForDiagram(graph, diagramResource, label, coordinates); + } + }); + } else { + + } + return Status.OK_STATUS; + } + }; + job.setUser(true); + job.schedule(); + } else { + LOGGER.warn("No diagram available for active editor {}", activeEditor); + } + } else { + LOGGER.warn("No CanvasContext available for active editor {}", activeEditor); + } + } +} diff --git a/org.simantics.district.region.ui/src/org/simantics/district/region/ui/DiagramRegionsTableUI.java b/org.simantics.district.region.ui/src/org/simantics/district/region/ui/DiagramRegionsTableUI.java new file mode 100644 index 00000000..f4b63978 --- /dev/null +++ b/org.simantics.district.region.ui/src/org/simantics/district/region/ui/DiagramRegionsTableUI.java @@ -0,0 +1,170 @@ +package org.simantics.district.region.ui; + +import java.awt.geom.Rectangle2D; +import java.text.DecimalFormat; +import java.util.Collection; +import java.util.Set; + +import org.eclipse.e4.ui.workbench.modeling.ESelectionService; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Tree; +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.common.procedure.adapter.SyncListenerAdapter; +import org.simantics.db.exception.DatabaseException; +import org.simantics.district.region.DiagramRegions; +import org.simantics.district.region.DiagramRegions.DiagramRegion; +import org.simantics.district.region.ui.handlers.ZoomToRegionHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DiagramRegionsTableUI extends Composite { + + private static final Logger LOGGER = LoggerFactory.getLogger(DiagramRegionsTableUI.class); + + private TreeViewer viewer; + private TreeViewerColumn column1; + private TreeViewerColumn column2; + + private ESelectionService selectionService; + + public DiagramRegionsTableUI(ESelectionService selectionService, Composite parent, int style) { + super(parent, style); + this.selectionService = selectionService; + parent.setLayout(new FillLayout()); +// GridDataFactory.fillDefaults().grab(true, true).applyTo(this); +// GridLayoutFactory.fillDefaults().numColumns(1).applyTo(this); + this.setLayout(new FillLayout()); + Simantics.getSession().asyncRequest(new DiagramRegions.DiagramRegionsRequest(), new SyncListenerAdapter>() { + + public void execute(ReadGraph graph, Collection result) { + parent.getDisplay().asyncExec(() -> { + viewer.setInput(result); + }); + } + + @Override + public void exception(ReadGraph graph, Throwable t) throws DatabaseException { + LOGGER.error("Could not listen", t); + } + + @Override + public boolean isDisposed() { + return DiagramRegionsTableUI.this.isDisposed(); + } + }); + + viewer = new TreeViewer(this, SWT.FULL_SELECTION); + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + + @Override + public void selectionChanged(SelectionChangedEvent event) { + DiagramRegionsTableUI.this.selectionService.setSelection(event.getSelection()); + } + }); + viewer.addDoubleClickListener(new IDoubleClickListener() { + + @Override + public void doubleClick(DoubleClickEvent event) { + LOGGER.info("event " + event); + TreeSelection selection = (TreeSelection) viewer.getSelection(); + DiagramRegion region = (DiagramRegion) selection.getFirstElement(); + ZoomToRegionHandler.zoomTo(viewer.getControl(), getDisplay(), region.getResource()); + } + }); + viewer.setContentProvider(new ITreeContentProvider() { + + @Override + public boolean hasChildren(Object element) { + return false; + } + + @Override + public Object getParent(Object element) { + return null; + } + + @Override + public Object[] getElements(Object inputElement) { + if (inputElement == null && (!(inputElement instanceof Collection))) + return new Object[0]; + Set set = (Set) inputElement; + return set.toArray(); + } + + @Override + public Object[] getChildren(Object parentElement) { + return null; + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + ITreeContentProvider.super.inputChanged(viewer, oldInput, newInput); + } + }); + + ColumnViewerToolTipSupport.enableFor(viewer); + + Tree table = viewer.getTree(); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + column1 = new TreeViewerColumn(viewer, SWT.NONE); + column1.getColumn().setText("Region"); + column1.getColumn().setWidth(200); + column1.getColumn().setResizable(true); + column1.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + DiagramRegion region = (DiagramRegion) element; + return region.getLabel(); + } + @Override + public Image getImage(Object element) { + return null; + } + }); + + column2 = new TreeViewerColumn(viewer, SWT.NONE); + column2.getColumn().setText("Coordinates"); + column2.getColumn().setWidth(200); + column2.getColumn().setResizable(true); + column2.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + DiagramRegion region = (DiagramRegion) element; + Rectangle2D rect = region.getShape().getBounds2D(); + DecimalFormat df = new DecimalFormat("0.00"); + String x = df.format(rect.getX()); + String y = df.format(rect.getY()); + String width = df.format(rect.getWidth()); + String height = df.format(rect.getHeight()); + return "[x=" + x + ", y=" + y + ", width=" + width + ", height=" + height + "]"; + } + @Override + public Image getImage(Object element) { + return null; + } + }); + + } + + public Tree getTree() { + return viewer.getTree(); + } + +} diff --git a/org.simantics.district.region.ui/src/org/simantics/district/region/ui/DiagramRegionsTableView.java b/org.simantics.district.region.ui/src/org/simantics/district/region/ui/DiagramRegionsTableView.java new file mode 100644 index 00000000..1fff18d1 --- /dev/null +++ b/org.simantics.district.region.ui/src/org/simantics/district/region/ui/DiagramRegionsTableView.java @@ -0,0 +1,83 @@ +package org.simantics.district.region.ui; + +import java.util.List; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.inject.Inject; + +import org.eclipse.e4.ui.di.Focus; +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.menu.MHandledToolItem; +import org.eclipse.e4.ui.model.application.ui.menu.MMenuContribution; +import org.eclipse.e4.ui.model.application.ui.menu.MMenuFactory; +import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu; +import org.eclipse.e4.ui.model.application.ui.menu.MToolBar; +import org.eclipse.e4.ui.services.EMenuService; +import org.eclipse.e4.ui.workbench.modeling.ESelectionService; +import org.eclipse.swt.widgets.Composite; + +/** + * @author Jani Simomaa + */ +public class DiagramRegionsTableView { + + DiagramRegionsTableUI ui; + + /** + * See + * http://www.vogella.com/tutorials/EclipsePlugin/article.html#adding-eclipse-4-x-parts-to-eclipse-3-x-applications-via-the-code-org-eclipse-ui-views-code-extension-point + * + * Cannot contribute toolbar items via fragment at this point + */ + @Inject + public void init(MPart part, MApplication app) { + MHandledToolItem createHandledToolItem = MMenuFactory.INSTANCE.createHandledToolItem(); + // Command is contributed via fragment + createHandledToolItem.setCommand(app.getCommand("org.simantics.district.region.ui.command.createRegionFromSelection")); + createHandledToolItem.setLabel("Create Region From Selection"); + createHandledToolItem.setIconURI("platform:/plugin/com.famfamfam.silk/icons/table_add.png"); + MToolBar toolBar = MMenuFactory.INSTANCE.createToolBar(); + toolBar.setToBeRendered(true); + toolBar.getChildren().add(createHandledToolItem); + part.setToolbar(toolBar); + + + MPopupMenu createPopupMenu = MMenuFactory.INSTANCE.createPopupMenu(); + createPopupMenu.setElementId(POPUP_ID); + createHandledToolItem.setContributorURI("org.simantics.district.region.ui.contextMenu"); + + List menuContributions = app.getMenuContributions(); + for (MMenuContribution menuContribution : menuContributions) { + if ("org.simantics.district.region.ui.contextMenu".equals(menuContribution.getParentId())) { + // ok, add to menu + createPopupMenu.getChildren().addAll(menuContribution.getChildren()); + } + } + + part.getMenus().add(createPopupMenu); + } + + public static final String POPUP_ID = "org.simantics.district.region.ui.popup"; + + @PostConstruct + public void postConstruct(ESelectionService selectionService, Composite parent, EMenuService menuService) { + // System.out.println("construct MPTV"); + this.ui = new DiagramRegionsTableUI(selectionService, parent, 0); + menuService.registerContextMenu(this.ui.getTree(), POPUP_ID); + } + + @PreDestroy + public void dispose() { + // System.out.println("dispose MPTV"); + ui.dispose(); + ui = null; + } + + @Focus + public void onFocus() { + ui.setFocus(); + } + +} \ No newline at end of file diff --git a/org.simantics.district.region.ui/src/org/simantics/district/region/ui/OpenDiagramRegionsTable.java b/org.simantics.district.region.ui/src/org/simantics/district/region/ui/OpenDiagramRegionsTable.java new file mode 100644 index 00000000..c4342985 --- /dev/null +++ b/org.simantics.district.region.ui/src/org/simantics/district/region/ui/OpenDiagramRegionsTable.java @@ -0,0 +1,19 @@ +package org.simantics.district.region.ui; + +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.workbench.modeling.ESelectionService; +import org.simantics.ui.workbench.e4.E4WorkbenchUtils; + +public class OpenDiagramRegionsTable { + + @CanExecute + public boolean canExecute(ESelectionService selectionService) { + return true; + } + + @Execute + public void openPropertyTable(ESelectionService selectionService) { + E4WorkbenchUtils.openAndShowPart("org.simantics.diagram.regions.diagramRegionsTable"); + } +} diff --git a/org.simantics.district.region.ui/src/org/simantics/district/region/ui/handlers/RemoveRegionHandler.java b/org.simantics.district.region.ui/src/org/simantics/district/region/ui/handlers/RemoveRegionHandler.java new file mode 100644 index 00000000..46b11a2f --- /dev/null +++ b/org.simantics.district.region.ui/src/org/simantics/district/region/ui/handlers/RemoveRegionHandler.java @@ -0,0 +1,39 @@ +package org.simantics.district.region.ui.handlers; + +import javax.inject.Named; + +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.services.IServiceConstants; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.Shell; +import org.simantics.Simantics; +import org.simantics.db.request.Write; +import org.simantics.district.region.DiagramRegions; +import org.simantics.district.region.DiagramRegions.DiagramRegion; +import org.simantics.utils.ui.ISelectionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RemoveRegionHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(RemoveRegionHandler.class); + public static final String COMMAND_ID = "org.simantics.district.region.ui.command.removeRegion"; + public static final String LABEL = "Remove Region"; + + @CanExecute + public boolean canExecute() { + return true; + } + + @Execute + public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell activeShell, + @Named(IServiceConstants.ACTIVE_PART) MPart part, + @Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) { + DiagramRegion region = ISelectionUtils.filterSingleSelection(selection, DiagramRegion.class); + Simantics.getSession().asyncRequest((Write) graph -> { + DiagramRegions.removeRegion(graph, region.getResource()); + }); + } +} diff --git a/org.simantics.district.region.ui/src/org/simantics/district/region/ui/handlers/ZoomToRegionHandler.java b/org.simantics.district.region.ui/src/org/simantics/district/region/ui/handlers/ZoomToRegionHandler.java new file mode 100644 index 00000000..47290bd7 --- /dev/null +++ b/org.simantics.district.region.ui/src/org/simantics/district/region/ui/handlers/ZoomToRegionHandler.java @@ -0,0 +1,124 @@ +package org.simantics.district.region.ui.handlers; + +import java.awt.Shape; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.inject.Named; + +import org.eclipse.e4.core.di.annotations.CanExecute; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.services.IServiceConstants; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPart; +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.ReadRequest; +import org.simantics.db.common.request.UniqueRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.district.region.DiagramRegions; +import org.simantics.district.region.DiagramRegions.DiagramRegion; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.diagram.handler.PickRequest; +import org.simantics.g2d.diagram.handler.impl.PickContextImpl; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.IElement; +import org.simantics.modeling.actions.NavigateToTarget; +import org.simantics.ui.workbench.action.DefaultActions; +import org.simantics.utils.threads.ThreadUtils; +import org.simantics.utils.ui.ISelectionUtils; +import org.simantics.utils.ui.workbench.WorkbenchUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ZoomToRegionHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(ZoomToRegionHandler.class); + public static final String COMMAND_ID = "org.simantics.district.region.ui.commands.zoomToRegion"; + public static final String LABEL = "Zoom To Region"; + + @CanExecute + public boolean canExecute() { + return true; + } + + @Execute + public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell activeShell, + @Named(IServiceConstants.ACTIVE_PART) MPart part, + @Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) { + DiagramRegion region = ISelectionUtils.filterSingleSelection(selection, DiagramRegion.class); + zoomTo(part, activeShell.getDisplay(), region.getResource()); + } + + public static void zoomTo(MPart part, Display display, Resource region) { + Resource dia; + try { + dia = Simantics.getSession().syncRequest(new UniqueRead() { + + @Override + public Resource perform(ReadGraph graph) throws DatabaseException { + return DiagramRegions.getDiagramForRegion(graph, region); + } + }); + + // get currentyl active workbench part + IWorkbenchPart beforePerformingDefaultAction = WorkbenchUtils.getActiveWorkbenchPart(); + IEditorPart activeEditor = WorkbenchUtils.getActiveEditor(); + LOGGER.info("activeWorkbenchPart {}", beforePerformingDefaultAction); + LOGGER.info("activeEditor {}", activeEditor); + DefaultActions.performDefaultAction((Control)part.getWidget(), dia); + Simantics.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + Shape shp = DiagramRegions.coordinatesToShape(graph, region); + display.asyncExec(() -> { + IWorkbenchPart afterPerformingDefaultAction = WorkbenchUtils.getActiveWorkbenchPart(); + LOGGER.info("afterActiveWorkbenchPart {}", afterPerformingDefaultAction); + int tries = 0; + while (Objects.equals(beforePerformingDefaultAction, afterPerformingDefaultAction) && tries <= 10) { + try { + Thread.sleep(150); + } catch (InterruptedException e) { + e.printStackTrace(); + } + afterPerformingDefaultAction = WorkbenchUtils.getActiveEditor(); + LOGGER.info("afterActiveWorkbenchPart {}", afterPerformingDefaultAction); + tries++; + } + LOGGER.info("afterActiveWorkbenchPart {}", afterPerformingDefaultAction); + if (beforePerformingDefaultAction.equals(afterPerformingDefaultAction)) { + LOGGER.warn("No can do"); + } else if (afterPerformingDefaultAction != null) { + // Okay, get the IDiagram now + IDiagram diagram = afterPerformingDefaultAction.getAdapter(IDiagram.class); + if (diagram == null) + LOGGER.warn("No can do - no IDiagram available"); + else { + Set elems = new HashSet<>(); + PickContextImpl.INSTANCE.pick(diagram, new PickRequest(shp), elems); + ICanvasContext context = afterPerformingDefaultAction.getAdapter(ICanvasContext.class); + List collect = elems.stream().map(el -> el.getHint(ElementHints.KEY_OBJECT)).collect(Collectors.toList()); + ThreadUtils.asyncExec(context.getThreadAccess(), NavigateToTarget.elementSelectorZoomer(context, collect, false)); + } + } else { + LOGGER.info("afterPerforming is null"); + } + }); + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); + } + } +} diff --git a/org.simantics.district.region/.classpath b/org.simantics.district.region/.classpath new file mode 100644 index 00000000..eca7bdba --- /dev/null +++ b/org.simantics.district.region/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.simantics.district.region/.project b/org.simantics.district.region/.project new file mode 100644 index 00000000..8879936c --- /dev/null +++ b/org.simantics.district.region/.project @@ -0,0 +1,28 @@ + + + org.simantics.district.region + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.simantics.district.region/META-INF/MANIFEST.MF b/org.simantics.district.region/META-INF/MANIFEST.MF new file mode 100644 index 00000000..0e4fe90c --- /dev/null +++ b/org.simantics.district.region/META-INF/MANIFEST.MF @@ -0,0 +1,19 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Simantics District Region +Bundle-SymbolicName: org.simantics.district.region +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.simantics.district.region.Activator +Require-Bundle: org.eclipse.core.runtime, + org.slf4j.api, + org.simantics.db, + org.simantics.district.region.ontology, + org.simantics.layer0;bundle-version="1.1.0", + org.simantics.db.layer0, + org.simantics.diagram.ontology, + org.simantics, + org.simantics.modeling.ontology, + org.simantics.modeling +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-ActivationPolicy: lazy +Export-Package: org.simantics.district.region diff --git a/org.simantics.district.region/build.properties b/org.simantics.district.region/build.properties new file mode 100644 index 00000000..a4fd10d4 --- /dev/null +++ b/org.simantics.district.region/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + scl/ diff --git a/org.simantics.district.region/scl/Simantics/Diagram/Regions.scl b/org.simantics.district.region/scl/Simantics/Diagram/Regions.scl new file mode 100644 index 00000000..d1ecf102 --- /dev/null +++ b/org.simantics.district.region/scl/Simantics/Diagram/Regions.scl @@ -0,0 +1,4 @@ +import "Simantics/Diagram" + +importJava "org.simantics.district.region.DiagramRegions" where + createRegionForDiagram :: Resource -> String -> Vector Double -> Resource \ No newline at end of file diff --git a/org.simantics.district.region/src/org/simantics/district/region/Activator.java b/org.simantics.district.region/src/org/simantics/district/region/Activator.java new file mode 100644 index 00000000..2ed5d3aa --- /dev/null +++ b/org.simantics.district.region/src/org/simantics/district/region/Activator.java @@ -0,0 +1,30 @@ +package org.simantics.district.region; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/org.simantics.district.region/src/org/simantics/district/region/DiagramRegions.java b/org.simantics.district.region/src/org/simantics/district/region/DiagramRegions.java new file mode 100644 index 00000000..57f31ae4 --- /dev/null +++ b/org.simantics.district.region/src/org/simantics/district/region/DiagramRegions.java @@ -0,0 +1,175 @@ +package org.simantics.district.region; + +import java.awt.Shape; +import java.awt.geom.FlatteningPathIterator; +import java.awt.geom.Path2D; +import java.awt.geom.PathIterator; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import org.simantics.Simantics; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.UniqueRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.QueryIndexUtils; +import org.simantics.db.layer0.request.PossibleActiveModel; +import org.simantics.db.layer0.util.RemoverUtil; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.district.region.ontology.DiagramRegionsResource; +import org.simantics.layer0.Layer0; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class DiagramRegions { + + private static final Logger LOGGER = LoggerFactory.getLogger(DiagramRegions.class); + + public static Resource createRegionForDiagram(WriteGraph graph, Resource diagram, String label, double[] coordinates) throws DatabaseException { + if (coordinates == null || coordinates.length < 6 || coordinates.length % 2 != 0) + throw new IllegalArgumentException("Provided coordinates are not valid : " + Arrays.toString(coordinates)); + Path2D path = new Path2D.Double(); + double startX = coordinates[0]; + double startY = coordinates[1]; + path.moveTo(startX, startY); + for (int i = 2; i < coordinates.length; i++) + path.lineTo(coordinates[i], coordinates[++i]); + + path.closePath(); // might not be needed + DiagramRegionsResource DRR = DiagramRegionsResource.getInstance(graph); + Layer0 L0 = Layer0.getInstance(graph); + Resource region = graph.newResource(); + graph.claim(region, L0.InstanceOf, DRR.Region); + graph.claim(diagram, DRR.hasRegion, region); + graph.claim(region, DRR.regionOf, diagram); + graph.claimLiteral(region, L0.HasName, UUID.randomUUID().toString(), Bindings.STRING); + graph.claimLiteral(region, L0.HasLabel, label, Bindings.STRING); + graph.claimLiteral(region, DRR.Region_area, coordinates, Bindings.DOUBLE_ARRAY); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Created region for diagram {} with label {} and area {}", diagram, label, Arrays.toString(coordinates)); + return region; + } + + public static void removeRegion(WriteGraph graph, Resource region) throws DatabaseException { + RemoverUtil.remove(graph, region); + } + + public static class DiagramRegion { + + private Resource resource; + private String label; + private Shape shape; + + public DiagramRegion(Resource resource, String label, Shape coordinatesToShape) { + this.resource = resource; + this.label = label; + this.shape = coordinatesToShape; + } + + public Resource getResource() { + return resource; + } + + public String getLabel() { + return label; + } + + public Shape getShape() { + return shape; + } + } + + public static Collection findRegions(ReadGraph graph, Resource model) throws DatabaseException { + List diagrams = QueryIndexUtils.searchByType(graph, model, DiagramResource.getInstance(graph).Diagram); + Set regions = new HashSet<>(); + + Layer0 L0 = Layer0.getInstance(graph); + + for (Resource diagram : diagrams) { + Collection region = graph.getObjects(diagram, DiagramRegionsResource.getInstance(graph).hasRegion); + for (Resource r : region) { + String label = graph.getRelatedValue(r, L0.HasLabel, Bindings.STRING); + Shape coordinatesToShape = DiagramRegions.coordinatesToShape(graph, r); + regions.add(new DiagramRegion(r, label, coordinatesToShape)); + } + } + return regions; + } + + public static class DiagramRegionsRequest extends UniqueRead> { + + @Override + public Collection perform(ReadGraph graph) throws DatabaseException { + return findRegions(graph, graph.syncRequest(new PossibleActiveModel(Simantics.getProjectResource()))); + } + } + + public static Shape coordinatesToShape(ReadGraph graph, Resource region) throws DatabaseException { + DiagramRegionsResource DRR = DiagramRegionsResource.getInstance(graph); + double[] coordinates = graph.getRelatedValue(region, DRR.Region_area, Bindings.DOUBLE_ARRAY); + Path2D path = new Path2D.Double(); + double startX = coordinates[0]; + double startY = coordinates[1]; + path.moveTo(startX, startY); + for (int i = 2; i < coordinates.length; i++) + path.lineTo(coordinates[i], coordinates[++i]); + + path.closePath(); // might not be needed + return path; + } + + public static double[] shapeToCoordinates(Shape shape) { + PathIterator it = new FlatteningPathIterator(shape.getPathIterator(null), 1); + double points[] = new double[6]; + double moveX = 0, moveY = 0; + double thisX = 0, thisY = 0; + int type = 0; + + List coords = new ArrayList<>(); + // float factor = 1; + + while (!it.isDone()) { + type = it.currentSegment(points); + switch (type) { + case PathIterator.SEG_MOVETO: + moveX = points[0]; + moveY = points[1]; + coords.add(moveX); + coords.add(moveY); + break; + + case PathIterator.SEG_CLOSE: + points[0] = moveX; + points[1] = moveY; + // Fall into.... + + case PathIterator.SEG_LINETO: + thisX = points[0]; + thisY = points[1]; + coords.add(thisX); + coords.add(thisY); + break; + } + it.next(); + } + double[] finalCoords = new double[coords.size()]; + for (int i = 0; i < coords.size(); i++) { + double d = coords.get(i); + finalCoords[i] = d; + } + return finalCoords; + } + + public static Resource getDiagramForRegion(ReadGraph graph, Resource region) throws DatabaseException { + DiagramRegionsResource DRR = DiagramRegionsResource.getInstance(graph); + Resource diagram = graph.getSingleObject(region, DRR.regionOf); + return diagram; + } +} diff --git a/org.simantics.district.regions.feature/.project b/org.simantics.district.regions.feature/.project new file mode 100644 index 00000000..4b7cafe5 --- /dev/null +++ b/org.simantics.district.regions.feature/.project @@ -0,0 +1,17 @@ + + + org.simantics.district.regions.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/org.simantics.district.regions.feature/build.properties b/org.simantics.district.regions.feature/build.properties new file mode 100644 index 00000000..64f93a9f --- /dev/null +++ b/org.simantics.district.regions.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/org.simantics.district.regions.feature/feature.xml b/org.simantics.district.regions.feature/feature.xml new file mode 100644 index 00000000..e7eb621a --- /dev/null +++ b/org.simantics.district.regions.feature/feature.xml @@ -0,0 +1,40 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + + +