public static ArrayList<NodeContext> augment(ReadGraph graph, BrowseContext bc, Collection<NodeContext> contexts, boolean resolveABC) throws DatabaseException {\r
ArrayList<NodeContext> result = new ArrayList<NodeContext>();\r
for(NodeContext context : contexts) {\r
- ActionBrowseContext abc = resolveABC ? graph.syncRequest(new ResolveActionBrowseContext(context)) : null;\r
+ ActionBrowseContext abc = null;\r
+ if(resolveABC) {\r
+ abc = graph.syncRequest(new ResolveActionBrowseContext(context));\r
+ if(abc == null) abc = (ActionBrowseContext)context.getConstant(BuiltinKeys.ACTION_BROWSE_CONTEXT);\r
+ }\r
result.add(NodeContextBuilder.buildWithData(NodeType.KEY_SEQUENCE_EXT,\r
new Object[] {\r
context.getConstant(BuiltinKeys.INPUT), \r
/**\r
* Selects tree items based on pressed key events.<p>\r
* \r
- * The default implementation of SWT.Tree (Windows?) uses only the the first column when matching the items.<p>\r
- * \r
- * This implementation checks all columns. Override <pre>matches(), matchesColumn()</pre> for customized behavior.<p>\r
* \r
* @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
*\r
prevEvent = e.time;\r
matcher = matcher += Character.toString(e.character);\r
\r
- \r
- //TreeItem item = null;\r
NatTable tree = explorer.getControl();\r
columns = explorer.getColumns().length;\r
\r
if (item != null) {\r
explorer.select(item);\r
explorer.show(item);\r
-// tree.select(item);\r
-// tree.showItem(item);\r
- \r
- \r
} \r
// without this the default handling would take over.\r
e.doit = false;\r
return false;\r
}\r
\r
-\r
}\r
public IJSONResult readChanges(String uri, String sessionGUID, int sequenceNumber);\r
public void initializeDocument(String documentURI, String sessionGUID, CommandContext context);\r
public void onPoll(String sessionGUID);\r
+ public String escapeURI(String unicode);\r
}\r
import org.simantics.document.DocumentResource;\r
import org.simantics.graphfile.ontology.GraphFileResource;\r
import org.simantics.graphfile.util.GraphFileUtil;\r
+import org.simantics.layer0.Layer0;\r
import org.simantics.ui.SimanticsUI;\r
import org.simantics.utils.ui.ExceptionUtils;\r
\r
@Override\r
public void run() {\r
try {\r
- String resourceName = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+ String name = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
public String perform(ReadGraph graph) throws DatabaseException {\r
DocumentResource doc = DocumentResource.getInstance(graph);\r
GraphFileResource gf = GraphFileResource.getInstance(graph);\r
if (!graph.isInstanceOf(resource, doc.FileDocument))\r
return null;\r
- return graph.getPossibleRelatedValue(resource, gf.HasResourceName);\r
+ String resourceName = graph.getPossibleRelatedValue(resource, gf.HasResourceName);\r
+ if (resourceName != null) {\r
+ return resourceName;\r
+ } else {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ return graph.getPossibleRelatedValue(resource, L0.HasName);\r
+ }\r
};\r
});\r
\r
FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(),SWT.SAVE);\r
- dialog.setFileName(resourceName);\r
+ dialog.setFileName(name);\r
final String filename = dialog.open();\r
if (filename == null)\r
return;\r
*/\r
public class ExportDocumentFolder implements ActionFactory {\r
Resource relation;\r
+ boolean useResourceNames;\r
\r
public ExportDocumentFolder(ReadGraph graph, String relationUri) throws DatabaseException {\r
relation = graph.getResource(relationUri);\r
+ useResourceNames = true;\r
+ }\r
+\r
+ public ExportDocumentFolder(ReadGraph graph, String relationUri, String useResourceNames) throws DatabaseException {\r
+ relation = graph.getResource(relationUri);\r
+ this.useResourceNames = useResourceNames.equals("true");\r
}\r
\r
@Override\r
GraphFileUtil.clearDirectoryStructure(folder);\r
monitor.worked(1);\r
}\r
- FileDocumentUtil.exportDocumentFolder(resource, folder, relation,monitor);\r
+ FileDocumentUtil.exportDocumentFolder(resource, folder, relation, useResourceNames, monitor);\r
monitor.done();\r
return new Status(IStatus.OK, Activator.PLUGIN_ID, "Folder exported.");\r
} catch (Exception e) {\r
*******************************************************************************/\r
package org.simantics.document.ui.actions;\r
\r
+import java.io.File;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Status;\r
import org.eclipse.swt.SWT;\r
import org.eclipse.swt.widgets.Display;\r
import org.eclipse.swt.widgets.FileDialog;\r
+import org.simantics.DatabaseJob;\r
import org.simantics.Simantics;\r
import org.simantics.db.ReadGraph;\r
import org.simantics.db.Resource;\r
import org.simantics.db.WriteGraph;\r
import org.simantics.db.common.request.WriteRequest;\r
import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.document.ui.Activator;\r
import org.simantics.document.ui.graphfile.FileDocumentUtil;\r
-import org.simantics.utils.datastructures.Callback;\r
-import org.simantics.utils.ui.ExceptionUtils;\r
\r
/**\r
* Action for importing files as documents.\r
\r
@Override\r
public void run() {\r
- FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(),SWT.OPEN);\r
+ FileDialog dialog = new FileDialog(Display.getCurrent().getActiveShell(),SWT.OPEN | SWT.MULTI);\r
// TODO : is there any way to read file/executable bindings from OS?\r
// if is, use those extensions to filter this list.\r
// note: in windows using "reg query ..." to read bindings form registry would work.\r
+ // Note : If the above mentioned filtering is implemented it should be made optional / configurable.\r
dialog.setFilterExtensions(new String[]{"*.*"});\r
- final String filename = dialog.open();\r
- if (filename == null) {\r
- return;\r
- }\r
- Simantics.getSession().asyncRequest(new WriteRequest() {\r
+ if (dialog.open() == null) return;\r
+\r
+ String filterPath = dialog.getFilterPath();\r
+ String[] filenames = dialog.getFileNames();\r
+ \r
+ ImportJob job = new ImportJob(filenames.length > 1 ? "Import files" : "Import file", resource, filterPath, filenames);\r
+ job.setUser(true);\r
+ job.schedule();\r
+ }\r
+ };\r
+ }\r
+ \r
+ private class ImportJob extends DatabaseJob {\r
+\r
+ public ImportJob(String name, Resource resource, String path, String[] filenames) {\r
+ super(name);\r
+ this.resource = resource;\r
+ this.path = path;\r
+ this.filenames = filenames;\r
+ }\r
+\r
+ Resource resource;\r
+ String path;\r
+ String[] filenames;\r
+\r
+ @Override\r
+ protected IStatus run(final IProgressMonitor monitor) {\r
+ monitor.beginTask("Importing...", filenames.length);\r
+ try {\r
+ Simantics.getSession().syncRequest(new WriteRequest() {\r
@Override\r
public void perform(WriteGraph graph) throws DatabaseException {\r
- graph.markUndoPoint();\r
- \r
- Resource newDoc = FileDocumentUtil.importFileWithName(graph,filename);\r
- linkDocument(graph, resource, newDoc);\r
- }\r
- },new Callback<DatabaseException>() { \r
- @Override\r
- public void run(DatabaseException parameter) {\r
- if (parameter != null) {\r
- ExceptionUtils.logAndShowError("Cannot import document.", parameter);\r
+ try {\r
+ graph.markUndoPoint();\r
+ for (String filename : filenames) {\r
+ File f = new File(path, filename);\r
+ Resource newDoc = FileDocumentUtil.importFileWithName(graph, f.getAbsolutePath());\r
+ linkDocument(graph, resource, newDoc);\r
+ monitor.worked(1);\r
+ }\r
+ } catch (Exception e) {\r
+ throw new DatabaseException(e);\r
}\r
- \r
}\r
});\r
+ return new Status(IStatus.OK, Activator.PLUGIN_ID, "Import succesful.");\r
+ } catch (DatabaseException e) {\r
+ return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import failed.", e);\r
+ } finally {\r
+ monitor.done();\r
}\r
- };\r
+ }\r
}\r
\r
}\r
--- /dev/null
+package org.simantics.document.ui.actions;\r
+\r
+import java.io.IOException;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.ActionFactory;\r
+import org.simantics.document.DocumentResource;\r
+import org.simantics.graphfile.util.GraphFileUtil;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class NewFileDocument implements ActionFactory {\r
+ Resource relation;\r
+ String defaultName;\r
+ \r
+ public NewFileDocument(ReadGraph graph, String relationUri, String defaultName) throws DatabaseException {\r
+ relation = graph.getResource(relationUri);\r
+ this.defaultName = defaultName;\r
+ }\r
+ \r
+ @Override\r
+ public Runnable create(Object target) {\r
+\r
+ if(!(target instanceof Resource))\r
+ return null;\r
+\r
+ final Resource resource = (Resource)target;\r
+\r
+ return new Runnable() {\r
+ @Override\r
+ public void run() {\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+ \r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ graph.markUndoPoint();\r
+ \r
+ Layer0 l0 = Layer0.getInstance(graph);\r
+\r
+ String name = NameUtils.findFreshName(graph, defaultName, resource, relation);\r
+ DocumentResource doc = DocumentResource.getInstance(graph);\r
+ \r
+ Resource fileResource = graph.newResource();\r
+ graph.claim(fileResource, l0.InstanceOf, doc.FileDocument);\r
+ graph.claimLiteral(fileResource, l0.HasName, name);\r
+ graph.claim(resource, relation, fileResource);\r
+ try {\r
+ GraphFileUtil.writeDataToGraph(graph, new byte[0], fileResource);\r
+ } catch (IOException e) {\r
+ throw new DatabaseException(e);\r
+ }\r
+ }\r
+ \r
+ });\r
+ }\r
+ };\r
+ }\r
+}\r
* @param relation\r
* @throws DatabaseException\r
*/\r
- public static void exportDocumentFolder(final Resource folderResource, final File folder, final Resource relation, final IProgressMonitor monitor) throws Exception{\r
+ public static void exportDocumentFolder(final Resource folderResource, final File folder, final Resource relation, boolean useResourceNames, final IProgressMonitor monitor) throws Exception{\r
Simantics.getSession().syncRequest(new ReadRequest() {\r
\r
@Override\r
public void run(ReadGraph graph) throws DatabaseException {\r
try {\r
- exportDocumentFolder(graph, folderResource, folder, relation, monitor);\r
+ exportDocumentFolder(graph, folderResource, folder, relation, useResourceNames, monitor);\r
} catch (Exception e) {\r
throw new DatabaseException(e);\r
}\r
* @param relation\r
* @throws DatabaseException\r
*/\r
- public static void exportDocumentFolder(ReadGraph graph, Resource folderResource, File folder, Resource relation, IProgressMonitor monitor) throws Exception{\r
+ public static void exportDocumentFolder(ReadGraph graph, Resource folderResource, File folder, Resource relation, boolean useResourceNames, IProgressMonitor monitor) throws Exception{\r
Layer0 l0 = Layer0.getInstance(graph);\r
DocumentResource doc = DocumentResource.getInstance(graph);\r
GraphFileResource gf = GraphFileResource.getInstance(graph);\r
String name = null;\r
boolean canExport = false;\r
if (graph.isInstanceOf(r, doc.FileDocument)) {\r
- name = graph.getRelatedValue(r, gf.HasResourceName);\r
+ name = graph.getRelatedValue(r, useResourceNames ? gf.HasResourceName : l0.HasName);\r
canExport = true;\r
} else if (graph.isInstanceOf(r, doc.UrlDocument)) {\r
name = graph.getRelatedValue(r, l0.HasName) +".url";\r
continue;\r
}\r
}\r
- exportDocumentFolder(graph, r, subFolder, relation,monitor);\r
+ exportDocumentFolder(graph, r, subFolder, relation, useResourceNames, monitor);\r
}\r
}\r
}\r
*******************************************************************************/\r
package org.simantics.graphfile.util;\r
\r
+import java.io.ByteArrayInputStream;\r
import java.io.File;\r
import java.io.FileInputStream;\r
import java.io.FileOutputStream;\r
import java.io.IOException;\r
+import java.io.InputStream;\r
import java.nio.ByteBuffer;\r
import java.nio.channels.FileChannel;\r
import java.nio.file.Path;\r
\r
}\r
\r
- public static void writeDataToGraph(WriteGraph graph, byte data[], Resource graphFile) throws IOException, ManyObjectsForFunctionalRelationException, ServiceException {\r
- \r
+ public static void writeDataToGraph(WriteGraph graph, byte data[], Resource graphFile) throws IOException, DatabaseException {\r
GraphFileResource gf = GraphFileResource.getInstance(graph);\r
- graph.claimLiteral(graphFile, gf.HasFiledata, data);\r
- graph.claimLiteral(graphFile, gf.LastModified, 0L);\r
+ if (USE_RANDOM_ACCESS_BINARY) {\r
+ Resource fileData = graph.getPossibleObject(graphFile, gf.HasFiledata);\r
+ if (fileData == null) {\r
+ Layer0 l0 = Layer0.getInstance(graph);\r
+ ClusteringSupport cs = graph.getService(ClusteringSupport.class);\r
+ fileData = graph.newResource(cs.createCluster());\r
+ graph.claim(fileData, l0.InstanceOf, l0.ByteArray);\r
+ graph.claim(graphFile, gf.HasFiledata, fileData);\r
+ graph.createRandomAccessBinary(fileData, Bindings.BYTE_ARRAY.type(), data);\r
+ } else {\r
+ InputStream input = new ByteArrayInputStream(data);\r
+ LiteralFileUtil.copyStreamToRandomAccessBinary(graph, input, fileData);\r
+ }\r
+ } else {\r
+ graph.claimLiteral(graphFile, gf.HasFiledata, data);\r
+ }\r
+ graph.claimLiteral(graphFile, gf.LastModified, System.currentTimeMillis());\r
}\r
\r
/**\r
ActionBrowseContext defaultContext = ActionBrowseContext.create(graph,\r
getBrowseContextResources(graph));\r
\r
- ActionBrowseContext browseContext = ActionBrowseContext.get(graph, nodeContext, defaultContext);\r
+ ActionBrowseContext browseContext = defaultContext;//ActionBrowseContext.get(graph, nodeContext, defaultContext);\r
\r
Map<IActionCategory, List<Action>> result = browseContext.getActions(graph, nodeContext, contexts);\r
Map<IActionCategory, List<Action>> current = result;\r
import org.simantics.issues.common.ListModelIssuesBySeverity;\r
import org.simantics.modeling.ModelingResources;\r
import org.simantics.modeling.ui.Activator;\r
+import org.simantics.modeling.ui.diagram.style.IssueDecorationStyle.IssueResult;\r
import org.simantics.scenegraph.INode;\r
import org.simantics.scenegraph.g2d.nodes.Decoration;\r
import org.simantics.scenegraph.g2d.nodes.DecorationSVGNode;\r
\r
SVGNode svgNode = ProfileVariables.claimChild(node, "", DECORATION_NODE_NAME, DecorationSVGNode.class, observer);\r
\r
- Rectangle2D bounds = NodeUtil.getLocalBounds(node, Decoration.class);\r
-\r
- double tx = bounds.getX();\r
- double ty = bounds.getY();\r
-\r
- //new Exception("tx=" + tx + " ty=" + ty).printStackTrace();\r
- \r
svgNode.setZIndex( Integer.MAX_VALUE );\r
- svgNode.setTransform( AffineTransform.getTranslateInstance(tx, ty) ); \r
+ svgNode.setTransform(getDecorationPosition(node)); \r
\r
String svgData = svgDataForSeverity(result.getSeverity());\r
if (svgData != null)\r
svgNode.setData(svgData);\r
}\r
\r
- private String svgDataForSeverity(Severity s) {\r
+ /**\r
+ * Returns position of the decoration.\r
+ * By default decoration is placed to the top left corner. Override this method to change the position.\r
+ * \r
+ * @param node\r
+ * @return\r
+ */\r
+ protected AffineTransform getDecorationPosition(INode node) {\r
+ Rectangle2D bounds = NodeUtil.getLocalBounds(node, Decoration.class);\r
+\r
+ double tx = bounds.getX();\r
+ double ty = bounds.getY();\r
+ return AffineTransform.getTranslateInstance(tx, ty);\r
+ }\r
+\r
+ protected String svgDataForSeverity(Severity s) {\r
switch (s) {\r
case FATAL: return Activator.FATAL_SVG_TEXT;\r
case ERROR: return Activator.ERROR_SVG_TEXT;\r
public String toString() {\r
return "Issue decoration";\r
}\r
+ \r
+ /**\r
+ * This is needed to keep the issue decoration up-to-date when its parent\r
+ * element moves.\r
+ */\r
+ public static class IssueResult extends Tuple {\r
+ public IssueResult(Severity severity, AffineTransform transform) {\r
+ super(severity, transform);\r
+ }\r
+ public Severity getSeverity() {\r
+ return (Severity) getField(0);\r
+ }\r
+ }\r
\r
}\r
\r
-/**\r
- * This is needed to keep the issue decoration up-to-date when its parent\r
- * element moves.\r
- */\r
-class IssueResult extends Tuple {\r
- public IssueResult(Severity severity, AffineTransform transform) {\r
- super(severity, transform);\r
- }\r
- public Severity getSeverity() {\r
- return (Severity) getField(0);\r
- }\r
-}\r
+\r
private StringBuffer formatSync(Object obj, StringBuffer toAppendTo, FieldPosition pos) {\r
double x = ( (Number) obj ).doubleValue(); \r
int initLen = toAppendTo.length();\r
- \r
+\r
+ if (Double.isInfinite(x)) {\r
+ return toAppendTo.append((x == Float.POSITIVE_INFINITY) ? "\u221E" : "-\u221E");\r
+ } else if (Double.isNaN(x)) {\r
+ return toAppendTo.append("NaN");\r
+ }\r
+\r
if (x<0) {\r
toAppendTo.append("-");\r
x=-x;\r