From: jsimomaa Date: Fri, 30 Jun 2017 10:30:57 +0000 (+0300) Subject: View for used SCL expressions X-Git-Tag: v1.31.0~286^2 X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=72a9c7e8e607ef7797116b55312a60aa6ebe8db6 View for used SCL expressions refs #7344 Change-Id: Ic2e902fc9742afce80e1ead764528e8eb35704a6 --- diff --git a/bundles/org.simantics.modeling.ui/icons/arrow_refresh.png b/bundles/org.simantics.modeling.ui/icons/arrow_refresh.png new file mode 100644 index 000000000..0de26566d Binary files /dev/null and b/bundles/org.simantics.modeling.ui/icons/arrow_refresh.png differ diff --git a/bundles/org.simantics.modeling.ui/plugin.xml b/bundles/org.simantics.modeling.ui/plugin.xml index c6596a7b0..64d39a0e2 100644 --- a/bundles/org.simantics.modeling.ui/plugin.xml +++ b/bundles/org.simantics.modeling.ui/plugin.xml @@ -40,6 +40,14 @@ + + properties = new Hashtable(); context.registerService(SCLConsoleListener.class, new SCLConsoleListener() { @@ -202,6 +206,7 @@ public class Activator extends AbstractUIPlugin { reg.put("arrowDown", ARROW_DOWN_ICON); reg.put("showProfileMonitors", SHOW_PROFILE_MONITOR_ICON); reg.put("hideProfileMonitors", HIDE_PROFILE_MONITOR_ICON); + reg.put("arrow_refresh", ARROW_REFRESH); } /* diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionItemFilter.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionItemFilter.java new file mode 100644 index 000000000..bcc8b02e6 --- /dev/null +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionItemFilter.java @@ -0,0 +1,24 @@ +package org.simantics.modeling.ui.scl.expressions; + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; + +public class SCLExpressionItemFilter extends ViewerFilter { + + private String searchString; + + public void setSearchText(String s) { + // ensure that the value can be used for matching + this.searchString = (".*" + s + ".*").toLowerCase(); + } + + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (searchString == null || searchString.length() == 0) + return true; + SCLExpressionTableEntry entry = (SCLExpressionTableEntry) element; + if (entry.getContent().toLowerCase().matches(searchString)) + return true; + return false; + } +} \ No newline at end of file diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionTableEntry.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionTableEntry.java new file mode 100644 index 000000000..6cfb46023 --- /dev/null +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionTableEntry.java @@ -0,0 +1,34 @@ +package org.simantics.modeling.ui.scl.expressions; + +import org.simantics.db.Resource; + +public class SCLExpressionTableEntry implements Comparable { + + private final String content; + private final String location; + private final Resource resource; + + public SCLExpressionTableEntry(String content, String position, Resource resource) { + this.content = content; + this.location = position; + this.resource = resource; + } + + public String getContent() { + return content; + } + + public String getLocation() { + return location; + } + + public Resource getResource() { + return resource; + } + + @Override + public int compareTo(SCLExpressionTableEntry o) { + return o.getContent().compareTo(content); + } + +} diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionView.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionView.java new file mode 100644 index 000000000..d9bf77e47 --- /dev/null +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionView.java @@ -0,0 +1,192 @@ +package org.simantics.modeling.ui.scl.expressions; + +import java.util.Collection; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.ViewPart; +import org.simantics.DatabaseJob; +import org.simantics.Simantics; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.modeling.ui.Activator; +import org.simantics.ui.workbench.action.ChooseActionRequest; +import org.simantics.utils.ui.workbench.WorkbenchUtils; + +public class SCLExpressionView extends ViewPart { + + private TableViewer tableViewer; + private TableViewerColumn expressionColumn; + private TableViewerColumn locationColumn; + + private ImageRegistry imageRegistry; + private IStructuredContentProvider expressionContentProvider; + private SCLExpressionItemFilter expressionFilter; + + public SCLExpressionView() { + imageRegistry = Activator.getDefault().getImageRegistry(); + expressionContentProvider = ArrayContentProvider.getInstance(); + } + + @Override + public void init(IViewSite site, IMemento memento) throws PartInitException { + super.init(site, memento); + IAction action = new Action("Refresh") { + @Override + public void run() { + scheduleUpdateEntries(); + } + }; + action.setImageDescriptor(imageRegistry.getDescriptor("arrow_refresh")); + site.getActionBars().getToolBarManager().add(action); + } + + private void createFilter(Composite parent) { + expressionFilter = new SCLExpressionItemFilter(); + + Text searchText = new Text(parent, SWT.BORDER | SWT.SEARCH); + GridDataFactory.fillDefaults().grab(true, false).applyTo(searchText); + searchText.addKeyListener(new KeyAdapter() { + + @Override + public void keyReleased(KeyEvent e) { + expressionFilter.setSearchText(searchText.getText()); + tableViewer.refresh(); + } + }); + } + + @Override + public void createPartControl(Composite parent) { + parent.setLayout(new GridLayout(1, false)); + GridDataFactory.fillDefaults().grab(true, true).applyTo(parent); + createFilter(parent); + + Composite tableParent = new Composite(parent, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(tableParent); + + tableViewer = new TableViewer(tableParent, + SWT.FULL_SELECTION | SWT.SINGLE | SWT.V_SCROLL | SWT.H_SCROLL | SWT.VIRTUAL); + ColumnViewerToolTipSupport.enableFor(tableViewer); + tableViewer.setContentProvider(expressionContentProvider); + tableViewer.addFilter(expressionFilter); + + Table table = tableViewer.getTable(); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + TableColumnLayout layout = new TableColumnLayout(); + tableParent.setLayout(layout); + + expressionColumn = new TableViewerColumn(tableViewer, SWT.NONE); + expressionColumn.getColumn().setText("Expression"); + expressionColumn.getColumn().setResizable(true); + expressionColumn.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + SCLExpressionTableEntry entry = (SCLExpressionTableEntry) element; + return entry.getContent(); + } + }); + + layout.setColumnData(expressionColumn.getColumn(), new ColumnWeightData(100)); + + locationColumn = new TableViewerColumn(tableViewer, SWT.NONE); + locationColumn.getColumn().setText("Location"); + locationColumn.getColumn().setResizable(false); + locationColumn.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + SCLExpressionTableEntry entry = (SCLExpressionTableEntry) element; + if (entry.getLocation() != null) + return entry.getLocation(); + return "null"; + } + }); + + layout.setColumnData(locationColumn.getColumn(), new ColumnWeightData(100)); + tableViewer.addDoubleClickListener(new IDoubleClickListener() { + @Override + public void doubleClick(DoubleClickEvent event) { + IStructuredSelection selection = (IStructuredSelection) event.getSelection(); + SCLExpressionTableEntry entry = (SCLExpressionTableEntry) selection.getFirstElement(); + + openResource(tableViewer.getControl().getDisplay().getActiveShell(), entry.getResource()); + } + }); + scheduleUpdateEntries(); + } + + private void scheduleUpdateEntries() { + Job updateJob = new DatabaseJob("Update used SCL expressions") { + + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + Collection result = Simantics.getSession() + .syncRequest(new UsedSCLExpressionsRequest()); + tableViewer.getTable().getDisplay().asyncExec(() -> { + tableViewer.setInput(result); + }); + return Status.OK_STATUS; + } catch (DatabaseException e) { + e.printStackTrace(); + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Could not update SCL expressions", e); + } + } + }; + updateJob.schedule(); + } + + private static void openResource(Shell shell, Resource resource) { + try { + ISelection input = new StructuredSelection(resource); + String perspectiveId = WorkbenchUtils.getCurrentPerspectiveId(); + // Try the doubleClick-extensions + Simantics.getSession().asyncRequest(new ChooseActionRequest(shell, input, perspectiveId, false, true)); + } catch (NumberFormatException e) { + return; + } + } + + @Override + public void setFocus() { + tableViewer.getControl().setFocus(); + } + + @Override + public void dispose() { + super.dispose(); + } + +} diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/UsedSCLExpressionsRequest.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/UsedSCLExpressionsRequest.java new file mode 100644 index 000000000..4e62af237 --- /dev/null +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/UsedSCLExpressionsRequest.java @@ -0,0 +1,90 @@ +package org.simantics.modeling.ui.scl.expressions; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import org.simantics.Simantics; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Statement; +import org.simantics.db.common.request.UniqueRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.Layer0Utils; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingUtils; +import org.simantics.structural.stubs.StructuralResource2; + +public class UsedSCLExpressionsRequest extends UniqueRead> { + + @Override + public Collection perform(ReadGraph graph) throws DatabaseException { + Collection result = new ArrayList<>(); + Layer0 L0 = Layer0.getInstance(graph); + + Set indexRoots = new TreeSet(); + for(Resource ontology : Layer0Utils.listOntologies(graph)) { + if (graph.isInstanceOf(ontology, L0.SharedOntology)) { + indexRoots.add(ontology); + } + } + + for(Resource child : graph.getObjects(Simantics.getProjectResource(), L0.ConsistsOf)) { + if (graph.isInstanceOf(child, L0.IndexRoot)) { + indexRoots.add(child); + } + } + + for (Resource ontology : indexRoots) { +// List modules = ModelingUtils.searchByTypeShallow(graph, ontology, L0.SCLModule); +// for (Resource module : modules) { +// String definition = graph.getPossibleRelatedValue2(module, L0.SCLModule_definition); +// Matcher matcher = pattern.matcher(definition); +// while (matcher.find()) { +// int index = matcher.start(); +// int line = 1; +// int pos = 0; +// while ((pos = definition.indexOf("\n", pos) + 1) > 0 && pos <= index) { +// line++; +// } +// String position = graph.getPossibleURI(module) + ":" + line; +// int lineBeginIndex = definition.lastIndexOf("\n", index); +// if (lineBeginIndex == -1) lineBeginIndex = 0; +// int lineEndIndex = definition.indexOf("\n", index); +// if (lineEndIndex <= 0) lineEndIndex = definition.length(); +// String content = definition.substring(lineBeginIndex, lineEndIndex).trim(); +// +// result.add(new SCLExpressionTableEntry(content, position)); +// } +// } + + StructuralResource2 STR = StructuralResource2.getInstance(graph); + + List components = ModelingUtils.searchByTypeShallow(graph, ontology, STR.Component); + for (Resource component : components) { + for (Statement propertyStatement : graph.getStatements(component, L0.HasProperty)) { + if (graph.isInstanceOf(propertyStatement.getObject(), L0.SCLValue)) { + Resource sclValue = propertyStatement.getObject(); + String expression = graph.getPossibleRelatedValue2(sclValue, L0.SCLValue_expression); + Resource source = graph.getPossibleObject(sclValue, L0.PropertyOf); + if (source != null) { + String uri = graph.getPossibleURI(source); + String pred = graph.getRelatedValue2(propertyStatement.getPredicate(), L0.HasName); + + if (uri != null) { +// SCLReporting.print(); +// SCLReporting.printError(expression + "\n"); + + result.add(new SCLExpressionTableEntry(expression, uri + "#" + pred, source)); + } + } + } + } + } + } + return result; + } + +}