diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..9d89fa03f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/org.eclipse.osgi
diff --git a/bundles/runtime/.gitignore b/bundles/runtime/.gitignore
new file mode 100644
index 000000000..9d89fa03f
--- /dev/null
+++ b/bundles/runtime/.gitignore
@@ -0,0 +1 @@
+/org.eclipse.osgi
diff --git a/demos/org.eclipse.fx.demo.contacts.app/.classpath b/demos/org.eclipse.fx.demo.contacts.app/.classpath
new file mode 100755
index 000000000..098194ca4
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/demos/org.eclipse.fx.demo.contacts.app/.gitignore b/demos/org.eclipse.fx.demo.contacts.app/.gitignore
new file mode 100755
index 000000000..4dc009173
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/.gitignore
@@ -0,0 +1,2 @@
+/target
+/bin
diff --git a/demos/org.eclipse.fx.demo.contacts.app/.project b/demos/org.eclipse.fx.demo.contacts.app/.project
new file mode 100755
index 000000000..ef0866633
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/.project
@@ -0,0 +1,39 @@
+
+
+ org.eclipse.fx.demo.contacts.app
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+ org.eclipse.xtext.ui.shared.xtextBuilder
+
+
+
+
+ org.eclipse.pde.ds.core.builder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+ org.eclipse.xtext.ui.shared.xtextNature
+
+
diff --git a/demos/org.eclipse.fx.demo.contacts.app/.settings/org.eclipse.core.resources.prefs b/demos/org.eclipse.fx.demo.contacts.app/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 000000000..02db9ba99
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,6 @@
+eclipse.preferences.version=1
+encoding//src/org/eclipse/fx/demo/contacts/handlers/AddContactHandler.java=UTF-8
+encoding//src/org/eclipse/fx/demo/contacts/handlers/AddGroupHandler.java=UTF-8
+encoding//src/org/eclipse/fx/demo/contacts/handlers/PasteHandler.java=UTF-8
+encoding//src/org/eclipse/fx/demo/contacts/handlers/SwitchThemeHandler.java=UTF-8
+encoding//src/org/eclipse/fx/demo/contacts/processors/AbstractThemeProcessor.java=UTF-8
diff --git a/demos/org.eclipse.fx.demo.contacts.app/.settings/org.eclipse.jdt.core.prefs b/demos/org.eclipse.fx.demo.contacts.app/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..f42de363a
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/demos/org.eclipse.fx.demo.contacts.app/Application.e4xmi b/demos/org.eclipse.fx.demo.contacts.app/Application.e4xmi
new file mode 100755
index 000000000..3c136dd70
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/Application.e4xmi
@@ -0,0 +1,78 @@
+
+
+
+ no-decoration#topdecoration.fxml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demos/org.eclipse.fx.demo.contacts.app/IP_TODOS.txt b/demos/org.eclipse.fx.demo.contacts.app/IP_TODOS.txt
new file mode 100755
index 000000000..1400c0596
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/IP_TODOS.txt
@@ -0,0 +1,24 @@
+e4 icons:
+---------
+css/blue.png
+css/bright.png
+css/dark.png
+
+FAM-FAM-FAM (Creative Commons Attribution 2.5 License):
+-------------------------------------------------------
+icons/slik/arrow_redo.png
+icons/slik/arrow_undo.png
+icons/slik/bright.png
+icons/slik/cross.png
+icons/slik/cut.png
+icons/slik/dark.png
+icons/slik/disk.png
+icons/slik/door_in.png
+icons/slik/folder_add.png
+icons/slik/folder_user.png
+icons/slik/folder.png
+icons/slik/page_copy.png
+icons/slik/page_paste.png
+icons/slik/report_user.png
+icons/slik/user_add.png
+icons/slik/user_delete.png
\ No newline at end of file
diff --git a/demos/org.eclipse.fx.demo.contacts.app/META-INF/MANIFEST.MF b/demos/org.eclipse.fx.demo.contacts.app/META-INF/MANIFEST.MF
new file mode 100755
index 000000000..6eaf39f84
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/META-INF/MANIFEST.MF
@@ -0,0 +1,71 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Contacts Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.fx.demo.contacts.app;singleton:=true
+Bundle-Version: 0.9.1.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.fx.ui.application,
+ org.eclipse.fx.ui.workbench.fx,
+ javax.inject;bundle-version="1.0.0",
+ org.eclipse.e4.ui.model.workbench;bundle-version="0.9.1",
+ org.eclipse.e4.core.services;bundle-version="0.9.1",
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.e4.core.di.extensions;bundle-version="0.9.0",
+ org.eclipse.fx.ui.di,
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0",
+ org.eclipse.fx.ui.databinding;bundle-version="0.8.1",
+ org.eclipse.core.databinding;bundle-version="1.4.0",
+ org.eclipse.core.databinding.beans;bundle-version="1.2.100",
+ org.eclipse.core.databinding.observable;bundle-version="1.4.0",
+ org.eclipse.core.databinding.property;bundle-version="1.4.0",
+ org.eclipse.e4.ui.services;bundle-version="0.9.0",
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.1",
+ org.eclipse.core.commands;bundle-version="3.6.0",
+ org.eclipse.e4.core.commands;bundle-version="0.9.0",
+ org.eclipse.fx.ui.services;bundle-version="0.8.1",
+ org.eclipse.fx.demo.contacts;bundle-version="1.0.0",
+ org.eclipse.fx.demo.contacts.edit;bundle-version="1.0.0",
+ org.eclipse.fx.emf.databinding;bundle-version="0.8.1",
+ org.eclipse.fx.emf.edit.ui;bundle-version="0.8.1"
+Import-Package: javafx.animation;version="2.0.0",
+ javafx.application;version="2.0.0",
+ javafx.beans;version="2.0.0",
+ javafx.beans.binding;version="2.0.0",
+ javafx.beans.property;version="2.0.0",
+ javafx.beans.value;version="2.0.0",
+ javafx.collections;version="2.0.0",
+ javafx.concurrent;version="2.0.0",
+ javafx.embed.swing;version="2.0.0",
+ javafx.event;version="2.0.0",
+ javafx.fxml;version="2.0.0",
+ javafx.geometry;version="2.0.0",
+ javafx.scene;version="2.0.0",
+ javafx.scene.chart;version="2.0.0",
+ javafx.scene.control;version="2.0.0",
+ javafx.scene.control.cell;version="2.0.0",
+ javafx.scene.effect;version="2.0.0",
+ javafx.scene.image;version="2.0.0",
+ javafx.scene.input;version="2.0.0",
+ javafx.scene.layout;version="2.0.0",
+ javafx.scene.media;version="2.0.0",
+ javafx.scene.paint;version="2.0.0",
+ javafx.scene.shape;version="2.0.0",
+ javafx.scene.text;version="2.0.0",
+ javafx.scene.transform;version="2.0.0",
+ javafx.scene.web;version="2.0.0",
+ javafx.stage;version="2.0.0",
+ javafx.util;version="2.0.0",
+ javax.annotation;version="1.0.0"
+Bundle-ActivationPolicy: lazy
+Bundle-Vendor: Eclipse.org
+Bundle-Activator: org.eclipse.fx.demo.contacts.BundleActivatorImpl
+Bundle-Localization: plugin
+Service-Component: OSGI-INF/component.xml
+Export-Package: org.eclipse.fx.demo.contacts,
+ org.eclipse.fx.demo.contacts.handlers,
+ org.eclipse.fx.demo.contacts.model,
+ org.eclipse.fx.demo.contacts.processors,
+ org.eclipse.fx.demo.contacts.views
+
+
diff --git a/demos/org.eclipse.fx.demo.contacts.app/OSGI-INF/component.xml b/demos/org.eclipse.fx.demo.contacts.app/OSGI-INF/component.xml
new file mode 100755
index 000000000..2a2b32aa3
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/OSGI-INF/component.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/demos/org.eclipse.fx.demo.contacts.app/build.properties b/demos/org.eclipse.fx.demo.contacts.app/build.properties
new file mode 100755
index 000000000..6827a4f3e
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/build.properties
@@ -0,0 +1,17 @@
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ images/,\
+ icons/,\
+ images/,\
+ Application.e4xmi,\
+ css/,\
+ splash.bmp,\
+ plugin_customization.ini,\
+ vcards/,\
+ plugin_ru.properties,\
+ plugin.properties,\
+ OSGI-INF/component.xml,\
+ OSGI-INF/component.xml
+source.. = src/
diff --git a/demos/org.eclipse.fx.demo.contacts.app/contacts.product b/demos/org.eclipse.fx.demo.contacts.app/contacts.product
new file mode 100755
index 000000000..5b3be890c
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/contacts.product
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+ -Dosgi.framework.extensions=org.eclipse.fx.osgi
+ -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demos/org.eclipse.fx.demo.contacts.app/css/blue.css b/demos/org.eclipse.fx.demo.contacts.app/css/blue.css
new file mode 100755
index 000000000..ced94cc3c
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/css/blue.css
@@ -0,0 +1,104 @@
+.root {
+ -fx-base: #7eaacc;
+ -fx-background: #7eaacc;
+ -fx-control-inner-background: white;
+}
+
+.tab {
+ -fx-background-color: linear-gradient(to top, -fx-base, derive(-fx-base,30%));
+}
+
+.button {
+ -fx-background-color: transparent;
+ -fx-padding: 4;
+}
+
+.button:hover {
+ -fx-background-color: -fx-shadow-highlight-color, -fx-outer-border, -fx-inner-border, -fx-body-color;
+ -fx-color: -fx-hover-base;
+}
+
+.tool-bar:horizontal .separator {
+ -fx-orientation: vertical;
+ -fx-padding: 2 0 2 0;
+}
+
+.table-view {
+ -fx-table-cell-border-color:derive(-fx-base,+10%);
+ -fx-table-header-border-color:derive(-fx-base,+20%);
+}
+
+.split-pane:horizontal > * > .split-pane-divider {
+ -fx-border-color: transparent -fx-base transparent -fx-base;
+ -fx-background-color: transparent, derive(-fx-base,20%);
+ -fx-background-insets: 0, 0 1 0 1;
+}
+
+.menu-bar {
+ -fx-background-color: linear-gradient(to bottom, #7eaacc, derive(#7eaacc,+50%));
+ }
+
+.menu-bar .menu .label {
+ -fx-padding: 0.333em 0.5em 0.333em 0.5em; /* 4 6 4 6*/
+ -fx-text-fill: black;
+}
+
+.my-gridpane {
+ -fx-background-color: radial-gradient(radius 100%, derive(-fx-base,70%), derive(-fx-base,20%));
+}
+
+.separator-label {
+ -fx-text-fill: derive(-fx-base,-50%) ;
+}
+
+#window-resize-button {
+ -fx-background-image: url("images/window-corner.png");
+ -fx-background-position: right 1px bottom 1px;
+ -fx-background-repeat: no-repeat;
+}
+
+#window_close {
+ -fx-font-size: 1px;
+ -fx-background-color: null;
+ -fx-background-image: url("images/window-close.png");
+ -fx-padding: 6 6 4 6;
+}
+
+#window_min {
+ -fx-font-size: 1px;
+ -fx-background-color: null;
+ -fx-background-image: url("images/window-min.png");
+ -fx-padding: 6 6 4 6;
+}
+
+#window_max {
+ -fx-font-size: 1px;
+ -fx-background-color: null;
+ -fx-background-image: url("images/window-expand.png");
+ -fx-padding: 6 6 4 6;
+}
+
+#window_close:hover {
+ -fx-background-image: url("images/window-close-over.png");
+}
+
+#window_min:hover {
+ -fx-background-image: url("images/window-min-over.png");
+}
+
+#window_max:hover {
+ -fx-background-image: url("images/window-expand-over.png");
+}
+
+.MTrimBar {
+ -fx-background-color:
+ linear-gradient(to bottom, derive(-fx-base,-30%), derive(-fx-base,-60%)),
+ linear-gradient(to bottom, derive(-fx-base,65%) 2%, derive(-fx-base,-20%) 95%);
+}
+
+.MTrimBar .tool-bar {
+ -fx-border-style: solid;
+ -fx-background-color: null;
+ -fx-border-color: null;
+ -fx-border-width: 0px;
+}
\ No newline at end of file
diff --git a/demos/org.eclipse.fx.demo.contacts.app/css/blue.png b/demos/org.eclipse.fx.demo.contacts.app/css/blue.png
new file mode 100755
index 000000000..aac83ea0f
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/css/blue.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/css/bright.css b/demos/org.eclipse.fx.demo.contacts.app/css/bright.css
new file mode 100755
index 000000000..1beae7fc3
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/css/bright.css
@@ -0,0 +1,85 @@
+.root {
+ -fx-base: #d0d0d0;
+ -fx-background: #f4f4f4;
+ -fx-control-inner-background: white;
+}
+
+.menu-bar {
+ -fx-background-color: linear-gradient(to bottom, #d0d0d0, derive(#d0d0d0,+50%));
+ -fx-text-fill: black;
+}
+
+.menu-bar .menu .label {
+ -fx-padding: 0.333em 0.5em 0.333em 0.5em; /* 4 6 4 6*/
+ -fx-text-fill: black;
+}
+
+.my-gridpane {
+ -fx-background-color: radial-gradient(radius 100%, derive(-fx-base,70%), derive(-fx-base,20%));
+}
+
+.separator-label {
+ -fx-text-fill: steelblue ;
+}
+
+.button {
+ -fx-background-color: transparent;
+ -fx-padding: 4;
+}
+
+.button:hover {
+ -fx-background-color: -fx-shadow-highlight-color, -fx-outer-border, -fx-inner-border, -fx-body-color;
+ -fx-color: -fx-hover-base;
+}
+
+#window-resize-button {
+ -fx-background-image: url("images/window-corner.png");
+ -fx-background-position: right 1px bottom 1px;
+ -fx-background-repeat: no-repeat;
+}
+
+#window_close {
+ -fx-font-size: 1px;
+ -fx-background-color: null;
+ -fx-background-image: url("images/window-close.png");
+ -fx-padding: 6 6 4 6;
+}
+
+#window_min {
+ -fx-font-size: 1px;
+ -fx-background-color: null;
+ -fx-background-image: url("images/window-min.png");
+ -fx-padding: 6 6 4 6;
+}
+
+#window_max {
+ -fx-font-size: 1px;
+ -fx-background-color: null;
+ -fx-background-image: url("images/window-expand.png");
+ -fx-padding: 6 6 4 6;
+}
+
+#window_close:hover {
+ -fx-background-image: url("images/window-close-over.png");
+}
+
+#window_min:hover {
+ -fx-background-image: url("images/window-min-over.png");
+}
+
+#window_max:hover {
+ -fx-background-image: url("images/window-expand-over.png");
+}
+
+.MTrimBar {
+ -fx-background-color:
+ linear-gradient(to bottom, derive(-fx-base,-30%), derive(-fx-base,-60%)),
+ linear-gradient(to bottom, derive(-fx-base,65%) 2%, derive(-fx-base,-20%) 95%);
+}
+
+.MTrimBar .tool-bar {
+ -fx-border-style: solid;
+ -fx-background-color: null;
+ -fx-border-color: null;
+ -fx-border-width: 0px;
+}
\ No newline at end of file
diff --git a/demos/org.eclipse.fx.demo.contacts.app/css/bright.png b/demos/org.eclipse.fx.demo.contacts.app/css/bright.png
new file mode 100755
index 000000000..ed1021257
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/css/bright.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/css/dark.css b/demos/org.eclipse.fx.demo.contacts.app/css/dark.css
new file mode 100755
index 000000000..6c2b79326
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/css/dark.css
@@ -0,0 +1,132 @@
+.root {
+ -fx-base: rgb(50, 50, 50);
+ -fx-background: rgb(50, 50, 50);
+ -fx-control-inner-background: rgb(50, 50, 50);
+}
+
+.tab {
+ -fx-background-color: linear-gradient(to top, -fx-base, derive(-fx-base,30%));
+}
+
+.menu-bar {
+ -fx-background-color: linear-gradient(to bottom, -fx-base, derive(-fx-base,30%));
+}
+
+.MTrimBar {
+ -fx-background-color:
+ linear-gradient(to bottom, derive(-fx-base,+50%),derive(-fx-base,-40%), derive(-fx-base,-20%));
+}
+
+.tool-bar:horizontal {
+ -fx-background-color:
+ linear-gradient(to bottom, derive(-fx-base,+50%), derive(-fx-base,-40%), derive(-fx-base,-20%));
+}
+
+.tool-bar:vertical {
+ -fx-background-color: linear-gradient(to bottom, derive(-fx-base,-50%), derive(-fx-base,-40%), derive(-fx-base,-20%));
+}
+
+.tool-bar .separator:vertical .line {
+ -fx-border-style: solid;
+ -fx-background-color: null;
+ -fx-border-color: transparent transparent derive(-fx-base,-35%) derive(-fx-base,+15%);
+}
+
+.tool-bar .separator:horizontal .line {
+ -fx-border-style: solid;
+ -fx-background-color: null;
+ -fx-border-color: transparent transparent derive(-fx-base,+15%) transparent;
+}
+
+.tooltip {
+ -fx-background-color:-fx-shadow-highlight-color, -fx-outer-border, -fx-inner-border, -fx-body-color;
+}
+
+.button {
+ -fx-background-color: transparent;
+ -fx-padding: 4;
+}
+
+.button:hover {
+ -fx-background-color: -fx-shadow-highlight-color, -fx-outer-border, -fx-inner-border, -fx-body-color;
+ -fx-color: -fx-hover-base;
+}
+
+.table-view {
+ -fx-table-cell-border-color:derive(-fx-base,+10%);
+ -fx-table-header-border-color:derive(-fx-base,+20%);
+}
+
+/* When the TableView is _not_ focused, we show alternate selection colors */
+.table-row-cell:filled:selected:focused, .table-row-cell:filled:selected {
+ -fx-background-color: derive(-fx-base,+60%);
+}
+
+ .table-row-cell:filled:hover {
+ -fx-background-color: derive(-fx-base,+40%);
+}
+
+.split-pane:horizontal > * > .split-pane-divider {
+ -fx-border-color: transparent -fx-base transparent -fx-base;
+ -fx-background-color: transparent, derive(-fx-base,20%);
+ -fx-background-insets: 0, 0 1 0 1;
+}
+
+.my-gridpane {
+ -fx-background-color: radial-gradient(radius 100%, derive(-fx-base,20%), derive(-fx-base,-20%));
+}
+
+.separator-label {
+ -fx-text-fill: orange;
+}
+
+#decorationArea {
+ -fx-padding: 10px;
+ -fx-background-color: derive(-fx-base,+10%);
+ /*
+ -fx-background-image: url("images/top-bar.png");
+ -fx-background-size: cover, contain;
+ -fx-background-position: left top, center center;
+ -fx-background-repeat: no-repeat;
+ */
+}
+
+#window-resize-button {
+ -fx-background-image: url("images/window-corner.png");
+ -fx-background-position: right 1px bottom 1px;
+ -fx-background-repeat: no-repeat;
+}
+
+#window_close {
+ -fx-font-size: 1px;
+ -fx-background-color: null;
+ -fx-background-image: url("images/window-close.png");
+ -fx-padding: 6 6 4 6;
+}
+
+#window_min {
+ -fx-font-size: 1px;
+ -fx-background-color: null;
+ -fx-background-image: url("images/window-min.png");
+ -fx-padding: 6 6 4 6;
+}
+
+#window_max {
+ -fx-font-size: 1px;
+ -fx-background-color: null;
+ -fx-background-image: url("images/window-expand.png");
+ -fx-padding: 6 6 4 6;
+}
+
+#window_close:hover {
+ -fx-background-image: url("images/window-close-over.png");
+}
+
+#window_min:hover {
+ -fx-background-image: url("images/window-min-over.png");
+}
+
+#window_max:hover {
+ -fx-background-image: url("images/window-expand-over.png");
+}
+
diff --git a/demos/org.eclipse.fx.demo.contacts.app/css/dark.png b/demos/org.eclipse.fx.demo.contacts.app/css/dark.png
new file mode 100755
index 000000000..cc5f8c08f
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/css/dark.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/arrow_redo.png b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/arrow_redo.png
new file mode 100755
index 000000000..fdc394c7c
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/arrow_redo.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/arrow_undo.png b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/arrow_undo.png
new file mode 100755
index 000000000..6972c5e59
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/arrow_undo.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/bright.png b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/bright.png
new file mode 100755
index 000000000..ed1021257
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/bright.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/cross.png b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/cross.png
new file mode 100755
index 000000000..1514d51a3
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/cross.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/cut.png b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/cut.png
new file mode 100755
index 000000000..f215d6f6b
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/cut.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/dark.png b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/dark.png
new file mode 100755
index 000000000..cc5f8c08f
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/dark.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/disk.png b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/disk.png
new file mode 100755
index 000000000..99d532e8b
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/disk.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/door_in.png b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/door_in.png
new file mode 100755
index 000000000..41676a0a5
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/door_in.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/folder.png b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/folder.png
new file mode 100755
index 000000000..784e8fa48
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/folder.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/folder_add.png b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/folder_add.png
new file mode 100755
index 000000000..529fe8fe0
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/folder_add.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/folder_user.png b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/folder_user.png
new file mode 100755
index 000000000..f021c3e12
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/folder_user.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/page_copy.png b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/page_copy.png
new file mode 100755
index 000000000..195dc6d6c
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/page_copy.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/page_paste.png b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/page_paste.png
new file mode 100755
index 000000000..968f073fd
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/page_paste.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/readme.txt b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/readme.txt
new file mode 100755
index 000000000..2cf67dcaf
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/readme.txt
@@ -0,0 +1,22 @@
+Silk icon set 1.3
+
+_________________________________________
+Mark James
+http://www.famfamfam.com/lab/icons/silk/
+_________________________________________
+
+This work is licensed under a
+Creative Commons Attribution 2.5 License.
+[ http://creativecommons.org/licenses/by/2.5/ ]
+
+This means you may use it for any purpose,
+and make any changes you like.
+All I ask is that you include a link back
+to this page in your credits.
+
+Are you using this icon set? Send me an email
+(including a link or picture if available) to
+mjames@gmail.com
+
+Any other questions about this icon set please
+contact mjames@gmail.com
\ No newline at end of file
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/report_user.png b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/report_user.png
new file mode 100755
index 000000000..7766edd74
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/report_user.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/user_add.png b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/user_add.png
new file mode 100755
index 000000000..deae99bcf
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/user_add.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/icons/silk/user_delete.png b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/user_delete.png
new file mode 100755
index 000000000..acbb5630e
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/icons/silk/user_delete.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/images/dummy.png b/demos/org.eclipse.fx.demo.contacts.app/images/dummy.png
new file mode 100755
index 000000000..bb30f82d3
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/images/dummy.png differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/plugin.properties b/demos/org.eclipse.fx.demo.contacts.app/plugin.properties
new file mode 100755
index 000000000..5d021c984
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/plugin.properties
@@ -0,0 +1,29 @@
+###############################################################################
+# Copyright (c) 2011 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+fileMenu = _File
+editMenu = _Edit
+switchThemeMenu = _Theme
+partDetails = Details
+contactsTree = Tree
+contactsTable = Table
+contactsList = List
+menuLabelSave = _Save
+menuLabelCut = Cut
+menuLabelCopy = Copy
+menuLabelPaste = Paste
+menuLabelUndo = Undo
+menuLabelDelete = _Delete
+menuLabelDirectExit = Direct E_xit
+menuLabelExit = _Exit
+windowTitle = e4 JavaFX Contacts Demo
+contactsTooltip = List of Contacts
+detailsTooltip = Contact Details
+toolbarSaveTooltip = Save
diff --git a/demos/org.eclipse.fx.demo.contacts.app/plugin.xml b/demos/org.eclipse.fx.demo.contacts.app/plugin.xml
new file mode 100755
index 000000000..a7f112faa
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/plugin.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demos/org.eclipse.fx.demo.contacts.app/plugin_customization.ini b/demos/org.eclipse.fx.demo.contacts.app/plugin_customization.ini
new file mode 100755
index 000000000..8a531fc70
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/plugin_customization.ini
@@ -0,0 +1,2 @@
+org.eclipse.ui/SHOW_PROGRESS_ON_STARTUP = true
+
diff --git a/demos/org.eclipse.fx.demo.contacts.app/plugin_ru.properties b/demos/org.eclipse.fx.demo.contacts.app/plugin_ru.properties
new file mode 100755
index 000000000..f572982c7
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/plugin_ru.properties
@@ -0,0 +1,22 @@
+###############################################################################
+# Copyright (c) 2011 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+fileMenu = &\u0424\u0430\u0439\u043B
+partDetails = \u041F\u043E\u0434\u0440\u043E\u0431\u043D\u043E
+contactsList = \u041A\u043E\u043D\u0442\u0430\u043A\u0442\u044B
+menuLabelSave = &\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C
+menuLabelDelete = &\u0423\u0434\u0430\u043B\u0438\u0442\u044C
+menuLabelDirectExit = &\u0411\u044B\u0441\u0442\u0440\u044B\u0439 \u0432\u044B\u0445\u043E\u0434
+menuLabelExit = &\u0412\u044B\u0445\u043E\u0434
+windowTitle = e4 \u0417\u0430\u043F\u0438\u0441\u043D\u0430\u044F \u043A\u043D\u0438\u0436\u043A\u0430
+contactsTooltip = \u0421\u043F\u0438\u0441\u043E\u043A \u043A\u043E\u043D\u0442\u0430\u043A\u0442\u043E\u0432
+detailsTooltip = \u041F\u043E\u0434\u0440\u043E\u0431\u043D\u0430\u044F \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043E \u043A\u043E\u043D\u0442\u0430\u043A\u0442\u0435
+toolbarSaveTooltip = \u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C
+
diff --git a/demos/org.eclipse.fx.demo.contacts.app/splash.bmp b/demos/org.eclipse.fx.demo.contacts.app/splash.bmp
new file mode 100755
index 000000000..68ce4201a
Binary files /dev/null and b/demos/org.eclipse.fx.demo.contacts.app/splash.bmp differ
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/BundleActivatorImpl.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/BundleActivatorImpl.java
new file mode 100755
index 000000000..1aea28d10
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/BundleActivatorImpl.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.fx.demo.contacts;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.osgi.service.datalocation.Location;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class BundleActivatorImpl implements BundleActivator {
+
+ private static final String F_META_AREA = ".metadata"; //$NON-NLS-1$
+ private static final String F_PLUGIN_DATA = ".plugins"; //$NON-NLS-1$
+
+ private static BundleActivatorImpl instance;
+
+ private BundleContext context;
+
+ private ServiceTracker locationServiceTracker;
+
+ private IPath stateLocation;
+
+ public void start(BundleContext context) throws Exception {
+ instance = this;
+ this.context = context;
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ this.context = null;
+ instance = null;
+ }
+
+ public IPath getStateLocation() {
+ try {
+ if (stateLocation == null) {
+ Filter filter = context.createFilter(Location.INSTANCE_FILTER);
+ if (locationServiceTracker == null) {
+ locationServiceTracker = new ServiceTracker(context,
+ filter, null);
+ locationServiceTracker.open();
+ }
+ Location location = (Location) locationServiceTracker
+ .getService();
+ if (location != null) {
+ IPath path = new Path(location.getURL().getPath());
+ stateLocation = path.append(F_META_AREA).append(
+ F_PLUGIN_DATA).append(
+ context.getBundle().getSymbolicName());
+ stateLocation.toFile().mkdirs();
+ }
+ }
+ } catch (InvalidSyntaxException e) {
+ // ignore this. It should never happen as we have tested the above
+ // format
+ }
+ return stateLocation;
+ }
+
+ public static BundleActivatorImpl getInstance() {
+ return instance;
+ }
+
+}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/DecorationController.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/DecorationController.java
new file mode 100755
index 000000000..ed3df76e5
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/DecorationController.java
@@ -0,0 +1,77 @@
+package org.eclipse.fx.demo.contacts;
+
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.fxml.FXML;
+import javafx.geometry.Rectangle2D;
+import javafx.scene.control.ToolBar;
+import javafx.scene.input.MouseEvent;
+import javafx.stage.Screen;
+import javafx.stage.Stage;
+import javax.annotation.PostConstruct;
+
+public class DecorationController {
+ private double mouseDragOffsetX = 0;
+ private double mouseDragOffsetY = 0;
+
+ @FXML
+ private ToolBar decorationArea;
+
+ private Rectangle2D backupWindowBounds;
+
+ public DecorationController() {
+ }
+
+ @PostConstruct
+ void init() {
+ decorationArea.setOnMousePressed(new EventHandler() {
+ public void handle(MouseEvent event) {
+ mouseDragOffsetX = event.getSceneX();
+ mouseDragOffsetY = event.getSceneY();
+ }
+ });
+ decorationArea.setOnMouseDragged(new EventHandler() {
+ public void handle(MouseEvent event) {
+ Stage w = getStage();
+ w.setX(event.getScreenX() - mouseDragOffsetX);
+ w.setY(event.getScreenY() - mouseDragOffsetY);
+ }
+ });
+ }
+
+ public void handleClose(ActionEvent event) {
+ Platform.exit();
+ }
+
+ public void handleMin(ActionEvent event) {
+ getStage().setIconified(true);
+ }
+
+ public void handleMax(ActionEvent event) {
+ Stage stage = getStage();
+ final double stageY = stage.getY();
+ final Screen screen = Screen.getScreensForRectangle(stage.getX(), stageY, 1, 1).get(0);
+ Rectangle2D bounds = screen.getVisualBounds();
+ if (bounds.getMinX() == stage.getX() && bounds.getMinY() == stageY && bounds.getWidth() == stage.getWidth()
+ && bounds.getHeight() == stage.getHeight()) {
+ if (backupWindowBounds != null) {
+ stage.setX(backupWindowBounds.getMinX());
+ stage.setY(backupWindowBounds.getMinY());
+ stage.setWidth(backupWindowBounds.getWidth());
+ stage.setHeight(backupWindowBounds.getHeight());
+ }
+ } else {
+ backupWindowBounds = new Rectangle2D(stage.getX(), stage.getY(), stage.getWidth(), stage.getHeight());
+ final double newStageY = screen.getVisualBounds().getMinY();
+ stage.setX(screen.getVisualBounds().getMinX());
+ stage.setY(newStageY);
+ stage.setWidth(screen.getVisualBounds().getWidth());
+ stage.setHeight(screen.getVisualBounds().getHeight());
+ }
+ }
+
+ Stage getStage() {
+ return (Stage) decorationArea.getScene().getWindow();
+ }
+}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/AddContactHandler.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/AddContactHandler.java
new file mode 100755
index 000000000..1476a8d62
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/AddContactHandler.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Siemens AG and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Kai T��dter - initial implementation
+ ******************************************************************************/
+
+package org.eclipse.fx.demo.contacts.handlers;
+
+import javax.inject.Inject;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.edit.command.AddCommand;
+import org.eclipse.fx.demo.contacts.Contact;
+import org.eclipse.fx.demo.contacts.ContactsFactory;
+import org.eclipse.fx.demo.contacts.ContactsPackage;
+import org.eclipse.fx.demo.contacts.model.ContactsManager;
+
+
+@SuppressWarnings("restriction")
+public class AddContactHandler {
+
+ @Inject
+ ContactsManager contactsManager;
+
+ @Execute
+ void execute() {
+ Contact contact = ContactsFactory.eINSTANCE.createContact();
+ Command command = AddCommand.create(contactsManager.getEditingDomain(), contactsManager.getRootGroup(), ContactsPackage.Literals.GROUP__CONTACTS, contact);
+ if (command != null && command.canExecute())
+ contactsManager.getEditingDomain().getCommandStack().execute(command);
+ }
+
+}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/AddGroupHandler.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/AddGroupHandler.java
new file mode 100755
index 000000000..7c4cacfbb
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/AddGroupHandler.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Siemens AG and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Kai T��dter - initial implementation
+ ******************************************************************************/
+
+package org.eclipse.fx.demo.contacts.handlers;
+
+import javax.inject.Inject;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.edit.command.AddCommand;
+import org.eclipse.fx.demo.contacts.ContactsFactory;
+import org.eclipse.fx.demo.contacts.ContactsPackage;
+import org.eclipse.fx.demo.contacts.Group;
+import org.eclipse.fx.demo.contacts.model.ContactsManager;
+
+
+@SuppressWarnings("restriction")
+public class AddGroupHandler {
+
+ @Inject
+ ContactsManager contactsManager;
+
+ @Execute
+ void execute() {
+ Group group = ContactsFactory.eINSTANCE.createGroup();
+ group.setName("New Group");
+ Command command = AddCommand.create(contactsManager.getEditingDomain(), contactsManager.getRootGroup(), ContactsPackage.Literals.GROUP__GROUPS, group);
+ if (command != null && command.canExecute())
+ contactsManager.getEditingDomain().getCommandStack().execute(command);
+ }
+
+}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/CopyHandler.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/CopyHandler.java
new file mode 100755
index 000000000..95be09f00
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/CopyHandler.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Siemens AG and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Kai T??dter - initial implementation
+ ******************************************************************************/
+
+package org.eclipse.fx.demo.contacts.handlers;
+
+import java.util.List;
+import javax.inject.Inject;
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.edit.command.CopyToClipboardCommand;
+import org.eclipse.fx.demo.contacts.model.ContactsManager;
+
+@SuppressWarnings("restriction")
+public class CopyHandler {
+
+ ContactsManager contactsManager;
+
+ Command command;
+
+ @Inject
+ public CopyHandler(ContactsManager contactsManager) {
+ this.contactsManager = contactsManager;
+ }
+
+ @CanExecute
+ public boolean canExecute(@Optional List> selection) {
+ if (selection != null) {
+ command = CopyToClipboardCommand.create(contactsManager.getEditingDomain(), selection);
+ return command.canExecute();
+ }
+ return false;
+ }
+
+ @Execute
+ public void execute() {
+ if (command != null && command.canExecute())
+ contactsManager.getEditingDomain().getCommandStack().execute(command);
+ }
+
+}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/CutHandler.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/CutHandler.java
new file mode 100755
index 000000000..2068adcdd
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/CutHandler.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Siemens AG and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Kai T??dter - initial implementation
+ ******************************************************************************/
+
+package org.eclipse.fx.demo.contacts.handlers;
+
+import java.util.List;
+import javax.inject.Inject;
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.edit.command.CutToClipboardCommand;
+import org.eclipse.fx.demo.contacts.model.ContactsManager;
+
+@SuppressWarnings("restriction")
+public class CutHandler {
+
+ ContactsManager contactsManager;
+ Command command;
+
+ @Inject
+ public CutHandler(ContactsManager contactsManager) {
+ this.contactsManager = contactsManager;
+ }
+
+ @CanExecute
+ public boolean canExecute(@Optional List> selection) {
+ if (selection != null) {
+ command = CutToClipboardCommand.create(contactsManager.getEditingDomain(), selection);
+ return command.canExecute();
+ }
+ return false;
+ }
+
+ @Execute
+ public void execute() {
+ if (command != null && command.canExecute())
+ contactsManager.getEditingDomain().getCommandStack().execute(command);
+ }
+
+}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/DeleteContactHandler.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/DeleteContactHandler.java
new file mode 100755
index 000000000..5c131b402
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/DeleteContactHandler.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Siemens AG and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Kai T??dter - initial implementation
+ ******************************************************************************/
+
+package org.eclipse.fx.demo.contacts.handlers;
+
+import java.util.List;
+import javax.inject.Inject;
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.edit.command.DeleteCommand;
+import org.eclipse.fx.demo.contacts.model.ContactsManager;
+
+@SuppressWarnings("restriction")
+public class DeleteContactHandler {
+
+ ContactsManager contactsManager;
+ Command command;
+
+ @Inject
+ public DeleteContactHandler(ContactsManager contactsManager) {
+ this.contactsManager = contactsManager;
+ }
+
+
+ @CanExecute
+ public boolean canExecute(@Optional List> selection) {
+ if (selection != null) {
+ command = DeleteCommand.create(contactsManager.getEditingDomain(), selection);
+ return command.canExecute();
+ }
+ return false;
+ }
+
+ @Execute
+ public void execute() {
+ if (command != null && command.canExecute())
+ contactsManager.getEditingDomain().getCommandStack().execute(command);
+ }
+
+}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/ExitHandler.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/ExitHandler.java
new file mode 100755
index 000000000..b6c8aa2a0
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/ExitHandler.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Siemens AG and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Kai T??dter - initial implementation
+ ******************************************************************************/
+
+package org.eclipse.fx.demo.contacts.handlers;
+
+import javafx.application.Platform;
+import org.eclipse.e4.core.di.annotations.Execute;
+
+@SuppressWarnings("restriction")
+public class ExitHandler {
+ @Execute
+ public void exit() {
+ // TODO better life cycle support
+ Platform.exit();
+ }
+}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/PasteHandler.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/PasteHandler.java
new file mode 100755
index 000000000..3d4e21c8e
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/PasteHandler.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Siemens AG and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Kai T��dter - initial implementation
+ ******************************************************************************/
+
+package org.eclipse.fx.demo.contacts.handlers;
+
+import javax.inject.Inject;
+
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.edit.command.PasteFromClipboardCommand;
+import org.eclipse.fx.demo.contacts.Contact;
+import org.eclipse.fx.demo.contacts.ContactsPackage;
+import org.eclipse.fx.demo.contacts.Group;
+import org.eclipse.fx.demo.contacts.model.ContactsManager;
+
+
+@SuppressWarnings("restriction")
+public class PasteHandler {
+
+ ContactsManager contactsManager;
+
+ Command command;
+
+ @Inject
+ public PasteHandler(ContactsManager contactsManager) {
+ this.contactsManager = contactsManager;
+ }
+
+ @CanExecute
+ public boolean canExecute(@Optional Object selectedItem) {
+ Group group = null;
+
+ if (selectedItem instanceof Contact)
+ // get containing Group if selection is a Contact
+ group = (Group) ((Contact) selectedItem).eContainer();
+
+ else if (selectedItem instanceof Group)
+ group = (Group) selectedItem;
+
+ if (group != null) {
+ command = PasteFromClipboardCommand.create(contactsManager.getEditingDomain(), group,
+ ContactsPackage.eINSTANCE.getGroup_Contacts());
+ return command.canExecute();
+ }
+
+ return false;
+ }
+
+ @Execute
+ public void execute() {
+ if (command != null && command.canExecute())
+ contactsManager.getEditingDomain().getCommandStack().execute(command);
+ }
+
+}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/RedoHandler.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/RedoHandler.java
new file mode 100755
index 000000000..123840f00
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/RedoHandler.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Siemens AG and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Kai T??dter - initial implementation
+ ******************************************************************************/
+package org.eclipse.fx.demo.contacts.handlers;
+
+
+import javax.inject.Inject;
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.fx.demo.contacts.model.ContactsManager;
+
+@SuppressWarnings("restriction")
+public class RedoHandler {
+
+ @Inject
+ ContactsManager contactsManager;
+
+ @CanExecute
+ public boolean canUndo() {
+ CommandStack commandStack = contactsManager.getEditingDomain().getCommandStack();
+ return commandStack.canRedo();
+ }
+
+ @Execute
+ public void undo() {
+ CommandStack commandStack = contactsManager.getEditingDomain().getCommandStack();
+ if (commandStack.canRedo())
+ commandStack.redo();
+ }
+}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/SwitchThemeHandler.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/SwitchThemeHandler.java
new file mode 100755
index 000000000..7cc4b6a17
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/SwitchThemeHandler.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tom Schindl - initial API and implementation
+ * Kai T��dter - Adoption to contacts demo
+ ******************************************************************************/
+package org.eclipse.fx.demo.contacts.handlers;
+
+import javax.inject.Named;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.fx.ui.services.theme.ThemeManager;
+
+@SuppressWarnings("restriction")
+public class SwitchThemeHandler {
+ @Execute
+ public void switchTheme(@Named("contacts.commands.switchtheme.themeid") String themeId,
+ @Optional ThemeManager themeManager) {
+ if (themeManager != null) {
+ themeManager.setCurrentThemeId(themeId);
+ }
+ }
+}
\ No newline at end of file
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/UndoHandler.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/UndoHandler.java
new file mode 100755
index 000000000..07f1deb52
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/handlers/UndoHandler.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Siemens AG and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Kai T??dter - initial implementation
+ ******************************************************************************/
+
+package org.eclipse.fx.demo.contacts.handlers;
+
+
+import javax.inject.Inject;
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.fx.demo.contacts.model.ContactsManager;
+
+@SuppressWarnings("restriction")
+public class UndoHandler {
+
+ @Inject
+ ContactsManager contactsManager;
+
+ @CanExecute
+ public boolean canUndo() {
+ CommandStack commandStack = contactsManager.getEditingDomain().getCommandStack();
+ return commandStack.canUndo();
+ }
+
+ @Execute
+ public void undo() {
+ CommandStack commandStack = contactsManager.getEditingDomain().getCommandStack();
+ if (commandStack.canUndo())
+ commandStack.undo();
+ }
+
+}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/model/ContactsManager.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/model/ContactsManager.java
new file mode 100755
index 000000000..377d1491b
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/model/ContactsManager.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2012 TESIS DYNAware GmbH and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Torsten Sommer - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.fx.demo.contacts.model;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.fx.demo.contacts.Group;
+
+public interface ContactsManager {
+
+ Group getRootGroup();
+
+ AdapterFactory getAdapterFactory();
+
+ EditingDomain getEditingDomain();
+
+}
\ No newline at end of file
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/model/ContactsManagerImpl.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/model/ContactsManagerImpl.java
new file mode 100755
index 000000000..425e9be6b
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/model/ContactsManagerImpl.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2012 TESIS DYNAware GmbH and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Torsten Sommer - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.fx.demo.contacts.model;
+
+
+import org.eclipse.emf.common.command.BasicCommandStack;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
+import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
+import org.eclipse.fx.demo.contacts.Group;
+import org.eclipse.fx.demo.contacts.provider.ContactsItemProviderAdapterFactory;
+
+public class ContactsManagerImpl implements ContactsManager {
+
+ protected EditingDomain editingDomain;
+ protected VCardContactsResource contactsResource;
+ protected ComposedAdapterFactory adapterFactory;
+
+ public ContactsManagerImpl() {
+ adapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
+ adapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory());
+ adapterFactory.addAdapterFactory(new ContactsItemProviderAdapterFactory());
+ adapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory());
+
+ contactsResource = new VCardContactsResource();
+ BasicCommandStack commandStack = new BasicCommandStack();
+ editingDomain = new AdapterFactoryEditingDomain(adapterFactory, commandStack);
+ editingDomain.getResourceSet().getResources().add(contactsResource);
+ }
+
+ public AdapterFactory getAdapterFactory() {
+ return adapterFactory;
+ }
+
+ public EditingDomain getEditingDomain() {
+ return editingDomain;
+ }
+
+ @Override
+ public Group getRootGroup() {
+ return (Group) contactsResource.getContents().get(0);
+ }
+
+}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/model/VCardContactsResource.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/model/VCardContactsResource.java
new file mode 100755
index 000000000..2f729f693
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/model/VCardContactsResource.java
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Siemens AG and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Kai T????dter - initial implementation
+ ******************************************************************************/
+
+package org.eclipse.fx.demo.contacts.model;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Enumeration;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
+import org.eclipse.fx.demo.contacts.BundleActivatorImpl;
+import org.eclipse.fx.demo.contacts.Contact;
+import org.eclipse.fx.demo.contacts.ContactsFactory;
+import org.eclipse.fx.demo.contacts.Group;
+import org.osgi.framework.Bundle;
+
+
+public class VCardContactsResource extends ResourceImpl {
+
+ public VCardContactsResource() {
+ super(URI.createPlatformResourceURI("org.eclipse.fx.demo.contacts/vcards", false));
+
+ try {
+ Group rootGroup = ContactsFactory.eINSTANCE.createGroup();
+ for (File file : getContacts()) {
+ Contact contact = readFromVCard(file.getAbsolutePath());
+ rootGroup.getContacts().add(contact);
+ }
+ getContents().add(rootGroup);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private File[] getContacts() throws Exception {
+ File[] localContacts = getLocalContacts();
+ if (localContacts.length == 0) {
+ IPath path = BundleActivatorImpl.getInstance().getStateLocation();
+ byte[] buffer = new byte[8192];
+ Bundle bundle = Platform.getBundle("org.eclipse.fx.demo.contacts.app"); //$NON-NLS-1$
+
+ for (Enumeration> contacts = getStoredContacts(); contacts.hasMoreElements();) {
+ String bundlePath = (String) contacts.nextElement();
+ if (!bundlePath.endsWith(".vcf")) { //$NON-NLS-1$
+ continue;
+ }
+
+ InputStream inputStream = FileLocator.openStream(bundle, new Path(bundlePath), false);
+ FileOutputStream outputStream = new FileOutputStream(path.append(
+ bundlePath.substring(bundlePath.indexOf('/') + 1)).toFile());
+
+ int read = inputStream.read(buffer);
+ while (read != -1) {
+ outputStream.write(buffer, 0, read);
+ read = inputStream.read(buffer);
+ }
+
+ inputStream.close();
+ outputStream.close();
+ }
+
+ return getLocalContacts();
+ }
+ return localContacts;
+ }
+
+ private File[] getLocalContacts() {
+ IPath path = BundleActivatorImpl.getInstance().getStateLocation();
+ File directory = path.toFile();
+ return directory.listFiles(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.endsWith(".vcf"); //$NON-NLS-1$
+ }
+ });
+ }
+
+ private Enumeration> getStoredContacts() throws Exception {
+ Bundle bundle = Platform.getBundle("org.eclipse.fx.demo.contacts.app"); //$NON-NLS-1$
+ return bundle.getEntryPaths("vcards"); //$NON-NLS-1$
+ }
+
+ /**
+ * Reads a Contact from a VCard. This method cannot parse a generic VCard,
+ * but can only parse VCards created with Microsoft Outlook. The intention
+ * is not to provide a generic VCard reader but an easy way to get contact
+ * data (including pictures) in the repository.
+ *
+ * @param fileName
+ * the vcard file
+ * @return the created Contact
+ */
+ public Contact readFromVCard(String fileName) {
+ Contact contact = ContactsFactory.eINSTANCE.createContact();
+ contact.setSourceFile(fileName);
+ BufferedReader bufferedReader = null;
+ String charSet = "Cp1252";
+
+ /*
+ * first try to guess the char set (currently not working under some
+ * JVMs
+ */
+
+ /*
+ * try { bufferedReader = new BufferedReader(new InputStreamReader( new
+ * FileInputStream(fileName))); String line; while ((line =
+ * bufferedReader.readLine()) != null) { int index =
+ * line.indexOf("CHARSET="); if (index != -1) { int endIndex = index +
+ * 8; while (line.charAt(endIndex) != ':' && line.charAt(endIndex) !=
+ * ';') { endIndex += 1; } charSet = line.substring(index + 8,
+ * endIndex); break; } } } catch (FileNotFoundException e) { // TODO
+ * Auto-generated catch block e.printStackTrace();
+ *
+ * } catch (IOException e) { // TODO Auto-generated catch block
+ * e.printStackTrace(); } finally { try { if (bufferedReader != null) {
+ * bufferedReader.close(); } } catch (IOException e) { // TODO
+ * Auto-generated catch block e.printStackTrace(); } }
+ */
+
+ // Then parse the vCard
+ try {
+ InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(fileName), charSet);
+ bufferedReader = new BufferedReader(inputStreamReader);
+ String line;
+ String value;
+ while ((line = bufferedReader.readLine()) != null) {
+ value = getVCardValue(line, "N");
+ if (value != null) {
+ String[] result = value.split(";");
+
+ if (result.length > 0) {
+ contact.setLastName(result[0]);
+ }
+ if (result.length > 1) {
+ contact.setFirstName(result[1]);
+ }
+ if (result.length > 2) {
+ contact.setMiddleName(result[2]);
+ }
+ if (result.length > 3) {
+ contact.setTitle(result[3]);
+ }
+ continue;
+ }
+ value = getVCardValue(line, "TEL;WORK");
+ if (value != null) {
+ contact.setPhone(value);
+ continue;
+ }
+ value = getVCardValue(line, "TEL;CELL");
+ if (value != null) {
+ contact.setMobile(value);
+ continue;
+ }
+ value = getVCardValue(line, "ADR;WORK");
+ if (value != null) {
+ String[] result = value.split(";");
+
+ if (result.length > 2) {
+ contact.setStreet(result[2]);
+ }
+ if (result.length > 3) {
+ contact.setCity(result[3]);
+ }
+ if (result.length > 4) {
+ contact.setState(result[4]);
+ }
+ if (result.length > 5) {
+ contact.setZip(result[5]);
+ }
+ if (result.length > 6) {
+ contact.setCountry(result[6]);
+ }
+ continue;
+ }
+ value = getVCardValue(line, "EMAIL;PREF;INTERNET");
+ if (value != null) {
+ contact.setEmail(value);
+ continue;
+ }
+ value = getVCardValue(line, "URL;WORK");
+ if (value != null) {
+ contact.setWebPage(value);
+ continue;
+ }
+ value = getVCardValue(line, "ORG");
+ if (value != null) {
+ contact.setCompany(value);
+ continue;
+ }
+ value = getVCardValue(line, "TITLE");
+ if (value != null) {
+ contact.setJobTitle(value);
+ continue;
+ }
+ value = getVCardValue(line, "NOTE");
+ if (value != null) {
+ contact.setNote(value);
+ continue;
+ }
+ value = getVCardValue(line, "PHOTO;TYPE=JPEG;ENCODING=BASE64");
+ if (value != null) {
+ line = bufferedReader.readLine();
+ StringBuilder builder = new StringBuilder();
+ while (line != null && line.length() > 0 && line.charAt(0) == ' ') {
+ builder.append(line.trim());
+ line = bufferedReader.readLine();
+ }
+ String jpegString = builder.toString();
+
+ contact.setJpegString(jpegString);
+ continue;
+ }
+ }
+ } catch (FileNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } finally {
+ try {
+ if (bufferedReader != null) {
+ bufferedReader.close();
+ }
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ return contact;
+ }
+
+ private String getVCardValue(String line, String token) {
+ if (line.startsWith(token + ":") || line.startsWith(token + ";")) {
+ String value = line.substring(line.indexOf(":") + 1);
+ return value;
+ }
+ return null;
+ }
+
+}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/processors/AbstractThemeProcessor.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/processors/AbstractThemeProcessor.java
new file mode 100755
index 000000000..4d0595526
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/processors/AbstractThemeProcessor.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at, Siemens AG and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tom Schindl - initial API and implementation
+ * Kai T��dter - Adoption to contacts demo
+ ******************************************************************************/
+package org.eclipse.fx.demo.contacts.processors;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.RegistryFactory;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.commands.MCommand;
+import org.eclipse.e4.ui.model.application.commands.MCommandsFactory;
+import org.eclipse.e4.ui.model.application.commands.MParameter;
+import org.eclipse.fx.ui.services.theme.Theme;
+import org.eclipse.fx.ui.services.theme.ThemeManager;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+
+@SuppressWarnings("restriction")
+public abstract class AbstractThemeProcessor {
+
+ @Execute
+ public void process() {
+ if (!check()) {
+ return;
+ }
+
+ // FIXME Remove once bug 314091 is resolved
+ Bundle bundle = FrameworkUtil.getBundle(getClass());
+ BundleContext context = bundle.getBundleContext();
+
+ ServiceReference reference = context.getServiceReference(ThemeManager.class.getName());
+ ThemeManager themeManager = (ThemeManager) context.getService(reference);
+
+ List themes = themeManager.getAvailableThemes();
+ if (themes.size() > 0) {
+ MApplication application = getApplication();
+
+ MCommand switchThemeCommand = null;
+ for (MCommand cmd : application.getCommands()) {
+ if ("contacts.switchTheme".equals(cmd.getElementId())) { //$NON-NLS-1$
+ switchThemeCommand = cmd;
+ break;
+ }
+ }
+
+ if (switchThemeCommand != null) {
+
+ preprocess();
+
+ for (Theme theme : themes) {
+ MParameter parameter = MCommandsFactory.INSTANCE.createParameter();
+ parameter.setName("contacts.commands.switchtheme.themeid"); //$NON-NLS-1$
+ parameter.setValue(theme.getId());
+ String iconURI = getCSSUri(theme.getId());
+ if (iconURI != null) {
+ iconURI = iconURI.replace(".css", ".png");
+ }
+ processTheme(theme.getName(), switchThemeCommand, parameter, iconURI);
+ }
+
+ postprocess();
+ }
+ }
+ }
+
+ abstract protected boolean check();
+
+ abstract protected void preprocess();
+
+ abstract protected void processTheme(String name, MCommand switchCommand, MParameter themeId, String iconURI);
+
+ abstract protected void postprocess();
+
+ abstract protected MApplication getApplication();
+
+ private String getCSSUri(String themeId) {
+ IExtensionRegistry registry = RegistryFactory.getRegistry();
+ IExtensionPoint extPoint = registry.getExtensionPoint("org.eclipse.fx.ui.theme");
+
+ for (IExtension e : extPoint.getExtensions()) {
+ for (IConfigurationElement ce : e.getConfigurationElements()) {
+ if (ce.getName().equals("theme") && ce.getAttribute("id").equals(themeId)) {
+ return "platform:/plugin/" + ce.getContributor().getName() + "/"
+ + ce.getAttribute("basestylesheet");
+ }
+ }
+ }
+ return null;
+ }
+
+ protected boolean isAreadyProcessed(String processorId) {
+ MApplication application = getApplication();
+ List tags = application.getTags();
+ for (String tag : tags) {
+ if (processorId.equals(tag)) {
+ return true; // already processed
+ }
+ }
+ tags.add(processorId);
+ return false;
+ }
+
+}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/processors/MenuThemeProcessor.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/processors/MenuThemeProcessor.java
new file mode 100755
index 000000000..dd48d12b9
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/processors/MenuThemeProcessor.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BestSolution.at, Siemens AG and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tom Schindl - initial API and implementation
+ * Kai T??dter - Adoption to contacts demo
+ ******************************************************************************/
+package org.eclipse.fx.demo.contacts.processors;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.commands.MCommand;
+import org.eclipse.e4.ui.model.application.commands.MParameter;
+import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenuFactory;
+import org.eclipse.emf.ecore.EObject;
+
+public class MenuThemeProcessor extends AbstractThemeProcessor {
+
+ private static final String BUNDLE_ID = "platform:/plugin/org.eclipse.fx.demo.contacts.app"; //$NON-NLS-1$
+ private final static String PROCESSOR_ID = "org.eclipse.fx.demo.contacts.processors.theme.menu";
+
+ @Inject
+ @Named("menu:org.eclipse.ui.main.menu")
+ private MMenu menu;
+ private MMenu themesMenu;
+
+ @Override
+ protected boolean check() {
+ if (isAreadyProcessed(PROCESSOR_ID)) {
+ return false;
+ }
+ return menu != null;
+ }
+
+ @Override
+ protected void preprocess() {
+ themesMenu = MMenuFactory.INSTANCE.createMenu();
+ themesMenu.setLabel("%switchThemeMenu"); //$NON-NLS-1$
+ themesMenu.setContributorURI(BUNDLE_ID);
+ }
+
+ @Override
+ protected void processTheme(String name, MCommand switchCommand, MParameter themeId, String iconURI) {
+ MHandledMenuItem menuItem = MMenuFactory.INSTANCE.createHandledMenuItem();
+ menuItem.setLabel(name);
+ menuItem.setCommand(switchCommand);
+ menuItem.getParameters().add(themeId);
+ menuItem.setContributorURI(BUNDLE_ID);
+ if (iconURI != null) {
+ menuItem.setIconURI(iconURI);
+ }
+ themesMenu.getChildren().add(menuItem);
+ }
+
+ @Override
+ protected void postprocess() {
+ menu.getChildren().add(themesMenu);
+ }
+
+ @Override
+ protected MApplication getApplication() {
+ return (MApplication) (((EObject) menu).eContainer()).eContainer();
+ }
+}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/processors/ToolbarThemeProcessor.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/processors/ToolbarThemeProcessor.java
new file mode 100755
index 000000000..e23a9c3de
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/processors/ToolbarThemeProcessor.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Siemens AG and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Contributors:
+ * Kai T??dter - initial implementation
+ ******************************************************************************/
+
+package org.eclipse.fx.demo.contacts.processors;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.commands.MCommand;
+import org.eclipse.e4.ui.model.application.commands.MParameter;
+import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar;
+import org.eclipse.e4.ui.model.application.ui.menu.MHandledToolItem;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenuFactory;
+import org.eclipse.e4.ui.model.application.ui.menu.MToolBar;
+import org.eclipse.emf.ecore.EObject;
+
+@SuppressWarnings("restriction")
+public class ToolbarThemeProcessor extends AbstractThemeProcessor {
+
+ private final static String PROCESSOR_ID = "org.eclipse.fx.demo.contacts.processors.theme.toolbar";
+
+ @Inject
+ @Named("toolbar:org.eclipse.ui.main.toolbar")
+ private MTrimBar topBar;
+ private MToolBar toolBar;
+
+ @Override
+ protected boolean check() {
+ if (isAreadyProcessed(PROCESSOR_ID)) {
+ return false;
+ }
+ return topBar != null;
+ }
+
+ @Override
+ protected void preprocess() {
+ toolBar = MMenuFactory.INSTANCE.createToolBar();
+ topBar.getChildren().add(toolBar);
+ }
+
+ @Override
+ protected void processTheme(String name, MCommand switchCommand, MParameter themeId, String iconURI) {
+ MHandledToolItem toolItem = MMenuFactory.INSTANCE.createHandledToolItem();
+ toolItem.setTooltip(name);
+ toolItem.setCommand(switchCommand);
+ toolItem.getParameters().add(themeId);
+ if (iconURI != null) {
+ toolItem.setIconURI(iconURI);
+ }
+ toolBar.getChildren().add(toolItem);
+ }
+
+ @Override
+ protected void postprocess() {
+ }
+
+ @Override
+ protected MApplication getApplication() {
+ return (MApplication) (((EObject) topBar).eContainer()).eContainer();
+ }
+}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/views/ContactsListView.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/views/ContactsListView.java
new file mode 100755
index 000000000..491661da0
--- /dev/null
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/views/ContactsListView.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2012 TESIS DYNAware GmbH and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Torsten Sommer - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.fx.demo.contacts.views;
+
+import java.util.List;
+
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.ListChangeListener;
+import javafx.scene.control.ListView;
+import javafx.scene.control.SelectionMode;
+import javafx.scene.layout.BorderPane;
+
+import javax.inject.Inject;
+
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.fx.demo.contacts.ContactsPackage;
+import org.eclipse.fx.demo.contacts.model.ContactsManager;
+import org.eclipse.fx.emf.edit.ui.AdapterFactoryListCellFactory;
+import org.eclipse.fx.emf.edit.ui.AdapterFactoryObservableList;
+import org.eclipse.fx.emf.edit.ui.EAttributeCellEditHandler;
+import org.eclipse.fx.emf.edit.ui.dnd.CellDragAdapter;
+import org.eclipse.fx.emf.edit.ui.dnd.EditingDomainCellDropAdapter;
+
+
+@SuppressWarnings("restriction")
+public class ContactsListView {
+
+ @Inject
+ public ContactsListView(BorderPane parent, final MApplication application, final ContactsManager contactsManager) {
+ EditingDomain editingDomain = contactsManager.getEditingDomain();
+ AdapterFactory adapterFactory = contactsManager.getAdapterFactory();
+
+ ListView