From 0b471805f017da83d715a0d8409f53bdd009d31e Mon Sep 17 00:00:00 2001 From: Tuukka Lehtonen Date: Wed, 19 Oct 2016 01:16:53 +0300 Subject: [PATCH] Sync git svn branch with SVN repository r33345. refs #6654 refs #6766 refs #6769 refs #6770 refs #6771 refs #6772 refs #6773 --- .../model/browsecontexts/BrowseContext.java | 6 +- .../ui/nattable/KeyToSelectionAdapter.java | 10 --- .../server/io/IAbstractRequestInterface.java | 1 + .../ui/actions/ExportDocumentFile.java | 13 +++- .../ui/actions/ExportDocumentFolder.java | 9 ++- .../document/ui/actions/ImportDocument.java | 75 ++++++++++++++----- .../document/ui/actions/NewFileDocument.java | 63 ++++++++++++++++ .../ui/graphfile/FileDocumentUtil.java | 10 +-- .../graphfile/util/GraphFileUtil.java | 24 +++++- .../ui/actions/ModeledDoubleClickActions.java | 2 +- .../diagram/style/IssueDecorationStyle.java | 53 +++++++------ .../simantics/utils/format/TimeFormat.java | 8 +- 12 files changed, 207 insertions(+), 67 deletions(-) create mode 100644 bundles/org.simantics.document.ui/src/org/simantics/document/ui/actions/NewFileDocument.java diff --git a/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/browsecontexts/BrowseContext.java b/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/browsecontexts/BrowseContext.java index a1eaf78a8..8d5a427c2 100644 --- a/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/browsecontexts/BrowseContext.java +++ b/bundles/org.simantics.browsing.ui.model/src/org/simantics/browsing/ui/model/browsecontexts/BrowseContext.java @@ -261,7 +261,11 @@ public class BrowseContext { public static ArrayList augment(ReadGraph graph, BrowseContext bc, Collection contexts, boolean resolveABC) throws DatabaseException { ArrayList result = new ArrayList(); for(NodeContext context : contexts) { - ActionBrowseContext abc = resolveABC ? graph.syncRequest(new ResolveActionBrowseContext(context)) : null; + ActionBrowseContext abc = null; + if(resolveABC) { + abc = graph.syncRequest(new ResolveActionBrowseContext(context)); + if(abc == null) abc = (ActionBrowseContext)context.getConstant(BuiltinKeys.ACTION_BROWSE_CONTEXT); + } result.add(NodeContextBuilder.buildWithData(NodeType.KEY_SEQUENCE_EXT, new Object[] { context.getConstant(BuiltinKeys.INPUT), diff --git a/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/KeyToSelectionAdapter.java b/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/KeyToSelectionAdapter.java index 9d43c351f..daf28f5d4 100644 --- a/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/KeyToSelectionAdapter.java +++ b/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/KeyToSelectionAdapter.java @@ -14,9 +14,6 @@ import org.simantics.utils.ui.AdaptionUtils; /** * Selects tree items based on pressed key events.

* - * The default implementation of SWT.Tree (Windows?) uses only the the first column when matching the items.

- * - * This implementation checks all columns. Override

matches(), matchesColumn()
for customized behavior.

* * @author Marko Luukkainen * @@ -58,8 +55,6 @@ public class KeyToSelectionAdapter extends KeyAdapter { prevEvent = e.time; matcher = matcher += Character.toString(e.character); - - //TreeItem item = null; NatTable tree = explorer.getControl(); columns = explorer.getColumns().length; @@ -77,10 +72,6 @@ public class KeyToSelectionAdapter extends KeyAdapter { if (item != null) { explorer.select(item); explorer.show(item); -// tree.select(item); -// tree.showItem(item); - - } // without this the default handling would take over. e.doit = false; @@ -159,5 +150,4 @@ public class KeyToSelectionAdapter extends KeyAdapter { return false; } - } diff --git a/bundles/org.simantics.document.server.io/src/org/simantics/document/server/io/IAbstractRequestInterface.java b/bundles/org.simantics.document.server.io/src/org/simantics/document/server/io/IAbstractRequestInterface.java index dce45ac05..9e736c821 100644 --- a/bundles/org.simantics.document.server.io/src/org/simantics/document/server/io/IAbstractRequestInterface.java +++ b/bundles/org.simantics.document.server.io/src/org/simantics/document/server/io/IAbstractRequestInterface.java @@ -18,4 +18,5 @@ public interface IAbstractRequestInterface { public IJSONResult readChanges(String uri, String sessionGUID, int sequenceNumber); public void initializeDocument(String documentURI, String sessionGUID, CommandContext context); public void onPoll(String sessionGUID); + public String escapeURI(String unicode); } diff --git a/bundles/org.simantics.document.ui/src/org/simantics/document/ui/actions/ExportDocumentFile.java b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/actions/ExportDocumentFile.java index c612f99bc..090437081 100644 --- a/bundles/org.simantics.document.ui/src/org/simantics/document/ui/actions/ExportDocumentFile.java +++ b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/actions/ExportDocumentFile.java @@ -24,6 +24,7 @@ import org.simantics.db.request.Read; import org.simantics.document.DocumentResource; import org.simantics.graphfile.ontology.GraphFileResource; import org.simantics.graphfile.util.GraphFileUtil; +import org.simantics.layer0.Layer0; import org.simantics.ui.SimanticsUI; import org.simantics.utils.ui.ExceptionUtils; @@ -48,18 +49,24 @@ public class ExportDocumentFile implements ActionFactory { @Override public void run() { try { - String resourceName = SimanticsUI.getSession().syncRequest(new Read() { + String name = SimanticsUI.getSession().syncRequest(new Read() { public String perform(ReadGraph graph) throws DatabaseException { DocumentResource doc = DocumentResource.getInstance(graph); GraphFileResource gf = GraphFileResource.getInstance(graph); if (!graph.isInstanceOf(resource, doc.FileDocument)) return null; - return graph.getPossibleRelatedValue(resource, gf.HasResourceName); + String resourceName = graph.getPossibleRelatedValue(resource, gf.HasResourceName); + if (resourceName != null) { + return resourceName; + } else { + Layer0 L0 = Layer0.getInstance(graph); + return graph.getPossibleRelatedValue(resource, L0.HasName); + } }; }); FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(),SWT.SAVE); - dialog.setFileName(resourceName); + dialog.setFileName(name); final String filename = dialog.open(); if (filename == null) return; diff --git a/bundles/org.simantics.document.ui/src/org/simantics/document/ui/actions/ExportDocumentFolder.java b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/actions/ExportDocumentFolder.java index e597ad54d..929598402 100644 --- a/bundles/org.simantics.document.ui/src/org/simantics/document/ui/actions/ExportDocumentFolder.java +++ b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/actions/ExportDocumentFolder.java @@ -38,9 +38,16 @@ import org.simantics.graphfile.util.GraphFileUtil; */ public class ExportDocumentFolder implements ActionFactory { Resource relation; + boolean useResourceNames; public ExportDocumentFolder(ReadGraph graph, String relationUri) throws DatabaseException { relation = graph.getResource(relationUri); + useResourceNames = true; + } + + public ExportDocumentFolder(ReadGraph graph, String relationUri, String useResourceNames) throws DatabaseException { + relation = graph.getResource(relationUri); + this.useResourceNames = useResourceNames.equals("true"); } @Override @@ -95,7 +102,7 @@ public class ExportDocumentFolder implements ActionFactory { GraphFileUtil.clearDirectoryStructure(folder); monitor.worked(1); } - FileDocumentUtil.exportDocumentFolder(resource, folder, relation,monitor); + FileDocumentUtil.exportDocumentFolder(resource, folder, relation, useResourceNames, monitor); monitor.done(); return new Status(IStatus.OK, Activator.PLUGIN_ID, "Folder exported."); } catch (Exception e) { diff --git a/bundles/org.simantics.document.ui/src/org/simantics/document/ui/actions/ImportDocument.java b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/actions/ImportDocument.java index ca50c8bb3..7a9595263 100644 --- a/bundles/org.simantics.document.ui/src/org/simantics/document/ui/actions/ImportDocument.java +++ b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/actions/ImportDocument.java @@ -11,18 +11,23 @@ *******************************************************************************/ package org.simantics.document.ui.actions; +import java.io.File; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; +import org.simantics.DatabaseJob; import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.exception.DatabaseException; +import org.simantics.document.ui.Activator; import org.simantics.document.ui.graphfile.FileDocumentUtil; -import org.simantics.utils.datastructures.Callback; -import org.simantics.utils.ui.ExceptionUtils; /** * Action for importing files as documents. @@ -46,34 +51,64 @@ public class ImportDocument extends AddDocumentAction { @Override public void run() { - FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(),SWT.OPEN); + FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(),SWT.OPEN | SWT.MULTI); // TODO : is there any way to read file/executable bindings from OS? // if is, use those extensions to filter this list. // note: in windows using "reg query ..." to read bindings form registry would work. + // Note : If the above mentioned filtering is implemented it should be made optional / configurable. dialog.setFilterExtensions(new String[]{"*.*"}); - final String filename = dialog.open(); - if (filename == null) { - return; - } - Simantics.getSession().asyncRequest(new WriteRequest() { + if (dialog.open() == null) return; + + String filterPath = dialog.getFilterPath(); + String[] filenames = dialog.getFileNames(); + + ImportJob job = new ImportJob(filenames.length > 1 ? "Import files" : "Import file", resource, filterPath, filenames); + job.setUser(true); + job.schedule(); + } + }; + } + + private class ImportJob extends DatabaseJob { + + public ImportJob(String name, Resource resource, String path, String[] filenames) { + super(name); + this.resource = resource; + this.path = path; + this.filenames = filenames; + } + + Resource resource; + String path; + String[] filenames; + + @Override + protected IStatus run(final IProgressMonitor monitor) { + monitor.beginTask("Importing...", filenames.length); + try { + Simantics.getSession().syncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { - graph.markUndoPoint(); - - Resource newDoc = FileDocumentUtil.importFileWithName(graph,filename); - linkDocument(graph, resource, newDoc); - } - },new Callback() { - @Override - public void run(DatabaseException parameter) { - if (parameter != null) { - ExceptionUtils.logAndShowError("Cannot import document.", parameter); + try { + graph.markUndoPoint(); + for (String filename : filenames) { + File f = new File(path, filename); + Resource newDoc = FileDocumentUtil.importFileWithName(graph, f.getAbsolutePath()); + linkDocument(graph, resource, newDoc); + monitor.worked(1); + } + } catch (Exception e) { + throw new DatabaseException(e); } - } }); + return new Status(IStatus.OK, Activator.PLUGIN_ID, "Import succesful."); + } catch (DatabaseException e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import failed.", e); + } finally { + monitor.done(); } - }; + } } } diff --git a/bundles/org.simantics.document.ui/src/org/simantics/document/ui/actions/NewFileDocument.java b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/actions/NewFileDocument.java new file mode 100644 index 000000000..9ddf2c000 --- /dev/null +++ b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/actions/NewFileDocument.java @@ -0,0 +1,63 @@ +package org.simantics.document.ui.actions; + +import java.io.IOException; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +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.adapter.ActionFactory; +import org.simantics.document.DocumentResource; +import org.simantics.graphfile.util.GraphFileUtil; +import org.simantics.layer0.Layer0; +import org.simantics.ui.SimanticsUI; + +public class NewFileDocument implements ActionFactory { + Resource relation; + String defaultName; + + public NewFileDocument(ReadGraph graph, String relationUri, String defaultName) throws DatabaseException { + relation = graph.getResource(relationUri); + this.defaultName = defaultName; + } + + @Override + public Runnable create(Object target) { + + if(!(target instanceof Resource)) + return null; + + final Resource resource = (Resource)target; + + return new Runnable() { + @Override + public void run() { + SimanticsUI.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + graph.markUndoPoint(); + + Layer0 l0 = Layer0.getInstance(graph); + + String name = NameUtils.findFreshName(graph, defaultName, resource, relation); + DocumentResource doc = DocumentResource.getInstance(graph); + + Resource fileResource = graph.newResource(); + graph.claim(fileResource, l0.InstanceOf, doc.FileDocument); + graph.claimLiteral(fileResource, l0.HasName, name); + graph.claim(resource, relation, fileResource); + try { + GraphFileUtil.writeDataToGraph(graph, new byte[0], fileResource); + } catch (IOException e) { + throw new DatabaseException(e); + } + } + + }); + } + }; + } +} diff --git a/bundles/org.simantics.document.ui/src/org/simantics/document/ui/graphfile/FileDocumentUtil.java b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/graphfile/FileDocumentUtil.java index 35b881328..ece4a38a5 100644 --- a/bundles/org.simantics.document.ui/src/org/simantics/document/ui/graphfile/FileDocumentUtil.java +++ b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/graphfile/FileDocumentUtil.java @@ -262,13 +262,13 @@ public class FileDocumentUtil { * @param relation * @throws DatabaseException */ - public static void exportDocumentFolder(final Resource folderResource, final File folder, final Resource relation, final IProgressMonitor monitor) throws Exception{ + public static void exportDocumentFolder(final Resource folderResource, final File folder, final Resource relation, boolean useResourceNames, final IProgressMonitor monitor) throws Exception{ Simantics.getSession().syncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { try { - exportDocumentFolder(graph, folderResource, folder, relation, monitor); + exportDocumentFolder(graph, folderResource, folder, relation, useResourceNames, monitor); } catch (Exception e) { throw new DatabaseException(e); } @@ -286,7 +286,7 @@ public class FileDocumentUtil { * @param relation * @throws DatabaseException */ - public static void exportDocumentFolder(ReadGraph graph, Resource folderResource, File folder, Resource relation, IProgressMonitor monitor) throws Exception{ + public static void exportDocumentFolder(ReadGraph graph, Resource folderResource, File folder, Resource relation, boolean useResourceNames, IProgressMonitor monitor) throws Exception{ Layer0 l0 = Layer0.getInstance(graph); DocumentResource doc = DocumentResource.getInstance(graph); GraphFileResource gf = GraphFileResource.getInstance(graph); @@ -297,7 +297,7 @@ public class FileDocumentUtil { String name = null; boolean canExport = false; if (graph.isInstanceOf(r, doc.FileDocument)) { - name = graph.getRelatedValue(r, gf.HasResourceName); + name = graph.getRelatedValue(r, useResourceNames ? gf.HasResourceName : l0.HasName); canExport = true; } else if (graph.isInstanceOf(r, doc.UrlDocument)) { name = graph.getRelatedValue(r, l0.HasName) +".url"; @@ -329,7 +329,7 @@ public class FileDocumentUtil { continue; } } - exportDocumentFolder(graph, r, subFolder, relation,monitor); + exportDocumentFolder(graph, r, subFolder, relation, useResourceNames, monitor); } } } diff --git a/bundles/org.simantics.graphfile/src/org/simantics/graphfile/util/GraphFileUtil.java b/bundles/org.simantics.graphfile/src/org/simantics/graphfile/util/GraphFileUtil.java index 3f668a051..9fdbf62c7 100644 --- a/bundles/org.simantics.graphfile/src/org/simantics/graphfile/util/GraphFileUtil.java +++ b/bundles/org.simantics.graphfile/src/org/simantics/graphfile/util/GraphFileUtil.java @@ -11,10 +11,12 @@ *******************************************************************************/ package org.simantics.graphfile.util; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.file.Path; @@ -239,11 +241,25 @@ public class GraphFileUtil { } - public static void writeDataToGraph(WriteGraph graph, byte data[], Resource graphFile) throws IOException, ManyObjectsForFunctionalRelationException, ServiceException { - + public static void writeDataToGraph(WriteGraph graph, byte data[], Resource graphFile) throws IOException, DatabaseException { GraphFileResource gf = GraphFileResource.getInstance(graph); - graph.claimLiteral(graphFile, gf.HasFiledata, data); - graph.claimLiteral(graphFile, gf.LastModified, 0L); + if (USE_RANDOM_ACCESS_BINARY) { + Resource fileData = graph.getPossibleObject(graphFile, gf.HasFiledata); + if (fileData == null) { + Layer0 l0 = Layer0.getInstance(graph); + ClusteringSupport cs = graph.getService(ClusteringSupport.class); + fileData = graph.newResource(cs.createCluster()); + graph.claim(fileData, l0.InstanceOf, l0.ByteArray); + graph.claim(graphFile, gf.HasFiledata, fileData); + graph.createRandomAccessBinary(fileData, Bindings.BYTE_ARRAY.type(), data); + } else { + InputStream input = new ByteArrayInputStream(data); + LiteralFileUtil.copyStreamToRandomAccessBinary(graph, input, fileData); + } + } else { + graph.claimLiteral(graphFile, gf.HasFiledata, data); + } + graph.claimLiteral(graphFile, gf.LastModified, System.currentTimeMillis()); } /** diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/ModeledDoubleClickActions.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/ModeledDoubleClickActions.java index 2c483166e..d0da5d3c7 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/ModeledDoubleClickActions.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/ModeledDoubleClickActions.java @@ -95,7 +95,7 @@ public class ModeledDoubleClickActions implements IDoubleClickAction, IExecutabl ActionBrowseContext defaultContext = ActionBrowseContext.create(graph, getBrowseContextResources(graph)); - ActionBrowseContext browseContext = ActionBrowseContext.get(graph, nodeContext, defaultContext); + ActionBrowseContext browseContext = defaultContext;//ActionBrowseContext.get(graph, nodeContext, defaultContext); Map> result = browseContext.getActions(graph, nodeContext, contexts); Map> current = result; diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/style/IssueDecorationStyle.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/style/IssueDecorationStyle.java index 6a2202ee0..f0384d115 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/style/IssueDecorationStyle.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/style/IssueDecorationStyle.java @@ -32,6 +32,7 @@ import org.simantics.issues.common.IssueResourcesContexts; import org.simantics.issues.common.ListModelIssuesBySeverity; import org.simantics.modeling.ModelingResources; import org.simantics.modeling.ui.Activator; +import org.simantics.modeling.ui.diagram.style.IssueDecorationStyle.IssueResult; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.g2d.nodes.Decoration; import org.simantics.scenegraph.g2d.nodes.DecorationSVGNode; @@ -98,22 +99,30 @@ public class IssueDecorationStyle extends StyleBase { SVGNode svgNode = ProfileVariables.claimChild(node, "", DECORATION_NODE_NAME, DecorationSVGNode.class, observer); - Rectangle2D bounds = NodeUtil.getLocalBounds(node, Decoration.class); - - double tx = bounds.getX(); - double ty = bounds.getY(); - - //new Exception("tx=" + tx + " ty=" + ty).printStackTrace(); - svgNode.setZIndex( Integer.MAX_VALUE ); - svgNode.setTransform( AffineTransform.getTranslateInstance(tx, ty) ); + svgNode.setTransform(getDecorationPosition(node)); String svgData = svgDataForSeverity(result.getSeverity()); if (svgData != null) svgNode.setData(svgData); } - private String svgDataForSeverity(Severity s) { + /** + * Returns position of the decoration. + * By default decoration is placed to the top left corner. Override this method to change the position. + * + * @param node + * @return + */ + protected AffineTransform getDecorationPosition(INode node) { + Rectangle2D bounds = NodeUtil.getLocalBounds(node, Decoration.class); + + double tx = bounds.getX(); + double ty = bounds.getY(); + return AffineTransform.getTranslateInstance(tx, ty); + } + + protected String svgDataForSeverity(Severity s) { switch (s) { case FATAL: return Activator.FATAL_SVG_TEXT; case ERROR: return Activator.ERROR_SVG_TEXT; @@ -133,18 +142,20 @@ public class IssueDecorationStyle extends StyleBase { public String toString() { return "Issue decoration"; } + + /** + * This is needed to keep the issue decoration up-to-date when its parent + * element moves. + */ + public static class IssueResult extends Tuple { + public IssueResult(Severity severity, AffineTransform transform) { + super(severity, transform); + } + public Severity getSeverity() { + return (Severity) getField(0); + } + } } -/** - * This is needed to keep the issue decoration up-to-date when its parent - * element moves. - */ -class IssueResult extends Tuple { - public IssueResult(Severity severity, AffineTransform transform) { - super(severity, transform); - } - public Severity getSeverity() { - return (Severity) getField(0); - } -} + diff --git a/bundles/org.simantics.utils/src/org/simantics/utils/format/TimeFormat.java b/bundles/org.simantics.utils/src/org/simantics/utils/format/TimeFormat.java index 48d961134..30451e149 100644 --- a/bundles/org.simantics.utils/src/org/simantics/utils/format/TimeFormat.java +++ b/bundles/org.simantics.utils/src/org/simantics/utils/format/TimeFormat.java @@ -106,7 +106,13 @@ public class TimeFormat extends Format { private StringBuffer formatSync(Object obj, StringBuffer toAppendTo, FieldPosition pos) { double x = ( (Number) obj ).doubleValue(); int initLen = toAppendTo.length(); - + + if (Double.isInfinite(x)) { + return toAppendTo.append((x == Float.POSITIVE_INFINITY) ? "\u221E" : "-\u221E"); + } else if (Double.isNaN(x)) { + return toAppendTo.append("NaN"); + } + if (x<0) { toAppendTo.append("-"); x=-x; -- 2.47.1