diff --git a/bundles/org.insilico.core/.gitignore b/bundles/org.insilico.core/.gitignore
new file mode 100644
index 0000000..ae3c172
--- /dev/null
+++ b/bundles/org.insilico.core/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/bundles/org.insilico.core/META-INF/MANIFEST.MF b/bundles/org.insilico.core/META-INF/MANIFEST.MF
index 5b1fa18..b87f424 100644
--- a/bundles/org.insilico.core/META-INF/MANIFEST.MF
+++ b/bundles/org.insilico.core/META-INF/MANIFEST.MF
@@ -5,7 +5,10 @@ Bundle-SymbolicName: org.insilico.core;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-Vendor: Draeger Lab
-Export-Package: org.insilico.core;uses:="org.eclipse.fx.ui.services.startup,org.eclipse.fx.ui.workbench.fx,org.eclipse.fx.core.app",
+Export-Package: org.insilico.core.handlers,
+ org.insilico.core;uses:="org.eclipse.fx.ui.services.startup,
+ org.eclipse.fx.ui.workbench.fx,
+ org.eclipse.fx.core.app",
org.insilico.core.handlers
Bundle-ActivationPolicy: lazy
Import-Package: javax.inject;version="1.0.0"
@@ -22,4 +25,5 @@ Require-Bundle: org.eclipse.core.resources;bundle-version="3.11.1",
org.eclipse.fx.ui.workbench.base;bundle-version="3.0.0",
org.eclipse.fx.core;bundle-version="3.0.0",
org.eclipse.core.databinding;bundle-version="1.6.0"
+Automatic-Module-Name: org.insilico.core
diff --git a/bundles/org.insilico.core/pom.xml b/bundles/org.insilico.core/pom.xml
index caedfb7..94824b9 100644
--- a/bundles/org.insilico.core/pom.xml
+++ b/bundles/org.insilico.core/pom.xml
@@ -23,13 +23,14 @@
-
-
-
- org.eclipse.tycho
- tycho-source-plugin
- ${tycho.version}
-
-
+
+
+
+ org.eclipse.tycho
+ tycho-source-plugin
+ ${tycho.version}
+
+
+
diff --git a/bundles/org.insilico.core/src/org/insilico/core/ApplicationLifecycle.java b/bundles/org.insilico.core/src/org/insilico/core/ApplicationLifecycle.java
index c251777..58ac411 100644
--- a/bundles/org.insilico.core/src/org/insilico/core/ApplicationLifecycle.java
+++ b/bundles/org.insilico.core/src/org/insilico/core/ApplicationLifecycle.java
@@ -1,4 +1,4 @@
-package org.insilico.core;
+package org.insilico.core;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.runtime.CoreException;
diff --git a/bundles/org.insilico.core/src/org/insilico/core/Main.java b/bundles/org.insilico.core/src/org/insilico/core/Main.java
index 3192495..45c3e6a 100644
--- a/bundles/org.insilico.core/src/org/insilico/core/Main.java
+++ b/bundles/org.insilico.core/src/org/insilico/core/Main.java
@@ -1,4 +1,4 @@
-package org.insilico.core;
+package org.insilico.core;
import org.eclipse.fx.ui.workbench.fx.E4MainThreadApplication;
diff --git a/bundles/org.insilico.core/src/org/insilico/core/package-info.java b/bundles/org.insilico.core/src/org/insilico/core/package-info.java
index beaac8b..c14941c 100644
--- a/bundles/org.insilico.core/src/org/insilico/core/package-info.java
+++ b/bundles/org.insilico.core/src/org/insilico/core/package-info.java
@@ -10,4 +10,4 @@
* @author roman
*
*/
-package org.insilico.core;
+package org.insilico.core;
diff --git a/bundles/org.insilico.jsbml.core/.project b/bundles/org.insilico.jsbml.core/.project
index 8cddf17..8fdb9c4 100644
--- a/bundles/org.insilico.jsbml.core/.project
+++ b/bundles/org.insilico.jsbml.core/.project
@@ -25,8 +25,14 @@
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+ org.eclipse.m2e.core.maven2Nature
org.eclipse.pde.PluginNature
org.eclipse.jdt.core.javanature
diff --git a/bundles/org.insilico.jsbml.core/META-INF/MANIFEST.MF b/bundles/org.insilico.jsbml.core/META-INF/MANIFEST.MF
index e27d242..577aeb5 100644
--- a/bundles/org.insilico.jsbml.core/META-INF/MANIFEST.MF
+++ b/bundles/org.insilico.jsbml.core/META-INF/MANIFEST.MF
@@ -15,8 +15,13 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Service-Component: OSGI-INF/services/org.insilico.jsbml.core.services.provider.SBMLEditorProvider.xml,
OSGI-INF/services/org.insilico.jsbml.core.services.provider.SBMLIconProvider.xml,
- OSGI-INF/services/org.insilico.jsbml.core.services.provider.SBMLDocumentLoader.xml
+ OSGI-INF/services/org.insilico.jsbml.core.services.provider.SBMLDocumentLoader.xml,
+ OSGI-INF/org.insilico.jsbml.core.services.provider.SBMLIconProvider.xml,
+ OSGI-INF/org.insilico.jsbml.core.services.provider.SBMLDocumentLoader.xml,
+ OSGI-INF/org.insilico.jsbml.core.services.provider.SBMLEditorProvider.xml
Export-Package: org.insilico.jsbml.core,
org.insilico.jsbml.core.editor,
org.insilico.jsbml.core.services,
org.insilico.jsbml.core.services.provider
+Automatic-Module-Name: org.insilico.jsbml.core
+Import-Package: org.osgi.service.component.annotations;version="1.2.0"
diff --git a/bundles/org.insilico.jsbml.core/OSGI-INF/org.insilico.jsbml.core.services.provider.SBMLDocumentLoader.xml b/bundles/org.insilico.jsbml.core/OSGI-INF/org.insilico.jsbml.core.services.provider.SBMLDocumentLoader.xml
new file mode 100644
index 0000000..f2730f3
--- /dev/null
+++ b/bundles/org.insilico.jsbml.core/OSGI-INF/org.insilico.jsbml.core.services.provider.SBMLDocumentLoader.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bundles/org.insilico.jsbml.core/OSGI-INF/org.insilico.jsbml.core.services.provider.SBMLEditorProvider.xml b/bundles/org.insilico.jsbml.core/OSGI-INF/org.insilico.jsbml.core.services.provider.SBMLEditorProvider.xml
new file mode 100644
index 0000000..08cdbf9
--- /dev/null
+++ b/bundles/org.insilico.jsbml.core/OSGI-INF/org.insilico.jsbml.core.services.provider.SBMLEditorProvider.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bundles/org.insilico.jsbml.core/OSGI-INF/org.insilico.jsbml.core.services.provider.SBMLIconProvider.xml b/bundles/org.insilico.jsbml.core/OSGI-INF/org.insilico.jsbml.core.services.provider.SBMLIconProvider.xml
new file mode 100644
index 0000000..28acde2
--- /dev/null
+++ b/bundles/org.insilico.jsbml.core/OSGI-INF/org.insilico.jsbml.core.services.provider.SBMLIconProvider.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bundles/org.insilico.jsbml.core/pom.xml b/bundles/org.insilico.jsbml.core/pom.xml
index 2c1c279..d92e5b5 100644
--- a/bundles/org.insilico.jsbml.core/pom.xml
+++ b/bundles/org.insilico.jsbml.core/pom.xml
@@ -23,13 +23,14 @@
-
-
-
- org.eclipse.tycho
- tycho-source-plugin
- ${tycho.version}
-
-
+
+
+
+ org.eclipse.tycho
+ tycho-source-plugin
+ ${tycho.version}
+
+
+
diff --git a/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/Constants.java b/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/Constants.java
index 8c66d67..780964a 100644
--- a/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/Constants.java
+++ b/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/Constants.java
@@ -1,4 +1,4 @@
-package org.insilico.jsbml.core;
+package org.insilico.jsbml.core;
public interface Constants {
diff --git a/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/editor/DocumentTreeView.java b/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/editor/DocumentTreeView.java
index fa5ffb1..1588b70 100644
--- a/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/editor/DocumentTreeView.java
+++ b/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/editor/DocumentTreeView.java
@@ -1,15 +1,12 @@
-package org.insilico.jsbml.core.editor;
+package org.insilico.jsbml.core.editor;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
-
import javax.annotation.PostConstruct;
import javax.inject.Inject;
-
import org.sbml.jsbml.SBMLDocument;
import org.sbml.jsbml.SBase;
-
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.BorderPane;
@@ -21,9 +18,11 @@ public class DocumentTreeView {
@PostConstruct
private void init(BorderPane parent) {
+ if (doc!=null) {
TreeView docTreeView = new TreeView<>(convertToTreeItem(doc, 2));
parent.setCenter(docTreeView);
+ }
}
private TreeItem convertToTreeItem(SBase elem, int expandLevels) {
diff --git a/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/SBMLAdapterBuilderProvider.java b/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/SBMLAdapterBuilderProvider.java
index 74b601b..6122642 100644
--- a/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/SBMLAdapterBuilderProvider.java
+++ b/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/SBMLAdapterBuilderProvider.java
@@ -1,4 +1,4 @@
-package org.insilico.jsbml.core.services;
+package org.insilico.jsbml.core.services;
import org.sbml.jsbml.SBMLDocument;
diff --git a/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/provider/SBMLDocumentLoader.java b/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/provider/SBMLDocumentLoader.java
index 28f169e..557dd09 100644
--- a/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/provider/SBMLDocumentLoader.java
+++ b/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/provider/SBMLDocumentLoader.java
@@ -31,7 +31,6 @@
* @author roman
*
*/
-@SuppressWarnings("restriction")
@Component(service = IContextFunction.class,
property = {"service.context.key=org.sbml.jsbml.SBMLDocument"})
public class SBMLDocumentLoader extends ContextFunction {
@@ -40,7 +39,8 @@ public class SBMLDocumentLoader extends ContextFunction {
@Override
public Object compute(IEclipseContext context, String contextKey) {
- System.out.println("Compute...");
+ return IInjector.NOT_A_VALUE;
+ /*System.out.println("Compute...");
Object urlVal = context.get(DOCUMENT_URL);
if (urlVal == null) {
@@ -69,7 +69,12 @@ public Object compute(IEclipseContext context, String contextKey) {
// Load if needed
try {
URI url = URIUtil.fromString(urlString);
- doc = JSBML.readSBMLFromFile(url.getPath());
+ if (url!=null) {
+ if (url.getPath()!=null) {
+ doc = JSBML.readSBMLFromFile(url.getPath());
+ }
+ }
+
// doc = SBMLReader.read(new File(url));
cache.put(urlString, doc);
}
@@ -85,6 +90,6 @@ public Object compute(IEclipseContext context, String contextKey) {
}
System.out.println("No doc selected");
- return IInjector.NOT_A_VALUE;
+ return IInjector.NOT_A_VALUE;*/
}
}
diff --git a/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/provider/SBMLEditorProvider.java b/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/provider/SBMLEditorProvider.java
index 85d506d..4c4b9f1 100644
--- a/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/provider/SBMLEditorProvider.java
+++ b/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/provider/SBMLEditorProvider.java
@@ -5,7 +5,7 @@
import org.osgi.service.component.annotations.Component;
/**
- * OSGi Service Component which provides a editor part for SBML files. The editor is provides via
+ * OSGi Service Component which provides an editor part for SBML files. The editor is provided via
* the {@link EditorClassURLProvider} service.
*
* @author roman
diff --git a/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/provider/SBMLIconProvider.java b/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/provider/SBMLIconProvider.java
index 6d1a99b..511d99a 100644
--- a/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/provider/SBMLIconProvider.java
+++ b/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/provider/SBMLIconProvider.java
@@ -13,7 +13,6 @@
*
*/
@Component
-@SuppressWarnings("restriction")
public class SBMLIconProvider implements FileIconProvider {
@Override
diff --git a/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/provider/package-info.java b/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/provider/package-info.java
index 5f802d9..26bdaf3 100644
--- a/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/provider/package-info.java
+++ b/bundles/org.insilico.jsbml.core/src/org/insilico/jsbml/core/services/provider/package-info.java
@@ -4,4 +4,4 @@
* @author roman
* @see org.insilico.jsbml.core
*/
-package org.insilico.jsbml.core.services.provider;
+package org.insilico.jsbml.core.services.provider;
diff --git a/bundles/org.insilico.sbmlsheets/.gitignore b/bundles/org.insilico.sbmlsheets/.gitignore
new file mode 100644
index 0000000..ae3c172
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/bundles/org.insilico.sbmlsheets/.project b/bundles/org.insilico.sbmlsheets/.project
new file mode 100644
index 0000000..882e5b9
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/.project
@@ -0,0 +1,39 @@
+
+
+ org.insilico.sbmlsheets
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+ org.eclipse.pde.ds.core.builder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.m2e.core.maven2Nature
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/bundles/org.insilico.sbmlsheets/META-INF/MANIFEST.MF b/bundles/org.insilico.sbmlsheets/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..d9b3f10
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/META-INF/MANIFEST.MF
@@ -0,0 +1,40 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: SBMLsheets
+Bundle-SymbolicName: org.insilico.sbmlsheets;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.fx.ui.services;bundle-version="3.0.0",
+ org.eclipse.fx.code.editor;bundle-version="3.0.0",
+ org.sbml.jsbml.core;bundle-version="1.3.1",
+ org.eclipse.fx.code.editor.fx.e4;bundle-version="3.0.0",
+ org.eclipse.e4.core.contexts;bundle-version="1.5.0",
+ org.eclipse.e4.core.di;bundle-version="1.6.1",
+ org.eclipse.e4.ui.model.workbench;bundle-version="1.2.0",
+ org.insilico.ui.themes.light;bundle-version="1.0.0",
+ org.insilico.ui;bundle-version="1.0.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-ActivationPolicy: lazy
+Service-Component: OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SBMLEditorProvider.xml,
+ OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SBMLIconProvider.xml,
+ OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SBMLDocumentLoader.xml,
+ OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SpreadsheetEditorProvider.xml,
+ OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SpreadsheetDocumentLoader.xml,
+ OSGI-INF/org.insilico.sbmlsheets.services.provider.SBMLIconProvider.xml,
+ OSGI-INF/org.insilico.sbmlsheets.services.provider.SBMLEditorProvider.xml,
+ OSGI-INF/org.insilico.sbmlsheets.services.provider.SBMLDocumentLoader.xml,
+ OSGI-INF/org.insilico.sbmlsheets.services.provider.SpreadsheetDocumentLoader.xml,
+ OSGI-INF/org.insilico.sbmlsheets.services.provider.SpreadsheetEditorProvider.xml,
+ OSGI-INF/org.insilico.sbmlsheets.services.provider.SheetProjectEditorProvider.xml,
+ OSGI-INF/org.insilico.sbmlsheets.services.provider.SheetProjectDocumentLoader.xml
+Export-Package: org.insilico.sbmlsheets.core,
+ org.insilico.sbmlsheets.editor,
+ org.insilico.sbmlsheets.services,
+ org.insilico.sbmlsheets.services.provider
+Automatic-Module-Name: org.insilico.sbmlsheets
+Import-Package: org.eclipse.core.databinding.observable.list,
+ org.eclipse.core.resources,
+ org.eclipse.e4.ui.workbench,
+ org.eclipse.e4.ui.workbench.modeling,
+ org.insilico.core,
+ org.osgi.service.component.annotations;version="1.2.0"
diff --git a/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SBMLDocumentLoader.xml b/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SBMLDocumentLoader.xml
new file mode 100644
index 0000000..d86d840
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SBMLDocumentLoader.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SBMLEditorProvider.xml b/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SBMLEditorProvider.xml
new file mode 100644
index 0000000..240f031
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SBMLEditorProvider.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SBMLIconProvider.xml b/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SBMLIconProvider.xml
new file mode 100644
index 0000000..04b5d08
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SBMLIconProvider.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SheetProjectDocumentLoader.xml b/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SheetProjectDocumentLoader.xml
new file mode 100644
index 0000000..31c63c9
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SheetProjectDocumentLoader.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SheetProjectEditorProvider.xml b/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SheetProjectEditorProvider.xml
new file mode 100644
index 0000000..fcf9e80
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SheetProjectEditorProvider.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SpreadsheetDocumentLoader.xml b/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SpreadsheetDocumentLoader.xml
new file mode 100644
index 0000000..c93959c
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SpreadsheetDocumentLoader.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SpreadsheetEditorProvider.xml b/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SpreadsheetEditorProvider.xml
new file mode 100644
index 0000000..f23b13a
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/OSGI-INF/org.insilico.sbmlsheets.services.provider.SpreadsheetEditorProvider.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bundles/org.insilico.sbmlsheets/OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SBMLDocumentLoader.xml b/bundles/org.insilico.sbmlsheets/OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SBMLDocumentLoader.xml
new file mode 100644
index 0000000..2c233a5
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SBMLDocumentLoader.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/bundles/org.insilico.sbmlsheets/OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SBMLEditorProvider.xml b/bundles/org.insilico.sbmlsheets/OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SBMLEditorProvider.xml
new file mode 100644
index 0000000..996c884
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SBMLEditorProvider.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/bundles/org.insilico.sbmlsheets/OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SBMLIconProvider.xml b/bundles/org.insilico.sbmlsheets/OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SBMLIconProvider.xml
new file mode 100644
index 0000000..5500d70
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SBMLIconProvider.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/bundles/org.insilico.sbmlsheets/OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SpreadsheetDocumentLoader.xml b/bundles/org.insilico.sbmlsheets/OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SpreadsheetDocumentLoader.xml
new file mode 100644
index 0000000..9520b25
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SpreadsheetDocumentLoader.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/bundles/org.insilico.sbmlsheets/OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SpreadsheetEditorProvider.xml b/bundles/org.insilico.sbmlsheets/OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SpreadsheetEditorProvider.xml
new file mode 100644
index 0000000..07e70b6
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/OSGI-INF/services/org.insilico.sbmlsheets.services.provider.SpreadsheetEditorProvider.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/bundles/org.insilico.sbmlsheets/build.properties b/bundles/org.insilico.sbmlsheets/build.properties
new file mode 100644
index 0000000..c3c7874
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/build.properties
@@ -0,0 +1,7 @@
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ res/,\
+ OSGI-INF/
+source.. = src/
+
diff --git a/bundles/org.insilico.sbmlsheets/pom.xml b/bundles/org.insilico.sbmlsheets/pom.xml
new file mode 100644
index 0000000..a37de55
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/pom.xml
@@ -0,0 +1,39 @@
+
+
+
+ org.insilico
+ org.insilico.bundles
+ 1.0.0-SNAPSHOT
+ ../
+
+ 4.0.0
+ org.insilico.sbmlsheets
+ eclipse-plugin
+ SBMLsheets
+
+
+ src
+
+
+
+ .
+
+ META-INF/
+
+
+
+
+
+
+ org.eclipse.tycho
+ tycho-source-plugin
+ ${tycho.version}
+
+
+
+
+
+
+
+
diff --git a/bundles/org.insilico.sbmlsheets/res/sbml-logo-16.png b/bundles/org.insilico.sbmlsheets/res/sbml-logo-16.png
new file mode 100644
index 0000000..15cfad7
Binary files /dev/null and b/bundles/org.insilico.sbmlsheets/res/sbml-logo-16.png differ
diff --git a/bundles/org.insilico.sbmlsheets/res/sbml-logo-24.png b/bundles/org.insilico.sbmlsheets/res/sbml-logo-24.png
new file mode 100644
index 0000000..9a7d24e
Binary files /dev/null and b/bundles/org.insilico.sbmlsheets/res/sbml-logo-24.png differ
diff --git a/bundles/org.insilico.sbmlsheets/res/sbml-logo-48.png b/bundles/org.insilico.sbmlsheets/res/sbml-logo-48.png
new file mode 100644
index 0000000..5e96caa
Binary files /dev/null and b/bundles/org.insilico.sbmlsheets/res/sbml-logo-48.png differ
diff --git a/bundles/org.insilico.sbmlsheets/res/sbml-logo.svg b/bundles/org.insilico.sbmlsheets/res/sbml-logo.svg
new file mode 100644
index 0000000..a3fc306
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/res/sbml-logo.svg
@@ -0,0 +1,3369 @@
+
+
+
+
\ No newline at end of file
diff --git a/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/CompartmentInstance.java b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/CompartmentInstance.java
new file mode 100644
index 0000000..0e67704
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/CompartmentInstance.java
@@ -0,0 +1,417 @@
+package org.insilico.sbmlsheets.core;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import org.sbml.jsbml.Compartment;
+import org.sbml.jsbml.Model;
+import org.sbml.jsbml.Species;
+import org.sbml.jsbml.Unit.Kind;
+import com.sun.javafx.print.Units;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.IntegerProperty;
+import javafx.beans.property.Property;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.property.SimpleIntegerProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ObservableValue;
+
+
+public class CompartmentInstance{
+
+ //define in attributeTypes whether value should be treated as string, double, integer
+ public static ArrayList attributeTypes = new ArrayList<>(Arrays.asList(
+ "id_Str", "name_Str", "sboId_Str", "sbmlCompartmentId_Str", "outerCompartment_Str",
+ "outerCompartmentId_Str", "size_Dbl", "unit_Str", "comment_Str", "referenceName_Str",
+ "referencePubMed_Str", "referenceDOI_Str",
+ "description_Str", "miriamAnnotations_Str", "type_Str", "symbol_Str",
+ "positionX_Dbl", "positionY_Dbl", "sboTerm_Str", "identifiers_Str"));
+
+ public static ArrayList sbTabCol = new ArrayList<>(Arrays.asList(
+ "!ID", "!Name", "!Identifiers:obo.sbo", "!SBML:compartment:id", "!OuterCompartment",
+ "!OuterCompartment:SBML:compartment:id", "!Size", "!Unit", "!Comment", "!ReferenceName",
+ "!ReferencePubMed", "!ReferenceDOI", "!Description",
+ "!MiriamAnnotations", "!Type", "!Symbol", "!PositionX", "!PositionY", "!SBOTerm", "!Identifiers"));
+
+ public static ArrayList primaryKeys = new ArrayList<>(Arrays.asList("id", "sbmlCompartmentId"));
+
+ String defaultDouble = "0.0";
+ String defaultInt = "0";
+ public StringProperty id = new SimpleStringProperty("nan");
+ public StringProperty name = new SimpleStringProperty("nan");
+ public StringProperty sboId = new SimpleStringProperty("0");
+ public StringProperty sbmlCompartmentId = new SimpleStringProperty("nan");
+ public StringProperty outerCompartment = new SimpleStringProperty("nan");
+ public StringProperty outerCompartmentId = new SimpleStringProperty("nan");
+ public StringProperty size = new SimpleStringProperty("0.0");
+ public StringProperty unit = new SimpleStringProperty("dimensionless");
+
+ public StringProperty comment = new SimpleStringProperty("nan");
+ public StringProperty referenceName = new SimpleStringProperty("nan");
+ public StringProperty referencePubMed = new SimpleStringProperty("nan");
+ public StringProperty referenceDOI = new SimpleStringProperty("nan");
+ public StringProperty description = new SimpleStringProperty("nan");
+
+ public StringProperty miriamAnnotations = new SimpleStringProperty("nan");
+ public StringProperty type = new SimpleStringProperty("nan");
+ public StringProperty symbol = new SimpleStringProperty("nan");
+
+ public StringProperty positionX = new SimpleStringProperty("0.0");
+ public StringProperty positionY = new SimpleStringProperty("0.0");
+
+ public StringProperty sboTerm = new SimpleStringProperty("0");
+ public StringProperty identifiers = new SimpleStringProperty("nan");
+ ArrayList attributes = new ArrayList<>(Arrays.asList(
+ id, name, sboId, sbmlCompartmentId, outerCompartment, outerCompartmentId, size,
+ unit, comment, referenceName, referencePubMed, referenceDOI, description,
+ miriamAnnotations, type, symbol, positionX, positionY,
+ sboTerm, identifiers));
+
+ public HashMap annotations = new HashMap<>();
+ public CompartmentInstance(String idStr, String compartmentIdStr) {
+ this.id.setValue(idStr);
+ this.sbmlCompartmentId.setValue(compartmentIdStr);
+ }
+
+
+ /*
+ * property value getter/setter
+ */
+
+ public String getId() {
+ return id.getValue();
+ }
+
+
+ public String getName() {
+ return name.getValue();
+ }
+
+ public String getSboId() {
+ return sboId.getValue();
+ }
+
+ public String getSbmlCompartmentId() {
+ return sbmlCompartmentId.getValue();
+ }
+
+ public String getOuterCompartment() {
+ return outerCompartment.getValue();
+ }
+
+
+ public String getOuterCompartmentId() {
+ return outerCompartmentId.getValue();
+ }
+
+
+ public String getUnit() {
+ return unit.getValue();
+ }
+
+ public String getSize() {
+ return size.getValue().toString();
+ }
+
+
+ public String getComment() {
+ return comment.getValue();
+ }
+
+ public String getReferenceName() {
+ return referenceName.getValue();
+ }
+
+ public String getReferencePubMed() {
+ return referencePubMed.getValue();
+ }
+
+ public String getReferenceDOI() {
+ return referenceDOI.getValue();
+ }
+
+ public String getDescription() {
+ return description.getValue();
+ }
+
+ public String getMiriamAnnotations() {
+ return miriamAnnotations.getValue();
+ }
+ public String getType() {
+ return type.getValue();
+ }
+ public String getSymbol() {
+ return symbol.getValue();
+ }
+ public String getPositonX() {
+ return positionX.getValue();
+ }
+ public String getPositionY() {
+ return positionY.getValue();
+ }
+ public String getSboTerm() {
+ return sboTerm.getValue();
+ }
+ public String getIdentifiers() {
+ return identifiers.getValue();
+ }
+
+ /*
+ * property getter/setter
+ */
+
+
+ public StringProperty idProperty() {
+ return id;
+ }
+
+ public StringProperty nameProperty() {
+ return name;
+ }
+
+
+
+ public StringProperty sboIdProperty() {
+ return sboId;
+ }
+
+ public StringProperty outerCompartmentProperty() {
+ return outerCompartment;
+ }
+
+
+ public StringProperty sbmlCompartmentIdProperty() {
+ return sbmlCompartmentId;
+ }
+
+
+ public StringProperty outerCompartmentIdProperty() {
+ return outerCompartmentId;
+ }
+
+
+ public StringProperty unitProperty() {
+ return unit;
+ }
+
+
+ public StringProperty sizeProperty() {
+ return size;
+ }
+
+
+
+ public StringProperty commentProperty() {
+ return comment;
+ }
+
+ public StringProperty referenceNameProperty() {
+ return referenceName;
+ }
+
+ public StringProperty referencePubMedProperty() {
+ return referencePubMed;
+ }
+
+ public StringProperty referenceDOIProperty() {
+ return referenceDOI;
+ }
+
+ public StringProperty descriptionProperty() {
+ return description;
+ }
+
+ public StringProperty miriamAnnotationsProperty() {
+ return miriamAnnotations;
+ }
+ public StringProperty typeProperty() {
+ return type;
+ }
+ public StringProperty symbolProperty() {
+ return symbol;
+ }
+ public StringProperty positionXProperty() {
+ return positionX;
+ }public StringProperty positionYProperty() {
+ return positionY;
+ }
+
+ public StringProperty sboTermProperty() {
+ return sboTerm;
+ }public StringProperty identifiersProperty() {
+ return identifiers;
+ }
+
+ public ObservableValue getProperty(String attribute) {
+ for (int j=0; j < attributeTypes.size(); j++) {
+ if (attributeTypes.get(j).split("_")[0].equals(attribute)) {
+ return attributes.get(j);
+ }
+ }
+ return id;
+ }
+
+ private void setProperDouble(StringProperty attribute, String newValue, String oldValue) {
+ if (newValue.matches("^[0-9]+\\.[0-9]+$")) {
+ attribute.set(newValue);
+ }else if (newValue.matches("^[0-9]+$")) {
+ attribute.set(newValue+".0");
+ }else {
+ if (oldValue.matches("^[0-9]+\\.[0-9]+$")) {
+ attribute.set(oldValue);
+ }else if (oldValue.matches("^[0-9]+$")) {
+ attribute.set(oldValue+".0");
+ }else {
+ attribute.set(defaultDouble);
+ }
+ }
+ }
+
+ private void setProperInteger(StringProperty attribute, String newValue, String oldValue) {
+ if (newValue.matches("^[0-9]+\\.[0-9]+$")) {
+ attribute.setValue(newValue.split("\\.")[0]);
+ }else if (newValue.matches("^[0-9]+")) {
+ attribute.setValue(newValue);
+ }else {
+ if (oldValue.matches("^[0-9]+\\.[0-9]+$")) {
+ attribute.setValue(oldValue.split("\\.")[0]);
+ }else if (oldValue.matches("^[0-9]+$")) {
+ attribute.setValue(oldValue);
+ }else {
+ attribute.setValue(defaultInt);
+ }
+ }
+ }
+
+ private String getCorrectValue(String newValue, String type) {
+ String value = newValue.toString();
+ switch (type) {
+ case "Int":
+ System.out.println("changing to proper int");
+ if (value.matches("^[0-9]+\\.[0-9]+$")) {
+ value = value.split("\\.")[0];
+ }else if (value.matches("^[0-9]+$")) {
+ System.out.println("int stays int");
+ }else {
+ System.out.println("default int");
+ value = "0";
+ }
+ break;
+ case "Dbl":
+ if (value.matches("^[0-9]+\\.[0-9]+$")) {
+ System.out.println("dbl stays dbl");
+ }else if (value.matches("^[0-9]+$")) {
+ System.out.println("changing to proper double");
+ value = value+".0";
+ }else {
+ System.out.println("default double");
+ value = "0.0";
+ }
+ break;
+ case "Str":
+ System.out.println("string stays string");
+ //
+
+ default:
+ break;
+ }
+ return newValue;
+ }
+
+
+ public String toCSVLine() {
+ StringBuilder stringBuilder = new StringBuilder();
+ for (ObservableValue prop : attributes) {
+ stringBuilder.append(prop.getValue()+"\t");
+ stringBuilder.append("\t");
+ }
+ stringBuilder.append("\n");
+ return stringBuilder.toString();
+ }
+
+ public void setProperty(String attribute, String value) {
+ switch (attribute) {
+ case "id":
+ id.setValue(value);
+ break;
+ case "name":
+ name.setValue(value);
+ break;
+ case "sboId":
+ sboId.setValue(value);
+ break;
+ case "outerCompartment":
+ outerCompartment.setValue(value);
+ break;
+ case "sbmlCompartmentId":
+ sbmlCompartmentId.setValue(value);
+ break;
+ case "outerCompartmentId":
+ outerCompartmentId.setValue(value);
+ break;
+ case "unit":
+ unit.setValue(value);
+ break;
+ case "size":
+ size.setValue(value);
+ break;
+ case "comment":
+ comment.setValue(value);
+ break;
+ case "referenceName":
+ referenceName.setValue(value);
+ break;
+ case "referencePubMed":
+ referencePubMed.setValue(value);
+ break;
+ case "referenceDOI":
+ referenceDOI.setValue(value);
+ break;
+ case "description":
+ description.setValue(value);
+ break;
+ case "miriamAnnotations":
+ miriamAnnotations.setValue(value);
+ break;
+ case "type":
+ type.setValue(value);
+ break;
+ case "symbol":
+ symbol.setValue(value);
+ break;
+ case "positionX":
+ positionX.setValue(value);
+ break;
+ case "positionY":
+ positionY.setValue(value);
+ break;
+ case "sboTerm":
+ sboTerm.setValue(value);
+ break;
+ case "identifiers":
+ identifiers.setValue(value);
+ break;
+ default:
+ break;
+ }
+ }
+
+ public Compartment instanceToSBMLCompartment(int level, int version, Model model) {
+ Compartment compartment = model.createCompartment();
+ compartment.setId(sbmlCompartmentId.getValue());
+ compartment.setName(name.getValue());
+ compartment.setSBOTerm(SBMLUtils.convertToSBO(sboTerm.getValue()));
+
+ compartment.setSize(SBMLUtils.convertToDbl(size.getValue()));
+ Kind u = SBMLUtils.convertToUnit(unit.getValue());
+ if (u != null) {
+ compartment.setUnits(u);
+ }
+ return compartment;
+ }
+}
+
+
\ No newline at end of file
diff --git a/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/CompartmentTableView.java b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/CompartmentTableView.java
new file mode 100644
index 0000000..44f7aab
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/CompartmentTableView.java
@@ -0,0 +1,606 @@
+package org.insilico.sbmlsheets.core;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.TreeSet;
+import org.insilico.sbmlsheets.editor.IdentifierChooser;
+import org.sbml.jsbml.CVTerm;
+import com.sun.javafx.scene.control.skin.TableColumnHeader;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.property.SimpleIntegerProperty;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.event.EventTarget;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.SelectionMode;
+import javafx.scene.control.TableCell;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableColumnBase;
+import javafx.scene.control.TableColumn.CellDataFeatures;
+import javafx.scene.control.TablePosition;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TextField;
+import javafx.scene.control.cell.CheckBoxTableCell;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.control.cell.TextFieldTableCell;
+import javafx.scene.input.Clipboard;
+import javafx.scene.input.ClipboardContent;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.VBox;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.util.Callback;
+import javafx.util.StringConverter;
+import javafx.util.converter.DefaultStringConverter;
+import javafx.util.converter.DoubleStringConverter;
+
+public class CompartmentTableView extends TableView{
+
+public int i = 0;
+
+ HashSet compartmentIds = new HashSet();
+ HashSet ids = new HashSet();
+ private ObservableList instances = FXCollections.observableArrayList();
+
+
+ public CompartmentTableView(){
+ setEditable(true);
+ initExampleData(3);
+ this.setItems(instances);
+ initColumns(this);
+ initSelectionListeners();
+ }
+
+
+ private void initSelectionListeners() {
+ this.addEventFilter(KeyEvent.KEY_PRESSED, e -> {
+ if (e.getCode().equals( KeyCode.DELETE)) {
+ if (e.isShortcutDown()) {
+ removeSelectedColumns();
+ }else {
+ removeSelection();
+ }
+
+ }else if (e.getCode().equals(KeyCode.C) && e.isShortcutDown()) {
+ copySelectionToClipboard();
+
+ }else if (e.getCode().equals(KeyCode.A) && e.isShortcutDown()) {
+ this.getSelectionModel().selectAll();
+ }else if (e.isShortcutDown() && e.getCode().equals(KeyCode.N) && e.getCode().equals(KeyCode.R)) {
+ addEmptyRow();
+ }else if (e.isShortcutDown() && e.getCode().equals(KeyCode.N) && e.getCode().equals(KeyCode.C)) {
+ addNewColumn("NewCol_"+getColumns().size());
+ }else if (e.isShortcutDown()) {
+ this.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
+ }
+ e.consume();
+ });
+ }
+
+ public void copySelectionToClipboard() {
+ final ArrayList rows = new ArrayList<>();
+ final ArrayList cellColumns = new ArrayList<>();
+ final ArrayList cells = new ArrayList<>();
+ for (final TablePosition tablePosition : this.getSelectionModel().getSelectedCells()) {
+ if (!rows.contains(tablePosition.getRow())){
+ rows.add(tablePosition.getRow());
+ }
+ if (!cells.contains(tablePosition.getRow()+"_"+tablePosition.getColumn())){
+ cells.add(tablePosition.getRow()+"_"+tablePosition.getColumn());
+ }
+ if (!cellColumns.contains(tablePosition.getColumn())) {
+ cellColumns.add(tablePosition.getColumn());
+ }
+
+ }
+ final StringBuilder strb = new StringBuilder();
+
+ if (this.getSelectionModel().cellSelectionEnabledProperty().getValue()) {
+ for (Integer col : cellColumns) {
+ strb.append(this.getColumns().get(col).getText());
+
+ if (cellColumns.indexOf(col)==cellColumns.size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append("\t");
+ }
+ }
+ for (String s : cells) {
+ for (Integer i : cellColumns) {
+ String[] split = s.split("_");
+ if (split[1].equals(String.valueOf(i))) {
+ Object cellData = this.getColumns().get(i).getCellData(Integer.parseInt(split[0]));
+ strb.append(cellData == null ? "" : cellData);
+ }
+ if (cellColumns.indexOf(i)==cellColumns.size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append("\t");
+ }
+ }
+ }
+
+ }else {
+ for (TableColumn col : this.getColumns()) {
+ strb.append(col.getText());
+ if (this.getColumns().indexOf(col)==this.getColumns().size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append("\t");
+ }
+ }
+ boolean firstRow = true;
+ for (final Integer row : rows) {
+ for (final TableColumn, ?> column : this.getColumns()) {
+ strb.append(column.getCellData(row) == null ? "" : column.getCellData(row));
+ if (this.getColumns().indexOf(column)==this.getColumns().size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append("\t");
+ }
+ }
+ }
+ }
+
+ final ClipboardContent clipboardContent = new ClipboardContent();
+ clipboardContent.putString(strb.toString());
+ Clipboard.getSystemClipboard().setContent(clipboardContent);
+ }
+
+ public void removeSelection() {
+ for (CompartmentInstance i : this.getSelectionModel().getSelectedItems()) {
+ this.getItems().remove(i);
+ }
+ }
+
+ public void removeSelectedColumns() {
+ HashSet s = new HashSet<>();
+ for (TablePosition t : this.getSelectionModel().getSelectedCells()) {
+ if (t.getTableColumn().getUserData()!=null) {
+ if (t.getTableColumn().getUserData().equals("editable")) {
+ s.add(t.getTableColumn());
+ }
+ }
+ }
+ this.getColumns().removeAll(s);
+ }
+
+
+ public void addEmptyRow() {
+ String newId = "comp_1";
+ int k = 1;
+ while (ids.contains(newId)) {
+ k+=1;
+ newId = "comp_"+k;
+ }
+
+ String newId2 = "comp_1";
+ int k2 = 1;
+ while (compartmentIds.contains(newId2)) {
+ k2+=1;
+ newId2 = "comp_"+k2;
+ }
+
+ compartmentIds.add(newId2);
+ ids.add(newId);
+ System.out.println(newId);
+ CompartmentInstance newRowData = new CompartmentInstance(newId, newId2);
+ instances.add(newRowData);
+
+ }
+
+ boolean addingIdentColumn = false;
+
+ public void addNewColumn(String colTitle) {
+ addingIdentColumn = true;
+ for (CompartmentInstance c : instances) {
+ if (!c.attributeTypes.contains(colTitle.replaceAll("[:!]", "")+"_Str")) {
+ //add
+ c.attributeTypes.add(colTitle.replaceAll("[:!]", "")+"_Str");
+ c.sbTabCol.add(colTitle);
+ }
+ }
+
+
+ Callback, TableCell> cellFactoryStr
+ = (TableColumn param) -> new EditableCell("Str", this, colTitle.replaceAll("[:!]", ""));
+ TableColumn strCol = new TableColumn(colTitle.replaceAll("[:!]", ""));
+ strCol.setCellValueFactory(new Callback, ObservableValue>() {
+ public ObservableValue call(CellDataFeatures p) {
+ return p.getValue().attributes.get(p.getValue().attributes.size()-1);
+ }
+ });
+ strCol.setCellFactory(cellFactoryStr);
+ strCol.setOnEditCommit(
+ (TableColumn.CellEditEvent t) -> {
+ ((CompartmentInstance) t.getTableView().getItems()
+ .get(t.getTablePosition().getRow()))
+ .setProperty(colTitle.replaceAll("[:!]", ""), t.getNewValue());
+ this.refresh();
+ });
+ strCol.setUserData("editable");
+
+
+ this.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
+ if (e.isPrimaryButtonDown() && e.getClickCount() > 1) {
+ EventTarget target = e.getTarget();
+ TableColumnBase, ?> column = null;
+ while (target instanceof Node) {
+ target = ((Node) target).getParent();
+ if (target instanceof TableColumnHeader) {
+ column = ((TableColumnHeader) target).getTableColumn();
+ if (column != null) break;
+ }
+ }
+ if (column != null) {
+ if (column.getUserData().equals("editable")) {
+ TableColumnBase,?> tableColumn = column;
+ TextField textField = new TextField(column.getText());
+ textField.setMaxWidth(column.getWidth());
+ textField.setOnAction(a -> {
+ tableColumn.setText(textField.getText());
+ tableColumn.setGraphic(null);
+ });
+ textField.focusedProperty().addListener((src, ov, nv) -> {
+ if (!nv) tableColumn.setGraphic(null);
+ });
+ column.setGraphic(textField);
+ textField.requestFocus();
+
+ ContextMenu contextMenu = new ContextMenu();
+ MenuItem choose = new MenuItem("Choose valid SBTab Column Title");
+ contextMenu.getItems().add(choose);
+ textField.setContextMenu(contextMenu);
+
+ choose.setOnAction(new EventHandler() {
+ @Override public void handle(ActionEvent e) {
+ IdentifierChooser chooser = new IdentifierChooser();
+ Stage dialogStage = new Stage();
+ dialogStage.centerOnScreen();
+ Scene dialogScene = new Scene(chooser, 300, 550);
+ dialogStage.show();
+ dialogStage.setScene(dialogScene);
+
+ final Stage[] stages = new Stage[] {dialogStage};
+
+ chooser.getB().setOnAction(new EventHandler() {
+ @Override public void handle(ActionEvent e) {
+ tableColumn.setText(chooser.getResultList().getSelectionModel().getSelectedItem());
+ tableColumn.setGraphic(null);
+ stages[0].close();
+ }
+ });
+ chooser.getB2().setOnAction(new EventHandler() {
+ @Override public void handle(ActionEvent e) {
+ stages[0].close();
+ tableColumn.setGraphic(null);
+ }
+ });
+ }
+ });
+
+ }
+ e.consume();
+ }
+ }
+ });
+
+
+ this.getColumns().add(strCol);
+ strCol.setEditable(true);
+
+ }
+
+
+ private void initExampleData(int m) {
+ for (int l = 0; l < m; l++) {
+ addEmptyRow();
+ }
+ }
+
+ private void initColumns(CompartmentTableView table) {
+
+ for (int j = 0; j < CompartmentInstance.attributeTypes.size(); j++) {
+ final int k = j;
+
+ String att = CompartmentInstance.attributeTypes.get(j);
+ String[] attSpl = att.split("_");
+ System.out.println(k + " : " + attSpl[0] + " --> " + attSpl[1]);
+ switch (attSpl[1]) {
+ case "Bool":
+ TableColumn boolCol = new TableColumn(attSpl[0]);
+ boolCol.setCellValueFactory(new PropertyValueFactory<>(attSpl[0]));
+ boolCol.setUserData("notEditable");
+ final CheckBoxTableCell ctCell = new CheckBoxTableCell<>();
+ ctCell.setSelectedStateCallback(new Callback>() {
+ @Override
+ public ObservableValue call(Integer index) {
+ return table.getItems().get(index).attributes.get(index);
+ }
+ });
+
+ boolCol.setCellFactory(column -> new CheckBoxTableCell());
+ this.getColumns().add(boolCol);
+ boolCol.setEditable(true);
+ break;
+ case "Str":
+ Callback, TableCell> cellFactoryStr
+ = (TableColumn param) -> new EditableCell(attSpl[1], this, attSpl[0]);
+ TableColumn strCol = new TableColumn(attSpl[0]);
+ strCol.setCellValueFactory(new Callback, ObservableValue>() {
+ public ObservableValue call(CellDataFeatures p) {
+ return p.getValue().attributes.get(k);
+ }
+ });
+ strCol.setUserData("notEditable");
+ strCol.setCellFactory(cellFactoryStr);
+ strCol.setOnEditCommit(
+ (TableColumn.CellEditEvent t) -> {
+ String val = t.getNewValue();
+ switch (attSpl[0]) {
+ case "sbmlCompartmentId":
+ if (!t.getOldValue().equals(t.getNewValue())) {
+ compartmentIds.remove(t.getOldValue());
+ String[] split = val.split("_");
+ String prefix = split[0];
+ String num = split[1];
+ while (compartmentIds.contains(val)) {
+ if (split.length>1) {
+ if (num.matches("[0-9]+")) {
+ num = String.valueOf(Integer.parseInt(num)+1);
+ val = prefix + "_" + num;
+
+ }else {
+ val = prefix + "_1";
+ num = "1";
+ }
+ }else {
+ val = prefix + "_1";
+ num = "1";
+ }
+ }
+ compartmentIds.add(val);
+ }
+ break;
+
+ case "id":
+
+ if (!t.getOldValue().equals(t.getNewValue())) {
+ ids.remove(t.getOldValue());
+ String[] split = val.split("_");
+ String prefix = split[0];
+ String num = split[1];
+ while (ids.contains(val)) {
+ if (split.length>1) {
+ if (num.matches("[0-9]+")) {
+ num = String.valueOf(Integer.parseInt(num)+1);
+ val = prefix + "_" + num;
+
+ }else {
+ val = prefix + "_1";
+ num = "1";
+ }
+ }else {
+ val = prefix + "_1";
+ num = "1";
+ }
+ }
+ ids.add(val);
+
+ }
+ break;
+ case "sboTerm":
+ val = SBMLUtils.convertToSBO(t.getNewValue());
+ break;
+ case "unit":
+ val = SBMLUtils.convertToUnit(t.getNewValue()).getName();
+ break;
+ }
+
+ ((CompartmentInstance) t.getTableView().getItems()
+ .get(t.getTablePosition().getRow()))
+ .setProperty(attSpl[0], val);
+ this.refresh();
+ });
+
+
+ this.getColumns().add(strCol);
+ strCol.setEditable(true);
+ break;
+ case "Int"://
+ Callback, TableCell> cellFactoryInt
+ = (TableColumn param) -> new EditableCell(attSpl[1], this, attSpl[0]);
+ TableColumn intCol = new TableColumn(attSpl[0]);
+ intCol.setCellValueFactory(new Callback, ObservableValue>() {
+ public ObservableValue call(CellDataFeatures p) {
+ return p.getValue().attributes.get(k);
+ }
+ });
+ intCol.setUserData("notEditable");
+ intCol.setCellFactory(cellFactoryInt);
+ intCol.setOnEditCommit(
+ (TableColumn.CellEditEvent t) -> {
+ String value = t.getNewValue();
+ System.out.println("changing to proper int");
+ if (value.matches("^[0-9]+\\.[0-9]+$")) {
+ value = value.split("\\.")[0];
+ }else if (value.matches("^[0-9]+$")) {
+ System.out.println("int stays int");
+ }else {
+ System.out.println("default int");
+ value = "0";
+ }
+
+ ((CompartmentInstance) t.getTableView().getItems()
+ .get(t.getTablePosition().getRow()))
+ .setProperty(attSpl[0], value);
+ this.refresh();
+ });
+
+ this.getColumns().add(intCol);
+ intCol.setEditable(true);
+ break;
+ case "Dbl":
+ Callback, TableCell> cellFactoryDbl
+ = (TableColumn param) -> new EditableCell(attSpl[1], this, attSpl[0]);
+ TableColumn dblCol = new TableColumn(attSpl[0]);
+ dblCol.setCellValueFactory(new Callback, ObservableValue>() {
+ public ObservableValue call(CellDataFeatures p) {
+ return p.getValue().attributes.get(k);
+ }
+ });
+ dblCol.setCellFactory(cellFactoryDbl);
+ dblCol.setUserData("notEditable");
+ dblCol.setOnEditCommit(
+ (TableColumn.CellEditEvent t) -> {
+ String value = t.getNewValue();
+ System.out.println("changing to proper int");
+ if (value.matches("^[0-9]+\\.[0-9]+$")) {
+ System.out.println("dbl stays dbl");
+ }else if (value.matches("^[0-9]+$")) {
+ System.out.println("changing to proper double");
+ value = value+".0";
+ }else {
+ System.out.println("default double");
+ value = "0.0";
+ }
+
+ ((CompartmentInstance) t.getTableView().getItems()
+ .get(t.getTablePosition().getRow()))
+ .setProperty(attSpl[0], value);
+ this.refresh();
+ });
+
+
+ this.getColumns().add(dblCol);
+ dblCol.setEditable(true);
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ }
+
+
+
+
+ public void addAnnotationColumn(String annotationType) {
+ Callback, TableCell> cellFactory
+ = (TableColumn param) -> new EditableCell("str", this);
+ TableColumn strCol = new TableColumn(annotationType);
+
+ this.getColumns().add(strCol);
+ strCol.setEditable(true);
+ //create
+ }
+
+ public String toCSVString() {
+
+ StringBuilder csvStringBuilder = new StringBuilder();
+ for (TableColumn column : this.getColumns()) {
+ csvStringBuilder.append(column.getText()+"\t");
+ }
+
+ for (int y = 0; y < instances.size(); y++) {
+ for (int x = 0; x < this.getColumns().size(); x++) {
+ csvStringBuilder.append(this.getColumns().get(x).getCellData(y).toString()+"\t");
+ }
+ csvStringBuilder.append("\n");
+ }
+
+ return csvStringBuilder.toString();
+
+ }
+
+ public String toSBTabString() {
+ StringBuilder sbTabStringBuilder = new StringBuilder();
+
+ sbTabStringBuilder.append(createSBTabHeader());
+ sbTabStringBuilder.append("\n");
+ sbTabStringBuilder.append(createSbTabColumnHeader());
+ sbTabStringBuilder.append("\n");
+ sbTabStringBuilder.append(createSbTabRows());
+ return sbTabStringBuilder.toString();
+ }
+
+ private String createSbTabRows() {
+ StringBuilder sbTabStringBuilder = new StringBuilder();
+ for (int y = 0; y < instances.size(); y++) {
+ for (int x = 0; x < this.getColumns().size(); x++) {
+ if (writtenColumns.contains(x)) {
+ String colTitle = this.getColumns().get(x).getText();
+ String value = this.getColumns().get(x).getCellData(y).toString();
+ String value2 = value.toString();
+
+ sbTabStringBuilder.append(value2+"\t");
+ }
+ }
+ sbTabStringBuilder.append("\n");
+ }
+ return sbTabStringBuilder.toString().replaceAll("\n(\n)*", "\n");
+ }
+
+ HashSet writtenColumns = new HashSet<>();
+ private String createSbTabColumnHeader() {
+ StringBuilder sbTabStringBuilder = new StringBuilder();
+ for (TableColumn col : this.getColumns()) {
+ String title = col.getText();
+ System.out.println(title);
+ if (CompartmentInstance.attributeTypes.contains(title+"_Str")){
+ writtenColumns.add(this.getColumns().indexOf(col));
+ sbTabStringBuilder.append(CompartmentInstance.sbTabCol.get(CompartmentInstance.attributeTypes.indexOf(title+"_Str")));
+ }else if (CompartmentInstance.attributeTypes.contains(title+"_Int")) {
+ writtenColumns.add(this.getColumns().indexOf(col));
+ sbTabStringBuilder.append(CompartmentInstance.sbTabCol.get(CompartmentInstance.attributeTypes.indexOf(title+"_Int")));
+ }else if (CompartmentInstance.attributeTypes.contains(title+"_Dbl")) {
+ writtenColumns.add(this.getColumns().indexOf(col));
+ sbTabStringBuilder.append(CompartmentInstance.sbTabCol.get(CompartmentInstance.attributeTypes.indexOf(title+"_Dbl")));
+ }else if (CompartmentInstance.attributeTypes.contains(title+"_Bool")) {
+ writtenColumns.add(this.getColumns().indexOf(col));
+ sbTabStringBuilder.append(CompartmentInstance.sbTabCol.get(CompartmentInstance.attributeTypes.indexOf(title+"_Bool")));
+ }else {
+ if (IdentifierChooser.sbTabDefinitions.contains(title)) {
+ writtenColumns.add(this.getColumns().indexOf(col));
+ sbTabStringBuilder.append(title);
+ }
+ }
+ sbTabStringBuilder.append("\t");
+ }
+ return sbTabStringBuilder.toString();
+ }
+
+ private Object createSBTabHeader() {
+ return "!!SBtab TableID='compartment' TableType='Compartment' TableName='Compartments' SBtabVersion='1.0'";
+ }
+
+ public HashSet getIds(){
+ return ids;
+ }
+
+
+}
+
+
+
+
+
+
+
diff --git a/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/CompoundInstance.java b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/CompoundInstance.java
new file mode 100644
index 0000000..f40325c
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/CompoundInstance.java
@@ -0,0 +1,429 @@
+package org.insilico.sbmlsheets.core;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import org.sbml.jsbml.Model;
+import org.sbml.jsbml.Species;
+import org.sbml.jsbml.Unit;
+import org.sbml.jsbml.Unit.Kind;
+import com.sun.corba.se.impl.orbutil.closure.Constant;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.IntegerProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.property.SimpleIntegerProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ObservableValue;
+
+public class CompoundInstance{
+
+ public static ArrayList attributeTypes = new ArrayList<>(Arrays.asList(
+ "id_Str", "name_Str", "speciesId_Str", "speciesType_Str", "initValue_Dbl", "unit_Str", "location_Str", "state_Str",
+ "compoundReactionFormula_Str", "structureFormula_Str", "charge_Int", "mass_Dbl", "isConstant_Bool",
+ "enzymeRole_Str", "regulatorRole_Str",
+ "comment_Str", "referenceName_Str", "referencePubMed_Str", "referenceDOI_Str", "description_Str", "miriamAnnotations_Str", "type_Str", "symbol_Str",
+ "positionX_Dbl", "positionY_Dbl", "sboTerm_Str", "identifiers_Str"));
+
+ public static ArrayList sbTabCol = new ArrayList<>(Arrays.asList(
+ "!ID", "!Name", "!SBML:species:id", "!SBML:speciestype:id", "!InitialValue", "!Unit", "!Location", "!State",
+ "!CompoundSumFormula", "!StructureFormula", "!Charge", "!Mass", "!IsConstant",
+ "!EnzymeRole", "!RegulatorRole", "!Comment", "!ReferenceName",
+ "!ReferencePubMed", "!ReferenceDOI", "!Description",
+ "!MiriamAnnotations", "!Type", "!Symbol", "!PositionX", "!PositionY", "!SBOTerm", "!Identifiers"));
+
+ public static ArrayList primaryKeys = new ArrayList<>(Arrays.asList("id", "speciesId"));
+
+ double defaultDouble = 0.0;
+ int defaultInt = 0;
+ public StringProperty id = new SimpleStringProperty("nan");
+ public StringProperty name = new SimpleStringProperty("nan");
+ public StringProperty speciesId = new SimpleStringProperty("nan");
+ public StringProperty speciesType = new SimpleStringProperty("nan");
+ public StringProperty initValue = new SimpleStringProperty("0.0");
+ public StringProperty unit = new SimpleStringProperty("dimensionless");
+ public StringProperty location = new SimpleStringProperty("nan");
+ public StringProperty state = new SimpleStringProperty("nan");
+ public StringProperty compoundReactionFormula = new SimpleStringProperty("nan");
+ public StringProperty structureFormula = new SimpleStringProperty("nan");
+ public StringProperty charge = new SimpleStringProperty("0");
+ public StringProperty mass = new SimpleStringProperty("0.0");
+ public BooleanProperty isConstant = new SimpleBooleanProperty(false);
+ public StringProperty enzymeRole = new SimpleStringProperty("nan");
+ public StringProperty regulatorRole = new SimpleStringProperty("nan");
+ public StringProperty comment = new SimpleStringProperty("nan");
+ public StringProperty referenceName = new SimpleStringProperty("nan");
+ public StringProperty referencePubMed = new SimpleStringProperty("nan");
+ public StringProperty referenceDOI = new SimpleStringProperty("nan");
+ public StringProperty description = new SimpleStringProperty("nan");
+
+ public StringProperty miriamAnnotations = new SimpleStringProperty("nan");
+ public StringProperty type = new SimpleStringProperty("nan");
+ public StringProperty symbol = new SimpleStringProperty("nan");
+
+ public StringProperty positionX = new SimpleStringProperty("0.0");
+ public StringProperty positionY = new SimpleStringProperty("0.0");
+ public StringProperty sboTerm = new SimpleStringProperty("SBO:0000001");
+ public StringProperty identifiers = new SimpleStringProperty("nan");
+ ArrayList attributes = new ArrayList<>(Arrays.asList(id, name, speciesId, speciesType, initValue,
+ unit, location, state, compoundReactionFormula,structureFormula, charge, mass, isConstant,
+ enzymeRole, regulatorRole, comment, referenceName,
+ referencePubMed, referenceDOI, description, miriamAnnotations, type, symbol, positionX,
+ positionY, sboTerm, identifiers));
+ public HashMap annotations = new HashMap<>();
+
+ public CompoundInstance(String idStr, String speciesIdStr) {
+ this.id.setValue(idStr);
+ this.speciesId.setValue(speciesIdStr);
+ }
+
+ /*
+ * property value getter/setter
+ */
+
+ public String getId() {
+ return id.getValue();
+ }
+
+ public String getName() {
+ return name.getValue();
+ }
+
+
+ public String getSpeciesId() {
+ return speciesId.getValue();
+ }
+
+
+ public String getSpeciesType() {
+ return speciesType.getValue();
+ }
+
+
+ public String getInitValue() {
+ return initValue.getValue();
+ }
+
+
+ public String getUnit() {
+ return unit.getValue();
+ }
+
+
+ public String getLocation() {
+ return location.getValue();
+ }
+
+
+ public String getState() {
+ return state.getValue();
+ }
+
+
+ public String getCompoundReactionFormula() {
+ return compoundReactionFormula.getValue();
+ }
+
+
+ public String getStructureFormula() {
+ return structureFormula.getValue();
+ }
+
+
+ public String getCharge() {
+ return charge.getValue();
+ }
+
+
+ public String getMass() {
+ return mass.getValue();
+ }
+
+
+ public boolean getIsConstant() {
+ return isConstant.getValue();
+ }
+
+
+ public String getEnzymeRole() {
+ return enzymeRole.getValue();
+ }
+
+
+ public String getRegulatorRole() {
+ return regulatorRole.getValue();
+ }
+
+ public String getComment() {
+ return comment.getValue();
+ }
+
+ public String getReferenceName() {
+ return referenceName.getValue();
+ }
+
+ public String getReferencePubMed() {
+ return referencePubMed.getValue();
+ }
+
+ public String getReferenceDOI() {
+ return referenceDOI.getValue();
+ }
+
+ public String getDescription() {
+ return description.getValue();
+ }
+
+
+ public String getMiriamAnnotations() {
+ return miriamAnnotations.getValue();
+ }
+ public String getType() {
+ return type.getValue();
+ }
+ public String getSymbol() {
+ return symbol.getValue();
+ }
+ public String getPositonX() {
+ return positionX.getValue();
+ }
+ public String getPositionY() {
+ return positionY.getValue();
+ }
+ public String getSboTerm() {
+ return sboTerm.getValue();
+ }
+ public String getIdentifiers() {
+ return identifiers.getValue();
+ }
+ /*
+ * property getter/setter
+ */
+
+ public BooleanProperty getIsConstantProperty() {
+ return isConstant;
+ }
+
+ public StringProperty idProperty() {
+ return id;
+ }
+
+ public StringProperty nameProperty() {
+ return name;
+ }
+
+ public StringProperty speciesIdProperty() {
+ return speciesId;
+ }
+
+ public StringProperty speciesTypeProperty() {
+ return speciesType;
+ }
+
+
+ public StringProperty initValueProperty() {
+ return initValue;
+ }
+
+
+ public StringProperty unitProperty() {
+ return unit;
+ }
+
+
+ public StringProperty locationProperty() {
+ return location;
+ }
+
+
+ public StringProperty stateProperty() {
+ return state;
+ }
+
+
+ public StringProperty compoundReactionFormulaProperty() {
+ return compoundReactionFormula;
+ }
+
+
+ public StringProperty structureFormulaProperty() {
+ return structureFormula;
+ }
+
+
+ public StringProperty chargeProperty() {
+ return charge;
+ }
+
+
+ public StringProperty massProperty() {
+ return mass;
+ }
+
+
+ public StringProperty enzymeRoleProperty() {
+ return enzymeRole;
+ }
+
+
+ public StringProperty regulatorRoleProperty() {
+ return regulatorRole;
+ }
+
+ public StringProperty commentProperty() {
+ return comment;
+ }
+
+ public StringProperty referenceNameProperty() {
+ return referenceName;
+ }
+
+ public StringProperty referencePubMedProperty() {
+ return referencePubMed;
+ }
+
+ public StringProperty referenceDOIProperty() {
+ return referenceDOI;
+ }
+
+ public StringProperty descriptionProperty() {
+ return description;
+ }
+
+ public StringProperty miriamAnnotationsProperty() {
+ return miriamAnnotations;
+ }
+ public StringProperty typeProperty() {
+ return type;
+ }
+ public StringProperty symbolProperty() {
+ return symbol;
+ }
+ public StringProperty positionXProperty() {
+ return positionX;
+ }public StringProperty positionYProperty() {
+ return positionY;
+ }
+
+ public StringProperty sboTermProperty() {
+ return sboTerm;
+ }public StringProperty identifiersProperty() {
+ return identifiers;
+ }
+ public String toCSVLine() {
+ StringBuilder stringBuilder = new StringBuilder();
+ for (ObservableValue prop : attributes) {
+ stringBuilder.append(prop.getValue()+"\t");
+ stringBuilder.append("\t");
+ }
+ stringBuilder.append("\n");
+ return stringBuilder.toString();
+ }
+
+
+ public void setProperty(String attribute, String value) {
+ switch (attribute) {
+ case "id":
+ id.setValue(value);
+ break;
+ case "name":
+ name.setValue(value);
+ break;
+ case "speciesId":
+ speciesId.setValue(value);
+ break;
+ case "speciesType":
+ speciesType.setValue(value);
+ break;
+ case "initValue":
+ initValue.setValue(value);
+ break;
+ case "unit":
+ unit.setValue(value);
+ break;
+ case "location":
+ location.setValue(value);
+ break;
+ case "state":
+ state.setValue(value);
+ break;
+ case "charge":
+ charge.setValue(value);
+ break;
+ case "mass":
+ mass.setValue(value);
+ break;
+ case "isConstant":
+ isConstant.setValue(Boolean.getBoolean(value));
+ break;
+ case "compoundReactionFormula":
+ compoundReactionFormula.setValue(value);
+ break;
+ case "structureFormula":
+ structureFormula.setValue(value);
+ break;
+ case "enzymeRole":
+ enzymeRole.setValue(value);
+ break;
+ case "regulatorRole":
+ regulatorRole.setValue(value);
+ break;
+ case "comment":
+ comment.setValue(value);
+ break;
+ case "referenceName":
+ referenceName.setValue(value);
+ break;
+ case "referencePubMed":
+ referencePubMed.setValue(value);
+ break;
+ case "referenceDOI":
+ referenceDOI.setValue(value);
+ break;
+ case "description":
+ description.setValue(value);
+ break;
+ case "miriamAnnotations":
+ miriamAnnotations.setValue(value);
+ break;
+ case "type":
+ type.setValue(value);
+ break;
+ case "symbol":
+ symbol.setValue(value);
+ break;
+ case "positionX":
+ positionX.setValue(value);
+ break;
+ case "positionY":
+ positionY.setValue(value);
+ break;
+ case "sboTerm":
+ sboTerm.setValue(value);
+ break;
+ case "identifiers":
+ identifiers.setValue(value);
+ break;
+ }
+ }
+
+
+ public Species instanceToSBMLSpecies(int level, int version, Model model) {
+ Species species = model.createSpecies();
+ species.setId(speciesId.getValue());
+ species.setName(name.getValue());
+ species.setInitialAmount(SBMLUtils.convertToDbl(initValue.getValue()));
+ Kind u = SBMLUtils.convertToUnit(unit.getValue());
+ if (u != null) {
+ species.setUnits(u);
+ }
+ species.setCompartment(location.getValue());
+ species.setConstant(isConstant.getValue());
+ species.setSBOTerm(SBMLUtils.convertToSBO(sboTerm.getValue()));
+ return species;
+ }
+
+}
\ No newline at end of file
diff --git a/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/CompoundTableView.java b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/CompoundTableView.java
new file mode 100644
index 0000000..e6bfb66
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/CompoundTableView.java
@@ -0,0 +1,570 @@
+package org.insilico.sbmlsheets.core;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.TreeSet;
+import org.insilico.sbmlsheets.editor.IdentifierChooser;
+import com.sun.javafx.scene.control.skin.TableColumnHeader;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.event.EventTarget;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.SelectionMode;
+import javafx.scene.control.TableCell;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableColumn.CellDataFeatures;
+import javafx.scene.control.TableColumnBase;
+import javafx.scene.control.TablePosition;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TextField;
+import javafx.scene.control.cell.CheckBoxTableCell;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.input.Clipboard;
+import javafx.scene.input.ClipboardContent;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.StackPane;
+import javafx.stage.Stage;
+import javafx.util.Callback;
+
+public class CompoundTableView extends TableView{
+
+ public int i = 0;
+
+ HashSet compoundIds = new HashSet();
+ HashSet ids = new HashSet();
+ private ObservableList instances = FXCollections.observableArrayList();
+
+ public CompoundTableView(){
+ setEditable(true);
+ initExampleData(3);
+ this.setItems(instances);
+ initColumns(this);
+ initSelectionListeners();
+
+ }
+
+ private void initSelectionListeners() {
+ this.addEventFilter(KeyEvent.KEY_PRESSED, e -> {
+ if (e.getCode().equals( KeyCode.DELETE)) {
+ if (e.isShortcutDown()) {
+ removeSelectedColumns();
+ }else {
+ removeSelection();
+ }
+
+ }else if (e.getCode().equals(KeyCode.C) && e.isShortcutDown()) {
+ copySelectionToClipboard();
+
+ }else if (e.getCode().equals(KeyCode.A) && e.isShortcutDown()) {
+ this.getSelectionModel().selectAll();
+ }else if (e.isShortcutDown() && e.getCode().equals(KeyCode.N) && e.getCode().equals(KeyCode.R)) {
+ addEmptyRow();
+ }else if (e.isShortcutDown() && e.getCode().equals(KeyCode.N) && e.getCode().equals(KeyCode.C)) {
+ addNewColumn("NewCol_"+getColumns().size());
+ }else if (e.isShortcutDown()) {
+ this.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
+ }
+ e.consume();
+ });
+ }
+
+ public void copySelectionToClipboard() {
+ final ArrayList rows = new ArrayList<>();
+ final ArrayList cellColumns = new ArrayList<>();
+ final ArrayList cells = new ArrayList<>();
+ for (final TablePosition tablePosition : this.getSelectionModel().getSelectedCells()) {
+ if (!rows.contains(tablePosition.getRow())){
+ rows.add(tablePosition.getRow());
+ }
+ if (!cells.contains(tablePosition.getRow()+"_"+tablePosition.getColumn())){
+ cells.add(tablePosition.getRow()+"_"+tablePosition.getColumn());
+ }
+ if (!cellColumns.contains(tablePosition.getColumn())) {
+ cellColumns.add(tablePosition.getColumn());
+ }
+
+ }
+ final StringBuilder strb = new StringBuilder();
+
+ if (this.getSelectionModel().cellSelectionEnabledProperty().getValue()) {
+ for (Integer col : cellColumns) {
+ strb.append(this.getColumns().get(col).getText());
+ if (cellColumns.indexOf(col)==cellColumns.size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append("\t");
+ }
+ }
+ for (String s : cells) {
+ for (Integer i : cellColumns) {
+ String[] split = s.split("_");
+ if (split[1].equals(String.valueOf(i))) {
+ Object cellData = this.getColumns().get(i).getCellData(Integer.parseInt(split[0]));
+ strb.append(cellData == null ? "" : cellData);
+ }
+ if (cellColumns.indexOf(i)==cellColumns.size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append("\t");
+ }
+ }
+ }
+
+ }else {
+ for (TableColumn col : this.getColumns()) {
+ strb.append(col.getText());
+ if (this.getColumns().indexOf(col)==this.getColumns().size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append("\t");
+ }
+ }
+ boolean firstRow = true;
+ for (final Integer row : rows) {
+ for (final TableColumn, ?> column : this.getColumns()) {
+ strb.append(column.getCellData(row) == null ? "" : column.getCellData(row));
+ if (this.getColumns().indexOf(column)==this.getColumns().size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append("\t");
+ }
+ }
+ }
+ }
+
+ final ClipboardContent clipboardContent = new ClipboardContent();
+ clipboardContent.putString(strb.toString());
+ Clipboard.getSystemClipboard().setContent(clipboardContent);
+ }
+
+
+ public void removeSelection() {
+ for (CompoundInstance i : this.getSelectionModel().getSelectedItems()) {
+ this.getItems().remove(i);
+ }
+ }
+
+ public void addEmptyRow() {
+ String newId = "spec_1";
+ int k = 1;
+ while (ids.contains(newId)) {
+ k+=1;
+ newId = "spec_"+k;
+ }
+
+ String newId2 = "spec_";
+ int k2 = 1;
+ while (compoundIds.contains(newId2)) {
+ k2+=1;
+ newId2 = "spec_"+k2;
+ }
+
+ compoundIds.add(newId2);
+ ids.add(newId);
+ System.out.println(newId);
+ CompoundInstance newRowData = new CompoundInstance(newId, newId2);
+ instances.add(newRowData);
+
+ }
+
+ public void removeSelectedColumns() {
+ HashSet s = new HashSet<>();
+ for (TablePosition t : this.getSelectionModel().getSelectedCells()) {
+ if (t.getTableColumn().getUserData()!=null) {
+ if (t.getTableColumn().getUserData().equals("editable")) {
+ s.add(t.getTableColumn());
+ }
+ }
+ }
+ this.getColumns().removeAll(s);
+ }
+
+
+ private void initExampleData(int j) {
+ for (int i = 0; i < j; i++) {
+ addEmptyRow();
+ }
+ }
+
+ private void initColumns(CompoundTableView table) {
+
+ for (int j = 0; j < CompoundInstance.attributeTypes.size(); j++) {
+ final int k = j;
+
+ String att = CompoundInstance.attributeTypes.get(j);
+ String[] attSpl = att.split("_");
+ System.out.println(k + " : " + attSpl[0] + " --> " + attSpl[1]);
+ switch (attSpl[1]) {
+ case "Bool":
+ TableColumn boolCol = new TableColumn(attSpl[0]);
+ boolCol.setCellValueFactory(new PropertyValueFactory<>(attSpl[0]));
+
+ final CheckBoxTableCell ctCell = new CheckBoxTableCell<>();
+ ctCell.setSelectedStateCallback(new Callback>() {
+ @Override
+ public ObservableValue call(Integer index) {
+ return table.getItems().get(index).attributes.get(index);
+ }
+ });
+
+ boolCol.setCellFactory(column -> new CheckBoxTableCell());
+ this.getColumns().add(boolCol);
+ boolCol.setEditable(true);
+ break;
+ case "Str":
+ Callback, TableCell> cellFactoryStr
+ = (TableColumn param) -> new EditableCell(attSpl[1], this, attSpl[0]);
+ TableColumn strCol = new TableColumn(attSpl[0]);
+ strCol.setCellValueFactory(new Callback, ObservableValue>() {
+ public ObservableValue call(CellDataFeatures p) {
+ return p.getValue().attributes.get(k);
+ }
+ });
+ strCol.setCellFactory(cellFactoryStr);
+ strCol.setOnEditCommit(
+ (TableColumn.CellEditEvent t) -> {
+ String val = t.getNewValue();
+ switch (attSpl[0]) {
+ case "speciesId":
+ if (!t.getOldValue().equals(t.getNewValue())) {
+ compoundIds.remove(t.getOldValue());
+ String[] split = val.split("_");
+ String prefix = split[0];
+ String num = split[1];
+ while (compoundIds.contains(val)) {
+ if (split.length>1) {
+ if (num.matches("[0-9]+")) {
+ num = String.valueOf(Integer.parseInt(num)+1);
+ val = prefix + "_" + num;
+
+ }else {
+ val = prefix + "_1";
+ num = "1";
+ }
+ }else {
+ val = prefix + "_1";
+ num = "1";
+ }
+ }
+ compoundIds.add(val);
+ }
+ break;
+
+ case "id":
+
+ if (!t.getOldValue().equals(t.getNewValue())) {
+ ids.remove(t.getOldValue());
+ String[] split = val.split("_");
+ String prefix = split[0];
+ String num = split[1];
+ while (ids.contains(val)) {
+ if (split.length>1) {
+ if (num.matches("[0-9]+")) {
+ num = String.valueOf(Integer.parseInt(num)+1);
+ val = prefix + "_" + num;
+
+ }else {
+ val = prefix + "_1";
+ num = "1";
+ }
+ }else {
+ val = prefix + "_1";
+ num = "1";
+ }
+ }
+ ids.add(val);
+
+ }
+ break;
+ case "sboTerm":
+ val = SBMLUtils.convertToSBO(t.getNewValue());
+ break;
+ case "unit":
+ val = SBMLUtils.convertToUnit(t.getNewValue()).getName();
+ break;
+ }
+
+
+
+ ((CompoundInstance) t.getTableView().getItems()
+ .get(t.getTablePosition().getRow()))
+ .setProperty(attSpl[0], val);
+ this.refresh();
+ });
+
+ this.getColumns().add(strCol);
+ strCol.setEditable(true);
+ break;
+ case "Int":
+ Callback, TableCell> cellFactoryInt
+ = (TableColumn param) -> new EditableCell(attSpl[1], this, attSpl[0]);
+ TableColumn intCol = new TableColumn(attSpl[0]);
+ intCol.setCellValueFactory(new Callback, ObservableValue>() {
+ public ObservableValue call(CellDataFeatures p) {
+ return p.getValue().attributes.get(k);
+ }
+ });
+ intCol.setCellFactory(cellFactoryInt);
+ intCol.setOnEditCommit(
+ (TableColumn.CellEditEvent t) -> {
+ String value = t.getNewValue();
+ System.out.println("changing to proper int");
+ if (value.matches("^[0-9]+\\.[0-9]+$")) {
+ value = value.split("\\.")[0];
+ }else if (value.matches("^[0-9]+$")) {
+ System.out.println("int stays int");
+ }else {
+ System.out.println("default int");
+ value = "0";
+ }
+
+ ((CompoundInstance) t.getTableView().getItems()
+ .get(t.getTablePosition().getRow()))
+ .setProperty(attSpl[0], value);
+
+ this.refresh();
+ });
+
+ this.getColumns().add(intCol);
+ intCol.setEditable(true);
+ break;
+
+ case "Dbl":
+ Callback, TableCell> cellFactoryDbl
+ = (TableColumn param) -> new EditableCell(attSpl[1], this, attSpl[0]);
+ TableColumn dblCol = new TableColumn(attSpl[0]);
+ dblCol.setCellValueFactory(new Callback, ObservableValue>() {
+ public ObservableValue call(CellDataFeatures p) {
+ return p.getValue().attributes.get(k);
+ }
+ });
+ dblCol.setCellFactory(cellFactoryDbl);
+ dblCol.setOnEditCommit(
+ (TableColumn.CellEditEvent t) -> {
+ String value = t.getNewValue();
+ System.out.println("changing to proper int");
+ if (value.matches("^[0-9]+\\.[0-9]+$")) {
+ System.out.println("dbl stays dbl");
+ }else if (value.matches("^[0-9]+$")) {
+ System.out.println("changing to proper double");
+ value = value+".0";
+ }else {
+ System.out.println("default double");
+ value = "0.0";
+ }
+
+ ((CompoundInstance) t.getTableView().getItems()
+ .get(t.getTablePosition().getRow()))
+ .setProperty(attSpl[0], value);
+
+ this.refresh();
+ });
+
+
+ this.getColumns().add(dblCol);
+ dblCol.setEditable(true);
+ break;
+
+ default:
+ break;
+ }
+
+ }
+
+ }
+
+ public void addAnnotationColumn(String annotationType) {
+ Callback, TableCell> cellFactory
+ = (TableColumn param) -> new EditableCell("str", this);
+ TableColumn strCol = new TableColumn(annotationType);
+
+ this.getColumns().add(strCol);
+ strCol.setEditable(true);
+ }
+
+ public String toSBTabString() {
+ StringBuilder sbTabStringBuilder = new StringBuilder();
+
+ sbTabStringBuilder.append(createSBTabHeader());
+ sbTabStringBuilder.append("\n");
+ sbTabStringBuilder.append(createSbTabColumnHeader());
+ sbTabStringBuilder.append("\n");
+ sbTabStringBuilder.append(createSbTabRows());
+ return sbTabStringBuilder.toString();
+ }
+
+ private String createSbTabRows() {
+ StringBuilder sbTabStringBuilder = new StringBuilder();
+ for (int y = 0; y < instances.size(); y++) {
+ for (int x = 0; x < this.getColumns().size(); x++) {
+ if (writtenColumns.contains(x)) {
+ String colTitle = this.getColumns().get(x).getText();
+ String value = this.getColumns().get(x).getCellData(y).toString();
+ String value2 = value.toString();
+ sbTabStringBuilder.append(value2+"\t");
+ }
+ }
+ sbTabStringBuilder.append("\n");
+ }
+ return sbTabStringBuilder.toString().replaceAll("\n(\n)*", "\n");
+ }
+
+
+
+ HashSet writtenColumns = new HashSet<>();
+ private String createSbTabColumnHeader() {
+ StringBuilder sbTabStringBuilder = new StringBuilder();
+ for (TableColumn col : this.getColumns()) {
+ String title = col.getText();
+ System.out.println(title);
+ if (CompoundInstance.attributeTypes.contains(title+"_Str")){
+ sbTabStringBuilder.append(CompoundInstance.sbTabCol.get(CompoundInstance.attributeTypes.indexOf(title+"_Str")));
+ writtenColumns.add(this.getColumns().indexOf(col));
+ }else if (CompoundInstance.attributeTypes.contains(title+"_Int")) {
+ sbTabStringBuilder.append(CompoundInstance.sbTabCol.get(CompoundInstance.attributeTypes.indexOf(title+"_Int")));
+ writtenColumns.add(this.getColumns().indexOf(col));
+ }else if (CompoundInstance.attributeTypes.contains(title+"_Dbl")) {
+ sbTabStringBuilder.append(CompoundInstance.sbTabCol.get(CompoundInstance.attributeTypes.indexOf(title+"_Dbl")));
+ writtenColumns.add(this.getColumns().indexOf(col));
+ }else if (CompoundInstance.attributeTypes.contains(title+"_Bool")) {
+ sbTabStringBuilder.append(CompoundInstance.sbTabCol.get(CompoundInstance.attributeTypes.indexOf(title+"_Bool")));
+ writtenColumns.add(this.getColumns().indexOf(col));
+ }else {
+ if (IdentifierChooser.sbTabDefinitions.contains(title)) {
+ writtenColumns.add(this.getColumns().indexOf(col));
+ sbTabStringBuilder.append(title);
+ }
+ }
+ sbTabStringBuilder.append("\t");
+ }
+ return sbTabStringBuilder.toString();
+ }
+
+ private Object createSBTabHeader() {
+ return "!!SBtab TableID='compound' TableType='Compound' TableName='Compounds' SBtabVersion='1.0'";
+ }
+
+ public void addNewColumn(String colTitle) {
+ for (CompoundInstance c : instances) {
+ if (!c.attributeTypes.contains(colTitle.replaceAll("[:!]", "")+"_Str")) {
+ c.sbTabCol.add(colTitle);
+ }
+ }
+
+
+ Callback, TableCell> cellFactoryStr
+ = (TableColumn param) -> new EditableCell("Str", this, colTitle.replaceAll("[:!]", ""));
+ TableColumn strCol = new TableColumn(colTitle.replaceAll("[:!]", ""));
+ strCol.setCellValueFactory(new Callback, ObservableValue>() {
+ public ObservableValue call(CellDataFeatures p) {
+ // p.getValue() returns the Person instance for a particular TableView row
+ return p.getValue().attributes.get(p.getValue().attributes.size()-1);
+ }
+ });
+ strCol.setCellFactory(cellFactoryStr);
+ strCol.setOnEditCommit(
+ (TableColumn.CellEditEvent t) -> {
+ ((CompoundInstance) t.getTableView().getItems()
+ .get(t.getTablePosition().getRow()))
+ .setProperty(colTitle.replaceAll("[:!]", ""), t.getNewValue());
+ this.refresh();
+ });
+
+
+ strCol.setUserData("editable");
+
+
+ this.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
+ TableColumnBase, ?> column = null;
+ if (e.isPrimaryButtonDown() && e.getClickCount() > 1) {
+
+ EventTarget target = e.getTarget();
+
+ while (target instanceof Node) {
+ target = ((Node) target).getParent();
+ if (target instanceof TableColumnHeader) {
+ column = ((TableColumnHeader) target).getTableColumn();
+ if (column != null) break;
+ }
+ }
+ if (column != null) {
+ if (column.getUserData().equals("editable")) {
+ TableColumnBase,?> tableColumn = column;
+ TextField textField = new TextField(column.getText());
+ textField.setMaxWidth(column.getWidth());
+ textField.setOnAction(a -> {
+ tableColumn.setText(textField.getText());
+ tableColumn.setGraphic(null);
+ });
+ textField.focusedProperty().addListener((src, ov, nv) -> {
+ if (!nv) tableColumn.setGraphic(null);
+ });
+ column.setGraphic(textField);
+ textField.requestFocus();
+
+ ContextMenu contextMenu = new ContextMenu();
+ MenuItem choose = new MenuItem("Choose valid SBTab Column Title");
+ contextMenu.getItems().add(choose);
+ textField.setContextMenu(contextMenu);
+
+ choose.setOnAction(new EventHandler() {
+ @Override public void handle(ActionEvent e) {
+ IdentifierChooser chooser = new IdentifierChooser();
+ Stage dialogStage = new Stage();
+ Scene dialogScene = new Scene(chooser, 300, 550);
+ dialogStage.centerOnScreen();
+
+ dialogStage.show();
+
+ dialogStage.setScene(dialogScene);
+
+ final Stage[] stages = new Stage[] {dialogStage};
+
+ chooser.getB().setOnAction(new EventHandler() {
+ @Override public void handle(ActionEvent e) {
+ tableColumn.setText(chooser.getResultList().getSelectionModel().getSelectedItem());
+ tableColumn.setGraphic(null);
+ stages[0].close();
+ }
+ });
+ chooser.getB2().setOnAction(new EventHandler() {
+ @Override public void handle(ActionEvent e) {
+ stages[0].close();
+ tableColumn.setGraphic(null);
+ }
+ });
+ }
+ });
+
+
+
+ }
+ e.consume();
+ }
+ }
+
+ });
+
+
+
+ this.getColumns().add(strCol);
+ strCol.setEditable(true);
+
+ }
+
+ public HashSet getIds(){
+ return ids;
+ }
+
+}
+
diff --git a/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/CustomTableView.java b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/CustomTableView.java
new file mode 100644
index 0000000..2e49af5
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/CustomTableView.java
@@ -0,0 +1,421 @@
+package org.insilico.sbmlsheets.core;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import org.insilico.sbmlsheets.editor.IdentifierChooser;
+import com.sun.javafx.scene.control.skin.TableColumnHeader;
+import javafx.application.Platform;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.concurrent.Task;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.event.EventTarget;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.Label;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.SelectionMode;
+import javafx.scene.control.TableCell;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TextField;
+import javafx.scene.control.TableColumn.CellDataFeatures;
+import javafx.scene.control.TableColumnBase;
+import javafx.scene.control.TablePosition;
+import javafx.scene.control.TableRow;
+import javafx.scene.control.cell.CheckBoxTableCell;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.input.Clipboard;
+import javafx.scene.input.ClipboardContent;
+import javafx.scene.input.DataFormat;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.stage.Stage;
+import javafx.util.Callback;
+
+public class CustomTableView extends TableView>{
+
+ private ObservableList instances = FXCollections.observableArrayList();
+
+ int firstLineToParse = 0;
+ boolean parseHeader = true;
+ String headerSeparator = "\\t";
+ String instancesSeparator = "\\t";
+
+ public CustomTableView(){
+ String str = "Col1\tCol2\nitem1\titem2";
+ populateTable(this, str ,true);
+ setEditable(true);
+ initSelectionListeners();
+ }
+
+ public CustomTableView(String string) {
+ populateTable(this, string ,true);
+ setEditable(true);
+ initSelectionListeners();
+ }
+
+ public CustomTableView(String string, String format) {
+ setTableFormat(format);
+ populateTable(this, string ,true);
+ setEditable(true);
+ initSelectionListeners();
+ }
+
+ private void initSelectionListeners() {
+ this.addEventFilter(KeyEvent.KEY_PRESSED, e -> {
+ if (e.getCode().equals( KeyCode.DELETE)) {
+ if (e.isShortcutDown()) {
+ removeSelectedColumns();
+ }else {
+ removeSelection();
+ }
+
+ }else if (e.getCode().equals(KeyCode.C) && e.isShortcutDown()) {
+ copySelectionToClipboard();
+
+ }else if (e.getCode().equals(KeyCode.A) && e.isShortcutDown()) {
+ this.getSelectionModel().selectAll();
+ }else if (e.isShortcutDown() && e.getCode().equals(KeyCode.N) && e.getCode().equals(KeyCode.R)) {
+ addEmptyRow();
+ }else if (e.isShortcutDown() && e.getCode().equals(KeyCode.N) && e.getCode().equals(KeyCode.C)) {
+ addEmptyColumn();
+ }else if (e.isShortcutDown()) {
+ this.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
+ }
+ e.consume();
+ });
+ }
+
+ public void copySelectionToClipboard() {
+ final ArrayList cellColumns = new ArrayList<>();
+ final ArrayList cells = new ArrayList<>();
+
+ for (final TablePosition tablePosition : this.getSelectionModel().getSelectedCells()) {
+ if (!cells.contains(tablePosition.getRow()+"_"+tablePosition.getColumn())){
+ cells.add(tablePosition.getRow()+"_"+tablePosition.getColumn());
+ }
+ if (!cellColumns.contains(tablePosition.getColumn())) {
+ cellColumns.add(tablePosition.getColumn());
+ }
+
+ }
+ final StringBuilder sB = new StringBuilder();
+
+ if (this.getSelectionModel().cellSelectionEnabledProperty().getValue()) {
+ for (Integer col : cellColumns) {
+ sB.append(this.getColumns().get(col).getText());
+ if (cellColumns.indexOf(col)==cellColumns.size()-1) {
+ sB.append("\n");
+ }else {
+ sB.append("\t");
+ }
+ }
+ for (String s : cells) {
+ for (Integer i : cellColumns) {
+ String[] split = s.split("_");
+ if (split[1].equals(String.valueOf(i))) {
+ Object cellData = this.getColumns().get(i).getCellData(Integer.parseInt(split[0]));
+ sB.append(cellData == null ? "" : cellData);
+ }
+ if (cellColumns.indexOf(i)==cellColumns.size()-1) {
+ sB.append("\n");
+ }else {
+ sB.append("\t");
+ }
+ }
+ }
+
+ }else {
+ for (TableColumn col : this.getColumns()) {
+ sB.append(col.getText());
+ if (this.getColumns().indexOf(col)==this.getColumns().size()-1) {
+ sB.append("\n");
+ }else {
+ sB.append("\t");
+ }
+ }
+ for (ObservableList i : this.getSelectionModel().getSelectedItems()) {
+ for (StringProperty sP : i) {
+ sB.append(sP.getValue()+"\t");
+ }sB.append("\n");
+ }
+ }
+
+ ClipboardContent content = new ClipboardContent();
+ content.putString(sB.toString());
+ Clipboard.getSystemClipboard().setContent(content);
+ }
+
+ public void removeSelection() {
+ for (ObservableList i : this.getSelectionModel().getSelectedItems()) {
+ this.getItems().remove(i);
+ }
+ }
+
+ public void removeSelectedColumns() {
+ HashSet s = new HashSet<>();
+ for (TablePosition t : this.getSelectionModel().getSelectedCells()) {
+ if (t.getTableColumn().getUserData()!=null) {
+ if (t.getTableColumn().getUserData().equals("editable")) {
+ s.add(t.getTableColumn());
+ }
+ }
+ }
+ this.getColumns().removeAll(s);
+ }
+
+ private String getDataString() {
+ String str = "!ID !Name !Location !IsConstant !SBOTerm !InitialConcentration !hasOnlySubstanceUnits !SBML:fbc:chemicalFormula !SBML:fbc:charge !Identifiers:bigg.metabolite\r\n" +
+ "M_glc__D_e D-Glucose e False SBO:0000247 nan False C6H12O6 0 glc__D\r\n" +
+ "M_gln__L_c L-Glutamine c False SBO:0000247 nan False C5H10N2O3 0 gln__L\r\n" +
+ "M_gln__L_e L-Glutamine e False SBO:0000247 nan False C5H10N2O3 0 gln__L\r\n" +
+ "M_glu__L_c L-Glutamate c False SBO:0000247 nan False C5H8NO4 -1 glu__L\r\n";
+ return str;
+ }
+
+ private void populateTable(
+ final TableView> table,
+ final String dataStr, final boolean hasHeader) {
+ table.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
+ if (e.isPrimaryButtonDown() && e.getClickCount() > 1) {
+ EventTarget target = e.getTarget();
+ TableColumnBase, ?> column = null;
+ while (target instanceof Node) {
+ target = ((Node) target).getParent();
+ if (target instanceof TableColumnHeader) {
+ column = ((TableColumnHeader) target).getTableColumn();
+ if (column != null) break;
+ }
+ }
+ if (column != null) {
+ TableColumnBase,?> tableColumn = column;
+ TextField textField = new TextField(column.getText());
+ textField.setMaxWidth(column.getWidth());
+ textField.setOnAction(a -> {
+ tableColumn.setText(textField.getText());
+ tableColumn.setGraphic(null);
+ });
+ textField.focusedProperty().addListener((src, ov, nv) -> {
+ if (!nv) tableColumn.setGraphic(null);
+ });
+ column.setGraphic(textField);
+ textField.requestFocus();
+ }
+ e.consume();
+ }
+ });
+
+ table.getItems().clear();
+ table.getColumns().clear();
+ table.setPlaceholder(new Label("Loading..."));
+ Task task = new Task() {
+ @Override
+ protected Void call() throws Exception {
+ int x = firstLineToParse;
+ final String dataStr2 = dataStr.replaceAll("\\r", "");
+ if (hasHeader) {
+ final String headerLine = dataStr2.split("\\n")[x];
+ System.out.println("headerLine: "+headerLine);
+ final String[] headerValues = headerLine.split(headerSeparator);
+ Platform.runLater(new Runnable() {
+ @Override
+ public void run() {
+ for (int column = x; column < headerValues.length; column++) {
+ table.getColumns().add(
+ createColumn(column, headerValues[column]));
+ }
+ }
+ });
+ }
+
+ String dataLine;
+ int cnt = x+1;
+ for (int i = cnt; i < dataStr2.split("\\n").length; i++) {
+ String s = dataStr2.split("\\n")[i];
+ System.out.println("rowLine "+cnt+": "+s);
+ final String[] dataValues = s.split(instancesSeparator);
+ Platform.runLater(new Runnable() {
+ @Override
+ public void run() {
+ for (int columnIndex = table.getColumns().size(); columnIndex < dataValues.length; columnIndex++) {
+ table.getColumns().add(createColumn(columnIndex, ""));
+ }
+ ObservableList data = FXCollections
+ .observableArrayList();
+ for (String value : dataValues) {
+ data.add(new SimpleStringProperty(value));
+ }
+ table.getItems().add(data);
+ }
+ });
+ cnt++;
+ }
+ return null;
+ }
+ };
+ Thread thread = new Thread(task);
+ thread.setDaemon(true);
+ thread.start();
+ }
+
+ private TableColumn, String> createColumn(
+ final int columnIndex, String columnTitle) {
+
+ Callback, String>, TableCell, String>> cellFactoryStr
+ = (TableColumn, String> param) -> new EditableCell>("Str", this, columnTitle);
+ TableColumn, String> column = new TableColumn<>();
+ column.setUserData("editable");
+ String title;
+ if (columnTitle == null || columnTitle.trim().length() == 0) {
+ title = "Column " + (columnIndex + 1);
+ } else {
+ title = columnTitle;
+ }
+
+ column.setText(title);
+ column
+ .setCellValueFactory(new Callback, String>, ObservableValue>() {
+ @Override
+ public ObservableValue call(
+ CellDataFeatures, String> cellDataFeatures) {
+ ObservableList values = cellDataFeatures.getValue();
+ if (columnIndex >= values.size()) {
+ return new SimpleStringProperty("");
+ } else {
+ return cellDataFeatures.getValue().get(columnIndex);
+ }
+ }
+ });
+ column.setCellFactory(cellFactoryStr);
+ column.setOnEditCommit(
+ (TableColumn.CellEditEvent, String> t) -> {
+ ObservableList s = ((ObservableList) t.getTableView().getItems().get(t.getTablePosition().getRow()));
+ s.set(columnIndex, new SimpleStringProperty(t.getNewValue()));
+ this.refresh();
+ });
+ column.setEditable(true);
+
+
+
+ return column;
+ }
+
+
+
+
+ public void setTableFormat(String format) {
+ switch (format) {
+ case "tab":
+ firstLineToParse = 0;
+ headerSeparator = "\t+|\\s\\s+";
+ instancesSeparator = "\t+|\\s\\s+";
+ parseHeader = true;
+ break;
+ case "sbtab":
+ firstLineToParse = 1;
+ headerSeparator = "\t|\\s\\s+";
+ instancesSeparator = "\t| | ";
+ parseHeader = true;
+ break;
+ case "csv ;":
+ firstLineToParse = 0;
+ headerSeparator = "[;]";
+ instancesSeparator = "[;]";
+ parseHeader = true;
+ break;
+ case "csv ,":
+ firstLineToParse = 0;
+ headerSeparator = "[,]";
+ instancesSeparator = "[,]";
+ parseHeader = true;
+ break;
+ case "txt":
+ firstLineToParse = 0;
+ headerSeparator = "[,]";
+ instancesSeparator = "[,]";
+ parseHeader = true;
+ break;
+ default:
+ break;
+
+ }
+ }
+
+ public String randomChar() {
+ Random r = new Random();
+ return String.valueOf((char)(r.nextInt(26) + 'a'));
+ }
+
+ public void addEmptyRow() {
+ ObservableList data = FXCollections
+ .observableArrayList();
+ for (TableColumn, ?> value : this.getColumns()) {
+ data.add(new SimpleStringProperty("nan"));
+ }
+ this.getItems().add(data);
+
+ }
+
+ public void addEmptyColumn() {
+ int idx = this.getColumns().size();
+ this.getColumns().add(createColumn(idx, "newCol_"+idx));
+
+
+
+ }
+
+ public String toSBTabString() {
+ StringBuilder sbTabStringBuilder = new StringBuilder();
+
+ sbTabStringBuilder.append(createSBTabHeader());
+ sbTabStringBuilder.append("\n");
+ sbTabStringBuilder.append(createSbTabColumnHeader());
+ sbTabStringBuilder.append("\n");
+ sbTabStringBuilder.append(createSbTabRows());
+ return sbTabStringBuilder.toString();
+ }
+
+ private String createSbTabRows() {
+ StringBuilder sbTabStringBuilder = new StringBuilder();
+ for (int y = 0; y extends TableCell {
+
+ String type = "Str";
+ private TextField textField;
+ private TableView table;
+ String columnType = "id";
+ String previousValue = "nan";
+
+ public EditableCell(String type, TableView table) {
+ this.table = table;
+ this.type = type;
+ }
+
+ public EditableCell(String type, TableView table, String columnType) {
+ this.type = type;
+ this.columnType = columnType;
+ this.table = table;
+ }
+
+
+ @Override
+ public void startEdit() {
+ if (!isEmpty()) {
+ super.startEdit();
+ createTextField();
+ setText(null);
+ setGraphic(textField);
+ textField.selectAll();
+ }
+ }
+
+ @Override
+ public void cancelEdit() {
+ super.cancelEdit();
+
+ setText((String) getItem());
+ setGraphic(null);
+ }
+
+ @Override
+ public void updateItem(String item, boolean empty) {
+ super.updateItem(item, empty);
+
+ if (empty) {
+ setText(item);
+ setGraphic(null);
+ } else {
+ if (isEditing()) {
+ if (textField != null) {
+ textField.setText(getString());
+ }
+ setText(null);
+ setGraphic(textField);
+ } else {
+ setText(getString());
+ setGraphic(null);
+ }
+ }
+ }
+
+ private void createTextField() {
+
+ textField = new TextField(getString());
+ textField.setStyle(".text-field:error{\r\n" +
+ " -fx-text-border: red;\r\n" +
+ " -fx-focus-border: red;\r\n" +
+ " -fx-text-fill: black;\r\n" +
+ "}");
+
+ textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
+ textField.setOnAction((e) -> commitEdit(textField.getText()));
+
+ textField.setOnKeyReleased(new EventHandler() {
+ @Override
+ public void handle(KeyEvent event) {
+ if (event.getCode().equals(KeyCode.ENTER)) {
+ table.requestFocus();
+ } else if (event.getCode().equals(KeyCode.ESCAPE)) {
+ textField.setText(previousValue);
+ table.requestFocus();
+ }
+
+ }
+ });
+
+ textField.focusedProperty().addListener((ObservableValue extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
+
+ if (!newValue) {
+
+ String value = textField.getText();
+
+ System.out.println("type: "+type + " attribute: "+columnType+" value: "+value);
+
+
+
+ switch (type) {
+ case "Int":
+ System.out.println("changing to proper int");
+ if (value.matches("^[0-9]+\\.[0-9]+$")) {
+ value = value.split("\\.")[0];
+ }else if (value.matches("^[0-9]+$")) {
+ System.out.println("int stays int");
+ }else {
+ System.out.println("default int");
+ value = "0";
+ }
+ break;
+ case "Dbl":
+ if (value.matches("^[0-9]+\\.[0-9]+$")) {
+ System.out.println("dbl stays dbl");
+ }else if (value.matches("^[0-9]+$")) {
+ System.out.println("changing to proper double");
+ value = value+".0";
+ }else {
+ System.out.println("default double");
+ value = "0.0";
+ }
+ break;
+ case "Str":
+ switch (columnType) {
+ case "sumFormula":
+ String s = "((\\d+(\\.\\d+)? )?\\S+)+( \\+ ((\\d+(\\.\\d+)? )?\\S+)+)* [<]?=> ((\\d+(\\.\\d+)? )?\\S+)+( \\+ ((\\d+(\\.\\d+)? )?\\S+)+)*";
+ if (!value.matches(s)) {
+ value = "nan + nan <=> nan";
+ }else {
+
+ }
+ break;
+ case "sboTerm":
+ if (!value.matches("SBO:[0-9]{7}|\\d{1,7}")) {
+ value = "SBO:0000001";
+ }else {
+ if (value.matches("\\d{1,7}")){
+ String zero = "0";
+ value = "SBO:"+IntStream.range(0, 7-value.length()).mapToObj(i -> zero).collect(Collectors.joining(""))+value;
+ }
+ }
+ case "id":
+
+ default:
+ break;
+
+ }
+
+ break;
+ //
+
+ default:
+ break;
+ }
+
+ textField.textProperty().set(value);
+ textField.setAccessibleText(value);
+
+ setString(value);
+ System.out.println("Commiting textfield:" + textField.getText() + " and item value:"+value + " getString():"+getString());
+ commitEdit(value);
+
+
+ }else {
+ previousValue = textField.getText();
+ }
+ });
+
+ }
+
+ private void setString(String newValue) {
+ setItem(newValue);
+ }
+
+ private String getString() {
+ return getItem() == null ? "" : getItem();
+ }
+
+ public String getType() {
+ return type;
+ }
+
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ @Override
+ public void commitEdit(String item) {
+ if (!isEditing() && !item.equals(getItem())) {
+ TableView table = getTableView();
+ if (table != null) {
+ TableColumn column = getTableColumn();
+ CellEditEvent event = new CellEditEvent<>(
+ table, new TablePosition(table, getIndex(), column),
+ TableColumn.editCommitEvent(), item
+ );
+ Event.fireEvent(column, event);
+ }
+ }
+
+ super.commitEdit(item);
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/EditorUtils.java b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/EditorUtils.java
new file mode 100644
index 0000000..850a2f9
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/EditorUtils.java
@@ -0,0 +1,242 @@
+package org.insilico.sbmlsheets.core;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+import javafx.beans.property.StringProperty;
+import javafx.collections.ObservableList;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TablePosition;
+import javafx.scene.control.TableView;
+import javafx.scene.input.Clipboard;
+import javafx.scene.input.ClipboardContent;
+import javafx.stage.FileChooser;
+import javafx.stage.Stage;
+
+public class EditorUtils {
+
+
+ private static void saveFile(String content, File file){
+ try {
+ FileWriter fileWriter;
+ fileWriter = new FileWriter(file);
+ fileWriter.write(content);
+ fileWriter.close();
+ } catch (IOException ex) {
+ }
+ }
+
+ private static String createString(String text, String fileType) {
+ StringBuilder string = new StringBuilder();
+
+ return null;
+ }
+
+
+ public static String getFileContent(String uri) {
+ final List lines;
+ try {
+ StringBuilder sB = new StringBuilder();
+ lines = Files.readAllLines(new File(uri).toPath());
+ for (String s : lines) {
+ sB.append(s.replaceAll("\t"," ")+"\n");
+ }
+ return sB.toString();
+ } catch (IOException ex) {
+ return "";
+ }
+
+ }
+
+
+ public static void saveTableToFile(CompoundTableView tableView, String separator) {
+ tableView.getSelectionModel().selectAll();
+ final ArrayList rows = new ArrayList<>();
+ final ArrayList cellColumns = new ArrayList<>();
+ final ArrayList cells = new ArrayList<>();
+ for (final TablePosition tablePosition : tableView.getSelectionModel().getSelectedCells()) {
+ if (!rows.contains(tablePosition.getRow())){
+ rows.add(tablePosition.getRow());
+ }
+ if (!cells.contains(tablePosition.getRow()+"_"+tablePosition.getColumn())){
+ cells.add(tablePosition.getRow()+"_"+tablePosition.getColumn());
+ }
+ if (!cellColumns.contains(tablePosition.getColumn())) {
+ cellColumns.add(tablePosition.getColumn());
+ }
+
+ }
+ final StringBuilder strb = new StringBuilder();
+
+ for (TableColumn col : tableView.getColumns()) {
+ strb.append(col.getText());
+ if (tableView.getColumns().indexOf(col)==tableView.getColumns().size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append(separator);
+ }
+ }
+ boolean firstRow = true;
+ for (final Integer row : rows) {
+ for (final TableColumn, ?> column : tableView.getColumns()) {
+ strb.append(column.getCellData(row) == null ? "" : column.getCellData(row));
+ if (tableView.getColumns().indexOf(column)==tableView.getColumns().size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append(separator);
+ }
+ }
+ }
+
+
+
+ Stage stage = new Stage();
+ FileChooser fileChooser = new FileChooser();
+ File file = fileChooser.showSaveDialog(stage);
+ if(file != null){
+ saveFile(strb.toString(), file);
+ }
+ }
+
+ public static void saveTableToFile(CompartmentTableView tableView, String separator) {
+ tableView.getSelectionModel().selectAll();
+ final ArrayList rows = new ArrayList<>();
+ final ArrayList cellColumns = new ArrayList<>();
+ final ArrayList cells = new ArrayList<>();
+ for (final TablePosition tablePosition : tableView.getSelectionModel().getSelectedCells()) {
+ if (!rows.contains(tablePosition.getRow())){
+ rows.add(tablePosition.getRow());
+ }
+ if (!cells.contains(tablePosition.getRow()+"_"+tablePosition.getColumn())){
+ cells.add(tablePosition.getRow()+"_"+tablePosition.getColumn());
+ }
+ if (!cellColumns.contains(tablePosition.getColumn())) {
+ cellColumns.add(tablePosition.getColumn());
+ }
+
+ }
+ final StringBuilder strb = new StringBuilder();
+
+ for (TableColumn col : tableView.getColumns()) {
+ strb.append(col.getText());
+ if (tableView.getColumns().indexOf(col)==tableView.getColumns().size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append(separator);
+ }
+ }
+ boolean firstRow = true;
+ for (final Integer row : rows) {
+ for (final TableColumn, ?> column : tableView.getColumns()) {
+ strb.append(column.getCellData(row) == null ? "" : column.getCellData(row));
+ if (tableView.getColumns().indexOf(column)==tableView.getColumns().size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append(separator);
+ }
+ }
+ }
+
+
+ Stage stage = new Stage();
+ FileChooser fileChooser = new FileChooser();
+ File file = fileChooser.showSaveDialog(stage);
+ if(file != null){
+ saveFile(strb.toString(), file);
+ }
+ }
+
+ public static void saveTableToFile(ReactionTableView tableView, String separator) {
+
+ tableView.getSelectionModel().selectAll();
+ final ArrayList rows = new ArrayList<>();
+ final ArrayList cellColumns = new ArrayList<>();
+ final ArrayList cells = new ArrayList<>();
+ for (final TablePosition tablePosition : tableView.getSelectionModel().getSelectedCells()) {
+ if (!rows.contains(tablePosition.getRow())){
+ rows.add(tablePosition.getRow());
+ }
+ if (!cells.contains(tablePosition.getRow()+"_"+tablePosition.getColumn())){
+ cells.add(tablePosition.getRow()+"_"+tablePosition.getColumn());
+ }
+ if (!cellColumns.contains(tablePosition.getColumn())) {
+ cellColumns.add(tablePosition.getColumn());
+ }
+
+ }
+ final StringBuilder strb = new StringBuilder();
+
+ for (TableColumn col : tableView.getColumns()) {
+ strb.append(col.getText());
+ if (tableView.getColumns().indexOf(col)==tableView.getColumns().size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append(separator);
+ }
+ }
+ boolean firstRow = true;
+ for (final Integer row : rows) {
+ for (final TableColumn, ?> column : tableView.getColumns()) {
+ strb.append(column.getCellData(row) == null ? "" : column.getCellData(row));
+ if (tableView.getColumns().indexOf(column)==tableView.getColumns().size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append(separator);
+ }
+ }
+ }
+
+
+
+ Stage stage = new Stage();
+ FileChooser fileChooser = new FileChooser();
+ File file = fileChooser.showSaveDialog(stage);
+ if(file != null){
+ saveFile(strb.toString(), file);
+ }
+ }
+
+
+ public static void saveTableToFile(CustomTableView tableView, String separator) {
+ tableView.getSelectionModel().selectAll();
+ final ArrayList cellColumns = new ArrayList<>();
+ final ArrayList cells = new ArrayList<>();
+
+ for (final TablePosition tablePosition : tableView.getSelectionModel().getSelectedCells()) {
+ if (!cells.contains(tablePosition.getRow()+"_"+tablePosition.getColumn())){
+ cells.add(tablePosition.getRow()+"_"+tablePosition.getColumn());
+ }
+ if (!cellColumns.contains(tablePosition.getColumn())) {
+ cellColumns.add(tablePosition.getColumn());
+ }
+
+ }
+ final StringBuilder sB = new StringBuilder();
+
+ for (TableColumn col : tableView.getColumns()) {
+ sB.append(col.getText());
+ if (tableView.getColumns().indexOf(col)==tableView.getColumns().size()-1) {
+ sB.append("\n");
+ }else {
+ sB.append(separator);
+ }
+ }
+ for (ObservableList i : tableView.getSelectionModel().getSelectedItems()) {
+ for (StringProperty sP : i) {
+ sB.append(sP.getValue()+separator);
+ }sB.append("\n");
+ }
+
+
+
+ Stage stage = new Stage();
+ FileChooser fileChooser = new FileChooser();
+ File file = fileChooser.showSaveDialog(stage);
+ if(file != null){
+ saveFile(sB.toString(), file);
+ }
+ }
+}
diff --git a/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/HelpContent.java b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/HelpContent.java
new file mode 100644
index 0000000..ade433f
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/HelpContent.java
@@ -0,0 +1,26 @@
+package org.insilico.sbmlsheets.core;
+
+public class HelpContent {
+
+ public static String getStartText() {
+ String s = "** InSilico: SBTabSheets - Plugin **\n" +
+ "\n" +
+ "* FUNCTIONALITY:\n" +
+ "* Start Table Editor via .sheets file\n" +
+ "* Auto-Import of .tsv, .csv, .tab to table editor\n" +
+ "* Manual import of custom table file\n" +
+ "* Modify and create SBTab or custom tables\n" +
+ " * Compound Table\n" +
+ " * Compartment Table\n" +
+ " * Reaction Table\n" +
+ " * Custom Table\n" +
+ "* Conversion and export to SBTab file\n" +
+ "* Conversion and export to SBML file\n" +
+ "* Browsing SBTab definitions for\n" +
+ " * Compound Table\n" +
+ " * Compartment Table\n" +
+ " * Reaction Table";
+ return s;
+ }
+
+}
diff --git a/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/ReactionInstance.java b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/ReactionInstance.java
new file mode 100644
index 0000000..81641d6
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/ReactionInstance.java
@@ -0,0 +1,528 @@
+package org.insilico.sbmlsheets.core;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import javax.swing.tree.TreeNode;
+import org.sbml.jsbml.Compartment;
+import org.sbml.jsbml.KineticLaw;
+import org.sbml.jsbml.Model;
+import org.sbml.jsbml.ModifierSpeciesReference;
+import org.sbml.jsbml.Reaction;
+import org.sbml.jsbml.Species;
+import org.sbml.jsbml.SpeciesReference;
+import org.sbml.jsbml.text.parser.ParseException;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ObservableValue;
+
+
+public class ReactionInstance{
+//define in attributeTypes whether value should be treated as string, double, integer
+ public static ArrayList attributeTypes = new ArrayList<>(Arrays.asList(
+ "id_Str", "name_Str", "reactionId_Str", "sumFormula_Str", "location_Str", "enzyme_Str", "model_Str", "pathway_Str",
+ "subreactionOf_Str", "isComplete_Bool", "isReversible_Bool", "isInEquilibrium_Bool", "isExchangeReaction_Bool",
+ "flux_Dbl", "isNonEnzymatic_Bool", "kineticLaw_Str",
+ "gene_Str", "operon_Str", "enzymeSpeciesId_Str",
+ "enzymeParameterId_Str", "buildReaction_Bool", "buildEnzyme_Bool", "buildEnzymeProduction_Bool",
+ "comment_Str", "referenceName_Str", "referencePubMed_Str", "referenceDOI_Str", "description_Str", "modifier_Str", "miriamAnnotations_Str", "type_Str", "symbol_Str",
+ "positionX_Dbl", "positionY_Dbl", "sboTerm_Str", "identifiers_Str"));
+
+ public static ArrayList sbTabCol = new ArrayList<>(Arrays.asList(
+ "!ID", "!Name", "!SBML:reaction:id", "!ReactionFormula", "!Location", "!Enzyme", "!Model", "!Pathway", "!SubreactionOf",
+ "!IsComplete", "!IsReversible", "!IsInEquilibrium", "!IsExchangeReaction", "!Flux", "!IsNonEnzymatic",
+ "!KineticLaw", "!Gene", "!Operon",
+ "!Enzyme:SBML:species:id", "!Enzyme:SBML:parameter:id",
+ "!BuildReaction", "!BuildEnzyme", "!BuildEnzymeProduction", "!Comment", "!ReferenceName", "!ReferencePubMed", "!ReferenceDOI", "!Description", "!Modifier",
+ "!MiriamAnnotations", "!Type", "!Symbol", "!PositionX", "!PositionY", "!SBOTerm", "!Identifiers"));
+
+ public static ArrayList primaryKeys = new ArrayList<>(Arrays.asList("id", "reactionId"));
+
+ String defaultDouble = "0.0";
+ String defaultInt = "0";
+ public StringProperty id = new SimpleStringProperty("nan");
+ public StringProperty name = new SimpleStringProperty("nan");
+ public StringProperty reactionId = new SimpleStringProperty("nan");
+ public StringProperty sumFormula = new SimpleStringProperty("nan + nan <=> nan");
+ public StringProperty location = new SimpleStringProperty("nan");
+ public StringProperty enzyme = new SimpleStringProperty("nan");
+ public StringProperty model = new SimpleStringProperty("nan");
+ public StringProperty pathway = new SimpleStringProperty("nan");
+ public StringProperty subreactionOf = new SimpleStringProperty("nan");
+ public BooleanProperty isComplete = new SimpleBooleanProperty(false);
+ public BooleanProperty isReversible = new SimpleBooleanProperty(false);
+ public BooleanProperty isInEquilibrium = new SimpleBooleanProperty(false);
+ public BooleanProperty isExchangeReaction = new SimpleBooleanProperty(false);
+ public BooleanProperty isNonEnzymatic = new SimpleBooleanProperty(false);
+
+ public StringProperty flux = new SimpleStringProperty("0.0");
+ public StringProperty kineticLaw = new SimpleStringProperty("nan");
+ public StringProperty gene = new SimpleStringProperty("nan");
+ public StringProperty operon = new SimpleStringProperty("nan");
+
+ public StringProperty enzymeSpeciesId = new SimpleStringProperty("nan");
+ public StringProperty enzymeParameterId = new SimpleStringProperty("nan");
+
+ public BooleanProperty buildReaction = new SimpleBooleanProperty(false);
+ public BooleanProperty buildEnzyme = new SimpleBooleanProperty(false);
+ public BooleanProperty buildEnzymeProduction = new SimpleBooleanProperty(false);
+
+ public StringProperty comment = new SimpleStringProperty("nan");
+ public StringProperty referenceName = new SimpleStringProperty("nan");
+ public StringProperty referencePubMed = new SimpleStringProperty("nan");
+ public StringProperty referenceDOI = new SimpleStringProperty("nan");
+ public StringProperty description = new SimpleStringProperty("nan");
+ public StringProperty modifier = new SimpleStringProperty("nan");
+
+ public StringProperty miriamAnnotations = new SimpleStringProperty("nan");
+ public StringProperty type = new SimpleStringProperty("nan");
+ public StringProperty symbol = new SimpleStringProperty("nan");
+
+ public StringProperty positionX = new SimpleStringProperty("0.0");
+ public StringProperty positionY = new SimpleStringProperty("0.0");
+
+ public StringProperty sboTerm = new SimpleStringProperty("0");
+ public StringProperty identifiers = new SimpleStringProperty("nan");
+
+ ArrayList attributes = new ArrayList<>(Arrays.asList(id, name, reactionId, sumFormula, location,
+ enzyme, model, pathway, subreactionOf, isComplete, isReversible, isInEquilibrium, isExchangeReaction,
+ flux, isNonEnzymatic, kineticLaw, gene, operon,
+ enzymeSpeciesId, enzymeParameterId, buildReaction, buildEnzyme, buildEnzymeProduction,
+ comment, referenceName, referencePubMed, referenceDOI, description, modifier, miriamAnnotations, type, symbol, positionX, positionY,
+ sboTerm, identifiers));
+
+ public HashMap annotations = new HashMap<>();
+
+ public ReactionInstance(String idStr, String reactionIdStr) {
+ this.id.setValue(idStr);
+ this.reactionId.setValue(reactionIdStr);
+ }
+
+ /*
+ * property value getter/setter
+ */
+
+ public String getId() {
+ return id.getValue();
+ }
+
+
+ public String getName() {
+ return name.getValue();
+ }
+
+
+ public String getReactionId() {
+ return reactionId.getValue();
+ }
+
+ public String getSumFormula() {
+ return sumFormula.getValue();
+ }
+
+ public String getLocation() {
+ return location.getValue();
+ }
+
+
+ public String getEnzyme() {
+ return enzyme.getValue();
+ }
+
+
+ public String getModel() {
+ return model.getValue();
+ }
+
+ public String getPathway() {
+ return pathway.getValue();
+ }
+
+
+ public String getSubreactionOf() {
+ return subreactionOf.getValue();
+ }
+
+ public String geKineticLaw() {
+ return kineticLaw.getValue();
+ }
+
+
+ public String getGene() {
+ return gene.getValue();
+ }
+
+ public String getOperon() {
+ return operon.getValue();
+ }
+
+ public String getFlux() {
+ return flux.getValue().toString();
+ }
+
+ public String getEnzymeSpeciesId() {
+ return enzymeSpeciesId.getValue().toString();
+ }
+ public String getEnzymeParameterId() {
+ return enzymeParameterId.getValue().toString();
+ }
+
+
+
+ public boolean getBuildReaction() {
+ return buildReaction.getValue();
+ }
+ public boolean getBuildEnzyme() {
+ return buildEnzyme.getValue();
+ }
+ public boolean getBuildEnzymeProduction() {
+ return buildEnzymeProduction.getValue();
+ }
+
+
+ public boolean getIsComplete() {
+ return isComplete.getValue();
+ }
+
+ public boolean getIsReversible() {
+ return isReversible.getValue();
+ }
+
+ public boolean getIsInEquilibrium() {
+ return isInEquilibrium.getValue();
+ }
+
+ public boolean getIsExchangeReaction() {
+ return isExchangeReaction.getValue();
+ }
+
+ public boolean getIsNonEnzymatic() {
+ return isNonEnzymatic.getValue();
+ }
+
+ public String getComment() {
+ return comment.getValue();
+ }
+
+ public String getReferenceName() {
+ return referenceName.getValue();
+ }
+
+ public String getReferencePubMed() {
+ return referencePubMed.getValue();
+ }
+
+ public String getReferenceDOI() {
+ return referenceDOI.getValue();
+ }
+
+ public String getDescription() {
+ return description.getValue();
+ }
+
+ public String getModifier() {
+ return modifier.getValue();
+ }
+
+ public String getMiriamAnnotations() {
+ return miriamAnnotations.getValue();
+ }
+ public String getType() {
+ return type.getValue();
+ }
+ public String getSymbol() {
+ return symbol.getValue();
+ }
+ public String getPositonX() {
+ return positionX.getValue();
+ }
+ public String getPositionY() {
+ return positionY.getValue();
+ }
+ public String getSboTerm() {
+ return sboTerm.getValue();
+ }
+ public String getIdentifiers() {
+ return identifiers.getValue();
+ }
+
+
+ /*
+ * property getter/setter
+ */
+
+ public StringProperty idProperty() {
+ return id;
+ }
+
+
+ public StringProperty nameProperty() {
+ return name;
+ }
+
+ public StringProperty reactionIdProperty() {
+ return reactionId;
+ }
+
+ public StringProperty locationProperty() {
+ return location;
+ }
+
+
+ public StringProperty sumFormulaProperty() {
+ return sumFormula;
+ }
+
+ public StringProperty enzymeProperty() {
+ return enzyme;
+ }
+
+
+ public StringProperty modelProperty() {
+ return model;
+ }
+
+
+ public StringProperty pathwayProperty() {
+ return pathway;
+ }
+ public StringProperty subreactionOfProperty() {
+ return subreactionOf;
+ }
+
+ public StringProperty fluxProperty() {
+ return flux;
+ }
+
+ public StringProperty kineticLawProperty() {
+ return kineticLaw;
+ }
+
+
+ public StringProperty geneProperty() {
+ return gene;
+ }
+
+ public StringProperty operonProperty() {
+ return operon;
+ }
+
+ public StringProperty enzymeSpeciesIdProperty() {
+ return enzymeSpeciesId;
+ }
+ public StringProperty enzymeParameterIdProperty() {
+ return enzymeParameterId;
+ }
+
+ public BooleanProperty buildReactionProperty() {
+ return buildReaction;
+ }
+ public BooleanProperty buildEnzymeProperty() {
+ return buildEnzyme;
+ }
+ public BooleanProperty buildEnzymeProductionProperty() {
+ return buildEnzymeProduction;
+ }
+
+ public BooleanProperty isCompleteProperty() {
+ return isComplete;
+ }
+ public BooleanProperty isReversibleProperty() {
+ return isReversible;
+ }
+ public BooleanProperty isInEquilibriumProperty() {
+ return isInEquilibrium;
+ }
+ public BooleanProperty isExchangeReactionProperty() {
+ return isExchangeReaction;
+ }
+
+ public BooleanProperty isNonEnzymaticProperty() {
+ return isNonEnzymatic;
+ }
+
+ public StringProperty commentProperty() {
+ return comment;
+ }
+
+ public StringProperty referenceNameProperty() {
+ return referenceName;
+ }
+
+ public StringProperty referencePubMedProperty() {
+ return referencePubMed;
+ }
+
+ public StringProperty referenceDOIProperty() {
+ return referenceDOI;
+ }
+
+ public StringProperty descriptionProperty() {
+ return description;
+ }
+
+ public StringProperty modifierProperty() {
+ return modifier;
+ }
+
+ public StringProperty miriamAnnotationsProperty() {
+ return miriamAnnotations;
+ }
+ public StringProperty typeProperty() {
+ return type;
+ }
+ public StringProperty symbolProperty() {
+ return symbol;
+ }
+ public StringProperty positionXProperty() {
+ return positionX;
+ }public StringProperty positionYProperty() {
+ return positionY;
+ }
+
+ public StringProperty sboTermProperty() {
+ return sboTerm;
+ }public StringProperty identifiersProperty() {
+ return identifiers;
+ }
+
+
+ public String toCSVLine() {
+ StringBuilder stringBuilder = new StringBuilder();
+ for (ObservableValue prop : attributes) {
+ stringBuilder.append(prop.getValue()+"\t");
+ stringBuilder.append("\t");
+ }
+ stringBuilder.append("\n");
+ return stringBuilder.toString();
+ }
+
+ public void setProperty(String attribute, String value) {
+
+ switch (attribute) {
+ case "id":
+ id.setValue(value);
+ break;
+ case "name":
+ name.setValue(value);
+ break;
+ case "reactionId":
+ reactionId.setValue(value);
+ break;
+ case "location":
+ location.setValue(value);
+ break;
+ case "sumFormula":
+ sumFormula.setValue(value);
+ break;
+ case "enzyme":
+ enzyme.setValue(value);
+ break;
+ case "model":
+ model.setValue(value);
+ break;
+ case "pathway":
+ pathway.setValue(value);
+ break;
+ case "subreactionOf":
+ subreactionOf.setValue(value);
+ break;
+ case "kineticLaw":
+ kineticLaw.setValue(value);
+ break;
+ case "gene":
+ gene.setValue(value);
+ break;
+ case "operon":
+ operon.setValue(value);
+ break;
+ case "flux":
+ flux.setValue(value);
+ break;
+ case "enzymeSpeciesId":
+ enzymeSpeciesId.setValue(value);
+ break;
+ case "enzymeParameterId":
+ enzymeParameterId.setValue(value);
+ break;
+ case "buildReaction":
+ buildReaction.setValue(Boolean.getBoolean(value));
+ break;
+ case "buildEnzyme":
+ buildEnzyme.setValue(Boolean.getBoolean(value));
+ break;
+ case "buildEnzymeProduction":
+ buildEnzymeProduction.setValue(Boolean.getBoolean(value));
+ break;
+ case "isComplete":
+ isComplete.setValue(Boolean.getBoolean(value));
+ break;
+ case "isReversible":
+ isReversible.setValue(Boolean.getBoolean(value));
+ break;
+ case "isInEquilibrium":
+ isInEquilibrium.setValue(Boolean.getBoolean(value));
+ break;
+ case "isExchangeReaction":
+ isExchangeReaction.setValue(Boolean.getBoolean(value));
+ break;
+ case "comment":
+ comment.setValue(value);
+ break;
+ case "referenceName":
+ referenceName.setValue(value);
+ break;
+ case "referencePubMed":
+ referencePubMed.setValue(value);
+ break;
+ case "referenceDOI":
+ referenceDOI.setValue(value);
+ break;
+ case "description":
+ description.setValue(value);
+ break;
+ case "modifier":
+ modifier.setValue(value);
+ break;
+ case "miriamAnnotations":
+ miriamAnnotations.setValue(value);
+ break;
+ case "type":
+ type.setValue(value);
+ break;
+ case "symbol":
+ symbol.setValue(value);
+ break;
+ case "positionX":
+ positionX.setValue(value);
+ break;
+ case "positionY":
+ positionY.setValue(value);
+ break;
+ case "sboTerm":
+ sboTerm.setValue(value);
+ break;
+ case "identifiers":
+ identifiers.setValue(value);
+ break;
+ default:
+ break;
+ }
+ }
+
+ public Reaction instanceToSBMLReaction(int level, int version, Model model) {
+
+ Reaction reaction = model.createReaction();
+ reaction.setId(reactionId.getValue());
+ reaction.setName(name.getValue());
+ reaction.setSBOTerm(SBMLUtils.convertToSBO(sboTerm.getValue()));
+ reaction.setCompartment(location.getValue());
+ reaction.setReversible(isReversible.getValue());
+ reaction.setKineticLaw(new KineticLaw());
+
+ return reaction;
+ }
+
+}
diff --git a/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/ReactionTableView.java b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/ReactionTableView.java
new file mode 100644
index 0000000..7b8a0cf
--- /dev/null
+++ b/bundles/org.insilico.sbmlsheets/src/org/insilico/sbmlsheets/core/ReactionTableView.java
@@ -0,0 +1,680 @@
+package org.insilico.sbmlsheets.core;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.TreeSet;
+import org.insilico.sbmlsheets.editor.IdentifierChooser;
+import com.sun.javafx.scene.control.skin.TableColumnHeader;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.event.EventTarget;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.SelectionMode;
+import javafx.scene.control.TableCell;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableColumnBase;
+import javafx.scene.control.TablePosition;
+import javafx.scene.control.TableRow;
+import javafx.scene.control.TableColumn.CellDataFeatures;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TextField;
+import javafx.scene.control.cell.CheckBoxTableCell;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.input.Clipboard;
+import javafx.scene.input.ClipboardContent;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.VBox;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.util.Callback;
+
+public class ReactionTableView extends TableView{
+
+public int i = 0;
+
+ HashSet reactionIds = new HashSet();
+ HashSet ids = new HashSet();
+
+ private ObservableList instances = FXCollections.observableArrayList();
+
+
+ public ReactionTableView(){
+ setEditable(true);
+ initExampleData(3);
+ this.setItems(instances);
+ initColumns(this);
+ initSelectionListeners();
+
+ }
+
+ public void addEmptyRow() {
+ String newId = "react_1";
+ int k = 1;
+ while (ids.contains(newId)) {
+ k+=1;
+ newId = "react_"+k;
+ }
+
+ String newId2 = "react_1";
+ int k2 = 1;
+ while (reactionIds.contains(newId2)) {
+ k2+=1;
+ newId2 = "react_"+k2;
+ }
+
+ reactionIds.add(newId2);
+ ids.add(newId);
+ System.out.println(newId);
+ ReactionInstance newRowData = new ReactionInstance(newId, newId2);
+ instances.add(newRowData);
+ }
+
+ private void initSelectionListeners() {
+ this.addEventFilter(KeyEvent.KEY_PRESSED, e -> {
+ if (e.getCode().equals( KeyCode.DELETE)) {
+ if (e.isShortcutDown()) {
+ removeSelectedColumns();
+ }else {
+ removeSelection();
+ }
+
+ }else if (e.getCode().equals(KeyCode.C) && e.isShortcutDown()) {
+ copySelectionToClipboard();
+
+ }else if (e.getCode().equals(KeyCode.A) && e.isShortcutDown()) {
+ this.getSelectionModel().selectAll();
+ }else if (e.isShortcutDown() && e.getCode().equals(KeyCode.N) && e.getCode().equals(KeyCode.R)) {
+ addEmptyRow();
+ }else if (e.isShortcutDown() && e.getCode().equals(KeyCode.N) && e.getCode().equals(KeyCode.C)) {
+ addNewColumn("NewCol_"+getColumns().size());
+ }else if (e.isShortcutDown()) {
+ this.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
+ }
+ e.consume();
+ });
+ }
+
+ public void copySelectionToClipboard() {
+ final ArrayList rows = new ArrayList<>();
+ final ArrayList cellColumns = new ArrayList<>();
+ final ArrayList cells = new ArrayList<>();
+ for (final TablePosition tablePosition : this.getSelectionModel().getSelectedCells()) {
+ if (!rows.contains(tablePosition.getRow())){
+ rows.add(tablePosition.getRow());
+ }
+ if (!cells.contains(tablePosition.getRow()+"_"+tablePosition.getColumn())){
+ cells.add(tablePosition.getRow()+"_"+tablePosition.getColumn());
+ }
+ if (!cellColumns.contains(tablePosition.getColumn())) {
+ cellColumns.add(tablePosition.getColumn());
+ }
+
+ }
+ final StringBuilder strb = new StringBuilder();
+
+ if (this.getSelectionModel().cellSelectionEnabledProperty().getValue()) {
+ for (Integer col : cellColumns) {
+ strb.append(this.getColumns().get(col).getText());
+ if (cellColumns.indexOf(col)==cellColumns.size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append("\t");
+ }
+ }
+ for (String s : cells) {
+ for (Integer i : cellColumns) {
+ String[] split = s.split("_");
+ if (split[1].equals(String.valueOf(i))) {
+ Object cellData = this.getColumns().get(i).getCellData(Integer.parseInt(split[0]));
+ strb.append(cellData == null ? "" : cellData);
+ }
+ if (cellColumns.indexOf(i)==cellColumns.size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append("\t");
+ }
+ }
+ }
+
+ }else {
+ for (TableColumn col : this.getColumns()) {
+ strb.append(col.getText());
+ if (this.getColumns().indexOf(col)==this.getColumns().size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append("\t");
+ }
+ }
+ boolean firstRow = true;
+ for (final Integer row : rows) {
+ for (final TableColumn, ?> column : this.getColumns()) {
+ strb.append(column.getCellData(row) == null ? "" : column.getCellData(row));
+ if (this.getColumns().indexOf(column)==this.getColumns().size()-1) {
+ strb.append("\n");
+ }else {
+ strb.append("\t");
+ }
+ }
+ }
+ }
+
+ final ClipboardContent clipboardContent = new ClipboardContent();
+ clipboardContent.putString(strb.toString());
+ Clipboard.getSystemClipboard().setContent(clipboardContent);
+ }
+
+ public void removeSelection() {
+ for (ReactionInstance i : this.getSelectionModel().getSelectedItems()) {
+ this.getItems().remove(i);
+ }
+ }
+
+ public void removeSelectedColumns() {
+ HashSet s = new HashSet<>();
+ for (TablePosition t : this.getSelectionModel().getSelectedCells()) {
+ if (t.getTableColumn().getUserData()!=null) {
+ if (t.getTableColumn().getUserData().equals("editable")) {
+ s.add(t.getTableColumn());
+ }
+ }
+ }
+ this.getColumns().removeAll(s);
+ }
+
+ public void addNewColumn(String colTitle) {
+ for (ReactionInstance c : instances) {
+ if (!c.attributeTypes.contains(colTitle.replaceAll("[:!]", "")+"_Str")) {
+ c.sbTabCol.add(colTitle);
+ }
+ }
+
+
+ Callback, TableCell> cellFactoryStr
+ = (TableColumn param) -> new EditableCell("Str", this, colTitle.replaceAll("[:!]", ""));
+ TableColumn strCol = new TableColumn(colTitle.replaceAll("[:!]", ""));
+ strCol.setCellValueFactory(new Callback, ObservableValue>() {
+ public ObservableValue call(CellDataFeatures p) {
+ return p.getValue().attributes.get(p.getValue().attributes.size()-1);
+ }
+ });
+ strCol.setCellFactory(cellFactoryStr);
+ strCol.setOnEditCommit(
+ (TableColumn.CellEditEvent t) -> {
+ ((ReactionInstance) t.getTableView().getItems()
+ .get(t.getTablePosition().getRow()))
+ .setProperty(colTitle.replaceAll("[:!]", ""), t.getNewValue());
+ this.refresh();
+ });
+ strCol.setUserData("editable");
+
+
+ this.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
+ if (e.isPrimaryButtonDown() && e.getClickCount() > 1) {
+ EventTarget target = e.getTarget();
+ TableColumnBase, ?> column = null;
+ ReactionInstance row = null;
+
+ while (target instanceof Node) {
+ target = ((Node) target).getParent();
+ if (target instanceof TableColumnHeader) {
+ column = ((TableColumnHeader) target).getTableColumn();
+ if (column != null) break;
+ }
+ if (target instanceof TableRow) {
+ row = ((ReactionInstance) target);
+ if (row != null) break;
+ }
+
+ }
+
+
+ if (column != null) {
+ if (column.getUserData().equals("editable")) {
+ TableColumnBase,?> tableColumn = column;
+ TextField textField = new TextField(column.getText());
+ textField.setMaxWidth(column.getWidth());
+ textField.setOnAction(a -> {
+ tableColumn.setText(textField.getText());
+ tableColumn.setGraphic(null);
+ });
+ textField.focusedProperty().addListener((src, ov, nv) -> {
+ if (!nv) tableColumn.setGraphic(null);
+ });
+ column.setGraphic(textField);
+ textField.requestFocus();
+
+ ContextMenu contextMenu = new ContextMenu();
+ MenuItem choose = new MenuItem("Choose valid SBTab Column Title");
+ contextMenu.getItems().add(choose);
+ textField.setContextMenu(contextMenu);
+
+ choose.setOnAction(new EventHandler() {
+ @Override public void handle(ActionEvent e) {
+ IdentifierChooser chooser = new IdentifierChooser();
+ Stage dialogStage = new Stage();
+ Scene dialogScene = new Scene(chooser, 300, 550);
+ dialogStage.show();
+ dialogStage.setScene(dialogScene);
+
+ final Stage[] stages = new Stage[] {dialogStage};
+
+ chooser.getB().setOnAction(new EventHandler() {
+ @Override public void handle(ActionEvent e) {
+ tableColumn.setText(chooser.getResultList().getSelectionModel().getSelectedItem());
+ tableColumn.setGraphic(null);
+ stages[0].close();
+ }
+ });
+ chooser.getB2().setOnAction(new EventHandler() {
+ @Override public void handle(ActionEvent e) {
+ stages[0].close();
+ tableColumn.setGraphic(null);
+ }
+ });
+ }
+ });
+
+
+ }
+ e.consume();
+ }
+ }
+
+ });
+
+
+ this.getColumns().add(strCol);
+ strCol.setEditable(true);
+
+ }
+
+
+ private void initExampleData(int m) {
+ for (int l = 0; l < m; l++) {
+ addEmptyRow();
+ }
+ }
+
+ private void initColumns(ReactionTableView table) {
+
+ for (int j = 0; j < ReactionInstance.attributeTypes.size(); j++) {
+ final int k = j;
+
+ String att = ReactionInstance.attributeTypes.get(j);
+ String[] attSpl = att.split("_");
+ System.out.println(k + " : " + attSpl[0] + " --> " + attSpl[1]);
+ switch (attSpl[1]) {
+ case "Bool":
+ TableColumn boolCol = new TableColumn(attSpl[0]);
+ boolCol.setCellValueFactory(new PropertyValueFactory<>(attSpl[0]));
+
+ final CheckBoxTableCell ctCell = new CheckBoxTableCell<>();
+ ctCell.setSelectedStateCallback(new Callback>() {
+ @Override
+ public ObservableValue call(Integer index) {
+ return table.getItems().get(index).attributes.get(index);
+ }
+ });
+
+ boolCol.setCellFactory(column -> new CheckBoxTableCell());
+ this.getColumns().add(boolCol);
+ boolCol.setEditable(true);
+ break;
+ case "Str":
+ if (attSpl[0].equals("sumFormula")) {
+ Callback, TableCell> cellFactoryStr
+ = (TableColumn param) -> new EditableCell(attSpl[1], this, attSpl[0]);
+ TableColumn strCol = new TableColumn(attSpl[0]);
+ strCol.setCellValueFactory(new Callback, ObservableValue>() {
+ public ObservableValue call(CellDataFeatures p) {
+ return p.getValue().attributes.get(k);
+ }
+ });
+ strCol.setCellFactory(cellFactoryStr);
+ strCol.setOnEditCommit(
+ (TableColumn.CellEditEvent t) -> {
+ ((ReactionInstance) t.getTableView().getItems()
+ .get(t.getTablePosition().getRow()))
+ .setProperty(attSpl[0], t.getNewValue());
+ this.refresh();
+ });
+
+ this.getColumns().add(strCol);
+ strCol.setEditable(true);
+ }else {
+ Callback, TableCell> cellFactoryStr
+ = (TableColumn param) -> new EditableCell(attSpl[1], this, attSpl[0]);
+ TableColumn strCol = new TableColumn(attSpl[0]);
+ strCol.setCellValueFactory(new Callback, ObservableValue>() {
+ public ObservableValue call(CellDataFeatures p) {
+ return p.getValue().attributes.get(k);
+ }
+ });
+ strCol.setCellFactory(cellFactoryStr);
+ strCol.setOnEditCommit(
+ (TableColumn.CellEditEvent t) -> {
+ String val = t.getNewValue();
+ switch (attSpl[0]) {
+ case "sumFormula":
+ System.out.println("changing to proper sum formula");
+ String s = "((\\d+(\\.\\d+)? )?\\S+)+( \\+ ((\\d+(\\.\\d+)? )?\\S+)+)* [<]?=> ((\\d+(\\.\\d+)? )?\\S+)+( \\+ ((\\d+(\\.\\d+)? )?\\S+)+)*";
+ if (val.matches(s)) {
+ System.out.println("string stays string");
+ }else {
+ val = "nan + nan <=> nan";
+ }
+ break;
+ case "reactionId":
+ if (!t.getOldValue().equals(t.getNewValue())) {
+ reactionIds.remove(t.getOldValue());
+ String[] split = val.split("_");
+ String prefix = split[0];
+ String num = split[1];
+ while (reactionIds.contains(val)) {
+ if (split.length>1) {
+ if (num.matches("[0-9]+")) {
+ num = String.valueOf(Integer.parseInt(num)+1);
+ val = prefix + "_" + num;
+
+ }else {
+ val = prefix + "_1";
+ num = "1";
+ }
+ }else {
+ val = prefix + "_1";
+ num = "1";
+ }
+ }
+ reactionIds.add(val);
+ }
+ break;
+
+ case "id":
+
+ if (!t.getOldValue().equals(t.getNewValue())) {
+ ids.remove(t.getOldValue());
+ String[] split = val.split("_");
+ String prefix = split[0];
+ String num = split[1];
+ while (ids.contains(val)) {
+ if (split.length>1) {
+ if (num.matches("[0-9]+")) {
+ num = String.valueOf(Integer.parseInt(num)+1);
+ val = prefix + "_" + num;
+
+ }else {
+ val = prefix + "_1";
+ num = "1";
+ }
+ }else {
+ val = prefix + "_1";
+ num = "1";
+ }
+ }
+ ids.add(val);
+
+ }
+ break;
+ case "sboTerm":
+ val = SBMLUtils.convertToSBO(t.getNewValue());
+ break;
+ }
+
+ ((ReactionInstance) t.getTableView().getItems()
+ .get(t.getTablePosition().getRow()))
+ .setProperty(attSpl[0], val);
+ this.refresh();
+ });
+
+
+ this.getColumns().add(strCol);
+ strCol.setEditable(true);
+ }
+ break;
+ case "Int"://
+ Callback, TableCell> cellFactoryInt
+ = (TableColumn param) -> new EditableCell(attSpl[1], this, attSpl[0]);
+ TableColumn intCol = new TableColumn(attSpl[0]);
+ intCol.setCellValueFactory(new Callback