Bug 330938 - Merge Eclipse Incubator with e4
Proovide the converted platform incubator repo
Merge remote branch 'inc/master'
Conflicts:
.gitignore
diff --git a/bundles/org.eclipse.e4.core.javascript/.classpath b/bundles/org.eclipse.e4.core.javascript/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.javascript/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.core.javascript/.project b/bundles/org.eclipse.e4.core.javascript/.project
new file mode 100644
index 0000000..4a3a255
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.javascript/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.core.javascript</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.core.javascript/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.core.javascript/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..46c764e
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.javascript/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Wed Nov 26 21:57:11 EST 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/bundles/org.eclipse.e4.core.javascript/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.core.javascript/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..36749d6
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.javascript/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Javascript Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.core.javascript;singleton:=true
+Bundle-Version: 0.9.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.core.services;bundle-version="0.9.0",
+ org.eclipse.core.runtime;bundle-version="3.4.0",
+ org.mozilla.javascript;bundle-version="1.6.6",
+ org.eclipse.e4.core.contexts,
+ org.eclipse.e4.core.di
+Bundle-Vendor: Eclipse.org
diff --git a/bundles/org.eclipse.e4.core.javascript/build.properties b/bundles/org.eclipse.e4.core.javascript/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.javascript/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml
diff --git a/bundles/org.eclipse.e4.core.javascript/plugin.xml b/bundles/org.eclipse.e4.core.javascript/plugin.xml
new file mode 100644
index 0000000..f333964
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.javascript/plugin.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+ <extension
+ point="org.eclipse.e4.languages">
+ <language
+ contributionFactory="org.eclipse.e4.demo.javascript.JSContributionFactory"
+ name="js">
+ </language>
+ </extension>
+</plugin>
diff --git a/bundles/org.eclipse.e4.core.javascript/src/org/eclipse/e4/demo/javascript/JSContributionFactory.java b/bundles/org.eclipse.e4.core.javascript/src/org/eclipse/e4/demo/javascript/JSContributionFactory.java
new file mode 100644
index 0000000..d3a5430
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.javascript/src/org/eclipse/e4/demo/javascript/JSContributionFactory.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 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.e4.demo.javascript;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.WeakHashMap;
+
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.core.services.contributions.IContributionFactorySpi;
+import org.mozilla.javascript.Scriptable;
+import org.osgi.framework.Bundle;
+
+public class JSContributionFactory implements IContributionFactorySpi {
+
+ private JSUtil js;
+ private WeakHashMap contributionDatas = new WeakHashMap();
+
+ public JSContributionFactory() {
+ js = new JSUtil();
+ }
+
+ private static class ContributionWrapper {
+ Object contribution;
+
+ public ContributionWrapper(Object c) {
+ contribution = c;
+ }
+ }
+
+ private static class ContributionData {
+ Bundle bundle;
+ String name;
+ String script;
+ IEclipseContext context;
+
+ private Object updateContribution(JSUtil js, Object contribution) {
+ InputStream stream;
+ try {
+ stream = bundle.getResource(name).openStream();
+ String newScript = readString(stream);
+ if (script != null && script.equals(newScript)) {
+ return contribution;
+ }
+ script = newScript;
+ contribution = js.eval(script);
+ Object initargs = js.get(contribution, "initargs");
+ if (initargs instanceof Scriptable) {
+ int len = js.length(initargs);
+ Object[] args = new Object[len];
+ for (int i = 0; i < len; i++) {
+ args[i] = context.get((String) js.get(initargs, i));
+ }
+ js.call(js.get(contribution, "init"), contribution, args);
+ }
+ return contribution;
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ }
+
+ private static String readString(InputStream is) throws IOException {
+ StringBuffer result = new StringBuffer();
+ BufferedInputStream bis = new BufferedInputStream(is);
+ int ch;
+ while ((ch = bis.read()) != -1) {
+ result.append((char) ch);
+ }
+ bis.close();
+ return result.toString();
+ }
+
+ public Object create(Bundle bundle, String name,
+ IEclipseContext context) {
+ ContributionData cd = new ContributionData();
+ cd.bundle = bundle;
+ cd.name = name;
+ cd.context = context;
+ Object result = cd.updateContribution(js, null);
+ ContributionWrapper wrapper = new ContributionWrapper(result);
+ contributionDatas.put(wrapper, cd);
+ return wrapper;
+ }
+
+ public Object call(Object o, String methodName,
+ IEclipseContext context, Object defaultValue) {
+ ContributionWrapper wrapper = (ContributionWrapper) o;
+ ContributionData cd = (ContributionData) contributionDatas.get(wrapper);
+ wrapper.contribution = cd.updateContribution(js, wrapper.contribution);
+ Object runargs = js.get(wrapper.contribution, methodName + "args");
+ int len = js.length(runargs);
+ Object[] args = new Object[len];
+ for (int i = 0; i < len; i++) {
+ args[i] = context.get((String) js.get(runargs, i));
+ }
+ Object function = js.get(wrapper.contribution, methodName);
+
+ if (function== null || !(function instanceof Scriptable)) {
+ if (defaultValue != null) {
+ return defaultValue;
+ }
+ throw new RuntimeException(
+ "could not find function " + methodName + " in " + cd.name); //$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ Object result = js.call(function,
+ wrapper.contribution, args);
+ return result;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.core.javascript/src/org/eclipse/e4/demo/javascript/JSUtil.java b/bundles/org.eclipse.e4.core.javascript/src/org/eclipse/e4/demo/javascript/JSUtil.java
new file mode 100644
index 0000000..6ac9e68
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.javascript/src/org/eclipse/e4/demo/javascript/JSUtil.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 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.e4.demo.javascript;
+
+import org.mozilla.javascript.*;
+
+public class JSUtil {
+
+ private Context jsContext;
+ private ImporterTopLevel jsScope;
+
+ public JSUtil() {
+ jsContext = Context.enter();
+ jsScope = new ImporterTopLevel(jsContext);
+ }
+
+ public Object eval(String js) {
+ Object result = jsContext.evaluateString(jsScope, "[" + js + "][0]", "eval", 0, null); //$NON-NLS-1$
+ return result;
+ }
+
+ public Object get(Object jsObject, String attribute) {
+ if (jsObject instanceof Scriptable) {
+ return ((Scriptable) jsObject).get(attribute,
+ (IdScriptableObject) jsObject);
+ }
+ return null;
+ }
+
+ public Object get(Object jsArray, int index) {
+ return ((IdScriptableObject) jsArray).get(index,
+ (IdScriptableObject) jsArray);
+ }
+
+ public int length(Object jsArray) {
+ Number number = (Number) get(jsArray, "length");
+ return number == null ? 0 : number.intValue();
+ }
+
+ public Object call(Object jsFunction, Object jsThis, Object[] args) {
+ return ((BaseFunction) jsFunction).call(jsContext, jsScope,
+ (Scriptable) jsThis, args);
+ }
+
+ static class Foo {
+ public int incremented(int i) {
+ return i + 1;
+ }
+ }
+
+ public static void main(String[] a) {
+ JSUtil js = new JSUtil();
+ Object result = js
+ .eval("{args:['foo','bar'], f:function(foo, x){return foo.incremented(x);}}");
+ System.out.println(result);
+ Object args = js.get(result, "args");
+ System.out.println(args);
+ System.out.println("length: " + js.length(args));
+ Object function = js.get(result, "f");
+ System.out.println(function);
+ System.out.println(js.get(args, 0));
+ System.out.println(js.get(args, 1));
+ Object fResult = js.call(function, null, new Object[] { new Foo(), 6 });
+ System.out.println(fResult);
+ }
+}
diff --git a/bundles/org.eclipse.e4.pde.ui/.classpath b/bundles/org.eclipse.e4.pde.ui/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.pde.ui/.project b/bundles/org.eclipse.e4.pde.ui/.project
new file mode 100644
index 0000000..9146e5a
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.pde.ui</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.pde.ui/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.pde.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..a3b5e6a
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Thu Jul 09 14:42:57 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/bundles/org.eclipse.e4.pde.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.pde.ui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e22a830
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: e4 PDE UI (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.pde.ui;singleton:=true
+Bundle-Version: 0.9.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.pde.webui;bundle-version="0.9.0",
+ org.eclipse.ui;bundle-version="3.5.0",
+ org.eclipse.equinox.common;bundle-version="3.5.0",
+ org.eclipse.equinox.registry;bundle-version="3.4.100",
+ org.eclipse.ui.ide;bundle-version="3.5.0",
+ org.eclipse.core.resources;bundle-version="3.5.0",
+ org.eclipse.e4.ui.web;bundle-version="0.9.0"
+Bundle-Vendor: Eclipse.org
diff --git a/bundles/org.eclipse.e4.pde.ui/build.properties b/bundles/org.eclipse.e4.pde.ui/build.properties
new file mode 100644
index 0000000..6c480f3
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.ui/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ icons/
diff --git a/bundles/org.eclipse.e4.pde.ui/icons/obj16/site_xml_obj.gif b/bundles/org.eclipse.e4.pde.ui/icons/obj16/site_xml_obj.gif
new file mode 100644
index 0000000..35ff8c1
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.ui/icons/obj16/site_xml_obj.gif
Binary files differ
diff --git a/bundles/org.eclipse.e4.pde.ui/plugin.xml b/bundles/org.eclipse.e4.pde.ui/plugin.xml
new file mode 100644
index 0000000..c29e853
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.ui/plugin.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.ui.editors">
+ <editor
+ class="org.eclipse.e4.pde.internal.ui.BrowserSiteEditor"
+ default="false"
+ icon="icons/obj16/site_xml_obj.gif"
+ id="org.eclipse.e4.pde.ui.siteEditor"
+ name="Site Manifest Editor (web ui-based)">
+ <contentTypeBinding contentTypeId="org.eclipse.pde.siteManifest"/>
+ </editor>
+ </extension>
+
+</plugin>
diff --git a/bundles/org.eclipse.e4.pde.ui/src/org/eclipse/e4/pde/internal/ui/BrowserSiteEditor.java b/bundles/org.eclipse.e4.pde.ui/src/org/eclipse/e4/pde/internal/ui/BrowserSiteEditor.java
new file mode 100644
index 0000000..ab3d9bc
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.ui/src/org/eclipse/e4/pde/internal/ui/BrowserSiteEditor.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.pde.internal.ui;
+
+import org.eclipse.e4.pde.internal.webui.Activator;
+import org.eclipse.e4.pde.internal.webui.PDEServlet;
+import org.eclipse.e4.ui.web.BrowserEditorPart;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.WindowEvent;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.PartInitException;
+
+public class BrowserSiteEditor extends BrowserEditorPart {
+
+ public BrowserSiteEditor() {
+ }
+
+ public void init(IEditorSite site, IEditorInput input)
+ throws PartInitException {
+ setSite(site);
+ setInput(input);
+ }
+
+ protected void configureBrowser(Browser b) {
+ Browser.setCookie("org.eclipse.e4.pde.auth="
+ + PDEServlet.getSessionId(), "http://localhost");
+ b
+ .setUrl("http://localhost:"
+ + Activator.PORT
+ + "/tree.html#"
+ + ((IFileEditorInput) getEditorInput()).getFile()
+ .getFullPath());
+ }
+
+ protected IEditorInput getNewWindowEditorInput(WindowEvent event) {
+ return null;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.pde.webui/.classpath b/bundles/org.eclipse.e4.pde.webui/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.pde.webui/.project b/bundles/org.eclipse.e4.pde.webui/.project
new file mode 100644
index 0000000..5644051
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.pde.webui</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.pde.webui/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.pde.webui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..a3b5e6a
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Thu Jul 09 14:42:57 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/bundles/org.eclipse.e4.pde.webui/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.pde.webui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..a02a109
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/META-INF/MANIFEST.MF
@@ -0,0 +1,22 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: PDE web ui (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.pde.webui
+Bundle-Version: 0.9.0.qualifier
+Bundle-Activator: org.eclipse.e4.pde.internal.webui.Activator
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Import-Package: org.eclipse.equinox.http.jetty;version="1.1.0",
+ org.osgi.service.http;version="1.2.1"
+Require-Bundle: org.eclipse.equinox.common;bundle-version="3.5.0",
+ org.eclipse.osgi;bundle-version="3.5.0",
+ javax.servlet;bundle-version="2.5.0",
+ org.eclipse.core.resources;bundle-version="3.5.0",
+ org.eclipse.equinox.preferences;bundle-version="3.2.300",
+ org.eclipse.core.jobs;bundle-version="3.4.100",
+ org.eclipse.pde.core;bundle-version="3.5.0",
+ org.eclipse.emf.ecore;bundle-version="2.5.0",
+ org.eclipse.emf.ecore.xmi;bundle-version="2.5.0",
+ org.dojotoolkit;bundle-version="1.1.0"
+Export-Package: org.eclipse.e4.pde.internal.webui;x-internal:=true
+Bundle-Vendor: Eclipse.org
diff --git a/bundles/org.eclipse.e4.pde.webui/build.properties b/bundles/org.eclipse.e4.pde.webui/build.properties
new file mode 100644
index 0000000..140c6e3
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ static/,\
+ model/Site.ecore
diff --git a/bundles/org.eclipse.e4.pde.webui/model/Site.ecore b/bundles/org.eclipse.e4.pde.webui/model/Site.ecore
new file mode 100644
index 0000000..c951a57
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/model/Site.ecore
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="site"
+ nsURI="platform:/plugin/org.eclipse.e4.pde.site.model/site.xsd" nsPrefix="org.eclipse.e4.pde.site">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="qualified" value="false"/>
+ </eAnnotations>
+ <eClassifiers xsi:type="ecore:EClass" name="CategoryDef">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="CategoryDef"/>
+ <details key="kind" value="elementOnly"/>
+ </eAnnotations>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" lowerBound="1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="description"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="label"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="name"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="CategoryType">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="category_._type"/>
+ <details key="kind" value="empty"/>
+ </eAnnotations>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="name"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Description">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="Description"/>
+ <details key="kind" value="simple"/>
+ </eAnnotations>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value=":0"/>
+ <details key="kind" value="simple"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="url" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnyURI">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="url"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="DocumentRoot">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value=""/>
+ <details key="kind" value="mixed"/>
+ </eAnnotations>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="mixed" unique="false" upperBound="-1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFeatureMapEntry">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="elementWildcard"/>
+ <details key="name" value=":mixed"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="xMLNSPrefixMap" upperBound="-1"
+ eType="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EStringToStringMapEntry"
+ transient="true" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="xmlns:prefix"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="xSISchemaLocation" upperBound="-1"
+ eType="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EStringToStringMapEntry"
+ transient="true" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="xsi:schemaLocation"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="site" upperBound="-2" eType="#//Site"
+ volatile="true" transient="true" derived="true" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="site"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Feature">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="Feature"/>
+ <details key="kind" value="elementOnly"/>
+ </eAnnotations>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="category" eType="#//CategoryType"
+ containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="category"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="id"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="url" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnyURI">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="url"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" eType="ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="attribute"/>
+ <details key="name" value="version"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Site">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="name" value="Site"/>
+ <details key="kind" value="elementOnly"/>
+ </eAnnotations>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="description" lowerBound="1"
+ eType="#//Description" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="description"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="feature" upperBound="-1"
+ eType="#//Feature" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="feature"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="categoryDef" upperBound="-1"
+ eType="#//CategoryDef" containment="true" resolveProxies="false">
+ <eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
+ <details key="kind" value="element"/>
+ <details key="name" value="category-def"/>
+ <details key="namespace" value="##targetNamespace"/>
+ </eAnnotations>
+ </eStructuralFeatures>
+ </eClassifiers>
+</ecore:EPackage>
diff --git a/bundles/org.eclipse.e4.pde.webui/model/site.genmodel b/bundles/org.eclipse.e4.pde.webui/model/site.genmodel
new file mode 100644
index 0000000..77c2494
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/model/site.genmodel
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<genmodel:GenModel xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+ xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.eclipse.e4.pde.site.model/src"
+ modelPluginID="org.eclipse.e4.pde.site.model" modelName="Site" importerID="org.eclipse.xsd.ecore.importer"
+ complianceLevel="6.0" copyrightFields="false">
+ <foreignModel>../site.xsd</foreignModel>
+ <genPackages prefix="site" basePackage="org.eclipse.e4.pde" resource="XML" disposableProviderFactory="true"
+ ecorePackage="Site.ecore#/">
+ <genClasses ecoreClass="Site.ecore#//CategoryDef">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//CategoryDef/description"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//CategoryDef/label"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//CategoryDef/name"/>
+ </genClasses>
+ <genClasses ecoreClass="Site.ecore#//CategoryType">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//CategoryType/name"/>
+ </genClasses>
+ <genClasses ecoreClass="Site.ecore#//Description">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//Description/value"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//Description/url"/>
+ </genClasses>
+ <genClasses ecoreClass="Site.ecore#//DocumentRoot">
+ <genFeatures property="None" notify="false" createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//DocumentRoot/mixed"/>
+ <genFeatures property="None" notify="false" createChild="false" ecoreFeature="ecore:EReference Site.ecore#//DocumentRoot/xMLNSPrefixMap"/>
+ <genFeatures property="None" notify="false" createChild="false" ecoreFeature="ecore:EReference Site.ecore#//DocumentRoot/xSISchemaLocation"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Site.ecore#//DocumentRoot/site"/>
+ </genClasses>
+ <genClasses ecoreClass="Site.ecore#//Feature">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Site.ecore#//Feature/category"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//Feature/id"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//Feature/url"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Site.ecore#//Feature/version"/>
+ </genClasses>
+ <genClasses ecoreClass="Site.ecore#//Site">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Site.ecore#//Site/description"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Site.ecore#//Site/feature"/>
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Site.ecore#//Site/categoryDef"/>
+ </genClasses>
+ </genPackages>
+</genmodel:GenModel>
diff --git a/bundles/org.eclipse.e4.pde.webui/model/site.xsd b/bundles/org.eclipse.e4.pde.webui/model/site.xsd
new file mode 100644
index 0000000..725cc75
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/model/site.xsd
@@ -0,0 +1,45 @@
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:element name="site" type="Site" />
+
+ <xsd:complexType name="Site">
+ <xsd:sequence>
+ <xsd:element name="description" type="Description" />
+ <xsd:element name="feature" minOccurs="0" maxOccurs="unbounded"
+ type="Feature" />
+ <xsd:element name="category-def" minOccurs="0" maxOccurs="unbounded"
+ type="CategoryDef" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="Description">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="url" type="xsd:anyURI" />
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="Feature">
+ <xsd:sequence>
+ <xsd:element name="category" minOccurs="0">
+ <xsd:complexType>
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:attribute name="url" type="xsd:anyURI" />
+ <xsd:attribute name="id" type="xsd:string" />
+ <xsd:attribute name="version" type="xsd:string" />
+ </xsd:complexType>
+
+ <xsd:complexType name="CategoryDef">
+ <xsd:sequence>
+ <xsd:element name="description" minOccurs="1" maxOccurs="1"
+ type="xsd:string" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="label" type="xsd:string" />
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/bundles/org.eclipse.e4.pde.webui/model/site.xsd2ecore b/bundles/org.eclipse.e4.pde.webui/model/site.xsd2ecore
new file mode 100644
index 0000000..0a82b27
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/model/site.xsd2ecore
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="ASCII"?>
+<xsd2ecore:XSD2EcoreMappingRoot xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:xsd2ecore="http://www.eclipse.org/emf/2002/XSD2Ecore" inputs="../site.xsd#/"
+ outputs="Site.ecore#/" topToBottom="true">
+ <nested inputs="bundleentry://623.fwk9489155/cache/www.w3.org/2001/XMLSchema.xsd#//string;XSDSimpleTypeDefinition=9"
+ outputs="http://www.eclipse.org/emf/2003/XMLType#//String"/>
+ <nested inputs="bundleentry://623.fwk9489155/cache/www.w3.org/2001/XMLSchema.xsd#//anyURI;XSDSimpleTypeDefinition=25"
+ outputs="http://www.eclipse.org/emf/2003/XMLType#//AnyURI"/>
+ <nested inputs="../site.xsd#//Description;XSDComplexTypeDefinition=1" outputs="Site.ecore#//Description">
+ <nested inputs="../site.xsd#//Description;XSDComplexTypeDefinition=1/XSDAttributeUse"
+ outputs="Site.ecore#//Description/url"/>
+ </nested>
+ <nested inputs="../site.xsd#//Feature;XSDComplexTypeDefinition=2/XSDParticle/XSDModelGroup/XSDParticle/category;XSDElementDeclaration/XSDComplexTypeDefinition"
+ outputs="Site.ecore#//CategoryType">
+ <nested inputs="../site.xsd#//Feature;XSDComplexTypeDefinition=2/XSDParticle/XSDModelGroup/XSDParticle/category;XSDElementDeclaration/XSDComplexTypeDefinition/XSDAttributeUse"
+ outputs="Site.ecore#//CategoryType/name"/>
+ </nested>
+ <nested inputs="../site.xsd#//Feature;XSDComplexTypeDefinition=2" outputs="Site.ecore#//Feature">
+ <nested inputs="../site.xsd#//Feature;XSDComplexTypeDefinition=2/XSDParticle/XSDModelGroup/XSDParticle"
+ outputs="Site.ecore#//Feature/category"/>
+ <nested inputs="../site.xsd#//Feature;XSDComplexTypeDefinition=2/XSDAttributeUse=1"
+ outputs="Site.ecore#//Feature/id"/>
+ <nested inputs="../site.xsd#//Feature;XSDComplexTypeDefinition=2/XSDAttributeUse"
+ outputs="Site.ecore#//Feature/url"/>
+ <nested inputs="../site.xsd#//Feature;XSDComplexTypeDefinition=2/XSDAttributeUse=2"
+ outputs="Site.ecore#//Feature/version"/>
+ </nested>
+ <nested inputs="../site.xsd#//CategoryDef;XSDComplexTypeDefinition=3" outputs="Site.ecore#//CategoryDef">
+ <nested inputs="../site.xsd#//CategoryDef;XSDComplexTypeDefinition=3/XSDParticle/XSDModelGroup/XSDParticle"
+ outputs="Site.ecore#//CategoryDef/description"/>
+ <nested inputs="../site.xsd#//CategoryDef;XSDComplexTypeDefinition=3/XSDAttributeUse=1"
+ outputs="Site.ecore#//CategoryDef/label"/>
+ <nested inputs="../site.xsd#//CategoryDef;XSDComplexTypeDefinition=3/XSDAttributeUse"
+ outputs="Site.ecore#//CategoryDef/name"/>
+ </nested>
+ <nested inputs="../site.xsd#//Site;XSDComplexTypeDefinition" outputs="Site.ecore#//Site">
+ <nested inputs="../site.xsd#//Site;XSDComplexTypeDefinition/XSDParticle/XSDModelGroup/XSDParticle"
+ outputs="Site.ecore#//Site/description"/>
+ <nested inputs="../site.xsd#//Site;XSDComplexTypeDefinition/XSDParticle/XSDModelGroup/XSDParticle=1"
+ outputs="Site.ecore#//Site/feature"/>
+ <nested inputs="../site.xsd#//Site;XSDComplexTypeDefinition/XSDParticle/XSDModelGroup/XSDParticle=2"
+ outputs="Site.ecore#//Site/categoryDef"/>
+ </nested>
+ <nested inputs="../site.xsd#//site;XSDElementDeclaration" outputs="Site.ecore#//DocumentRoot/site"/>
+</xsd2ecore:XSD2EcoreMappingRoot>
diff --git a/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/Activator.java b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/Activator.java
new file mode 100644
index 0000000..d731e91
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/Activator.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * 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:
+ * Simon Kaegi, Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.pde.internal.webui;
+
+import java.util.Hashtable;
+
+import org.eclipse.equinox.http.jetty.JettyConfigurator;
+import org.eclipse.equinox.http.jetty.JettyConstants;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.http.HttpContext;
+import org.osgi.service.http.HttpService;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class Activator implements BundleActivator {
+
+ private ServiceTracker httpServiceTracker;
+ protected static volatile BundleContext bundleContext;
+ static boolean DEBUG;
+ {
+ String debug = System.getProperty("org.eclipse.e4.pde.webui.debug");
+ if (debug != null && !"false".equals(debug.toLowerCase())) {
+ DEBUG = true;
+ }
+ }
+
+ public void start(BundleContext context) throws Exception {
+ Hashtable settings = new Hashtable();
+
+ if (DEBUG) {
+ settings.put(JettyConstants.HTTP_HOST,"127.0.0.1");
+ } else {
+ // in non-debug mode, only accept connections from localhost:
+ settings.put(JettyConstants.HTTP_HOST,"0.0.0.0");
+ }
+
+ settings.put(JettyConstants.HTTP_PORT,Integer.valueOf(0));
+ settings.put(JettyConstants.OTHER_INFO, "e4.pde.webui");
+ JettyConfigurator.startServer("e4.pde.webui", settings);
+
+
+ bundleContext = context;
+ Filter filter = context.createFilter("(&(" + Constants.OBJECTCLASS + "=" + HttpService.class.getName() + ")(other.info=e4.pde.webui))");
+ httpServiceTracker = new HttpServiceTracker(context, filter);
+ httpServiceTracker.open();
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ httpServiceTracker.close();
+ httpServiceTracker = null;
+ bundleContext = null;
+ JettyConfigurator.stopServer("e4.pde.webui");
+ }
+
+ public static Object PORT;
+
+ private class HttpServiceTracker extends ServiceTracker {
+
+
+ public HttpServiceTracker(BundleContext context, Filter filter) {
+ super(context, filter, null);
+ }
+
+
+ public Object addingService(ServiceReference reference) {
+ HttpService httpService = (HttpService) super.addingService(reference); // calls context.getService(reference);
+ PORT = reference.getProperty(JettyConstants.HTTP_PORT);
+ if (DEBUG) {
+ System.out.println("listening on: " + PORT);
+ }
+ if (httpService == null)
+ return null;
+
+ HttpContext httpContext = new BundleEntryHttpContext(context.getBundle());
+ Bundle dojoBundle = getDojoBundle();
+ HttpContext dojoHttpContext = new BundleEntryHttpContext(dojoBundle);
+
+ try {
+ httpService.registerResources("/org.dojotoolkit", "/", dojoHttpContext);
+ httpService.registerResources("/", "/static", httpContext);
+ httpService.registerServlet("/pde", new PDEServlet(), null, httpContext);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return httpService;
+ }
+
+ private Bundle getDojoBundle() {
+ Bundle[] bundles = context.getBundles();
+ for (int i = 0; i < bundles.length; i++) {
+ if (bundles[i].getSymbolicName().equals("org.dojotoolkit"))
+ return bundles[i];
+ }
+ throw new IllegalStateException("Couldn't find the 'org.dojotoolkit' bundle.");
+ }
+
+ public void removedService(ServiceReference reference, Object service) {
+ HttpService httpService = (HttpService) service;
+ httpService.unregister("/org.dojotoolkit");
+ httpService.unregister("/");
+ super.removedService(reference, service); // calls context.ungetService(reference);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/BundleEntryHttpContext.java b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/BundleEntryHttpContext.java
new file mode 100644
index 0000000..6ea8d39
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/BundleEntryHttpContext.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation, Cognos Incorporated 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
+ *******************************************************************************/
+package org.eclipse.e4.pde.internal.webui;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.osgi.framework.Bundle;
+import org.osgi.service.http.HttpContext;
+
+public class BundleEntryHttpContext implements HttpContext {
+ private Bundle bundle;
+ private String bundlePath;
+
+ public BundleEntryHttpContext(Bundle bundle) {
+ this.bundle = bundle;
+ }
+
+ public BundleEntryHttpContext(Bundle b, String bundlePath) {
+ this(b);
+ if (bundlePath != null) {
+ if (bundlePath.endsWith("/")) //$NON-NLS-1$
+ bundlePath = bundlePath.substring(0, bundlePath.length() - 1);
+
+ if (bundlePath.length() == 0)
+ bundlePath = null;
+ }
+ this.bundlePath = bundlePath;
+ }
+
+ public String getMimeType(String arg0) {
+ return null;
+ }
+
+ public boolean handleSecurity(HttpServletRequest arg0, HttpServletResponse arg1) throws IOException {
+ return true;
+ }
+
+ public URL getResource(String resourceName) {
+ if (bundlePath != null)
+ resourceName = bundlePath + resourceName;
+
+ int lastSlash = resourceName.lastIndexOf('/');
+ if (lastSlash == -1)
+ return null;
+
+ if (resourceName.endsWith("/"))
+ resourceName += "index.html";
+
+ String path = resourceName.substring(0, lastSlash);
+ if (path.length() == 0)
+ path = "/"; //$NON-NLS-1$
+ String file = resourceName.substring(lastSlash + 1);
+ Enumeration entryPaths = bundle.findEntries(path, file, false);
+
+ if (entryPaths != null && entryPaths.hasMoreElements())
+ return (URL) entryPaths.nextElement();
+
+ return null;
+ }
+
+ public Set getResourcePaths(String path) {
+ if (bundlePath != null)
+ path = bundlePath + path;
+
+ Enumeration entryPaths = bundle.findEntries(path, null, false);
+ if (entryPaths == null)
+ return null;
+
+ Set result = new HashSet();
+ while (entryPaths.hasMoreElements()) {
+ URL entryURL = (URL) entryPaths.nextElement();
+ String entryPath = entryURL.getFile();
+
+ if (bundlePath == null)
+ result.add(entryPath);
+ else
+ result.add(entryPath.substring(bundlePath.length()));
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/EMFJSONUtil.java b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/EMFJSONUtil.java
new file mode 100644
index 0000000..31322e7
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/EMFJSONUtil.java
@@ -0,0 +1,371 @@
+/*******************************************************************************
+ * 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.e4.pde.internal.webui;
+
+import java.math.BigDecimal;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.ecore.util.FeatureMap.Entry;
+
+// JSON <--> Java
+//------------------
+// string <--> java.lang.String
+// number <--> java.math.Number (BigDecimal)
+// object <--> java.util.Map (HashMap)
+// array <--> java.util.Collection (ArrayList)
+// true <--> java.lang.Boolean.TRUE
+// false <--> java.lang.Boolean.FALSE
+// null <--> null
+
+public class EMFJSONUtil {
+ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+ private static final String NULL = "null"; //$NON-NLS-1$
+
+ public static Object read(String jsonString) {
+ return parse(new StringCharacterIterator(jsonString));
+ }
+
+ public static String write(EObject jsonObject) {
+ StringBuffer buffer = new StringBuffer();
+ writeValue(jsonObject, buffer);
+ return buffer.toString();
+ }
+
+ private static RuntimeException error(String message, CharacterIterator it) {
+ return new IllegalStateException("[" + it.getIndex() + "] " + message); //$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ private static RuntimeException error(String message) {
+ return new IllegalStateException(message);
+ }
+
+ private static Object parse(CharacterIterator it) {
+ parseWhitespace(it);
+ Object result = parseValue(it);
+ parseWhitespace(it);
+
+ if (it.current() != CharacterIterator.DONE)
+ throw error("should be done", it); //$NON-NLS-1$
+ return result;
+ }
+
+ private static void parseWhitespace(CharacterIterator it) {
+ char c = it.current();
+ while (Character.isWhitespace(c))
+ c = it.next();
+ }
+
+ private static Object parseValue(CharacterIterator it) {
+ switch (it.current()) {
+ case '{' :
+ return parseObject(it);
+ case '[' :
+ return parseArray(it);
+ case '"' :
+ return parseString(it);
+ case '-' :
+ case '0' :
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ return parseNumber(it);
+ case 't' :
+ parseText(Boolean.TRUE.toString(), it);
+ return Boolean.TRUE;
+ case 'f' :
+ parseText(Boolean.FALSE.toString(), it);
+ return Boolean.FALSE;
+ case 'n' :
+ parseText(NULL, it);
+ return null;
+ }
+ throw error("Bad JSON starting character '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$;
+ }
+
+ private static Map parseObject(CharacterIterator it) {
+ it.next();
+ parseWhitespace(it);
+ if (it.current() == '}') {
+ it.next();
+ return Collections.EMPTY_MAP;
+ }
+
+ Map map = new HashMap();
+ while (true) {
+ if (it.current() != '"')
+ throw error("expected a string start '\"' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+ String key = parseString(it);
+ if (map.containsKey(key))
+ throw error("' already defined" + "key '" + key, it); //$NON-NLS-1$ //$NON-NLS-2$
+ parseWhitespace(it);
+ if (it.current() != ':')
+ throw error("expected a pair separator ':' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+ it.next();
+ parseWhitespace(it);
+ Object value = parseValue(it);
+ map.put(key, value);
+ parseWhitespace(it);
+ if (it.current() == ',') {
+ it.next();
+ parseWhitespace(it);
+ continue;
+ }
+
+ if (it.current() != '}')
+ throw error("expected an object close '}' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ }
+ it.next();
+ return map;
+ }
+
+ private static List parseArray(CharacterIterator it) {
+ it.next();
+ parseWhitespace(it);
+ if (it.current() == ']') {
+ it.next();
+ return Collections.EMPTY_LIST;
+ }
+
+ List list = new ArrayList();
+ while (true) {
+ Object value = parseValue(it);
+ list.add(value);
+ parseWhitespace(it);
+ if (it.current() == ',') {
+ it.next();
+ parseWhitespace(it);
+ continue;
+ }
+
+ if (it.current() != ']')
+ throw error("expected an array close ']' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ }
+ it.next();
+ return list;
+ }
+
+ private static void parseText(String string, CharacterIterator it) {
+ int length = string.length();
+ char c = it.current();
+ for (int i = 0; i < length; i++) {
+ if (c != string.charAt(i))
+ throw error("expected to parse '" + string + "' but character " + (i + 1) + " was '" + c + "'", it); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$;
+ c = it.next();
+ }
+ }
+
+ private static Object parseNumber(CharacterIterator it) {
+ StringBuffer buffer = new StringBuffer();
+ char c = it.current();
+ while (Character.isDigit(c) || c == '-' || c == '+' || c == '.' || c == 'e' || c == 'E') {
+ buffer.append(c);
+ c = it.next();
+ }
+ try {
+ return new BigDecimal(buffer.toString());
+ } catch (NumberFormatException e) {
+ throw error("expected a number but was '" + buffer.toString() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$;
+ }
+ }
+
+ private static String parseString(CharacterIterator it) {
+ char c = it.next();
+ if (c == '"') {
+ it.next();
+ return EMPTY_STRING;
+ }
+ StringBuffer buffer = new StringBuffer();
+ while (c != '"') {
+ if (Character.isISOControl(c))
+ throw error("illegal iso control character: '" + Integer.toHexString(c) + "'", it); //$NON-NLS-1$ //$NON-NLS-2$);
+
+ if (c == '\\') {
+ c = it.next();
+ switch (c) {
+ case '"' :
+ case '\\' :
+ case '/' :
+ buffer.append(c);
+ break;
+ case 'b' :
+ buffer.append('\b');
+ break;
+ case 'f' :
+ buffer.append('\f');
+ break;
+ case 'n' :
+ buffer.append('\n');
+ break;
+ case 'r' :
+ buffer.append('\r');
+ break;
+ case 't' :
+ buffer.append('\t');
+ break;
+ case 'u' :
+ StringBuffer unicode = new StringBuffer(4);
+ for (int i = 0; i < 4; i++) {
+ unicode.append(it.next());
+ }
+ try {
+ buffer.append((char) Integer.parseInt(unicode.toString(), 16));
+ } catch (NumberFormatException e) {
+ throw error("expected a unicode hex number but was '" + unicode.toString() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$););
+ }
+ break;
+ default :
+ throw error("illegal escape character '" + c + "'", it); //$NON-NLS-1$ //$NON-NLS-2$););
+ }
+ } else
+ buffer.append(c);
+
+ c = it.next();
+ }
+ c = it.next();
+ return buffer.toString();
+ }
+
+ private static void writeValue(Object value, StringBuffer buffer) {
+ if (value == null)
+ buffer.append(NULL);
+ else if (value instanceof Boolean || value instanceof Number)
+ buffer.append(value.toString());
+ else if (value instanceof String)
+ writeString((String) value, buffer);
+ else if (value instanceof FeatureMap)
+ writeFeatureMap((FeatureMap) value, buffer);
+ else if (value instanceof EObject)
+ writeObject((EObject) value, buffer);
+ else if (value instanceof Map)
+ writeMap((Map) value, buffer);
+ else if (value instanceof Collection)
+ writeArray((Collection) value, buffer);
+ else
+ throw error("Unexpected object instance type was '" + value.getClass().getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$););
+ }
+
+ private static void writeObject(EObject eObject, StringBuffer buffer) {
+ buffer.append('{');
+ for (Iterator iterator = eObject.eClass().getEAllStructuralFeatures().iterator(); iterator.hasNext();) {
+ EStructuralFeature feature = (EStructuralFeature) iterator.next();
+ writeString(feature.getName(), buffer);
+ buffer.append(':');
+ writeValue(eObject.eGet(feature), buffer);
+ buffer.append(',');
+ }
+ if (buffer.charAt(buffer.length() - 1) == ',')
+ buffer.setCharAt(buffer.length() - 1, '}');
+ else
+ buffer.append('}');
+ }
+
+ private static void writeFeatureMap(FeatureMap featureMap, StringBuffer buffer) {
+ buffer.append('{');
+ for (Iterator iterator = featureMap.iterator(); iterator.hasNext();) {
+ FeatureMap.Entry entry = (Entry) iterator.next();
+ writeString(entry.getEStructuralFeature().getName(), buffer);
+ buffer.append(':');
+ writeValue(entry.getValue(), buffer);
+ buffer.append(',');
+ }
+ if (buffer.charAt(buffer.length() - 1) == ',')
+ buffer.setCharAt(buffer.length() - 1, '}');
+ else
+ buffer.append('}');
+ }
+
+ private static void writeMap(Map map, StringBuffer buffer) {
+ buffer.append('{');
+ for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) {
+ Object key = iterator.next();
+ if (!(key instanceof String))
+ throw error("Map keys must be an instance of String but was '" + key.getClass().getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$););
+ writeString((String) key, buffer);
+ buffer.append(':');
+ writeValue(map.get(key), buffer);
+ buffer.append(',');
+ }
+ if (buffer.charAt(buffer.length() - 1) == ',')
+ buffer.setCharAt(buffer.length() - 1, '}');
+ else
+ buffer.append('}');
+ }
+
+ private static void writeArray(Collection collection, StringBuffer buffer) {
+ buffer.append('[');
+ for (Iterator iterator = collection.iterator(); iterator.hasNext();) {
+ writeValue(iterator.next(), buffer);
+ buffer.append(',');
+ }
+ if (buffer.charAt(buffer.length() - 1) == ',')
+ buffer.setCharAt(buffer.length() - 1, ']');
+ else
+ buffer.append(']');
+ }
+
+ private static void writeString(String string, StringBuffer buffer) {
+ buffer.append('"');
+ int length = string.length();
+ for (int i = 0; i < length; i++) {
+ char c = string.charAt(i);
+ switch (c) {
+ case '"' :
+ case '\\' :
+ case '/' :
+ buffer.append('\\');
+ buffer.append(c);
+ break;
+ case '\b' :
+ buffer.append("\\b"); //$NON-NLS-1$
+ break;
+ case '\f' :
+ buffer.append("\\f"); //$NON-NLS-1$
+ break;
+ case '\n' :
+ buffer.append("\\n"); //$NON-NLS-1$
+ break;
+ case '\r' :
+ buffer.append("\\r"); //$NON-NLS-1$
+ break;
+ case '\t' :
+ buffer.append("\\t"); //$NON-NLS-1$
+ break;
+ default :
+ if (Character.isISOControl(c)) {
+ buffer.append("\\u"); //$NON-NLS-1$
+ String hexString = Integer.toHexString(c);
+ for (int j = hexString.length(); j < 4; j++)
+ buffer.append('0');
+ buffer.append(hexString);
+ } else
+ buffer.append(c);
+ }
+ }
+ buffer.append('"');
+ }
+}
diff --git a/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/JSONUtil.java b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/JSONUtil.java
new file mode 100644
index 0000000..3dec041
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/JSONUtil.java
@@ -0,0 +1,326 @@
+/*******************************************************************************
+ * 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.e4.pde.internal.webui;
+
+import java.math.BigDecimal;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.*;
+
+// JSON <--> Java
+//------------------
+// string <--> java.lang.String
+// number <--> java.math.Number (BigDecimal)
+// object <--> java.util.Map (HashMap)
+// array <--> java.util.Collection (ArrayList)
+// true <--> java.lang.Boolean.TRUE
+// false <--> java.lang.Boolean.FALSE
+// null <--> null
+
+public class JSONUtil {
+ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+ private static final String NULL = "null"; //$NON-NLS-1$
+
+ public static Object read(String jsonString) {
+ return parse(new StringCharacterIterator(jsonString));
+ }
+
+ public static String write(Object jsonObject) {
+ StringBuffer buffer = new StringBuffer();
+ writeValue(jsonObject, buffer);
+ return buffer.toString();
+ }
+
+ private static RuntimeException error(String message, CharacterIterator it) {
+ return new IllegalStateException("[" + it.getIndex() + "] " + message); //$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ private static RuntimeException error(String message) {
+ return new IllegalStateException(message);
+ }
+
+ private static Object parse(CharacterIterator it) {
+ parseWhitespace(it);
+ Object result = parseValue(it);
+ parseWhitespace(it);
+
+ if (it.current() != CharacterIterator.DONE)
+ throw error("should be done", it); //$NON-NLS-1$
+ return result;
+ }
+
+ private static void parseWhitespace(CharacterIterator it) {
+ char c = it.current();
+ while (Character.isWhitespace(c))
+ c = it.next();
+ }
+
+ private static Object parseValue(CharacterIterator it) {
+ switch (it.current()) {
+ case '{' :
+ return parseObject(it);
+ case '[' :
+ return parseArray(it);
+ case '"' :
+ return parseString(it);
+ case '-' :
+ case '0' :
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ return parseNumber(it);
+ case 't' :
+ parseText(Boolean.TRUE.toString(), it);
+ return Boolean.TRUE;
+ case 'f' :
+ parseText(Boolean.FALSE.toString(), it);
+ return Boolean.FALSE;
+ case 'n' :
+ parseText(NULL, it);
+ return null;
+ }
+ throw error("Bad JSON starting character '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$;
+ }
+
+ private static Map parseObject(CharacterIterator it) {
+ it.next();
+ parseWhitespace(it);
+ if (it.current() == '}') {
+ it.next();
+ return Collections.EMPTY_MAP;
+ }
+
+ Map map = new HashMap();
+ while (true) {
+ if (it.current() != '"')
+ throw error("expected a string start '\"' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+ String key = parseString(it);
+ if (map.containsKey(key))
+ throw error("' already defined" + "key '" + key, it); //$NON-NLS-1$ //$NON-NLS-2$
+ parseWhitespace(it);
+ if (it.current() != ':')
+ throw error("expected a pair separator ':' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+ it.next();
+ parseWhitespace(it);
+ Object value = parseValue(it);
+ map.put(key, value);
+ parseWhitespace(it);
+ if (it.current() == ',') {
+ it.next();
+ parseWhitespace(it);
+ continue;
+ }
+
+ if (it.current() != '}')
+ throw error("expected an object close '}' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ }
+ it.next();
+ return map;
+ }
+
+ private static List parseArray(CharacterIterator it) {
+ it.next();
+ parseWhitespace(it);
+ if (it.current() == ']') {
+ it.next();
+ return Collections.EMPTY_LIST;
+ }
+
+ List list = new ArrayList();
+ while (true) {
+ Object value = parseValue(it);
+ list.add(value);
+ parseWhitespace(it);
+ if (it.current() == ',') {
+ it.next();
+ parseWhitespace(it);
+ continue;
+ }
+
+ if (it.current() != ']')
+ throw error("expected an array close ']' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ }
+ it.next();
+ return list;
+ }
+
+ private static void parseText(String string, CharacterIterator it) {
+ int length = string.length();
+ char c = it.current();
+ for (int i = 0; i < length; i++) {
+ if (c != string.charAt(i))
+ throw error("expected to parse '" + string + "' but character " + (i + 1) + " was '" + c + "'", it); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$;
+ c = it.next();
+ }
+ }
+
+ private static Object parseNumber(CharacterIterator it) {
+ StringBuffer buffer = new StringBuffer();
+ char c = it.current();
+ while (Character.isDigit(c) || c == '-' || c == '+' || c == '.' || c == 'e' || c == 'E') {
+ buffer.append(c);
+ c = it.next();
+ }
+ try {
+ return new BigDecimal(buffer.toString());
+ } catch (NumberFormatException e) {
+ throw error("expected a number but was '" + buffer.toString() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$;
+ }
+ }
+
+ private static String parseString(CharacterIterator it) {
+ char c = it.next();
+ if (c == '"') {
+ it.next();
+ return EMPTY_STRING;
+ }
+ StringBuffer buffer = new StringBuffer();
+ while (c != '"') {
+ if (Character.isISOControl(c))
+ throw error("illegal iso control character: '" + Integer.toHexString(c) + "'", it); //$NON-NLS-1$ //$NON-NLS-2$);
+
+ if (c == '\\') {
+ c = it.next();
+ switch (c) {
+ case '"' :
+ case '\\' :
+ case '/' :
+ buffer.append(c);
+ break;
+ case 'b' :
+ buffer.append('\b');
+ break;
+ case 'f' :
+ buffer.append('\f');
+ break;
+ case 'n' :
+ buffer.append('\n');
+ break;
+ case 'r' :
+ buffer.append('\r');
+ break;
+ case 't' :
+ buffer.append('\t');
+ break;
+ case 'u' :
+ StringBuffer unicode = new StringBuffer(4);
+ for (int i = 0; i < 4; i++) {
+ unicode.append(it.next());
+ }
+ try {
+ buffer.append((char) Integer.parseInt(unicode.toString(), 16));
+ } catch (NumberFormatException e) {
+ throw error("expected a unicode hex number but was '" + unicode.toString() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$););
+ }
+ break;
+ default :
+ throw error("illegal escape character '" + c + "'", it); //$NON-NLS-1$ //$NON-NLS-2$););
+ }
+ } else
+ buffer.append(c);
+
+ c = it.next();
+ }
+ c = it.next();
+ return buffer.toString();
+ }
+
+ private static void writeValue(Object value, StringBuffer buffer) {
+ if (value == null)
+ buffer.append(NULL);
+ else if (value instanceof Boolean || value instanceof Number)
+ buffer.append(value.toString());
+ else if (value instanceof String)
+ writeString((String) value, buffer);
+ else if (value instanceof Collection)
+ writeArray((Collection) value, buffer);
+ else if (value instanceof Map)
+ writeObject((Map) value, buffer);
+ else
+ throw error("Unexpected object instance type was '" + value.getClass().getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$););
+ }
+
+ private static void writeObject(Map map, StringBuffer buffer) {
+ buffer.append('{');
+ for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) {
+ Object key = iterator.next();
+ if (!(key instanceof String))
+ throw error("Map keys must be an instance of String but was '" + key.getClass().getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$););
+ writeString((String) key, buffer);
+ buffer.append(':');
+ writeValue(map.get(key), buffer);
+ buffer.append(',');
+ }
+ if (buffer.charAt(buffer.length() - 1) == ',')
+ buffer.setCharAt(buffer.length() - 1, '}');
+ else
+ buffer.append('}');
+ }
+
+ private static void writeArray(Collection collection, StringBuffer buffer) {
+ buffer.append('[');
+ for (Iterator iterator = collection.iterator(); iterator.hasNext();) {
+ writeValue(iterator.next(), buffer);
+ buffer.append(',');
+ }
+ if (buffer.charAt(buffer.length() - 1) == ',')
+ buffer.setCharAt(buffer.length() - 1, ']');
+ else
+ buffer.append(']');
+ }
+
+ private static void writeString(String string, StringBuffer buffer) {
+ buffer.append('"');
+ int length = string.length();
+ for (int i = 0; i < length; i++) {
+ char c = string.charAt(i);
+ switch (c) {
+ case '"' :
+ case '\\' :
+ case '/' :
+ buffer.append('\\');
+ buffer.append(c);
+ break;
+ case '\b' :
+ buffer.append("\\b"); //$NON-NLS-1$
+ break;
+ case '\f' :
+ buffer.append("\\f"); //$NON-NLS-1$
+ break;
+ case '\n' :
+ buffer.append("\\n"); //$NON-NLS-1$
+ break;
+ case '\r' :
+ buffer.append("\\r"); //$NON-NLS-1$
+ break;
+ case '\t' :
+ buffer.append("\\t"); //$NON-NLS-1$
+ break;
+ default :
+ if (Character.isISOControl(c)) {
+ buffer.append("\\u"); //$NON-NLS-1$
+ String hexString = Integer.toHexString(c);
+ for (int j = hexString.length(); j < 4; j++)
+ buffer.append('0');
+ buffer.append(hexString);
+ } else
+ buffer.append(c);
+ }
+ }
+ buffer.append('"');
+ }
+}
diff --git a/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/PDEServlet.java b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/PDEServlet.java
new file mode 100644
index 0000000..86e6af0
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/src/org/eclipse/e4/pde/internal/webui/PDEServlet.java
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * 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:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.pde.internal.webui;
+
+import java.io.*;
+import java.net.URLEncoder;
+import java.util.*;
+import java.util.Map.Entry;
+import javax.servlet.ServletException;
+import javax.servlet.http.*;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.*;
+import org.eclipse.emf.ecore.impl.EPackageRegistryImpl;
+import org.eclipse.emf.ecore.resource.*;
+import org.eclipse.emf.ecore.resource.Resource.Factory;
+import org.eclipse.emf.ecore.resource.impl.ResourceFactoryImpl;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.BasicExtendedMetaData;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl;
+import org.eclipse.pde.internal.core.PDECore;
+import org.eclipse.pde.internal.core.ifeature.IFeature;
+import org.eclipse.pde.internal.core.ifeature.IFeatureModel;
+import org.osgi.framework.Version;
+
+public class PDEServlet extends HttpServlet {
+
+ private static final long serialVersionUID = -5263759597889185038L;
+
+ private IWorkspace workspace;
+
+ private static String sessionID;
+
+ private synchronized IWorkspace getWorkspace() {
+ if (workspace == null) {
+ // enable auto-refresh:
+ new InstanceScope().getNode(ResourcesPlugin.PI_RESOURCES)
+ .putBoolean(ResourcesPlugin.PREF_AUTO_REFRESH, true);
+ workspace = ResourcesPlugin.getWorkspace();
+ }
+ return workspace;
+ }
+
+ protected void doPut(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ if (!isAuthenticated(req)) {
+ resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+ String pathInfo = req.getPathInfo();
+ if (pathInfo.startsWith("/site/")) {
+ String wsPath = pathInfo.substring("/site".length());
+ IResource resource = getWorkspace().getRoot().findMember(
+ new Path(wsPath));
+ if (resource.getType() != IResource.FILE) {
+ resp.setStatus(405);
+ return;
+ }
+ InputStream is = req.getInputStream();
+ int BUFFER_SIZE = 8192;
+ byte[] buffer = new byte[BUFFER_SIZE];
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ int numRead = 0;
+ while ((numRead = is.read(buffer)) > 0) {
+ os.write(buffer, 0, numRead);
+ }
+ String jsonString = new String(os.toByteArray(), "ISO-8859-1");
+ Object json = JSONUtil.read(jsonString);
+// System.out.println(json);
+ URI siteEcoreURI = URI.createPlatformPluginURI("/org.eclipse.e4.pde.webui/model/Site.ecore", true);
+ ResourceSet resourceSet = createResourceSet(siteEcoreURI);
+ EPackage ePackage = resourceSet.getPackageRegistry().getEPackage("platform:/plugin/org.eclipse.e4.pde.site.model/site.xsd");
+
+ Resource.Factory factory = (Factory) resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().get(Resource.Factory.Registry.DEFAULT_EXTENSION);
+ URI uri = URI.createPlatformResourceURI(resource.getFullPath()
+ .toString(), true);
+ Resource r = factory.createResource(uri);
+
+ EClass documentRootClass = (EClass) ePackage.getEClassifier("DocumentRoot");
+ EObject documentRoot = ePackage.getEFactoryInstance().create(documentRootClass);
+ EClass siteClass = (EClass) ePackage.getEClassifier("Site");
+ EObject site = ePackage.getEFactoryInstance().create(siteClass);
+ fill(site, (HashMap) json, ePackage.getEFactoryInstance());
+ documentRoot.eSet(documentRootClass.getEStructuralFeature("site"), site);
+ r.getContents().add(documentRoot);
+
+ OutputStream outputStream = resourceSet.getURIConverter().createOutputStream(uri);
+ r.save(outputStream, new HashMap());
+ outputStream.close();
+ }
+ }
+
+ private void fill(EObject eObject, HashMap json, EFactory eFactory) {
+ for(Iterator it = json.entrySet().iterator(); it.hasNext(); ) {
+ Entry entry = (Entry) it.next();
+ EStructuralFeature feature = eObject.eClass().getEStructuralFeature((String) entry.getKey());
+ if (entry.getValue() instanceof Collection) {
+ Collection targetCollection = (Collection) eObject.eGet(feature);
+ Collection sourceCollection = (Collection) entry.getValue();
+ for (Iterator it2 = sourceCollection.iterator(); it2
+ .hasNext();) {
+ Object element = it2.next();
+ EClass elementClass = (EClass) feature.getEType();
+ EObject targetElement = eFactory.create(elementClass);
+ fill(targetElement, (HashMap) element, eFactory);
+ targetCollection.add(targetElement);
+ }
+ } else if (entry.getValue() instanceof Map) {
+ EClass elementClass = (EClass) feature.getEType();
+ EObject targetElement = eFactory.create(elementClass);
+ fill(targetElement, (HashMap) entry.getValue(), eFactory);
+ eObject.eSet(feature, targetElement);
+ } else if (entry.getValue() instanceof String) {
+ eObject.eSet(feature, entry.getValue());
+ } else if (entry.getValue() != null) {
+ throw new RuntimeException("unsupported: " + entry.getValue());
+ }
+ }
+ }
+
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
+ String pathInfo = req.getPathInfo();
+ if (pathInfo.startsWith("/login")) {
+ if ("e4".equals(req.getParameter("username"))) {
+ if ("e4".equals(req.getParameter("password"))) {
+ resp.addCookie(new Cookie("org.eclipse.e4.pde.auth", getSessionId()));
+ try {
+ resp.sendRedirect(req.getParameter("nextURL"));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return;
+ }
+ }
+ }
+ try {
+ resp.sendRedirect("/pde/login?nextURL=" + URLEncoder.encode(req.getParameter("nextURL"), "UTF-8"));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ String pathInfo = req.getPathInfo();
+ if (pathInfo.startsWith("/login")) {
+ resp.setStatus(HttpServletResponse.SC_OK);
+ resp.setContentType("text/html; charset=UTF-8");
+ PrintWriter writer = resp.getWriter();
+ writer.append("<html>");
+ writer.append("<head>");
+ writer.append("<title>Please Log In</title>");
+ writer.append("</head>");
+ writer.append("<body>");
+ writer.append("<form method='post' action='/pde/login'>");
+ writer.append("username: ");
+ writer.append("<input type='text' name='username' />");
+ writer.append("<br />");
+ writer.append("password: ");
+ writer.append("<input type='password' name='password' />");
+ writer.append("<br />");
+ writer.append("<input type='submit' value='Login' />");
+ writer.append("<input type='hidden' name='nextURL' value='" + req.getParameter("nextURL") + "' />");
+ writer.append("</form>");
+ if (Activator.DEBUG) {
+ writer.append("<script type='text/javascript' src='/listCookies.js'></script>");
+ }
+ writer.append("</body>");
+ writer.append("</html>");
+ return;
+ }
+ if (!isAuthenticated(req)) {
+ resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+ if (pathInfo.startsWith("/features/")) {
+ IFeatureModel[] allModels = PDECore.getDefault().getFeatureModelManager().getModels();
+ Arrays.sort(allModels, new Comparator() {
+ public int compare(Object arg0, Object arg1) {
+ IFeature f0 = ((IFeatureModel)arg0).getFeature();
+ IFeature f1 = ((IFeatureModel)arg1).getFeature();
+ return f0.getId().compareTo(f1.getId());
+ }
+ });
+ List features = new ArrayList(allModels.length);
+ for (int i = 0; i < allModels.length; i++) {
+ IFeature feature = allModels[i].getFeature();
+ Map featureJSON = new HashMap();
+ featureJSON.put("feature", null);
+ featureJSON.put("id", feature.getId());
+ featureJSON.put("url", "features/" + feature.getId() + "_" + new Version(feature.getVersion()).toString() + ".jar");
+ featureJSON.put("version", feature.getVersion());
+ features.add(featureJSON);
+ }
+ resp.setStatus(200);
+ resp.setContentType("application/json; charset=UTF-8");
+ Map jsonResult = new HashMap();
+ jsonResult.put("identifier", "id");
+ jsonResult.put("label", "id");
+ jsonResult.put("items", features);
+ PrintWriter writer = resp.getWriter();
+ writer.write("/*");
+ writer.write(JSONUtil.write(jsonResult));
+ writer.write("*/");
+ return;
+ } else if (pathInfo.startsWith("/site/")) {
+ String wsPath = pathInfo.substring("/site".length());
+ IResource resource = getWorkspace().getRoot().findMember(
+ new Path(wsPath));
+ if (resource.getType() != IResource.FILE) {
+ resp.setStatus(405);
+ return;
+ }
+ PrintWriter writer = resp.getWriter();
+ try {
+ URI siteEcoreURI = URI.createPlatformPluginURI("/org.eclipse.e4.pde.webui/model/Site.ecore", true);
+ ResourceSet resourceSet = createResourceSet(siteEcoreURI);
+
+ URI uri = URI.createPlatformResourceURI(resource.getFullPath()
+ .toString(), true);
+ Resource r = resourceSet.getResource(uri, true);
+ EObject eRootObject = (EObject) r.getContents().get(0);
+ resp.setStatus(200);
+ resp.setContentType("application/json; charset=UTF-8");
+ writer.write("/*");
+ writer.write(EMFJSONUtil.write((EObject) eRootObject.eContents().get(0)));
+ writer.write("*/");
+ return;
+ } catch (Exception e) {
+ e.printStackTrace(writer);
+ resp.setStatus(500);
+ return;
+ }
+ }
+ }
+
+ private boolean isAuthenticated(HttpServletRequest req) {
+ Cookie[] cookies = req.getCookies();
+ if (cookies != null) {
+ for (int i = 0; i < cookies.length; i++) {
+ if (cookies[i].getName().equals("org.eclipse.e4.pde.auth")) {
+ if (cookies[i].getValue().equals(getSessionId())) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public static String getSessionId() {
+ if (sessionID == null) {
+ sessionID = UUID.randomUUID().toString();
+ }
+ return sessionID;
+ }
+
+ private ResourceSet createResourceSet(URI siteEcoreURI) {
+ ResourceSet resourceSet = new ResourceSetImpl();
+ Resource ecoreResource = resourceSet.getResource(siteEcoreURI, true);
+
+ final BasicExtendedMetaData extendedMetaData = new BasicExtendedMetaData(new EPackageRegistryImpl(EPackage.Registry.INSTANCE));
+ EPackage ecorePackage = (EPackage) ecoreResource.getContents().get(0);
+ extendedMetaData.putPackage(null, ecorePackage);
+
+ // Register the appropriate resource factory to handle all file extensions.
+ resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put
+ (Resource.Factory.Registry.DEFAULT_EXTENSION,
+ new ResourceFactoryImpl(){
+ public Resource createResource(URI uri) {
+ XMLResource result = new XMLResourceImpl(uri);
+ result.getDefaultSaveOptions().put(XMLResource.OPTION_EXTENDED_META_DATA, extendedMetaData);
+ result.getDefaultLoadOptions().put(XMLResource.OPTION_EXTENDED_META_DATA, extendedMetaData);
+
+ result.getDefaultSaveOptions().put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
+
+ result.getDefaultLoadOptions().put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE);
+ result.getDefaultSaveOptions().put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE);
+
+ result.getDefaultLoadOptions().put(XMLResource.OPTION_USE_LEXICAL_HANDLER, Boolean.TRUE);
+ return result;
+ }
+ });
+ // Register the package to ensure it is available during loading.
+ //
+ resourceSet.getPackageRegistry().put
+ (ecorePackage.getNsURI(), ecorePackage);
+ return resourceSet;
+ }
+
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.pde.webui/static/images/category_obj.gif b/bundles/org.eclipse.e4.pde.webui/static/images/category_obj.gif
new file mode 100644
index 0000000..5ef0ed7
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/images/category_obj.gif
Binary files differ
diff --git a/bundles/org.eclipse.e4.pde.webui/static/images/feature_obj.gif b/bundles/org.eclipse.e4.pde.webui/static/images/feature_obj.gif
new file mode 100644
index 0000000..411a32a
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/images/feature_obj.gif
Binary files differ
diff --git a/bundles/org.eclipse.e4.pde.webui/static/images/header-top.png b/bundles/org.eclipse.e4.pde.webui/static/images/header-top.png
new file mode 100644
index 0000000..496a4d1
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/images/header-top.png
Binary files differ
diff --git a/bundles/org.eclipse.e4.pde.webui/static/images/section-left-top.png b/bundles/org.eclipse.e4.pde.webui/static/images/section-left-top.png
new file mode 100644
index 0000000..abe7645
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/images/section-left-top.png
Binary files differ
diff --git a/bundles/org.eclipse.e4.pde.webui/static/images/section-middle-top.png b/bundles/org.eclipse.e4.pde.webui/static/images/section-middle-top.png
new file mode 100644
index 0000000..af2d6b0
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/images/section-middle-top.png
Binary files differ
diff --git a/bundles/org.eclipse.e4.pde.webui/static/images/section-right-top.png b/bundles/org.eclipse.e4.pde.webui/static/images/section-right-top.png
new file mode 100644
index 0000000..a8b68e5
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/images/section-right-top.png
Binary files differ
diff --git a/bundles/org.eclipse.e4.pde.webui/static/listCookies.js b/bundles/org.eclipse.e4.pde.webui/static/listCookies.js
new file mode 100644
index 0000000..017a9be
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/listCookies.js
@@ -0,0 +1,7 @@
+var cookies = document.cookie.split("; ");
+//alert("cookies");
+for (var i = 0; i < cookies.length; i++) {
+ //alert(cookies[i]);
+ document.write(cookies[i]);
+ document.write("<br/>");
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.pde.webui/static/tree-standalone.css b/bundles/org.eclipse.e4.pde.webui/static/tree-standalone.css
new file mode 100644
index 0000000..d7c5e66
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/tree-standalone.css
@@ -0,0 +1,8 @@
+html, body {
+ margin: 0;
+ padding: 0;
+}
+
+iframe {
+ border: none;
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.pde.webui/static/tree-standalone.html b/bundles/org.eclipse.e4.pde.webui/static/tree-standalone.html
new file mode 100644
index 0000000..e503bb2
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/tree-standalone.html
@@ -0,0 +1,26 @@
+<!--*****************************************************************************
+ * 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:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ ******************************************************************************-->
+<html>
+<head>
+<title>Site Manifest Editor</title>
+ <style type="text/css">
+ @import "tree-standalone.css";
+ </style>
+</head>
+<body>
+<iframe frameborder="0" id="editor" width="100%" height="100%"></iframe>
+<script type="text/javascript">
+ var hash = window.document.location.hash;
+ var editor = document.getElementById("editor");
+ editor.src = "/tree.html" + hash;
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.pde.webui/static/tree.css b/bundles/org.eclipse.e4.pde.webui/static/tree.css
new file mode 100644
index 0000000..ce97b2d
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/tree.css
@@ -0,0 +1,154 @@
+html {
+ overflow-x: hidden; // hack to get rid of horizontal scrollbar
+}
+
+html, body {
+ margin: 0;
+ padding: 0;
+ font-size: 12px;
+}
+
+#header {
+ margin: 0;
+ width: 100%;
+ height: 36px;
+ background: url(images/header-top.png) 0 0 repeat-x;
+ padding-left: 5px;
+ padding-top: 5px;
+}
+
+#saveButton {
+ margin-right: 10px;
+ width: 80px;
+ float: right;
+ visibility: hidden;
+}
+
+#saveButton input {
+ width: 100%;
+ font-weight:bold;
+ color: #316ac5;
+}
+
+h1 {
+ font-size:1.5em;
+ font-weight:bold;
+ color: #316ac5;
+ line-height: 36px;
+ position:absolute;
+ top:0;
+ bottom:0;
+ margin:auto;
+}
+
+h2 {
+ font-size: 1.1em;
+ font-weight: bold;
+ color: #316ac5;
+ margin: 0;
+}
+
+.pane {
+ margin: 10px;
+}
+
+.sectionTop, .sectionTop2 {
+ background: url(images/section-middle-top.png) 0 0 repeat-x;
+}
+
+.sectionTL {
+ background: url(images/section-left-top.png) 0 0 no-repeat;
+}
+
+.sectionTR {
+ background: url(images/section-right-top.png) 100% 0 no-repeat;
+ padding-left: 5px;
+ padding-top: 3px;
+}
+
+.sectionTop2 {
+ margin-top: 2em;
+}
+
+.soria .dijitSplitterV .dijitSplitterThumb {
+ background: #FFFFFF;
+}
+
+.soria .dijitSplitterV {
+ background: #FFFFFF;
+}
+
+#tree {
+ margin-right: 9em;
+ overflow-x: hidden;
+}
+
+#treeButtons br {
+ line-height: 0.5em;
+}
+
+#treeButtons {
+ margin: 0;
+ padding: 0;
+ float: right;
+ width: 9em;
+}
+
+#treeButtons .contentButton {
+ width: 8.5em;
+ margin: 0;
+ margin-bottom: 3px;
+ font-size: 1em;
+}
+
+.categoryItem {
+ background: url(images/category_obj.gif);
+}
+
+.featureItem {
+ background: url(images/feature_obj.gif);
+}
+
+#categoryProperties {
+ display: none;
+}
+
+#featureProperties {
+ display: none;
+}
+
+.fieldLabel {
+ color: #316ac5;
+ width: 6em;
+ float: left;
+ margin-top: 4px;
+}
+
+.fieldText {
+ margin-left: 6em;
+ padding: 2px;
+}
+
+.longfieldLabel {
+ color: #316ac5;
+ width: 9.5em;
+ float: left;
+ margin-top: 4px;
+}
+
+.longfieldText {
+ margin-left: 9.5em;
+ padding: 2px;
+}
+
+.fieldText input {
+ width: 100%;
+}
+
+.longfieldText input {
+ width: 100%;
+}
+
+.fieldText textarea {
+ width: 100%;
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.pde.webui/static/tree.html b/bundles/org.eclipse.e4.pde.webui/static/tree.html
new file mode 100644
index 0000000..a818796
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/tree.html
@@ -0,0 +1,97 @@
+<!--*****************************************************************************
+ * 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:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ ******************************************************************************-->
+<html>
+ <head>
+ <title>Update Site Map</title>
+
+ <script type="text/javascript">
+ var djConfig = {
+ isDebug:false,
+ parseOnLoad:true
+ };
+ </script>
+ <script type="text/javascript" src="/org.dojotoolkit/dojo/dojo.js.uncompressed.js"></script>
+
+ <style type="text/css">
+ @import "/org.dojotoolkit/dojo/resources/dojo.css";
+ @import "/org.dojotoolkit/dijit/themes/soria/soria.css";
+ @import "/org.dojotoolkit/dijit/themes/soria/Tree.css";
+ @import "/org.dojotoolkit/dijit/themes/soria/layout/BorderContainer.css";
+ @import "/org.dojotoolkit/dijit/themes/soria/form/Common.css";
+ @import "/org.dojotoolkit/dijit/themes/soria/form/Button.css";
+ @import "tree.css";
+ </style>
+
+ </head>
+
+ <body class="soria">
+ <script type="text/javascript" src="tree.js"></script>
+
+ <div id="header"><h1>Update Site Map<span style="visibility:hidden;" id="dirtyIndicator">*</span></h1><div id="saveButton"><input type="button" value="Save" /></div></div>
+
+ <div dojoType="dijit.layout.BorderContainer" design="sidebar" liveSplitters="false" gutters="false" style="width: 100%; height: 90%;">
+ <div class="pane" id="leftPane" dojoType="dijit.layout.ContentPane" region="center">
+ <div class="sectionTop"><div class="sectionTL"><div class="sectionTR">
+ <h2>Managing the Site</h2>
+ <ol>
+ <li>Add the features to be published on the site.</li>
+ <li>For easier browsing of the site, categorize the features by dragging.</li>
+ <li>Build the features.</li>
+ </ol>
+ <div id="treeButtons">
+ <button class="contentButton" id="newCategory">New Category</button><br/>
+ <button class="contentButton" id="addFeature">Add Feature...</button><br/><br/>
+ <button class="contentButton" id="synchronize">Synchronize...</button><br/><br/>
+ <button class="contentButton" id="build">Build</button><br/>
+ <button class="contentButton" id="buildAll">Build All</button><br/>
+ </div>
+ <div id="tree"></div>
+ </div></div></div>
+ </div>
+ <div class="pane" id="rightPane" dojoType="dijit.layout.ContentPane" region="trailing" style="width: 50%;" splitter="true">
+ <div id="categoryProperties">
+ <div class="sectionTop"><div class="sectionTL"><div class="sectionTR">
+ <h2>Category Properties</h2>
+ Provide a unique id, a name and a description for each category.<br/>
+ "*" denotes a required field.<br/>
+ <div class="fieldLabel">ID*:</div><div class="fieldText"><input type="text" id="categoryID""/></div>
+ <div class="fieldLabel">Name*:</div><div class="fieldText"><input type="text" id="categoryName""/></div>
+ <div class="fieldLabel">Description:</div><div class="fieldText"><textarea id="categoryDescription"></textarea></div>
+ </div></div></div>
+ </div>
+ <div id="featureProperties">
+ <div class="sectionTop"><div class="sectionTL"><div class="sectionTR">
+ <h2>Feature Properties</h2>
+ Properties for the selected feature. "*" denotes a required field.<br/>
+ <div class="fieldLabel">ID*:</div><div class="fieldText"><input type="text" id="featureID""/></div>
+ <div class="fieldLabel">Version:</div><div class="fieldText"><input type="text" id="featureVersion""/></div>
+ <div class="fieldLabel">URL*:</div><div class="fieldText"><input type="text" id="featureURL""/></div>
+ <input type="checkbox"/ id="featureIsPatch"> This feature is a patch for another feature
+ </div></div></div>
+ <div class="sectionTop2"><div class="sectionTL"><div class="sectionTR">
+ <h2>Feature Environments</h2>
+ Specify the environments in which this feature can be installed.<br/>
+ Leave blank if the feature does not contain platform-specific code.<br/>
+ <div class="longfieldLabel">Operating Systems:</div><div class="longfieldText"><input type="text" id="featureOS""/></div>
+ <div class="longfieldLabel">Window Systems:</div><div class="longfieldText"><input type="text" id="featureWS""/></div>
+ <div class="longfieldLabel">Languages:</div><div class="longfieldText"><input type="text" id="featureLanguages""/></div>
+ <div class="longfieldLabel">Architecture:</div><div class="longfieldText"><input type="text" id="featureArchitecture""/></div>
+ </div></div></div>
+ </div>
+ </div>
+ </div>
+ <div dojoType="dijit.Dialog" id="featureDialog" title="Dialog Test">
+ Select a feature:<br/>
+ <input id="featureSelect"></input>
+ <input id="featureSelectOK" type="submit" dojoType="dijit.form.Button" value="OK">OK</input>
+ </div>
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.pde.webui/static/tree.js b/bundles/org.eclipse.e4.pde.webui/static/tree.js
new file mode 100644
index 0000000..cd978fb
--- /dev/null
+++ b/bundles/org.eclipse.e4.pde.webui/static/tree.js
@@ -0,0 +1,283 @@
+/*******************************************************************************
+ * 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:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+var dirty = false;
+
+window.e4 = window.e4 || {
+ status : {
+ setMessage : function(msg) { alert(msg); },
+ setDirty : function(d) {
+ dirty = d;
+ dojo.byId("dirtyIndicator").style.visibility = d ? "visible" : "hidden";
+ dojo.byId("saveButton").style.visibility = d ? "visible" : "hidden";
+ }
+ },
+
+ saveable : {
+ doSave : function(callback) {}
+ }
+};
+
+treeRoot = {categories:{}, children:[]};
+
+function doSave() {
+ var jsonData = {categoryDef: [], feature: []};
+ for (var i in treeRoot.children) {
+ var child = treeRoot.children[i];
+ if (child.id) {
+ // child is a feature
+ jsonData.feature.push(child);
+ } else {
+ // child is a category
+ var category = { name: child.name, label: child.label, description: child.label};
+ jsonData.categoryDef.push(category);
+ for (var j in child.children) {
+ var feature = child.children[j];
+ feature.category = {name: child.name};
+ jsonData.feature.push(feature);
+ }
+ }
+ }
+ var jsonString = dojo.toJson(jsonData);
+ //alert(jsonString);
+ dojo.rawXhrPut({
+ url: "/pde/site" + dojo.doc.location.hash.substring(1),
+ putData: jsonString,
+ timeout: 5000,
+ load: function(response, ioArgs) {
+ //alert("success: " + response + ", " + ioArgs);
+ window.e4.status.setDirty(false);
+ return response;
+ },
+ error: function(response, ioArgs) {
+ alert("ERROR: " + response + ", " + ioArgs);
+ return response;
+ }
+ });
+}
+
+dojo.require("dijit.dijit");
+dojo.require("dijit.Dialog");
+dojo.require("dijit.Tree");
+dojo.require("dijit.form.Button");
+dojo.require("dijit.form.FilteringSelect");
+dojo.require("dijit.layout.BorderContainer");
+dojo.require("dijit.layout.ContentPane");
+dojo.require("dojo.data.ItemFileReadStore");
+dojo.require("dojo.cookie");
+
+var modelPrototype = {
+ destroy: function(){
+ },
+
+ getRoot: function(onItem){
+ onItem(this.root);
+ },
+
+ mayHaveChildren: function(/*dojo.data.Item*/ item){
+ var result = item.children != undefined;
+ return result;
+ },
+
+ getChildren: function(/*dojo.data.Item*/ parentItem, /*function(items)*/ onComplete){
+ if (parentItem.children) {
+ onComplete(parentItem.children);
+ } else {
+ onComplete([]);
+ }
+ },
+
+ getIdentity: function(/* item */ item){
+ var result = item.id;
+ if (item === this.root) {
+ result = "ROOT";
+ }
+ if (!result) {
+ result = item.name;
+ }
+ return result;
+ },
+
+ getLabel: function(/*dojo.data.Item*/ item){
+ return item.id || item.name;
+ },
+
+ newItem: function(/* Object? */ args, /*Item?*/ parent){
+ },
+
+ pasteItem: function(/*Item*/ childItem, /*Item*/ oldParentItem, /*Item*/ newParentItem, /*Boolean*/ bCopy){
+ },
+
+ onChange: function(/*dojo.data.Item*/ item){
+ window.e4.status.setDirty(true);
+ },
+
+ onChildrenChange: function(/*dojo.data.Item*/ parent, /*dojo.data.Item[]*/ newChildrenList){
+ window.e4.status.setDirty(true);
+ }
+};
+
+window.onbeforeunload = function (evt) {
+ var message = "You have unsaved changes.";
+ if (dirty) {
+ return message;
+ }
+};
+dojo.addOnLoad(function(){
+ dojo.xhrGet({
+ url: "/pde/site" + dojo.doc.location.hash.substring(1),
+ handleAs: "json-comment-filtered",
+ timeout: 5000,
+ load: function(jsonData, ioArgs) {
+ createTree(jsonData);
+ return jsonData;
+ },
+ error: function(response, ioArgs) {
+ if (ioArgs.xhr && (ioArgs.xhr.status == 403)) {
+ dojo.doc.location.href="/pde/login?nextURL=" + encodeURIComponent(dojo.doc.location.pathname) + encodeURIComponent(dojo.doc.location.search) + encodeURIComponent(dojo.doc.location.hash);
+ }
+ console.error("HTTP status code: ", ioArgs.xhr.status);
+ return response;
+ }
+ });
+});
+
+function createTree(jsonData){
+ for (var c in jsonData.categoryDef) {
+ var category = jsonData.categoryDef[c];
+ treeRoot.categories[category.name] = category;
+ treeRoot.children.push(category);
+ }
+ for (var f in jsonData.feature) {
+ var feature = jsonData.feature[f];
+ if (feature["category"]) {
+ var category = treeRoot.categories[feature["category"].name];
+ if (category) {
+ if (!category.children) {
+ category.children = [];
+ }
+ category.children.push(feature);
+ } else {
+ treeRoot.children.push(feature);
+ }
+ } else {
+ treeRoot.children.push(feature);
+ }
+ }
+ var Model = function(root) { this.root=root; };
+ Model.prototype = modelPrototype;
+ var model = new Model(treeRoot);
+ var detailConnections = [];
+ function bind(connections, inputID, domAttribute, modelObject, modelAttribute) {
+ var inputElement = dojo.byId(inputID);
+ inputElement[domAttribute] = modelObject[modelAttribute];
+ connections.push(
+ dojo.connect(inputElement, "onchange", function() {
+ modelObject[modelAttribute] = inputElement[domAttribute];
+ model.onChange(modelObject);
+ })
+ );
+ connections.push(
+ dojo.connect(inputElement, "onkeypress", function() {
+ model.onChange(modelObject);
+ })
+ );
+ }
+ myTree = new dijit.Tree({
+ id: "myTree",
+ model: model,
+ showRoot: false,
+ getLabel: function(item) {
+ if (item.id) {
+ return item.id + (item.version?(" ("+item.version+")"):"");
+ } else {
+ return item.label;
+ }
+ },
+ onClick: function(item,treeNode) {
+ if (item.id) {
+ dojo.byId("categoryProperties").style.display="none";
+ dojo.forEach(detailConnections, dojo.disconnect);
+ bind(detailConnections, "featureID", "value", item, "id");
+ bind(detailConnections, "featureVersion", "value", item, "version");
+ bind(detailConnections, "featureURL", "value", item, "url");
+ dojo.byId("featureProperties").style.display="block";
+ } else {
+ dojo.byId("featureProperties").style.display="none";
+ dojo.forEach(detailConnections, dojo.disconnect);
+ bind(detailConnections, "categoryID", "value", item, "name");
+ bind(detailConnections, "categoryName", "value", item, "label");
+ bind(detailConnections, "categoryDescription", "innerText", item, "description");
+ dojo.byId("categoryProperties").style.display="block";
+ }
+ },
+ getIconClass: function(/*dojo.data.Item*/ item, /*Boolean*/ opened){
+ return item.id ? "featureItem" : "categoryItem";
+ }
+ });
+ myTree.startup();
+ dojo.byId("tree").appendChild(myTree.domNode);
+ dojo.connect(dojo.byId('newCategory'), 'onclick', function() {
+ var newCategory = {
+ "description":"",
+ "label":"New Category",
+ "name":"newCategory"
+ };
+ treeRoot.children.push(newCategory);
+ model.onChildrenChange(treeRoot, treeRoot.children);
+ var node = myTree._itemNodeMap["newCategory"];
+ myTree.focusNode(node);
+ myTree.onClick(newCategory, node);
+ });
+ dojo.connect(dojo.byId('addFeature'), 'onclick', function() {
+ var featureStore = new dojo.data.ItemFileReadStore({
+ url: "/pde/features/"
+ });
+ var featureSelectWidget = dijit.byId("featureSelect");
+ if (featureSelectWidget) {
+ // since "featureSelectWidget.reset();" doesn't work:
+ featureSelectWidget._hasBeenBlurred = false;
+ featureSelectWidget.setDisplayedValue("");
+ } else {
+ featureSelectWidget = new dijit.form.FilteringSelect({
+ id: "featureSelect",
+ name: "id",
+ store: featureStore,
+ searchAttr: "id"
+ }, "featureSelect");
+ }
+ var dialog = dijit.byId('featureDialog');
+ dojo.connect(dialog, "onExecute", function() {
+ var newFeature = {
+ "category":null,
+ "url":""
+ };
+ var id = dijit.byId("featureSelect").getValue();
+ var newFeature = featureSelectWidget.store._getItemByIdentity(id);
+ treeRoot.children.push(newFeature);
+ model.onChildrenChange(treeRoot, treeRoot.children);
+ var node = myTree._itemNodeMap[newFeature.id];
+ myTree.focusNode(node);
+ myTree.onClick(newFeature, node);
+ });
+ dialog.show();
+ });
+ dojo.connect(dojo.byId('synchronize'), 'onclick', function() {
+ alert("Sorry - 'Synchronize' is not yet implemented.");
+ });
+ dojo.connect(dojo.byId('build'), 'onclick', function() {
+ alert("Sorry - 'Build' is not yet implemented.");
+ });
+ dojo.connect(dojo.byId('buildAll'), 'onclick', function() {
+ alert("Sorry - 'BuildAll' is not yet implemented.");
+ });
+ window.e4.saveable.doSave("doSave();");
+}
diff --git a/bundles/org.eclipse.e4.ui.css.jface/.classpath b/bundles/org.eclipse.e4.ui.css.jface/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.ui.css.jface/.project b/bundles/org.eclipse.e4.ui.css.jface/.project
new file mode 100644
index 0000000..a6aab21
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.ui.css.jface</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.ui.css.jface/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.ui.css.jface/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..28f50da
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Tue Nov 18 20:31:15 EST 2008
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
diff --git a/bundles/org.eclipse.e4.ui.css.jface/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.ui.css.jface/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..9a3188f
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/META-INF/MANIFEST.MF
@@ -0,0 +1,15 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.eclipse.e4.ui.css.jface
+Bundle-Version: 0.9.0.qualifier
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-Activator: org.eclipse.e4.ui.css.jface.Activator
+Require-Bundle: org.eclipse.ui;bundle-version="3.4.1",
+ org.eclipse.core.runtime;bundle-version="3.4.0",
+ org.eclipse.e4.ui.css.core;bundle-version="0.9.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.e4.ui.css.jface;x-internal:=true,
+ org.eclipse.e4.ui.css.jface.viewers;x-internal:=true
diff --git a/bundles/org.eclipse.e4.ui.css.jface/about.html b/bundles/org.eclipse.e4.ui.css.jface/about.html
new file mode 100644
index 0000000..3ce4e7e
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>November 20, 2008</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.ui.css.jface/build.properties b/bundles/org.eclipse.e4.ui.css.jface/build.properties
new file mode 100644
index 0000000..9d06aea
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/build.properties
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 2010 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
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ about.html,\
+ plugin.properties
diff --git a/bundles/org.eclipse.e4.ui.css.jface/plugin.properties b/bundles/org.eclipse.e4.ui.css.jface/plugin.properties
new file mode 100644
index 0000000..cdff0c5
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/plugin.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2010 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
+###############################################################################
+pluginName = Eclipse CSS JFace Support
+providerName = Eclipse.org
diff --git a/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/Activator.java b/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/Activator.java
new file mode 100644
index 0000000..faa99f0
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/Activator.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.e4.ui.css.jface;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.e4.ui.css.jface";
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSBaseLabelProvider.java b/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSBaseLabelProvider.java
new file mode 100644
index 0000000..d0d5310
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSBaseLabelProvider.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Angelo Zerr 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.jface.viewers;
+
+import org.eclipse.e4.ui.css.core.css2.CSS2FontPropertiesHelpers;
+import org.eclipse.e4.ui.css.core.dom.properties.css2.CSS2FontProperties;
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Widget;
+import org.w3c.dom.Element;
+import org.w3c.dom.css.CSSStyleDeclaration;
+import org.w3c.dom.css.CSSValue;
+
+public class CSSBaseLabelProvider extends LabelProvider {
+
+ protected CSSEngine engine;
+ protected StructuredViewer viewer;
+
+ public CSSBaseLabelProvider(CSSEngine engine, StructuredViewer viewer) {
+ this.engine = engine;
+ this.viewer = viewer;
+ }
+
+ protected Font getFont(Object element, String propertyName, int columnIndex) {
+ Widget widget = getWidget(element, columnIndex);
+ return getFont(widget, propertyName);
+ }
+
+ protected Font getFont(Object element, String propertyName) {
+ Widget widget = getWidget(element);
+ return getFont(widget, propertyName);
+ }
+
+ protected Font getFont(Widget widget, String propertyName) {
+ CSSValue value = getCSSValue(widget, propertyName);
+ if (value == null)
+ return null;
+ CSS2FontProperties fontProperties = CSS2FontPropertiesHelpers
+ .createCSS2FontProperties(value, propertyName);
+ try {
+ return (Font) engine.convert(fontProperties, Font.class, widget
+ .getDisplay());
+ } catch (Exception e) {
+ engine.handleExceptions(e);
+ }
+ return null;
+ }
+
+ protected Image getImage(Object element, String propertyName,
+ int columnIndex) {
+ Widget widget = getWidget(element, columnIndex);
+ return getImage(widget, propertyName);
+ }
+
+ protected Image getImage(Object element, String propertyName) {
+ Widget widget = getWidget(element);
+ return getImage(widget, propertyName);
+ }
+
+ protected Image getImage(Widget widget, String propertyName) {
+ return (Image) getResource(widget, propertyName, Image.class);
+ }
+
+ protected Color getColor(Object element, String propertyName,
+ int columnIndex) {
+ Widget widget = getWidget(element, columnIndex);
+ return getColor(widget, propertyName);
+ }
+
+ protected Color getColor(Object element, String propertyName) {
+ Widget widget = getWidget(element);
+ return getColor(widget, propertyName);
+ }
+
+ protected Color getColor(Widget widget, String propertyName) {
+ return (Color) getResource(widget, propertyName, Color.class);
+ }
+
+ protected Object getResource(Widget widget, String propertyName,
+ Object toType) {
+ CSSValue value = getCSSValue(widget, propertyName);
+ if (value != null) {
+ try {
+ return engine.convert(value, toType, widget.getDisplay());
+ } catch (Exception e) {
+ engine.handleExceptions(e);
+ }
+ }
+ return null;
+ }
+
+ protected CSSValue getCSSValue(Widget widget, String propertyName) {
+ if (widget == null)
+ return null;
+ Element elt = engine.getElement(widget);
+ if (elt == null)
+ return null;
+ CSSStyleDeclaration styleDeclaration = engine.getViewCSS()
+ .getComputedStyle(elt, null);
+ if (styleDeclaration == null)
+ return null;
+
+ return styleDeclaration.getPropertyCSSValue(propertyName);
+ }
+
+ protected Widget getWidget(Object element) {
+ return viewer.testFindItem(element);
+ }
+
+ protected Widget getWidget(Object element, int columnIndex) {
+// Widget[] widgets = viewer.testFindItems(element);
+// if (widgets.length > columnIndex)
+// return widgets[columnIndex];
+ return null;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSLabelProvider.java b/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSLabelProvider.java
new file mode 100644
index 0000000..e5d3c25
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSLabelProvider.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Angelo Zerr 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.jface.viewers;
+
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.jface.viewers.IColorProvider;
+import org.eclipse.jface.viewers.IFontProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+
+public abstract class CSSLabelProvider extends CSSBaseLabelProvider implements
+ ILabelProvider, IColorProvider, IFontProvider {
+
+ public CSSLabelProvider(CSSEngine engine, TableViewer tableViewer) {
+ super(engine, tableViewer);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
+ */
+ public Image getImage(Object element) {
+ return getImage(element, "background-image");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object)
+ */
+ public Color getBackground(Object element) {
+ return getColor(element, "background-color");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object)
+ */
+ public Color getForeground(Object element) {
+ return getColor(element, "color");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.IFontProvider#getFont(java.lang.Object)
+ */
+ public Font getFont(Object element) {
+ return getFont(element, "font");
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSTableLabelProvider.java b/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSTableLabelProvider.java
new file mode 100644
index 0000000..e8db8a9
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.jface/src/org/eclipse/e4/ui/css/jface/viewers/CSSTableLabelProvider.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Angelo Zerr 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.jface.viewers;
+
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.jface.viewers.ITableColorProvider;
+import org.eclipse.jface.viewers.ITableFontProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+
+public abstract class CSSTableLabelProvider extends CSSBaseLabelProvider
+ implements ITableLabelProvider, ITableColorProvider, ITableFontProvider {
+
+ public CSSTableLabelProvider(CSSEngine engine, TableViewer tableViewer) {
+ super(engine, tableViewer);
+ }
+
+ public Color getBackground(Object element, int columnIndex) {
+ return getColor(element, "background-color", columnIndex);
+ }
+
+ public Font getFont(Object element, int columnIndex) {
+ return getFont(element, "font", columnIndex);
+ }
+
+ public Color getForeground(Object element, int columnIndex) {
+ return getColor(element, "color", columnIndex);
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.legacy/.classpath b/bundles/org.eclipse.e4.ui.css.legacy/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.legacy/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.ui.css.legacy/.project b/bundles/org.eclipse.e4.ui.css.legacy/.project
new file mode 100644
index 0000000..785b4ad
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.legacy/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.ui.css.legacy</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.ui.css.legacy/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.ui.css.legacy/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..6d16c74
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.legacy/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Wed Feb 25 20:08:17 EST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/bundles/org.eclipse.e4.ui.css.legacy/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.ui.css.legacy/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..0ca6d41
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.legacy/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Legacy CSS Presentation Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.ui.css.legacy;singleton:=true
+Bundle-Version: 0.9.1.qualifier
+Require-Bundle: org.eclipse.ui;bundle-version="[3.6.0,3.100.0)",
+ org.eclipse.core.runtime,
+ org.eclipse.e4.ui.css.core;bundle-version="0.9.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.e4.ui.css.legacy.presentation
+Bundle-Vendor: Eclipse.org
diff --git a/bundles/org.eclipse.e4.ui.css.legacy/build.properties b/bundles/org.eclipse.e4.ui.css.legacy/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.legacy/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml
diff --git a/bundles/org.eclipse.e4.ui.css.legacy/plugin.xml b/bundles/org.eclipse.e4.ui.css.legacy/plugin.xml
new file mode 100644
index 0000000..aa3ac36
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.legacy/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+ <extension
+ point="org.eclipse.ui.presentationFactories">
+ <factory
+ class="org.eclipse.e4.ui.css.legacy.presentation.CSSPresentationFactory"
+ id="org.eclipse.e4.ui.css.legacy.presentation.presentationFactory"
+ name="CSS Presentation">
+ </factory>
+ </extension>
+</plugin>
diff --git a/bundles/org.eclipse.e4.ui.css.legacy/src/org/eclipse/e4/ui/css/legacy/presentation/CSSPresentationFactory.java b/bundles/org.eclipse.e4.ui.css.legacy/src/org/eclipse/e4/ui/css/legacy/presentation/CSSPresentationFactory.java
new file mode 100644
index 0000000..2084ca1
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.legacy/src/org/eclipse/e4/ui/css/legacy/presentation/CSSPresentationFactory.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * 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.e4.ui.css.legacy.presentation;
+
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.internal.css.legacy.presentation.CSSTabFolder;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbenchPreferenceConstants;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.presentations.defaultpresentation.DefaultMultiTabListener;
+import org.eclipse.ui.internal.presentations.defaultpresentation.DefaultSimpleTabListener;
+import org.eclipse.ui.internal.presentations.util.PresentablePartFolder;
+import org.eclipse.ui.internal.presentations.util.StandardEditorSystemMenu;
+import org.eclipse.ui.internal.presentations.util.StandardViewSystemMenu;
+import org.eclipse.ui.internal.presentations.util.TabbedStackPresentation;
+import org.eclipse.ui.presentations.IStackPresentationSite;
+import org.eclipse.ui.presentations.StackPresentation;
+import org.eclipse.ui.presentations.WorkbenchPresentationFactory;
+
+/**
+ *
+ * @since 3.5
+ *
+ */
+public class CSSPresentationFactory extends
+ WorkbenchPresentationFactory {
+
+ public static String ID = "org.eclipse.e4.ui.css.legacy.presentation.presentationFactory";
+
+ // don't reset these dynamically, so just keep the information static.
+ // see bug:
+ // 75422 [Presentations] Switching presentation to R21 switches immediately,
+ // but only partially
+ private static int editorTabPosition = PlatformUI.getPreferenceStore()
+ .getInt(IWorkbenchPreferenceConstants.EDITOR_TAB_POSITION);
+ private static int viewTabPosition = PlatformUI.getPreferenceStore()
+ .getInt(IWorkbenchPreferenceConstants.VIEW_TAB_POSITION);
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.presentations.AbstractPresentationFactory#createEditorPresentation(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.ui.presentations.IStackPresentationSite)
+ */
+ public StackPresentation createEditorPresentation(Composite parent,
+ IStackPresentationSite site) {
+ CSSTabFolder folder = new CSSTabFolder(parent,
+ editorTabPosition | SWT.BORDER, site
+ .supportsState(IStackPresentationSite.STATE_MINIMIZED),
+ site.supportsState(IStackPresentationSite.STATE_MAXIMIZED));
+
+ /*
+ * Set the minimum characters to display, if the preference is something
+ * other than the default. This is mainly intended for RCP applications
+ * or for expert users (i.e., via the plug-in customization file).
+ *
+ * Bug 32789.
+ */
+ final IPreferenceStore store = PlatformUI.getPreferenceStore();
+ if (store
+ .contains(IWorkbenchPreferenceConstants.EDITOR_MINIMUM_CHARACTERS)) {
+ final int minimumCharacters = store
+ .getInt(IWorkbenchPreferenceConstants.EDITOR_MINIMUM_CHARACTERS);
+ if (minimumCharacters >= 0) {
+ folder.setMinimumCharacters(minimumCharacters);
+ }
+ }
+
+ PresentablePartFolder partFolder = new PresentablePartFolder(folder);
+
+ TabbedStackPresentation result = new TabbedStackPresentation(site,
+ partFolder, new StandardEditorSystemMenu(site));
+
+ new DefaultMultiTabListener(result.getApiPreferences(),
+ IWorkbenchPreferenceConstants.SHOW_MULTIPLE_EDITOR_TABS, folder);
+
+ new DefaultSimpleTabListener(result.getApiPreferences(),
+ IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS,
+ folder);
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.presentations.AbstractPresentationFactory#createViewPresentation(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.ui.presentations.IStackPresentationSite)
+ */
+ public StackPresentation createViewPresentation(Composite parent,
+ IStackPresentationSite site) {
+
+ CSSTabFolder folder = new CSSTabFolder(parent, viewTabPosition
+ | SWT.BORDER, site
+ .supportsState(IStackPresentationSite.STATE_MINIMIZED), site
+ .supportsState(IStackPresentationSite.STATE_MAXIMIZED));
+
+ final IPreferenceStore store = PlatformUI.getPreferenceStore();
+ final int minimumCharacters = store
+ .getInt(IWorkbenchPreferenceConstants.VIEW_MINIMUM_CHARACTERS);
+ if (minimumCharacters >= 0) {
+ folder.setMinimumCharacters(minimumCharacters);
+ }
+
+ PresentablePartFolder partFolder = new PresentablePartFolder(folder);
+
+ folder.setUnselectedCloseVisible(false);
+ folder.setUnselectedImageVisible(true);
+
+ TabbedStackPresentation result = new TabbedStackPresentation(site,
+ partFolder, new StandardViewSystemMenu(site));
+
+ new DefaultSimpleTabListener(result.getApiPreferences(),
+ IWorkbenchPreferenceConstants.SHOW_TRADITIONAL_STYLE_TABS,
+ folder);
+
+ return result;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.css.legacy/src/org/eclipse/e4/ui/internal/css/legacy/presentation/CSSTabFolder.java b/bundles/org.eclipse.e4.ui.css.legacy/src/org/eclipse/e4/ui/internal/css/legacy/presentation/CSSTabFolder.java
new file mode 100644
index 0000000..b6155f8
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.legacy/src/org/eclipse/e4/ui/internal/css/legacy/presentation/CSSTabFolder.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * 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.e4.ui.internal.css.legacy.presentation;
+
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.internal.presentations.defaultpresentation.DefaultTabFolder;
+import org.eclipse.ui.internal.presentations.defaultpresentation.DefaultTabItem;
+import org.eclipse.ui.internal.presentations.util.AbstractTabItem;
+
+/**
+ * @since 3.5
+ */
+public class CSSTabFolder extends DefaultTabFolder {
+
+ public CSSTabFolder(Composite parent, int flags, boolean allowMin,
+ boolean allowMax) {
+ super(parent, flags, allowMin, allowMax);
+ // TODO Auto-generated constructor stub
+ }
+ public void updateColors() {
+ //do nothing, CSS will handle
+ }
+
+ public AbstractTabItem add(int index, int flags) {
+ DefaultTabItem result = (DefaultTabItem) super.add(index, flags);
+ Widget widget = result.getWidget();
+
+ CSSEngine engine = getEngine(widget.getDisplay());
+ if(engine != null) {
+ engine.applyStyles(widget, true);
+ }
+
+ return result;
+ }
+
+ private CSSEngine getEngine(Display display) {
+ //TODO post 0.9 this can be retrieved via API on SWTElement
+ return (CSSEngine) display.getData("org.eclipse.e4.ui.css.core.engine");
+ }
+
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/.classpath b/bundles/org.eclipse.e4.ui.css.nebula/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/.project b/bundles/org.eclipse.e4.ui.css.nebula/.project
new file mode 100644
index 0000000..ef335c8
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.ui.css.nebula</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.ui.css.nebula/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..9b6c36f
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Wed Jan 28 17:50:20 EST 2009
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.ui.css.nebula/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e739188
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/META-INF/MANIFEST.MF
@@ -0,0 +1,18 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: CSS Nebula Support Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.ui.css.nebula
+Bundle-Version: 0.9.0.qualifier
+Require-Bundle: org.eclipse.swt;bundle-version="3.4.1",
+ org.eclipse.e4.ui.css.core;bundle-version="0.9.0",
+ org.eclipse.e4.ui.css.swt;bundle-version="0.9.0",
+ org.eclipse.nebula.widgets.gallery;bundle-version="1.0.0",
+ org.w3c.css.sac;bundle-version="1.3.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.e4.ui.css.nebula.dom,
+ org.eclipse.e4.ui.css.nebula.engine,
+ org.eclipse.e4.ui.css.nebula.gallery,
+ org.eclipse.e4.ui.css.nebula.helpers,
+ org.eclipse.e4.ui.css.nebula.properties.css2
+Bundle-Vendor: Eclipse.org
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/build.properties b/bundles/org.eclipse.e4.ui.css.nebula/build.properties
new file mode 100644
index 0000000..dd019cd
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/build.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2010 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
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/dom/NebulaElement.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/dom/NebulaElement.java
new file mode 100644
index 0000000..c8451be
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/dom/NebulaElement.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.dom;
+
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.css.swt.dom.WidgetElement;
+import org.eclipse.nebula.widgets.gallery.Gallery;
+import org.eclipse.nebula.widgets.gallery.GalleryItem;
+import org.eclipse.swt.widgets.Widget;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class NebulaElement extends WidgetElement {
+
+ public NebulaElement(Widget widget, CSSEngine engine) {
+ super(widget, engine);
+ }
+
+ public NodeList getChildNodes() {
+ return super.getChildNodes();
+ }
+
+ protected void computeStaticPseudoInstances() {
+ Widget widget = getWidget();
+ if (widget instanceof GalleryItem) {
+ // it's GalleryItem. Set selected as static pseudo instance.
+ // because this widget define methods
+ // GalleryItem#setSelectionBackground (Color color)
+ // which set background Color when a CTabItem is selected.
+ super.addStaticPseudoInstance("selected");
+ }
+ super.computeStaticPseudoInstances();
+ }
+
+ public Node getParentNode() {
+ Widget widget = getWidget();
+ if (widget instanceof GalleryItem) {
+ GalleryItem galleryItem = (GalleryItem) widget;
+ Widget parent = galleryItem.getParentItem();
+ if (parent == null)
+ parent = galleryItem.getParent();
+ if (parent != null) {
+ Element element = getElement(parent);
+ return element;
+ }
+ }
+ return super.getParentNode();
+ }
+
+ public int getLength() {
+ Widget widget = getWidget();
+ if (widget instanceof Gallery) {
+ Gallery gallery = (Gallery) widget;
+ return gallery.getItemCount();
+ }
+ if (widget instanceof GalleryItem) {
+ GalleryItem galleryItem = (GalleryItem) widget;
+ return galleryItem.getItemCount();
+ }
+ return super.getLength();
+ }
+
+ public Node item(int index) {
+ Widget widget = getWidget();
+ if (widget instanceof Gallery) {
+ Gallery gallery = (Gallery) widget;
+ GalleryItem galleryItem = gallery.getItem(index);
+ return getElement(galleryItem);
+ }
+ if (widget instanceof GalleryItem) {
+ GalleryItem galleryItem = (GalleryItem) widget;
+ GalleryItem galleryItemChild = galleryItem.getItem(index);
+ return getElement(galleryItemChild);
+ }
+ return super.item(index);
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/dom/NebulaElementProvider.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/dom/NebulaElementProvider.java
new file mode 100644
index 0000000..cdef92e
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/dom/NebulaElementProvider.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.dom;
+
+import org.eclipse.e4.ui.css.core.dom.IElementProvider;
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.css.nebula.helpers.NebulaElementHelpers;
+import org.eclipse.swt.widgets.Widget;
+import org.w3c.dom.Element;
+
+/**
+ * {@link IElementProvider} SWT and Nebula widget implementation to retrieve w3c
+ * Element {@link SWTElement} linked to SWT widget.
+ *
+ * @version 1.0.0
+ * @author <a href="mailto:angelo.zerr@gmail.com">Angelo ZERR</a>
+ *
+ */
+public class NebulaElementProvider implements IElementProvider {
+
+ public static final IElementProvider INSTANCE = new NebulaElementProvider();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.e4.ui.css.swt.dom.SWTElementProvider#getElement(java.lang.Object,
+ * org.eclipse.e4.ui.css.core.engine.CSSEngine)
+ */
+ public Element getElement(Object element, CSSEngine engine) {
+ if (element instanceof Widget) {
+ // element is SWT Widget
+ Widget widget = (Widget) element;
+ // Return the w3c Element linked to the SWT widget.
+ return NebulaElementHelpers.getElement(widget, engine);
+ }
+ return null;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/engine/CSSNebulaEngineImpl.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/engine/CSSNebulaEngineImpl.java
new file mode 100644
index 0000000..9419348
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/engine/CSSNebulaEngineImpl.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ * IBM Corporation - ongoing development
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.engine;
+
+import org.eclipse.e4.ui.css.core.dom.properties.css2.ICSSPropertyBackgroundHandler;
+import org.eclipse.e4.ui.css.core.dom.properties.css2.ICSSPropertyTextHandler;
+import org.eclipse.e4.ui.css.nebula.dom.NebulaElementProvider;
+import org.eclipse.e4.ui.css.nebula.properties.css2.CSSPropertyBackgroundNebulaHandler;
+import org.eclipse.e4.ui.css.nebula.properties.css2.CSSPropertyTextNebulaHandler;
+import org.eclipse.e4.ui.css.swt.engine.CSSSWTEngineImpl;
+import org.eclipse.swt.widgets.Display;
+
+public class CSSNebulaEngineImpl extends CSSSWTEngineImpl {
+
+ public CSSNebulaEngineImpl(Display display) {
+ super(display);
+ this.initializeNebulaConfig();
+ }
+
+ public CSSNebulaEngineImpl(Display display, boolean lazyApplyingStyles) {
+ super(display, lazyApplyingStyles);
+ this.initializeNebulaConfig();
+ }
+
+ protected void initializeNebulaConfig() {
+ // Register Nebula Element Provider to retrieve
+ // w3c Element NebulaElement which wrap SWT/Nebula widget.
+ super.setElementProvider(NebulaElementProvider.INSTANCE);
+ }
+
+ protected void initializeCSSPropertyHandlers() {
+ // Register Nebula CSS Property Background Handler
+ super.registerCSSPropertyHandler(ICSSPropertyBackgroundHandler.class,
+ CSSPropertyBackgroundNebulaHandler.INSTANCE);
+ // Register Nebula CSS Property Text Handler
+ super.registerCSSPropertyHandler(ICSSPropertyTextHandler.class,
+ CSSPropertyTextNebulaHandler.INSTANCE);
+ super.initializeCSSPropertyHandlers();
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/DefaultGalleryItemRendererDelegate.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/DefaultGalleryItemRendererDelegate.java
new file mode 100644
index 0000000..32ff93b
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/DefaultGalleryItemRendererDelegate.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.gallery;
+
+import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer;
+import org.eclipse.swt.graphics.Color;
+
+public class DefaultGalleryItemRendererDelegate implements IGalleryItemRenderer {
+
+ private DefaultGalleryItemRenderer itemRenderer;
+
+ public DefaultGalleryItemRendererDelegate(
+ DefaultGalleryItemRenderer itemRenderer) {
+ this.itemRenderer = itemRenderer;
+ }
+
+ public Color getBackgroundColor() {
+ return itemRenderer.getBackgroundColor();
+ }
+
+ public Color getForegroundColor() {
+ return itemRenderer.getForegroundColor();
+ }
+
+ public Color getSelectionBackgroundColor() {
+ return itemRenderer.getSelectionBackgroundColor();
+ }
+
+ public Color getSelectionForegroundColor() {
+ return itemRenderer.getSelectionForegroundColor();
+ }
+
+ public void setBackgroundColor(Color backgroundColor) {
+ itemRenderer.setBackgroundColor(backgroundColor);
+ }
+
+ public void setForegroundColor(Color foregroundColor) {
+ itemRenderer.setForegroundColor(foregroundColor);
+ }
+
+ public void setSelectionBackgroundColor(Color selectionBackgroundColor) {
+ itemRenderer.setSelectionBackgroundColor(selectionBackgroundColor);
+ }
+
+ public void setSelectionForegroundColor(Color selectionForegroundColor) {
+ itemRenderer.setSelectionForegroundColor(selectionForegroundColor);
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/IGalleryItemRenderer.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/IGalleryItemRenderer.java
new file mode 100644
index 0000000..9e5e93f
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/IGalleryItemRenderer.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.gallery;
+
+import org.eclipse.swt.graphics.Color;
+
+public interface IGalleryItemRenderer {
+
+ public Color getForegroundColor();
+
+ public void setForegroundColor(Color foregroundColor);
+
+ public Color getSelectionForegroundColor();
+
+ public void setSelectionForegroundColor(Color selectionForegroundColor);
+
+ public Color getSelectionBackgroundColor();
+
+ public void setSelectionBackgroundColor(Color selectionBackgroundColor);
+
+ public Color getBackgroundColor();
+
+ public void setBackgroundColor(Color backgroundColor);
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/ListItemRendererDelegate.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/ListItemRendererDelegate.java
new file mode 100644
index 0000000..cbbdd3b
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/gallery/ListItemRendererDelegate.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.gallery;
+
+import org.eclipse.nebula.widgets.gallery.ListItemRenderer;
+import org.eclipse.swt.graphics.Color;
+
+public class ListItemRendererDelegate implements IGalleryItemRenderer {
+
+ private ListItemRenderer itemRenderer;
+
+ public ListItemRendererDelegate(
+ ListItemRenderer itemRenderer) {
+ this.itemRenderer = itemRenderer;
+ }
+
+ public Color getBackgroundColor() {
+ return itemRenderer.getBackgroundColor();
+ }
+
+ public Color getForegroundColor() {
+ return itemRenderer.getForegroundColor();
+ }
+
+ public Color getSelectionBackgroundColor() {
+ return itemRenderer.getSelectionBackgroundColor();
+ }
+
+ public Color getSelectionForegroundColor() {
+ return itemRenderer.getSelectionForegroundColor();
+ }
+
+ public void setBackgroundColor(Color backgroundColor) {
+ itemRenderer.setBackgroundColor(backgroundColor);
+ }
+
+ public void setForegroundColor(Color foregroundColor) {
+ itemRenderer.setForegroundColor(foregroundColor);
+ }
+
+ public void setSelectionBackgroundColor(Color selectionBackgroundColor) {
+ itemRenderer.setSelectionBackgroundColor(selectionBackgroundColor);
+ }
+
+ public void setSelectionForegroundColor(Color selectionForegroundColor) {
+ itemRenderer.setSelectionForegroundColor(selectionForegroundColor);
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/helpers/GalleryHelpers.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/helpers/GalleryHelpers.java
new file mode 100644
index 0000000..96a4ae0
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/helpers/GalleryHelpers.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.helpers;
+
+import org.eclipse.e4.ui.css.nebula.gallery.DefaultGalleryItemRendererDelegate;
+import org.eclipse.e4.ui.css.nebula.gallery.IGalleryItemRenderer;
+import org.eclipse.nebula.widgets.gallery.AbstractGalleryItemRenderer;
+import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer;
+import org.eclipse.nebula.widgets.gallery.Gallery;
+import org.eclipse.nebula.widgets.gallery.GalleryItem;
+import org.eclipse.swt.graphics.Color;
+
+public class GalleryHelpers {
+
+ private static final String ITEM_RENDERER_KEY = "org.eclipse.e4.ui.css.nebula.helpers.ITEM_RENDERER_KEY";
+
+ public static AbstractGalleryItemRenderer getItemRenderer(
+ GalleryItem galleryItem) {
+ return getItemRenderer(galleryItem.getParent());
+ }
+
+ public static AbstractGalleryItemRenderer getItemRenderer(Gallery gallery) {
+
+ return gallery.getItemRenderer();
+ }
+
+ public static Color getSelectionBackgroundColor(Gallery gallery) {
+ IGalleryItemRenderer itemRenderer = getGalleryItemRenderer(gallery);
+ if (itemRenderer != null) {
+ return itemRenderer.getSelectionBackgroundColor();
+ }
+ return null;
+ }
+
+ public static void setSelectionBackgroundColor(Gallery gallery, Color color) {
+ IGalleryItemRenderer itemRenderer = getGalleryItemRenderer(gallery);
+ if (itemRenderer != null) {
+ itemRenderer.setSelectionBackgroundColor(color);
+ }
+ }
+
+ public static Color getSelectionForegroundColor(Gallery gallery) {
+ IGalleryItemRenderer itemRenderer = getGalleryItemRenderer(gallery);
+ if (itemRenderer != null) {
+ return itemRenderer.getSelectionForegroundColor();
+ }
+ return null;
+ }
+
+ public static void setSelectionForegroundColor(Gallery gallery, Color color) {
+ IGalleryItemRenderer itemRenderer = getGalleryItemRenderer(gallery);
+ if (itemRenderer != null) {
+ itemRenderer.setSelectionForegroundColor(color);
+ }
+ }
+
+ public static IGalleryItemRenderer getGalleryItemRenderer(Gallery gallery) {
+ AbstractGalleryItemRenderer itemRenderer = gallery.getItemRenderer();
+ if (itemRenderer instanceof IGalleryItemRenderer)
+ return (IGalleryItemRenderer) itemRenderer;
+ IGalleryItemRenderer galleryItemRenderer = (IGalleryItemRenderer) gallery
+ .getData(ITEM_RENDERER_KEY);
+ if (galleryItemRenderer != null)
+ return galleryItemRenderer;
+ // DefaultGalleryItemRenderer
+ if (itemRenderer instanceof DefaultGalleryItemRenderer) {
+ galleryItemRenderer = new DefaultGalleryItemRendererDelegate(
+ (DefaultGalleryItemRenderer) itemRenderer);
+ }
+ // DefaultGalleryItemRenderer
+ if (itemRenderer instanceof DefaultGalleryItemRenderer) {
+ galleryItemRenderer = new DefaultGalleryItemRendererDelegate(
+ (DefaultGalleryItemRenderer) itemRenderer);
+ }
+ if (galleryItemRenderer != null)
+ gallery.setData(ITEM_RENDERER_KEY, galleryItemRenderer);
+ return galleryItemRenderer;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/helpers/NebulaElementHelpers.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/helpers/NebulaElementHelpers.java
new file mode 100644
index 0000000..303c03f
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/helpers/NebulaElementHelpers.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.helpers;
+
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.css.nebula.dom.NebulaElement;
+import org.eclipse.e4.ui.css.swt.helpers.SWTElementHelpers;
+import org.eclipse.nebula.widgets.gallery.GalleryItem;
+import org.eclipse.swt.widgets.Widget;
+import org.w3c.dom.Element;
+
+public class NebulaElementHelpers extends SWTElementHelpers {
+
+ /**
+ * Return the w3c Element linked to the SWT widget.
+ *
+ * @param widget
+ * @return
+ */
+ public static Element getElement(Widget widget, CSSEngine engine) {
+ try {
+ return getElement(widget, engine, NebulaElement.class);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public static boolean isNebulaWidget(Object element) {
+ Widget widget = getWidget(element);
+ if (widget instanceof GalleryItem)
+ return true;
+ return false;
+
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/properties/css2/CSSPropertyBackgroundNebulaHandler.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/properties/css2/CSSPropertyBackgroundNebulaHandler.java
new file mode 100644
index 0000000..f07cd80
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/properties/css2/CSSPropertyBackgroundNebulaHandler.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.properties.css2;
+
+import org.eclipse.e4.ui.css.core.dom.properties.css2.AbstractCSSPropertyBackgroundHandler;
+import org.eclipse.e4.ui.css.core.dom.properties.css2.ICSSPropertyBackgroundHandler;
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.css.nebula.helpers.GalleryHelpers;
+import org.eclipse.e4.ui.css.nebula.helpers.NebulaElementHelpers;
+import org.eclipse.e4.ui.css.swt.helpers.SWTElementHelpers;
+import org.eclipse.nebula.widgets.gallery.GalleryItem;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Widget;
+import org.w3c.dom.css.CSSValue;
+
+public class CSSPropertyBackgroundNebulaHandler extends
+ AbstractCSSPropertyBackgroundHandler {
+
+ public final static ICSSPropertyBackgroundHandler INSTANCE = new CSSPropertyBackgroundNebulaHandler();
+
+ public boolean applyCSSProperty(Object element, String property,
+ CSSValue value, String pseudo, CSSEngine engine) throws Exception {
+ if (!NebulaElementHelpers.isNebulaWidget(element))
+ return false;
+ Widget widget = SWTElementHelpers.getWidget(element);
+ if (widget != null) {
+ super.applyCSSProperty(widget, property, value, pseudo, engine);
+ return true;
+ }
+ return false;
+ }
+
+ public String retrieveCSSProperty(Object element, String property,
+ String pseudo, CSSEngine engine) throws Exception {
+ if (!NebulaElementHelpers.isNebulaWidget(element))
+ return null;
+ Widget widget = SWTElementHelpers.getWidget(element);
+ if (widget != null) {
+ return super.retrieveCSSProperty(widget, property, pseudo, engine);
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.e4.ui.core.css.dom.properties.css2.AbstractCSSPropertyBackgroundHandler#applyCSSPropertyBackgroundColor(java.lang.Object,
+ * org.w3c.dom.css.CSSValue, java.lang.String,
+ * org.eclipse.e4.ui.core.css.engine.CSSEngine)
+ */
+ public void applyCSSPropertyBackgroundColor(Object element, CSSValue value,
+ String pseudo, CSSEngine engine) throws Exception {
+ Widget widget = (Widget) element;
+ if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ Color newColor = (Color) engine.convert(value, Color.class, widget
+ .getDisplay());
+ if (widget instanceof GalleryItem) {
+ GalleryItem galleryItem = (GalleryItem) widget;
+ if ("selected".equals(pseudo)) {
+ GalleryHelpers.setSelectionBackgroundColor(galleryItem
+ .getParent(), newColor);
+ } else
+ galleryItem.setBackground(newColor);
+
+ } else {
+ if (widget instanceof Control)
+ ((Control) widget).setBackground(newColor);
+ }
+ }
+ }
+
+ public String retrieveCSSPropertyBackgroundAttachment(Object element,
+ String pseudo, CSSEngine engine) throws Exception {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String retrieveCSSPropertyBackgroundColor(Object element,
+ String pseudo, CSSEngine engine) throws Exception {
+ Widget widget = (Widget) element;
+ Color color = null;
+ if (widget instanceof GalleryItem) {
+ GalleryItem galleryItem = (GalleryItem) widget;
+ if ("selected".equals(pseudo)) {
+ color = GalleryHelpers.getSelectionBackgroundColor(galleryItem
+ .getParent());
+ } else {
+ color = galleryItem.getBackground();
+ }
+ }
+ if (color != null) {
+ return engine.convert(color, Color.class, null);
+ }
+ return null;
+ }
+
+ public String retrieveCSSPropertyBackgroundImage(Object element,
+ String pseudo, CSSEngine engine) throws Exception {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String retrieveCSSPropertyBackgroundPosition(Object element,
+ String pseudo, CSSEngine engine) throws Exception {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String retrieveCSSPropertyBackgroundRepeat(Object element,
+ String pseudo, CSSEngine engine) throws Exception {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/properties/css2/CSSPropertyTextNebulaHandler.java b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/properties/css2/CSSPropertyTextNebulaHandler.java
new file mode 100644
index 0000000..3e6f896
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.nebula/src/org/eclipse/e4/ui/css/nebula/properties/css2/CSSPropertyTextNebulaHandler.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 Angelo Zerr 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.nebula.properties.css2;
+
+import org.eclipse.e4.ui.css.core.dom.properties.css2.AbstractCSSPropertyTextHandler;
+import org.eclipse.e4.ui.css.core.dom.properties.css2.ICSSPropertyTextHandler;
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.css.nebula.helpers.GalleryHelpers;
+import org.eclipse.e4.ui.css.nebula.helpers.NebulaElementHelpers;
+import org.eclipse.e4.ui.css.swt.helpers.SWTElementHelpers;
+import org.eclipse.nebula.widgets.gallery.GalleryItem;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Widget;
+import org.w3c.dom.css.CSSValue;
+
+public class CSSPropertyTextNebulaHandler extends
+ AbstractCSSPropertyTextHandler {
+
+ public final static ICSSPropertyTextHandler INSTANCE = new CSSPropertyTextNebulaHandler();
+
+ public boolean applyCSSProperty(Object element, String property,
+ CSSValue value, String pseudo, CSSEngine engine) throws Exception {
+ if (!NebulaElementHelpers.isNebulaWidget(element))
+ return false;
+ Widget widget = SWTElementHelpers.getWidget(element);
+ if (widget != null) {
+ super.applyCSSProperty(widget, property, value, pseudo, engine);
+ return true;
+ }
+ return false;
+
+ }
+
+ public String retrieveCSSProperty(Object element, String property,
+ String pseudo, CSSEngine engine) throws Exception {
+ if (!NebulaElementHelpers.isNebulaWidget(element))
+ return null;
+ Widget widget = SWTElementHelpers.getWidget(element);
+ if (widget != null) {
+ return super.retrieveCSSProperty(widget, property, pseudo, engine);
+ }
+ return null;
+ }
+
+ public void applyCSSPropertyColor(Object element, CSSValue value,
+ String pseudo, CSSEngine engine) throws Exception {
+ Widget widget = (Widget) element;
+ if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ Color newColor = (Color) engine.convert(value, Color.class, widget
+ .getDisplay());
+ if (widget instanceof GalleryItem) {
+ GalleryItem galleryItem = (GalleryItem) widget;
+ if ("selected".equals(pseudo)) {
+ GalleryHelpers.setSelectionForegroundColor(galleryItem
+ .getParent(), newColor);
+ } else
+ galleryItem.setForeground(newColor);
+
+ } else {
+ if (widget instanceof Control)
+ ((Control) widget).setForeground(newColor);
+ }
+ }
+ }
+
+ public String retrieveCSSPropertyColor(Object element, String pseudo,
+ CSSEngine engine) throws Exception {
+ Widget widget = (Widget) element;
+ Color color = null;
+ if (widget instanceof GalleryItem) {
+ GalleryItem galleryItem = (GalleryItem) widget;
+ if ("selected".equals(pseudo)) {
+ color = GalleryHelpers.getSelectionForegroundColor(galleryItem
+ .getParent());
+ } else {
+ color = galleryItem.getForeground();
+ }
+ }
+ if (color != null) {
+ return engine.convert(color, Color.class, null);
+ }
+ return null;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/.classpath b/bundles/org.eclipse.e4.ui.gadgets/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.ui.gadgets/.project b/bundles/org.eclipse.e4.ui.gadgets/.project
new file mode 100644
index 0000000..3a5d0f9
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.ui.gadgets</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.ui.gadgets/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.ui.gadgets/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..43fb5cd
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Fri Oct 09 16:11:38 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/bundles/org.eclipse.e4.ui.gadgets/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.e4.ui.gadgets/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..69bb514
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,55 @@
+#Sat Oct 24 21:58:57 CEST 2009
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=false
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/bundles/org.eclipse.e4.ui.gadgets/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.ui.gadgets/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..2b15ea3
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/META-INF/MANIFEST.MF
@@ -0,0 +1,18 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Opensocial-demo
+Bundle-SymbolicName: org.eclipse.e4.ui.gadgets;singleton:=true
+Bundle-Version: 0.9.2.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.ui;bundle-version="3.5.0",
+ org.eclipse.equinox.common;bundle-version="3.5.0",
+ org.eclipse.equinox.registry;bundle-version="3.4.0",
+ org.eclipse.core.jobs;bundle-version="3.4.0",
+ org.eclipse.core.resources;bundle-version="3.5.0",
+ javax.servlet;bundle-version="2.5.0",
+ org.eclipse.ui.views;bundle-version="3.5.0",
+ org.eclipse.e4.ui.web;bundle-version="0.9.0"
+Import-Package: org.apache.commons.httpclient;version="3.0.0",
+ org.apache.commons.httpclient.methods;version="3.0.0",
+ org.osgi.framework;version="1.5.0"
+Bundle-ActivationPolicy: lazy
diff --git a/bundles/org.eclipse.e4.ui.gadgets/build.properties b/bundles/org.eclipse.e4.ui.gadgets/build.properties
new file mode 100644
index 0000000..8274abe
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/build.properties
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ js/,\
+ icons/
diff --git a/bundles/org.eclipse.e4.ui.gadgets/icons/full/dlcl16/refresh.gif b/bundles/org.eclipse.e4.ui.gadgets/icons/full/dlcl16/refresh.gif
new file mode 100644
index 0000000..6eafa48
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/icons/full/dlcl16/refresh.gif
Binary files differ
diff --git a/bundles/org.eclipse.e4.ui.gadgets/icons/full/elcl16/refresh.gif b/bundles/org.eclipse.e4.ui.gadgets/icons/full/elcl16/refresh.gif
new file mode 100644
index 0000000..e383147
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/icons/full/elcl16/refresh.gif
Binary files differ
diff --git a/bundles/org.eclipse.e4.ui.gadgets/js/io.js b/bundles/org.eclipse.e4.ui.gadgets/js/io.js
new file mode 100644
index 0000000..2cf910c
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/js/io.js
@@ -0,0 +1,47 @@
+var gadgets = gadgets || {};
+
+gadgets.io = function() {
+ return {
+ makeRequest : function(url, callback, params) {
+ try {
+ // Retrieve parameters to forward them to the java part
+ var method = params[gadgets.io.RequestParameters.METHOD];
+ var contentType = params[gadgets.io.RequestParameters.CONTENT_TYPE];
+
+ // All headers will be converted in a single String. The format will be :
+ // headerName#headerValue>header2Name#header2Value
+ var headers = params[gadgets.io.RequestParameters.HEADERS];
+ var headersStr = "" ;
+ if (headers != null) {
+ headersStr = "Authorization#" + headers["Authorization"];
+ headersStr += "\n" + "ContentType#" + headers["ContentType"];
+ }
+
+ var postData = params[gadgets.io.RequestParameters.POST_DATA];
+
+ e4_makeXmlHttpRequest(url, callback.toString(), method,
+ contentType, headersStr, postData);
+ } catch (err) {
+ // FIXME: this should not happen, but for some reason
+ // e4_makeXmlHttpRequest is not declared at the very beginning
+ // of the execution...
+ }
+
+ }
+ }
+}();
+
+gadgets.io.RequestParameters = gadgets.util.makeEnum( [ "METHOD",
+ "CONTENT_TYPE", "POST_DATA", "HEADERS", "AUTHORIZATION", "NUM_ENTRIES",
+ "GET_SUMMARIES", "REFRESH_INTERVAL", "OAUTH_SERVICE_NAME",
+ "OAUTH_USE_TOKEN", "OAUTH_TOKEN_NAME", "OAUTH_REQUEST_TOKEN",
+ "OAUTH_REQUEST_TOKEN_SECRET" ]);
+
+gadgets.io.MethodType = gadgets.util.makeEnum( [ "GET", "POST", "PUT",
+ "DELETE", "HEAD" ]);
+
+gadgets.io.ContentType = gadgets.util
+ .makeEnum( [ "TEXT", "DOM", "JSON", "FEED" ]);
+
+gadgets.io.AuthorizationType = gadgets.util.makeEnum( [ "NONE", "SIGNED",
+ "OAUTH" ]);
diff --git a/bundles/org.eclipse.e4.ui.gadgets/js/misc.js b/bundles/org.eclipse.e4.ui.gadgets/js/misc.js
new file mode 100644
index 0000000..773add4
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/js/misc.js
@@ -0,0 +1,29 @@
+function _IG_LoadLibraryDeferred(url, callback) {
+ var scriptElement = document.createElement("script");
+ scriptElement.src=url;
+ document.getElementsByTagName("head")[0].appendChild(scriptElement);
+ setTimeout(function(){eval(callback)}, 1000);
+}
+function _gel(id) {
+ if(document.all) {
+ return document.all[id];
+ } else {
+ return document.getElementById(id);
+ }
+}
+function _IG_AddDOMEventHandler(domObject,event,callback){
+ if (domObject.addEventListener){
+ domObject.addEventListener(event, callback, true);}
+ else{
+ domObject.attachEvent('on'+event,callback);
+ }
+}
+function _IG_AdjustIFrameHeight() {
+}
+function _IG_Analytics() {
+}
+function _IG_RegisterOnloadHandler(handler) {
+ _IG_AddDOMEventHandler(window, "load", function(){handler();});
+}
+function _IG_RegisterMaximizeHandler(handler) {
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/js/prefs.js b/bundles/org.eclipse.e4.ui.gadgets/js/prefs.js
new file mode 100644
index 0000000..23c0722
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/js/prefs.js
@@ -0,0 +1,23 @@
+var gadgets = gadgets || {};
+
+gadgets.Prefs.prototype.set = function(key, value) {
+ this[key] = value;
+};
+gadgets.Prefs.prototype.getString = function(key) {
+ return this[key] || "";
+};
+gadgets.Prefs.prototype.getBool = function(key) {
+ return this[key] || true;
+};
+gadgets.Prefs.prototype.getInt = function(key) {
+ return 0 + this[key] || 0;
+};
+gadgets.Prefs.prototype.getMsg = function(key) {
+ return key;
+};
+gadgets.Prefs.prototype.getArray = function(key) {
+ return [];
+};
+
+//Alias for legacy code
+var _IG_Prefs = gadgets.Prefs;
diff --git a/bundles/org.eclipse.e4.ui.gadgets/js/util.js b/bundles/org.eclipse.e4.ui.gadgets/js/util.js
new file mode 100644
index 0000000..fb62a83
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/js/util.js
@@ -0,0 +1,18 @@
+var gadgets = gadgets || {};
+
+gadgets.util = function() {
+ return {
+ registerOnLoadHandler : function(callback) {
+ callback() ;
+ //window.onload = callback;
+ },
+
+ makeEnum : function (values) {
+ var obj = {};
+ for (var i = 0, v; v = values[i]; ++i) {
+ obj[v] = v;
+ }
+ return obj;
+ }
+ }
+}();
diff --git a/bundles/org.eclipse.e4.ui.gadgets/js/window.js b/bundles/org.eclipse.e4.ui.gadgets/js/window.js
new file mode 100644
index 0000000..d62cb18
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/js/window.js
@@ -0,0 +1,11 @@
+var gadgets = gadgets || {};
+
+gadgets.window = gadgets.window || {};
+
+gadgets.window.setTitle = function(title) {
+ // TODO set the view's title
+};
+
+// Alias for legacy code
+var _IG_SetTitle = gadgets.window.setTitle;
+
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.ui.gadgets/plugin.xml b/bundles/org.eclipse.e4.ui.gadgets/plugin.xml
new file mode 100644
index 0000000..95ebf49
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/plugin.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.ui.views">
+ <view
+ allowMultiple="true"
+ class="org.eclipse.e4.ui.internal.gadgets.opensocial.OpenSocialView"
+ id="opensocial-demo.view"
+ name="Gadget"
+ restorable="true">
+ </view>
+ </extension>
+ <extension
+ point="org.eclipse.ui.commands">
+ <command
+ defaultHandler="org.eclipse.e4.ui.internal.gadgets.opensocial.OpenGadgetHandler"
+ id="opensocialdemo.opengadget"
+ name="Open Gadget">
+ </command>
+ </extension>
+ <extension
+ point="org.eclipse.ui.propertyPages">
+ <page
+ class="org.eclipse.e4.ui.internal.gadgets.opensocial.propertyPages.MainPropertyPage"
+ id="org.eclipse.e4.ui.gadgets.Main"
+ name="Gadget">
+ <enabledWhen>
+ <adapt
+ type="org.eclipse.e4.ui.internal.gadgets.opensocial.OSGModule">
+ </adapt>
+ </enabledWhen>
+ </page>
+ <page
+ category="org.eclipse.e4.ui.gadgets.Main"
+ class="org.eclipse.e4.ui.internal.gadgets.opensocial.propertyPages.OSGModulePrefsPropertyPage"
+ id="org.eclipse.e4.ui.gadgets.OSGModuleUserPreferences"
+ name="User Preferences">
+ <enabledWhen>
+ <adapt
+ type="org.eclipse.e4.ui.internal.gadgets.opensocial.OSGModule">
+ </adapt>
+ </enabledWhen>
+ </page>
+ </extension>
+
+</plugin>
diff --git a/bundles/org.eclipse.e4.ui.gadgets/pom.xml b/bundles/org.eclipse.e4.ui.gadgets/pom.xml
new file mode 100644
index 0000000..0029f4a
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/pom.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.eclipse.e4.ui</groupId>
+ <artifactId>org.eclipse.e4.ui.gadgets</artifactId>
+ <version>0.9.1-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.eclipse.e4.ui</groupId>
+ <artifactId>org.eclipse.e4.ui.web</artifactId>
+ <version>0.9.0-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+
+ <properties>
+ <tycho-version>0.11.1</tycho-version>
+ </properties>
+
+ <repositories>
+ <repository>
+ <id>helios</id>
+ <layout>p2</layout>
+ <url>http://download.eclipse.org/releases/helios</url>
+ </repository>
+ <repository>
+ <id>orbit</id>
+ <layout>p2</layout>
+ <url>http://download.eclipse.org/tools/orbit/downloads/drops/S20110422041657/repository/</url>
+ </repository>
+ </repositories>
+
+ <build>
+ <plugins>
+ <plugin>
+ <!-- TODO switch to org.eclipse.tycho when it will be publicly available -->
+ <groupId>org.sonatype.tycho</groupId>
+ <artifactId>tycho-maven-plugin</artifactId>
+ <version>${tycho-version}</version>
+ <extensions>true</extensions>
+ </plugin>
+ <plugin>
+ <groupId>org.sonatype.tycho</groupId>
+ <artifactId>target-platform-configuration</artifactId>
+ <version>${tycho-version}</version>
+ <configuration>
+ <resolver>p2</resolver>
+ <pomDependencies>consider</pomDependencies>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/LocaleKey.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/LocaleKey.java
new file mode 100644
index 0000000..b205191
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/LocaleKey.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * 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:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial;
+
+class LocaleKey {
+ String language;
+ String country;
+
+ public LocaleKey(String language, String country) {
+ this.language = language;
+ this.country = country;
+ }
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((country == null) ? 0 : country.hashCode());
+ result = prime * result
+ + ((language == null) ? 0 : language.hashCode());
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ LocaleKey other = (LocaleKey) obj;
+ if (country == null) {
+ if (other.country != null)
+ return false;
+ } else if (!country.equals(other.country))
+ return false;
+ if (language == null) {
+ if (other.language != null)
+ return false;
+ } else if (!language.equals(other.language))
+ return false;
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGContent.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGContent.java
new file mode 100644
index 0000000..bf0ff40
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGContent.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial;
+
+public class OSGContent {
+ String type;
+ String view;
+ String href;
+ String value;
+
+ public OSGContent(String type, String view, String href) {
+ this.type = type;
+ this.view = view == null ? "" : view;
+ this.href = href;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getView() {
+ return view;
+ }
+
+ public String getHref() {
+ return href;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGLocale.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGLocale.java
new file mode 100644
index 0000000..8601559
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGLocale.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class OSGLocale {
+ String lang;
+ String country;
+ String languageDirection;
+ String messagesURI;
+ Map<String, String> messages = new HashMap<String, String>();
+
+ public OSGLocale(String lang, String country, String languageDirection,
+ String messagesURI) {
+ this.lang = lang;
+ this.country = country;
+ this.languageDirection = languageDirection;
+ this.messagesURI = messagesURI;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGModule.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGModule.java
new file mode 100644
index 0000000..cd16c97
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGModule.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * 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:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class OSGModule {
+ String title;
+ String author;
+ String description;
+ Map<LocaleKey, OSGLocale> locales = new HashMap<LocaleKey, OSGLocale>();
+ List<OSGUserPref> userPrefs = new ArrayList<OSGUserPref>();
+ Map<String, OSGContent> contents = new HashMap<String, OSGContent>();
+
+ public OSGModule(String title, String author, String description) {
+ this.title = title;
+ this.author = author;
+ this.description = description;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public Map<String, OSGContent> getContents() {
+ return contents;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public List<OSGUserPref> getUserPrefs() {
+ return userPrefs;
+ }
+
+ public void setUserPrefValue(String key, String value) {
+ for (OSGUserPref pref : getUserPrefs()) {
+ if (pref.getName().equals(key)) {
+ pref.setValue((String) value);
+ }
+ }
+ }
+
+ public String getUserPrefValue(String key) {
+ for (OSGUserPref pref : getUserPrefs()) {
+ if (pref.getName().equals(key))
+ return (pref.getValue() == null) ? "" : pref.getValue();
+ }
+ return null;
+ }
+
+ public String getUserPrefDefaultValue(String key) {
+ for (OSGUserPref pref : getUserPrefs()) {
+ if (pref.getName().equals(key))
+ return (pref.getDefaultValue() == null) ? "" : pref.getValue();
+ }
+ return null;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGUserPref.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGUserPref.java
new file mode 100644
index 0000000..fe451bc
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OSGUserPref.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial;
+
+public class OSGUserPref {
+ String name;
+ String value;
+ String defaultValue;
+
+ public OSGUserPref(String name, String defaultValue) {
+ this.name = name;
+ this.value = defaultValue;
+ this.defaultValue = defaultValue;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ @Override
+ public String toString() {
+ return "OSGUserPref [name=" + name + ", value=" + value
+ + ", defaultValue=" + defaultValue + "]";
+ }
+
+
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenGadgetHandler.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenGadgetHandler.java
new file mode 100644
index 0000000..562ff04
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenGadgetHandler.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * 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:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial;
+
+import java.lang.reflect.Method;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+public class OpenGadgetHandler extends AbstractHandler {
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ IWorkbenchWindow wwin = HandlerUtil
+ .getActiveWorkbenchWindowChecked(event);
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ String selectedText = "";
+ if (selection != null) {
+ Method getText;
+ try {
+ getText = selection.getClass().getMethod("getText");
+ selectedText = (String) getText.invoke(selection);
+ } catch (Exception e) {
+ }
+ }
+ InputDialog inputDialog = new InputDialog(wwin.getShell(),
+ "Open Gadget", "Please enter the gadget URL.", selectedText,
+ null);
+ if (inputDialog.open() == Dialog.OK) {
+ try {
+ String url = inputDialog.getValue();
+ url = url.replace(":", "%3A");
+ wwin.getActivePage().showView("opensocial-demo.view", url,
+ IWorkbenchPage.VIEW_ACTIVATE);
+ } catch (PartInitException e) {
+ StatusManager.getManager().handle(
+ new Status(IStatus.ERROR, "e4.opensocial",
+ "Could not open gadget", e));
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenSocialUtil.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenSocialUtil.java
new file mode 100644
index 0000000..ed07ef7
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenSocialUtil.java
@@ -0,0 +1,336 @@
+/*******************************************************************************
+ * 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:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class OpenSocialUtil {
+
+ private static int moduleId = 0;
+
+ public static OSGModule loadModule(String uriString) {
+ java.net.URI uri;
+ OSGModule module;
+ try {
+ uri = new java.net.URI(uriString);
+ module = parseModuleXML(uri);
+ } catch (Exception e) {
+ throw new RuntimeException("Could not load module", e);
+ }
+ OSGLocale locale = determineLocale(module);
+
+ Map<String, String> hangmanMap = new HashMap<String, String>();
+ hangmanMap.put("__MODULE_ID__", String.valueOf(moduleId++));
+ hangmanMap.put("__ENV_google_apps_auth_path__", "render#");
+
+ populateHangmanMapFromLocale(hangmanMap, locale, uri);
+ populateHangmanMapFromUserPrefs(hangmanMap, module.userPrefs);
+
+ module.title = hangmanExpand(module.title, hangmanMap);
+ module.description = hangmanExpand(module.description, hangmanMap);
+ module.author = hangmanExpand(module.author, hangmanMap);
+
+ // System.out.println("Gadget: " + module.title);
+ // System.out.println("Author: " + module.author);
+ // System.out.println("Description: " + module.description);
+
+ for (OSGContent content : new HashSet<OSGContent>(module.contents
+ .values())) {
+ if ("url".equalsIgnoreCase(content.type)) {
+ content.href = hangmanExpand(content.href, hangmanMap);
+ // System.out.println("URL: " + content.href);
+ } else if ("html".equalsIgnoreCase(content.type)) {
+ content.value = hangmanExpand(content.value, hangmanMap);
+ // System.out.println("HTML: ...");
+ } else {
+ // System.out.println("unhandled type: " + content.type);
+ }
+ // System.out.println("Views: " + content.view);
+ }
+ return module;
+ }
+
+ private static void populateHangmanMapFromUserPrefs(
+ Map<String, String> hangmanMap, List<OSGUserPref> userPrefs) {
+ for (OSGUserPref pref : userPrefs) {
+ hangmanMap.put("__UP_" + pref.name + "__", pref.defaultValue);
+ }
+ }
+
+ private static void populateHangmanMapFromLocale(
+ Map<String, String> hangmanMap, OSGLocale locale, java.net.URI uri) {
+ hangmanMap.put("__BIDI_START_EDGE__", "left");
+ hangmanMap.put("__BIDI_END_EDGE__", "right");
+ hangmanMap.put("__BIDI_DIR__", "ltr");
+ hangmanMap.put("__BIDI_REVERSE_DIR__", "rtl");
+ if (locale != null) {
+ if ("rtl".equals(locale.languageDirection)) {
+ hangmanMap.put("__BIDI_START_EDGE__", "right");
+ hangmanMap.put("__BIDI_END_EDGE__", "left");
+ hangmanMap.put("__BIDI_DIR__", "rtl");
+ hangmanMap.put("__BIDI_REVERSE_DIR__", "ltr");
+ }
+ String messagesURIString = locale.messagesURI;
+ if (messagesURIString != null) {
+ if (!messagesURIString.startsWith("http")) {
+ if (!messagesURIString.startsWith("/")) {
+ String uriString = uri.toString();
+ messagesURIString = uriString.substring(0, uriString
+ .lastIndexOf('/'))
+ + "/" + messagesURIString;
+ } else {
+ messagesURIString = "http://" + uri.getHost()
+ + messagesURIString;
+ }
+ }
+ try {
+ addMessagesToMap(hangmanMap, messagesURIString);
+ } catch (Exception e) {
+ throw new RuntimeException("Could not parse messages", e);
+ }
+ } else {
+ addMessagesToMap(hangmanMap, locale.messages);
+ }
+ }
+ }
+
+ private static OSGLocale determineLocale(OSGModule module) {
+ OSGLocale locale = module.locales.get(new LocaleKey(System
+ .getProperty("osgi.nl"), System.getProperty("user.country")));
+ if (locale == null) {
+ locale = module.locales.get(new LocaleKey(System
+ .getProperty("user.language"), System
+ .getProperty("user.country")));
+ }
+ if (locale == null) {
+ locale = module.locales.get(new LocaleKey(System
+ .getProperty("osgi.nl"), null));
+ }
+ if (locale == null) {
+ locale = module.locales.get(new LocaleKey(System
+ .getProperty("user.language"), null));
+ }
+ if (locale == null) {
+ locale = module.locales.get(new LocaleKey(null, System
+ .getProperty("user.country")));
+ }
+ if (locale == null) {
+ locale = module.locales.get(new LocaleKey(null, null));
+ }
+ return locale;
+ }
+
+ private static OSGModule parseModuleXML(java.net.URI uri) throws Exception {
+ final OSGModule[] result = { null };
+ parseXML(uri, new DefaultHandler() {
+ OSGModule module;
+ OSGContent content;
+ StringBuffer contentBuffer;
+ OSGLocale locale;
+ String currentMsgName = null;
+ StringBuffer currentMsgValue = null;
+
+ public void startElement(String uri, String localName,
+ String qName, Attributes attributes) throws SAXException {
+ if (contentBuffer != null) {
+ contentBuffer.append("<" + qName);
+ for (int i = 0; i < attributes.getLength(); i++) {
+ contentBuffer.append(" " + attributes.getQName(i)
+ + "=\"" + attributes.getValue(i) + "\"");
+ }
+ contentBuffer.append(">");
+ } else if ("ModulePrefs".equalsIgnoreCase(qName)) {
+ module = new OSGModule(attributes.getValue("title"),
+ attributes.getValue("author"), attributes
+ .getValue("description"));
+ result[0] = module;
+ } else if ("Locale".equalsIgnoreCase(qName)) {
+ locale = new OSGLocale(attributes.getValue("lang"),
+ attributes.getValue("country"), attributes
+ .getValue("language_direction"), attributes
+ .getValue("messages"));
+ module.locales.put(new LocaleKey(locale.lang,
+ locale.country), locale);
+ } else if ("msg".equalsIgnoreCase(qName)) {
+ currentMsgName = attributes.getValue("name");
+ currentMsgValue = new StringBuffer();
+ } else if ("UserPref".equalsIgnoreCase(qName)) {
+ module.userPrefs.add(new OSGUserPref(attributes
+ .getValue("name"), attributes
+ .getValue("default_value")));
+ } else if ("Content".equalsIgnoreCase(qName)) {
+ content = new OSGContent(attributes.getValue("type"),
+ attributes.getValue("view"), attributes
+ .getValue("href"));
+ contentBuffer = new StringBuffer();
+ }
+ }
+
+ public void characters(char[] ch, int start, int length)
+ throws SAXException {
+ if (contentBuffer != null) {
+ contentBuffer.append(ch, start, length);
+ }
+ if (currentMsgName != null) {
+ currentMsgValue.append(ch, start, length);
+ }
+ }
+
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ if ("Content".equalsIgnoreCase(qName) && content != null
+ && contentBuffer != null) {
+ content.value = contentBuffer.toString();
+ StringTokenizer t = new StringTokenizer(content.view, ",");
+ if (!t.hasMoreTokens()) {
+ module.contents.put("default", content);
+ } else
+ while (t.hasMoreTokens()) {
+ module.contents.put(t.nextToken(), content);
+ }
+ contentBuffer = null;
+ } else if ("Locale".equalsIgnoreCase(qName)) {
+ locale = null;
+ } else if ("msg".equalsIgnoreCase(qName)) {
+ locale.messages.put(currentMsgName, currentMsgValue
+ .toString());
+ currentMsgName = null;
+ } else if (contentBuffer != null) {
+ contentBuffer.append("</" + qName);
+ contentBuffer.append(">");
+ }
+ content = null;
+ }
+ });
+ return result[0];
+ }
+
+ private static void addMessagesToMap(final Map<String, String> hangmanMap,
+ String messagesURIString) throws Exception {
+ // System.out.println("Loading message bundle from: " +
+ // messagesURIString);
+ DefaultHandler handler = new DefaultHandler() {
+ String name;
+ String value;
+
+ public void startElement(String uri, String localName,
+ String qName, Attributes attributes) throws SAXException {
+ name = attributes.getValue("name");
+ }
+
+ public void characters(char[] ch, int start, int length)
+ throws SAXException {
+ value = new String(ch, start, length);
+ }
+
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ if ("msg".equalsIgnoreCase(qName) && name != null
+ && value != null) {
+ hangmanMap.put("__MSG_" + name + "__", value);
+ }
+ }
+ };
+ parseXML(new java.net.URI(messagesURIString), handler);
+ }
+
+ private static void addMessagesToMap(Map<String, String> hangmanMap,
+ Map<String, String> messages) {
+ for (Map.Entry<String, String> entry : messages.entrySet()) {
+ hangmanMap.put("__MSG_" + entry.getKey() + "__", entry.getValue());
+ }
+ }
+
+ private static void parseXML(java.net.URI uri, DefaultHandler handler)
+ throws MalformedURLException, IOException,
+ ParserConfigurationException, SAXException {
+ URL messagesURL = uri.toURL();
+ URLConnection connection = messagesURL.openConnection();
+ String encoding = connection.getContentEncoding();
+ if (encoding == null) {
+ String contentType = connection.getHeaderField("Content-Type");
+ int charsetIndex;
+ if (contentType != null
+ && (charsetIndex = contentType.indexOf("charset=")) != -1) {
+ int charsetBegin = charsetIndex + "charset=".length();
+ int charsetEnd = charsetBegin;
+ while (contentType.length() > charsetEnd
+ && " ,;".indexOf(contentType.charAt(charsetEnd)) == -1) {
+ charsetEnd++;
+ }
+ if (charsetEnd > charsetBegin) {
+ encoding = contentType.substring(charsetBegin, charsetEnd);
+ }
+ }
+ }
+ InputStream is = connection.getInputStream();
+ try {
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ SAXParser parser = spf.newSAXParser();
+ InputSource source = new InputSource(is);
+ if (encoding != null) {
+ source.setEncoding(encoding);
+ }
+ parser.parse(source, handler);
+ } finally {
+ is.close();
+ }
+ }
+
+ private static String hangmanExpand(String s, Map<String, String> hangmanMap) {
+ if (s == null) {
+ return null;
+ }
+ StringBuffer result = new StringBuffer(s.length());
+ int currentIndex = 0;
+ int indexOfUnderscores;
+ while ((indexOfUnderscores = s.indexOf("__", currentIndex)) != -1) {
+ result.append(s.substring(currentIndex, indexOfUnderscores));
+ int indexOfNextUnderscores = s
+ .indexOf("__", indexOfUnderscores + 2);
+ if (indexOfNextUnderscores != -1) {
+ String key = s.substring(indexOfUnderscores,
+ indexOfNextUnderscores + 2);
+ String value = hangmanMap.get(key);
+ if (value != null) {
+ result.append(value);
+ } else {
+ result.append(key);
+ }
+ currentIndex = indexOfNextUnderscores + 2;
+ } else {
+ result.append("__");
+ currentIndex = indexOfUnderscores + 2;
+ }
+ }
+ result.append(s.substring(currentIndex));
+ return result.toString();
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenSocialView.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenSocialView.java
new file mode 100644
index 0000000..1c2cd47
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/OpenSocialView.java
@@ -0,0 +1,361 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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:
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ * Benjamin Cabe, Sierra Wireless - ongoing improvements
+ * Sebastien Moran, Sierra Wireless - bug 298291
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Map;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.e4.ui.internal.gadgets.opensocial.browserfunctions.MakeXmlHttpRequest;
+import org.eclipse.e4.ui.web.BrowserViewPart;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.BrowserFunction;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.dialogs.PropertyDialogAction;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+public class OpenSocialView extends BrowserViewPart implements
+ IResourceChangeListener {
+
+ public static final String NO_HEADER_VALUE = "undefined";
+
+ public static final String HEADER_NAME_VALUE_SEPARATOR = "#";
+
+ public static final String HEADERS_SEPARATOR = "\n";
+
+ public static final String GET_METHOD = "GET";
+
+ public static final String USERPREFS = "userprefs";
+
+ private String url;
+ private String html;
+ private OSGModule module;
+ private IMemento memento;
+ private final String[] scripts = new String[] { "util.js", "io.js",
+ "misc.js", "prefs.js", "window.js" }; // util.js must always be
+ // loaded first
+ private Bundle bundle;
+ private Action editPropertiesAction;
+ private Action refreshAction;
+
+ private IFile moduleFile;
+
+ private BrowserFunction makeRequestBrowserFunction;
+
+ protected String getNewWindowViewId() {
+ return getSite().getId();
+ }
+
+ @Override
+ public void init(IViewSite site, IMemento memento) throws PartInitException {
+ super.init(site, memento);
+ url = site.getSecondaryId();
+ this.memento = memento;
+ bundle = FrameworkUtil.getBundle(this.getClass());
+
+ url = url.replace("%3A", ":");
+ URI uri = URI.create(url);
+ if (!uri.isAbsolute())
+ return;
+ IFile[] files = ResourcesPlugin.getWorkspace().getRoot()
+ .findFilesForLocationURI(uri);
+ if (files.length > 0) {
+ moduleFile = files[0];
+ moduleFile.getWorkspace().addResourceChangeListener(this,
+ IResourceChangeEvent.POST_CHANGE);
+ }
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ super.createPartControl(parent);
+ makeActions();
+ contributeToActionBars();
+ contributeToToolBars();
+ }
+
+ private void makeActions() {
+ editPropertiesAction = new Action() {
+ public void run() {
+ new PropertyDialogAction(getSite(), new ISelectionProvider() {
+ public void setSelection(ISelection selection) {
+ }
+
+ public void removeSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ }
+
+ public ISelection getSelection() {
+ return new StructuredSelection(module);
+ }
+
+ public void addSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ }
+ }).createDialog().open();
+ configureBrowser(browser);
+ }
+ };
+ editPropertiesAction.setText("Module settings");
+ editPropertiesAction.setToolTipText("Edit Module Settings");
+
+ refreshAction = new Action() {
+ public void run() {
+ module = null;
+ configureBrowser(browser);
+ }
+ };
+ refreshAction.setText("Refresh");
+ refreshAction.setDisabledImageDescriptor(ImageDescriptor
+ .createFromURL(bundle
+ .getEntry("/icons/full/dlcl16/refresh.gif")));
+ refreshAction.setImageDescriptor(ImageDescriptor.createFromURL(bundle
+ .getEntry("/icons/full/elcl16/refresh.gif")));
+ refreshAction.setToolTipText("Refresh module");
+ }
+
+ private void contributeToActionBars() {
+ IActionBars bars = getViewSite().getActionBars();
+ bars.getMenuManager().add(editPropertiesAction);
+ bars.getMenuManager().update(true);
+ }
+
+ private void contributeToToolBars() {
+ IActionBars bars = getViewSite().getActionBars();
+ bars.getToolBarManager().add(refreshAction);
+ bars.getToolBarManager().update(true);
+ }
+
+ private void registerBrowserFunctions() {
+ if (makeRequestBrowserFunction != null)
+ makeRequestBrowserFunction.dispose();
+
+ makeRequestBrowserFunction = new MakeXmlHttpRequest(browser);
+ }
+
+ @Override
+ public void dispose() {
+ if (moduleFile != null)
+ moduleFile.getWorkspace().removeResourceChangeListener(this);
+ if (makeRequestBrowserFunction != null)
+ makeRequestBrowserFunction.dispose();
+ super.dispose();
+ }
+
+ @Override
+ public void saveState(IMemento memento) {
+ saveUserPreferences(memento);
+ }
+
+ private void saveUserPreferences(IMemento memento) {
+ IMemento node = memento.createChild(USERPREFS);
+ for (OSGUserPref pref : module.getUserPrefs()) {
+ node.putString(pref.getName(), pref.getValue());
+ }
+ }
+
+ protected void configureBrowser(Browser browser) {
+ registerBrowserFunctions();
+
+ String localUrl = null;
+ if (url != null) {
+ url = url.replace("%3A", ":");
+ final String uriForIcon = url;
+ if (module == null) {
+ module = OpenSocialUtil.loadModule(url);
+ loadUserPreferences(module, memento);
+ }
+ setPartName(module.getTitle());
+ setTitleToolTip(module.getDescription());
+ Map<String, OSGContent> contents = module.getContents();
+ OSGContent content = contents.get("home");
+ if (content == null) {
+ content = contents.get("default");
+ }
+ if (content == null) {
+ content = contents.get("canvas");
+ }
+ if (content == null) {
+ content = contents.get("");
+ }
+ if ("url".equalsIgnoreCase(content.getType())) {
+ localUrl = content.getHref();
+ } else if ("html".equalsIgnoreCase(content.getType())) {
+ StringBuilder igFunctions = new StringBuilder();
+ igFunctions.append("<head></head><script>\r\n");
+ igFunctions.append("var gadgets = gadgets || {};\r\n");
+ igFunctions.append("gadgets.Prefs = function() {\r\n");
+ for (OSGUserPref userPref : module.getUserPrefs()) {
+ igFunctions.append("this." + userPref.getName());
+ igFunctions.append("='");
+ igFunctions.append(userPref.getValue());
+ igFunctions.append("';");
+ }
+ igFunctions.append("\r\n}\r\n\r\n");
+ try {
+ // inject Javascript gadgets.* functions
+ for (String script : scripts) {
+ // append the script to igFunctions
+ InputStream scriptInputStream = bundle.getEntry(
+ "js/" + script).openStream();
+ BufferedReader scriptReader = new BufferedReader(
+ new InputStreamReader(scriptInputStream));
+ String line = null;
+ while ((line = scriptReader.readLine()) != null) {
+ igFunctions.append(line + "\r\n");
+ }
+ scriptReader.close();
+ }
+ } catch (IOException e) {
+ // TODO log
+ }
+ igFunctions.append("\r\n</script>\r\n");
+ html = igFunctions.toString() + content.getValue();
+ }
+ if (localUrl == null && html == null) {
+ throw new RuntimeException("could not find Gadget URL");
+ } else if (uriForIcon != null) {
+ Job job = new Job("Retrieve Icon for " + module.getTitle()) {
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ URI uri;
+ try {
+ uri = new URI(uriForIcon);
+ } catch (URISyntaxException e1) {
+ return Status.CANCEL_STATUS;
+ }
+ String host = uri.getHost();
+ try {
+ URL favicon = new URL("http://" + host
+ + "/favicon.ico");
+ InputStream is = favicon.openConnection()
+ .getInputStream();
+ Display display = getSite().getWorkbenchWindow()
+ .getShell().getDisplay();
+ final Image icon = new Image(display, is);
+ display.asyncExec(new Runnable() {
+
+ public void run() {
+ setTitleImage(icon);
+ }
+ });
+ } catch (MalformedURLException e) {
+ return Status.CANCEL_STATUS;
+ } catch (IOException e) {
+ return Status.CANCEL_STATUS;
+ } catch (SWTException e) {
+ // the Image might be malformed or not readable by
+ // SWT
+ return Status.CANCEL_STATUS;
+ }
+ return Status.OK_STATUS;
+ }
+ };
+ job.schedule();
+ }
+ } else {
+ localUrl = "http://ig.gmodules.com/gadgets/ifr?view=home&url="
+ + "http://hosting.gmodules.com/ig/gadgets/file/104276582316790234013/test-1.xml"
+ + "&nocache=0&up_feed=http://picasaweb.google.com/data/feed/base/user/picasateam/albumid/5114659638793351217%3Fkind%3Dphoto%26alt%3Drss%26hl%3Den_US&up_title=My+Picasa+Photos&up_gallery=&up_desc=1&lang=en&country=us&.lang=en&.country=us&synd=ig&mid=110&ifpctok=-6064860744303900509&exp_split_js=1&exp_track_js=1&exp_ids=17259,300668&parent=http://www.google.com&refresh=3600&libs=core:core.io:core.iglegacy&extern_js=/extern_js/f/CgJlbhICdXMrMNIBOAEs/SH2Zv0WBdfQ.js&is_signedin=1";
+ }
+ if (html != null) {
+ browser.setText(html);
+ }
+ if (localUrl != null) {
+ browser.setUrl(localUrl);
+ }
+
+ }
+
+ private void loadUserPreferences(OSGModule module, IMemento memento) {
+ if (memento == null)
+ return;
+
+ IMemento node = memento.getChild(USERPREFS);
+ if (node == null)
+ return;
+
+ for (String key : node.getAttributeKeys()) {
+ for (OSGUserPref pref : module.getUserPrefs()) {
+ if (pref.getName().equals(key))
+ pref.setValue(node.getString(key));
+ }
+ }
+ }
+
+ public void resourceChanged(IResourceChangeEvent event) {
+ IResourceDelta rootDelta = event.getDelta();
+ if (rootDelta.findMember(moduleFile.getFullPath()) == null)
+ return;
+
+ try {
+ event.getDelta().accept(new IResourceDeltaVisitor() {
+ public boolean visit(IResourceDelta delta) throws CoreException {
+ if (delta.getResource() instanceof IContainer)
+ return true;
+
+ if (moduleFile.equals(delta.getResource())) {
+ if (delta.getKind() == IResourceDelta.REMOVED) {
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ getViewSite().getPage().hideView(
+ OpenSocialView.this);
+ }
+ });
+ } else {
+ module = null;
+ configureBrowser(browser);
+ }
+ }
+ return false;
+ }
+ });
+ } catch (CoreException e) {
+ // TODO log correctly
+ }
+
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/browserfunctions/MakeXmlHttpRequest.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/browserfunctions/MakeXmlHttpRequest.java
new file mode 100644
index 0000000..b1198ee
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/browserfunctions/MakeXmlHttpRequest.java
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Sierra Wireless 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: Benjamin Cabe, Sierra Wireless - initial API and implementation
+ * Sebastien Moran, Sierra Wireless - bug 298291
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial.browserfunctions;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.StringRequestEntity;
+import org.eclipse.e4.ui.internal.gadgets.opensocial.OpenSocialView;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.BrowserFunction;
+import org.eclipse.swt.widgets.Display;
+
+public final class MakeXmlHttpRequest extends BrowserFunction {
+ public MakeXmlHttpRequest(Browser browser) {
+ super(browser, "e4_makeXmlHttpRequest");
+ }
+
+ @Override
+ public Object function(Object[] arguments) {
+ /*
+ * e4_makeXmlHttpRequest : function(url, callback, method, contentType,
+ * headers, postData)
+ */
+ try {
+ // Retrieve arguments
+ String url = (String) arguments[0];
+ String callback = (String) arguments[1];
+ String method = (String) arguments[2];
+ String contentType = (String) arguments[3];
+ // headers format :
+ // headerName#headerValue\nheader2Name#header2Value
+ String headers = (String) arguments[4];
+ String postData = (String) arguments[5];
+
+ HttpClient httpClient = new HttpClient();
+ // Create GET or POST http method
+ HttpMethod httpMethod = createMethod(url, method);
+
+ // Add needed headers
+ if (!"".equals(headers))
+ addHeaders(httpMethod, headers);
+
+ // Handle PostData if needed
+ if (postData != null) {
+ ((PostMethod) httpMethod)
+ .setRequestEntity(new StringRequestEntity(postData,
+ "text/xml", "utf-8"));
+ }
+
+ int status = httpClient.executeMethod(httpMethod);
+
+ String responseBodyAsString = retrieveResponseBody(httpMethod);
+
+ // FIXME: at the moment, remove single quotes causing js
+ // problems.
+ responseBodyAsString = responseBodyAsString.replaceAll("'", " ");
+
+ String responseScript = "\n";
+ // Create and fill response object
+ responseScript += "var response = new Object();\n";
+ responseScript += "response.rc=" + status + ";\n";
+ responseScript += "response.text='" + responseBodyAsString + "';\n";
+
+ // Create the response's data property
+ if ("DOM".equals(contentType)) {
+ responseScript = createDOMResponseData(responseScript);
+ } else if ("JSON".equals(contentType)) {
+ responseScript = createJSONResponseData(responseBodyAsString,
+ responseScript);
+ } else if ("TEXT".equals(contentType)) {
+ responseScript = createTEXTReponseData(responseScript);
+ } else if ("FEED".equals(contentType)) {
+ // FIXME : Not implemented for the moment.
+ responseScript = createFEEDResponseData(responseScript);
+ }
+
+ // Instanciate and call callback
+ responseScript += "var callback = " + callback + ";\n"
+ + "callback(response);\n";
+
+ final String script = responseScript;
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ getBrowser().execute(script);
+ }
+ });
+ return status;
+ } catch (HttpException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return HttpStatus.SC_INTERNAL_SERVER_ERROR;
+ }
+
+ /**
+ * TODO : Create a JSON representation of the RSS XML data
+ *
+ * @param responseScript
+ * String
+ */
+ protected String createFEEDResponseData(String responseScript) {
+ responseScript += "response.data='Not implemented';";
+ return responseScript;
+ }
+
+ /**
+ * TEXT data corresponds to the raw response text
+ *
+ * @param responseScript
+ * String
+ */
+ protected String createTEXTReponseData(String responseScript) {
+ responseScript += "response.data=response.text;";
+ return responseScript;
+ }
+
+ /**
+ * Create the JSON Object
+ *
+ * @param responseBodyAsString
+ * String, raw response body
+ * @param responseScript
+ * String
+ */
+ protected String createJSONResponseData(String responseBodyAsString,
+ String responseScript) {
+ // Parse response body to create the corresponding JSON
+ // object
+ responseScript += "response.data=eval('(" + responseBodyAsString
+ + ")')\n";
+ return responseScript;
+ }
+
+ /**
+ * Parse the XML response body to create the corresponding DOM.
+ *
+ * @param responseScript
+ * String
+ */
+ protected String createDOMResponseData(String responseScript) {
+ // Parse response body to create the corresponding DOM
+ // object
+ responseScript += "var xmlDoc;\n";
+ responseScript += "if (window.DOMParser){\n"
+ + "parser=new DOMParser();\n"
+ + "xmlDoc=parser.parseFromString(response.text,'text/xml');\n"
+ + "} else {\n// Internet Explorer\n"
+ + "xmlDoc=new ActiveXObject('Microsoft.XMLDOM');\n"
+ + "xmlDoc.async='false';\n"
+ + "xmlDoc.loadXML(response.text);\n" + "}\n";
+ responseScript += "response.data=xmlDoc;\n";
+ return responseScript;
+ }
+
+ protected String retrieveResponseBody(HttpMethod httpMethod)
+ throws IOException, UnsupportedEncodingException {
+
+ String responseBodyAsString = "";
+ InputStream bodyAsStream = httpMethod.getResponseBodyAsStream();
+
+ StringBuilder sb = new StringBuilder();
+ String line;
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(
+ bodyAsStream, "UTF-8"));
+ while ((line = reader.readLine()) != null) {
+ sb.append(line);
+ }
+ } finally {
+ bodyAsStream.close();
+ }
+
+ responseBodyAsString = sb.toString();
+ return responseBodyAsString;
+ }
+
+ /**
+ * Parse the String corresponding the headers and add them to the HttpMethod
+ *
+ * @param httpMethod
+ * HttpMethod which will be filled with the given headers
+ * @param headers
+ * String representation of the headers to add. They respect the
+ * following format :
+ * headerName#headerValue>header2Name#header2Value
+ *
+ */
+ private void addHeaders(HttpMethod httpMethod, String headers) {
+ // Split to retrieve all headers
+ String[] splittedHeader = headers
+ .split(OpenSocialView.HEADERS_SEPARATOR);
+
+ // Loop through the headers
+ for (String header : splittedHeader) {
+ // Split to retrieve the header name & value
+ String[] headerNameAndValue = header
+ .split(OpenSocialView.HEADER_NAME_VALUE_SEPARATOR);
+ String name = headerNameAndValue[0];
+ String value = headerNameAndValue[1];
+ // If the value exists add it to the
+ // HttpMethod
+ if (!OpenSocialView.NO_HEADER_VALUE.equals(value))
+ httpMethod.addRequestHeader(name, value);
+ }
+ }
+
+ /**
+ *
+ * @param url
+ * @param method
+ * @return
+ */
+ protected HttpMethod createMethod(String url, String method) {
+ if (OpenSocialView.GET_METHOD.equals(method))
+ return new GetMethod(url);
+
+ return new PostMethod(url);
+ }
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/propertyPages/MainPropertyPage.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/propertyPages/MainPropertyPage.java
new file mode 100644
index 0000000..aa03bec
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/propertyPages/MainPropertyPage.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Sierra Wireless 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:
+ * Benjamin Cabe, Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial.propertyPages;
+
+import org.eclipse.e4.ui.internal.gadgets.opensocial.OSGModule;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbenchPropertyPage;
+import org.eclipse.ui.dialogs.PropertyPage;
+
+public class MainPropertyPage extends PropertyPage implements
+ IWorkbenchPropertyPage {
+
+ public MainPropertyPage() {
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ composite.setLayout(layout);
+ GridData data = new GridData(GridData.FILL);
+ data.grabExcessHorizontalSpace = true;
+ composite.setLayoutData(data);
+
+ OSGModule module = (OSGModule) getElement().getAdapter(OSGModule.class);
+ addProperty(composite, "Title:", module.getTitle());
+ addProperty(composite, "Author:", module.getAuthor());
+ addProperty(composite, "Description:", module.getDescription());
+
+ return composite;
+ }
+
+ private void addProperty(Composite parent, String name, String value) {
+ Label label = new Label(parent, SWT.NULL);
+ label.setText(name);
+
+ Text text = new Text(parent, SWT.READ_ONLY);
+ if (value == null)
+ value = "";
+ text.setText(value.trim());
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ text.setLayoutData(gd);
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/propertyPages/OSGModulePrefsPropertyPage.java b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/propertyPages/OSGModulePrefsPropertyPage.java
new file mode 100644
index 0000000..d371f3a
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.gadgets/src/org/eclipse/e4/ui/internal/gadgets/opensocial/propertyPages/OSGModulePrefsPropertyPage.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Sierra Wireless 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:
+ * Benjamin Cabe, Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.gadgets.opensocial.propertyPages;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.e4.ui.internal.gadgets.opensocial.OSGModule;
+import org.eclipse.e4.ui.internal.gadgets.opensocial.OSGUserPref;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbenchPropertyPage;
+import org.eclipse.ui.dialogs.PropertyPage;
+
+public class OSGModulePrefsPropertyPage extends PropertyPage implements
+ IWorkbenchPropertyPage {
+
+ private Map<String, Text> preferenceEditors = new HashMap<String, Text>();
+
+ public OSGModulePrefsPropertyPage() {
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ composite.setLayout(layout);
+ GridData data = new GridData(GridData.FILL);
+ data.grabExcessHorizontalSpace = true;
+ composite.setLayoutData(data);
+
+ OSGModule module = (OSGModule) getElement().getAdapter(OSGModule.class);
+ for (OSGUserPref pref : module.getUserPrefs()) {
+ addProperty(composite, pref.getName(), pref.getValue());
+ }
+
+ return composite;
+ }
+
+ @Override
+ public boolean performOk() {
+ OSGModule module = (OSGModule) getElement().getAdapter(OSGModule.class);
+ for (Map.Entry<String, Text> entry : preferenceEditors.entrySet()) {
+ module.setUserPrefValue(entry.getKey(), entry.getValue().getText());
+ }
+
+ return true;
+ }
+
+ @Override
+ protected void performDefaults() {
+ OSGModule module = (OSGModule) getElement().getAdapter(OSGModule.class);
+ for (Map.Entry<String, Text> entry : preferenceEditors.entrySet()) {
+ String userPrefDefaultValue = module.getUserPrefDefaultValue(entry
+ .getKey());
+ entry.getValue().setText(userPrefDefaultValue);
+ }
+ }
+
+ private void addProperty(Composite parent, String key, String value) {
+ Label label = new Label(parent, SWT.NULL);
+ label.setText(key);
+
+ Text text = new Text(parent, SWT.BORDER);
+ if (value == null)
+ value = "";
+ text.setText(value);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ text.setLayoutData(gd);
+ preferenceEditors.put(key, text);
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.selection/.classpath b/bundles/org.eclipse.e4.ui.selection/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.ui.selection/.project b/bundles/org.eclipse.e4.ui.selection/.project
new file mode 100644
index 0000000..2e6f00f
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.ui.selection</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.jdt.core.prefs
new file mode 100755
index 0000000..081f9c7
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,365 @@
+#Tue Jun 23 16:26:13 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=error
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=error
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unsafeTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=100
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=100
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.jdt.ui.prefs
new file mode 100755
index 0000000..fd71409
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,118 @@
+#Thu Jun 18 15:40:58 EDT 2009
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=false
+cleanup.format_source_code=false
+cleanup.format_source_code_changes_only=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=false
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_trailing_whitespaces=false
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_blocks=false
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup_profile=org.eclipse.jdt.ui.default.eclipse_clean_up_profile
+cleanup_settings_version=2
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_Eclipse long lines
+formatter_settings_version=11
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.javadoc=true
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/*******************************************************************************\n * Copyright (c) ${year} IBM Corporation and others.\n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n * IBM Corporation - initial API and implementation\n ******************************************************************************/\n</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=false
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.pde.core.prefs b/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.pde.core.prefs
new file mode 100755
index 0000000..d237e73
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,4 @@
+#Thu Jul 24 16:23:03 EDT 2008
+eclipse.preferences.version=1
+pluginProject.extensions=true
+resolve.requirebundle=false
diff --git a/bundles/org.eclipse.e4.ui.selection/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.ui.selection/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..821f400
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/META-INF/MANIFEST.MF
@@ -0,0 +1,15 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Context Selection Provider
+Bundle-SymbolicName: org.eclipse.e4.ui.selection;singleton:=true
+Bundle-Version: 0.9.0.qualifier
+Bundle-Activator: org.eclipse.e4.ui.selection.internal.Activator
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Import-Package: javax.inject;version="1.0.0",
+ org.eclipse.e4.core.services.context,
+ org.eclipse.e4.core.services.context.spi,
+ org.osgi.framework;version="1.5.0"
+Service-Component: OSGI-INF/selectionService.xml, OSGI-INF/selectionLookup.xml
+Export-Package: org.eclipse.e4.ui.selection,
+ org.eclipse.e4.ui.selection.internal
diff --git a/bundles/org.eclipse.e4.ui.selection/OSGI-INF/selectionLookup.xml b/bundles/org.eclipse.e4.ui.selection/OSGI-INF/selectionLookup.xml
new file mode 100644
index 0000000..0f9033e
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/OSGI-INF/selectionLookup.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.e4.ui.selection.lookUp">
+ <implementation class="org.eclipse.e4.ui.selection.internal.SelectionLookupFunction"/>
+ <service>
+ <provide interface="org.eclipse.e4.core.services.context.IContextFunction"/>
+ </service>
+ <property name="service.context.key" type="String" value="selection"/>
+</scr:component>
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.ui.selection/OSGI-INF/selectionService.xml b/bundles/org.eclipse.e4.ui.selection/OSGI-INF/selectionService.xml
new file mode 100644
index 0000000..64570b7
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/OSGI-INF/selectionService.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.e4.ui.selection.ESelectionService">
+ <implementation class="org.eclipse.e4.ui.selection.internal.SelectionServiceCreationFunction"/>
+ <service>
+ <provide interface="org.eclipse.e4.core.services.context.IContextFunction"/>
+ </service>
+ <property name="service.context.key" type="String" value="org.eclipse.e4.ui.selection.ESelectionService"/>
+</scr:component>
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.ui.selection/build.properties b/bundles/org.eclipse.e4.ui.selection/build.properties
new file mode 100644
index 0000000..6210e84
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/build.properties
@@ -0,0 +1,5 @@
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ OSGI-INF/
+source.. = src/
diff --git a/bundles/org.eclipse.e4.ui.selection/selection.psf b/bundles/org.eclipse.e4.ui.selection/selection.psf
new file mode 100755
index 0000000..19f0b3d
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/selection.psf
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<psf version="2.0">
+<provider id="org.eclipse.team.cvs.core.cvsnature">
+<project reference="1.0,:pserver:dev.eclipse.org:/cvsroot/eclipse,e4/org.eclipse.e4.ui/bundles/org.eclipse.e4.ui.selection,org.eclipse.e4.ui.selection"/>
+<project reference="1.0,:pserver:dev.eclipse.org:/cvsroot/eclipse,e4/org.eclipse.e4.ui/tests/org.eclipse.e4.ui.selection.tests,org.eclipse.e4.ui.selection.tests"/>
+</provider>
+</psf>
diff --git a/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/ESelectionService.java b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/ESelectionService.java
new file mode 100644
index 0000000..8414544
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/ESelectionService.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * 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.e4.ui.selection;
+
+public interface ESelectionService {
+ static final String SELECTION = "selection"; //$NON-NLS-1$
+
+ void setSelection(Object selection);
+
+ Object getSelection();
+}
diff --git a/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/Activator.java b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/Activator.java
new file mode 100644
index 0000000..cc524d0
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/Activator.java
@@ -0,0 +1,50 @@
+package org.eclipse.e4.ui.selection.internal;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator implements BundleActivator {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.e4.ui.selection"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionLookupFunction.java b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionLookupFunction.java
new file mode 100644
index 0000000..966906a
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionLookupFunction.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * 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.e4.ui.selection.internal;
+
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.ContextFunction;
+import org.eclipse.e4.core.services.context.spi.IContextConstants;
+
+/**
+ *
+ */
+public class SelectionLookupFunction extends ContextFunction {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.e4.core.services.context.spi.ContextFunction#compute(org.eclipse.e4.core.services
+ * .context.IEclipseContext, java.lang.Object[])
+ */
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ IEclipseContext leafContext = context;
+ IEclipseContext child = (IEclipseContext) leafContext.getLocal(IContextConstants.ACTIVE_CHILD);
+ while (child != null) {
+ leafContext = child;
+ child = (IEclipseContext) leafContext.getLocal(IContextConstants.ACTIVE_CHILD);
+ }
+ return leafContext.get(SelectionServiceImpl.OUT_SELECTION);
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionServiceCreationFunction.java b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionServiceCreationFunction.java
new file mode 100644
index 0000000..e034b5c
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionServiceCreationFunction.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * 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.e4.ui.selection.internal;
+
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.ContextFunction;
+import org.eclipse.e4.core.services.context.spi.ContextInjectionFactory;
+
+/**
+ *
+ */
+public class SelectionServiceCreationFunction extends ContextFunction {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.e4.core.services.context.spi.ContextFunction#compute(org.eclipse.e4.core.services
+ * .context.IEclipseContext, java.lang.Object[])
+ */
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ SelectionServiceImpl impl = new SelectionServiceImpl();
+ ContextInjectionFactory.inject(impl, context);
+ return impl;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionServiceImpl.java b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionServiceImpl.java
new file mode 100644
index 0000000..f2b0140
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.selection/src/org/eclipse/e4/ui/selection/internal/SelectionServiceImpl.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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.e4.ui.selection.internal;
+
+import javax.inject.Inject;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.ui.selection.ESelectionService;
+
+/**
+ *
+ */
+public class SelectionServiceImpl implements ESelectionService {
+
+ static final String OUT_SELECTION = "output.selection"; //$NON-NLS-1$
+
+ private IEclipseContext context;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.e4.ui.selection.ESelectionService#setSelection(java.lang.Object)
+ */
+ public void setSelection(Object selection) {
+ if (selection != null) {
+ context.set(OUT_SELECTION, selection);
+ } else {
+ context.remove(OUT_SELECTION);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.e4.ui.selection.ESelectionService#getSelection()
+ */
+ public Object getSelection() {
+ return context.get(ESelectionService.SELECTION);
+ }
+
+ @Inject
+ public void setContext(IEclipseContext c) {
+ context = c;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.web/.classpath b/bundles/org.eclipse.e4.ui.web/.classpath
new file mode 100644
index 0000000..2fbb7a2
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.ui.web/.project b/bundles/org.eclipse.e4.ui.web/.project
new file mode 100644
index 0000000..2de00f1
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.ui.web</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.ui.web/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.ui.web/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..e820172
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+#Wed Jul 08 16:27:06 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.3
diff --git a/bundles/org.eclipse.e4.ui.web/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.e4.ui.web/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..48898c4
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,55 @@
+#Sat Oct 24 21:59:03 CEST 2009
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=false
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/bundles/org.eclipse.e4.ui.web/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.ui.web/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..b92bc35
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Eclipse UI web embedding (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.ui.web
+Bundle-Version: 0.9.0.qualifier
+Require-Bundle: org.eclipse.swt;bundle-version="3.5.0",
+ org.eclipse.ui;bundle-version="3.5.0",
+ org.eclipse.equinox.common;bundle-version="3.5.0",
+ org.eclipse.equinox.registry;bundle-version="3.4.0"
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Export-Package: org.eclipse.e4.ui.internal.web;x-internal:=true,
+ org.eclipse.e4.ui.web
+Bundle-Vendor: Eclipse.org
diff --git a/bundles/org.eclipse.e4.ui.web/build.properties b/bundles/org.eclipse.e4.ui.web/build.properties
new file mode 100644
index 0000000..3884924
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ js/
diff --git a/bundles/org.eclipse.e4.ui.web/js/e4.js b/bundles/org.eclipse.e4.ui.web/js/e4.js
new file mode 100644
index 0000000..a384b89
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/js/e4.js
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * 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:
+ * Matthew Hatem, IBM Corporation - initial API and implementation
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+window.e4 = {
+
+ isInstalled : function() {
+ try {
+ return typeof e4RPC == "function";
+ } catch(e) {
+ return false;
+ }
+ },
+
+ hasFeature : function(feature) {
+ return this.isInstalled() && typeof this[feature] == "object";
+ },
+
+ dialogs : {
+ confirm : function(msg) {
+ return e4RPC("dialogs", "confirm", msg);
+ },
+ openFiles : function() {
+
+ }
+ },
+
+ clipboard: {
+ getContents : function() {
+ return e4RPC("clipboard", "getContents");
+ }
+ },
+
+ log: {
+ info : function(msg) {
+ return e4RPC("log", "info", msg);
+ }
+ },
+
+ menus : {
+ addContextMenuItem : function(label, callback) {
+ return e4RPC("menus", "addContextMenuItem", label, callback);
+ }
+ },
+
+ status : {
+ setMessage : function(msg) {
+ return e4RPC("status", "setMessage", msg);
+ },
+ _dirty : false,
+ setDirty : function(dirty) {
+ if (window.e4.status._dirty != dirty) {
+ window.e4.status._dirty = dirty;
+ return e4RPC("status", "setDirty", dirty);
+ }
+ }
+ },
+
+ saveable : {
+ promptToSaveOnClose : function(callback) {
+ return e4RPC("saveable", "promptToSaveOnClose", callback);
+ },
+ doSave : function(callback) {
+ return e4RPC("saveable", "doSave", callback);
+ }
+ }
+};
diff --git a/bundles/org.eclipse.e4.ui.web/pom.xml b/bundles/org.eclipse.e4.ui.web/pom.xml
new file mode 100644
index 0000000..15a6241
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/pom.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.eclipse.e4.ui</groupId>
+ <artifactId>org.eclipse.e4.ui.web</artifactId>
+ <version>0.9.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+
+ <properties>
+ <tycho-version>0.11.1</tycho-version>
+ </properties>
+
+ <repositories>
+ <repository>
+ <id>helios</id>
+ <layout>p2</layout>
+ <url>http://download.eclipse.org/releases/helios</url>
+ </repository>
+ </repositories>
+
+ <build>
+ <plugins>
+ <plugin>
+ <!-- TODO switch to org.eclipse.tycho when it will be publicly available -->
+ <groupId>org.sonatype.tycho</groupId>
+ <artifactId>tycho-maven-plugin</artifactId>
+ <version>${tycho-version}</version>
+ <extensions>true</extensions>
+ </plugin>
+
+ </plugins>
+ </build>
+</project>
diff --git a/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/internal/web/Base64.java b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/internal/web/Base64.java
new file mode 100644
index 0000000..087a13e
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/internal/web/Base64.java
@@ -0,0 +1,212 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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.e4.ui.internal.web;
+
+/**
+ * Base64 is a helper class for converting byte arrays to and
+ * from base 64 encoded Strings.
+ *
+ */
+public class Base64 {
+
+ private static final byte equalSign = (byte) '=';
+
+ static char digits[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', //
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', //
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', //
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
+
+ /**
+ * This method decodes the byte array in base 64 encoding into a char array
+ * Base 64 encoding has to be according to the specification given by the
+ * RFC 1521 (5.2).
+ *
+ * @param data the encoded byte array
+ * @return the decoded byte array
+ */
+ public static byte[] decode(byte[] data) {
+ if (data.length == 0) {
+ return data;
+ }
+ int lastRealDataIndex = data.length - 1;
+ while (data[lastRealDataIndex] == equalSign) {
+ lastRealDataIndex--;
+ }
+ // original data digit is 8 bits long, but base64 digit is 6 bits long
+ int padBytes = data.length - 1 - lastRealDataIndex;
+ int byteLength = data.length * 6 / 8 - padBytes;
+ byte[] result = new byte[byteLength];
+ // Each 4 bytes of input (encoded) we end up with 3 bytes of output
+ int dataIndex = 0;
+ int resultIndex = 0;
+ int allBits = 0;
+ // how many result chunks we can process before getting to pad bytes
+ int resultChunks = (lastRealDataIndex + 1) / 4;
+ for (int i = 0; i < resultChunks; i++) {
+ allBits = 0;
+ // Loop 4 times gathering input bits (4 * 6 = 24)
+ for (int j = 0; j < 4; j++) {
+ allBits = (allBits << 6) | decodeDigit(data[dataIndex++]);
+ }
+ // Loop 3 times generating output bits (3 * 8 = 24)
+ for (int j = resultIndex + 2; j >= resultIndex; j--) {
+ result[j] = (byte) (allBits & 0xff); // Bottom 8 bits
+ allBits = allBits >>> 8;
+ }
+ resultIndex += 3; // processed 3 result bytes
+ }
+ // Now we do the extra bytes in case the original (non-encoded) data
+ // was not multiple of 3 bytes
+ switch (padBytes) {
+ case 1 :
+ // 1 pad byte means 3 (4-1) extra Base64 bytes of input, 18
+ // bits, of which only 16 are meaningful
+ // Or: 2 bytes of result data
+ allBits = 0;
+ // Loop 3 times gathering input bits
+ for (int j = 0; j < 3; j++) {
+ allBits = (allBits << 6) | decodeDigit(data[dataIndex++]);
+ }
+ // NOTE - The code below ends up being equivalent to allBits =
+ // allBits>>>2
+ // But we code it in a non-optimized way for clarity
+ // The 4th, missing 6 bits are all 0
+ allBits = allBits << 6;
+ // The 3rd, missing 8 bits are all 0
+ allBits = allBits >>> 8;
+ // Loop 2 times generating output bits
+ for (int j = resultIndex + 1; j >= resultIndex; j--) {
+ result[j] = (byte) (allBits & 0xff); // Bottom 8
+ // bits
+ allBits = allBits >>> 8;
+ }
+ break;
+ case 2 :
+ // 2 pad bytes mean 2 (4-2) extra Base64 bytes of input, 12 bits
+ // of data, of which only 8 are meaningful
+ // Or: 1 byte of result data
+ allBits = 0;
+ // Loop 2 times gathering input bits
+ for (int j = 0; j < 2; j++) {
+ allBits = (allBits << 6) | decodeDigit(data[dataIndex++]);
+ }
+ // NOTE - The code below ends up being equivalent to allBits =
+ // allBits>>>4
+ // But we code it in a non-optimized way for clarity
+ // The 3rd and 4th, missing 6 bits are all 0
+ allBits = allBits << 6;
+ allBits = allBits << 6;
+ // The 3rd and 4th, missing 8 bits are all 0
+ allBits = allBits >>> 8;
+ allBits = allBits >>> 8;
+ result[resultIndex] = (byte) (allBits & 0xff); // Bottom
+ // 8
+ // bits
+ break;
+ }
+ return result;
+ }
+
+ /**
+ * This method converts a Base 64 digit to its numeric value.
+ *
+ * @param data digit (character) to convert
+ * @return value for the digit
+ */
+ static int decodeDigit(byte data) {
+ char charData = (char) data;
+ if (charData <= 'Z' && charData >= 'A') {
+ return charData - 'A';
+ }
+ if (charData <= 'z' && charData >= 'a') {
+ return charData - 'a' + 26;
+ }
+ if (charData <= '9' && charData >= '0') {
+ return charData - '0' + 52;
+ }
+ switch (charData) {
+ case '+' :
+ return 62;
+ case '/' :
+ return 63;
+ default :
+ throw new IllegalArgumentException("Invalid char to decode: " + data); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * This method encodes the byte array into a char array in base 64 according
+ * to the specification given by the RFC 1521 (5.2).
+ *
+ * @param data the encoded char array
+ * @return the byte array that needs to be encoded
+ */
+ public static byte[] encode(byte[] data) {
+ int sourceChunks = data.length / 3;
+ int len = ((data.length + 2) / 3) * 4;
+ byte[] result = new byte[len];
+ int extraBytes = data.length - (sourceChunks * 3);
+ // Each 4 bytes of input (encoded) we end up with 3 bytes of output
+ int dataIndex = 0;
+ int resultIndex = 0;
+ int allBits = 0;
+ for (int i = 0; i < sourceChunks; i++) {
+ allBits = 0;
+ // Loop 3 times gathering input bits (3 * 8 = 24)
+ for (int j = 0; j < 3; j++) {
+ allBits = (allBits << 8) | (data[dataIndex++] & 0xff);
+ }
+ // Loop 4 times generating output bits (4 * 6 = 24)
+ for (int j = resultIndex + 3; j >= resultIndex; j--) {
+ result[j] = (byte) digits[(allBits & 0x3f)]; // Bottom
+ // 6
+ // bits
+ allBits = allBits >>> 6;
+ }
+ resultIndex += 4; // processed 4 result bytes
+ }
+ // Now we do the extra bytes in case the original (non-encoded) data
+ // is not multiple of 4 bytes
+ switch (extraBytes) {
+ case 1 :
+ allBits = data[dataIndex++]; // actual byte
+ allBits = allBits << 8; // 8 bits of zeroes
+ allBits = allBits << 8; // 8 bits of zeroes
+ // Loop 4 times generating output bits (4 * 6 = 24)
+ for (int j = resultIndex + 3; j >= resultIndex; j--) {
+ result[j] = (byte) digits[(allBits & 0x3f)]; // Bottom
+ // 6
+ // bits
+ allBits = allBits >>> 6;
+ }
+ // 2 pad tags
+ result[result.length - 1] = (byte) '=';
+ result[result.length - 2] = (byte) '=';
+ break;
+ case 2 :
+ allBits = data[dataIndex++]; // actual byte
+ allBits = (allBits << 8) | (data[dataIndex++] & 0xff); // actual
+ // byte
+ allBits = allBits << 8; // 8 bits of zeroes
+ // Loop 4 times generating output bits (4 * 6 = 24)
+ for (int j = resultIndex + 3; j >= resultIndex; j--) {
+ result[j] = (byte) digits[(allBits & 0x3f)]; // Bottom
+ // 6
+ // bits
+ allBits = allBits >>> 6;
+ }
+ // 1 pad tag
+ result[result.length - 1] = (byte) '=';
+ break;
+ }
+ return result;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/internal/web/E4BrowserUtil.java b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/internal/web/E4BrowserUtil.java
new file mode 100644
index 0000000..93fc098
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/internal/web/E4BrowserUtil.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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:
+ * Matthew Hatem, IBM Corporation - initial API and implementation
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.internal.web;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class E4BrowserUtil {
+
+ public static byte[] getBytesFromFile(File file) throws IOException {
+ InputStream is = new FileInputStream(file);
+ long length = file.length();
+ byte[] bytes = new byte[(int)length];
+ int offset = 0;
+ int numRead = 0;
+ while (offset < bytes.length
+ && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
+ offset += numRead;
+ }
+ if (offset < bytes.length) {
+ throw new IOException("File read incomplete"+file.getName());
+ }
+ is.close();
+ return bytes;
+ }
+
+ public static byte[] getBytesFromStream(InputStream is) throws IOException {
+ int BUFFER_SIZE = 8192;
+ byte[] buffer = new byte[BUFFER_SIZE];
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ int numRead = 0;
+ while ((numRead = is.read(buffer)) > 0) {
+ os.write(buffer, 0, numRead);
+ }
+ return os.toByteArray();
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserEditorPart.java b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserEditorPart.java
new file mode 100644
index 0000000..c2ee615
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserEditorPart.java
@@ -0,0 +1,306 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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:
+ * Matthew Hatem, IBM Corporation - initial API and implementation
+ * Boris Bokowski, IBM Corporation - initial API and implementation
+ * Benjamin Cabe <BCabe@sierrawireless.com> - ongoing enhancements
+ *******************************************************************************/
+package org.eclipse.e4.ui.web;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.e4.ui.internal.web.Base64;
+import org.eclipse.e4.ui.internal.web.E4BrowserUtil;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.CloseWindowListener;
+import org.eclipse.swt.browser.OpenWindowListener;
+import org.eclipse.swt.browser.WindowEvent;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.ISaveablePart2;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.part.EditorPart;
+
+public abstract class BrowserEditorPart extends EditorPart {
+
+ private Browser browser;
+ private BrowserRPC browserRPC;
+ private boolean isDirty;
+ private List menuItems = new ArrayList(3);
+ private SaveableProxy saveable;
+
+ public void createPartControl(Composite parent) {
+ parent.setLayout(new FillLayout());
+ browser = new Browser(parent, SWT.NONE);
+ browser.addOpenWindowListener(new OpenWindowListener() {
+ public void open(WindowEvent event) {
+ BrowserEditorPart view = openWindow(event);
+ if (view != null) {
+ event.browser = view.getBrowser();
+ event.required = true;
+ }
+ }
+ });
+
+ browser.addCloseWindowListener(new CloseWindowListener() {
+ public void close(WindowEvent event) {
+ isDirty = false;
+ getEditorSite().getPage().closeEditor(BrowserEditorPart.this,
+ true);
+ }
+ });
+
+ browserRPC = new BrowserRPC(browser);
+ saveable = new SaveableProxy(browser);
+ browserRPC.addRPCHandler("dialogs", new BrowserRPCHandler() {
+ public Object handle(Browser browser, Object[] args) {
+ if ("confirm".equals(args[1])) {
+ IEditorSite site = getEditorSite();
+ String title = "Confirmation - "
+ + BrowserEditorPart.this.getTitle();
+ return Boolean.valueOf(MessageDialog.openConfirm(site
+ .getShell(), title, (String) args[2]));
+ }
+ return null;
+ }
+
+ public void dispose() {
+ // Nothing
+ }
+ });
+
+ browserRPC.addRPCHandler("clipboard", new BrowserRPCHandler() {
+ public Object handle(Browser browser, Object[] args) {
+ if ("getContents".equals(args[1])) {
+ Clipboard cb = new Clipboard(browser.getDisplay());
+ FileTransfer ft = FileTransfer.getInstance();
+ String[] files = (String[]) cb.getContents(ft);
+ if (files.length > 0) {
+ File file = new File(files[0]);
+ if (file.exists()) {
+ byte[] data;
+ try {
+ data = E4BrowserUtil.getBytesFromFile(file);
+ byte[] encoded = Base64.encode(data);
+ return new String(encoded);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public void dispose() {
+ // Nothing
+ }
+ });
+
+ browserRPC.addRPCHandler("menus", new BrowserRPCHandler() {
+ public Object handle(Browser browser, Object[] args) {
+ if ("addContextMenuItem".equals(args[1])) {
+ menuItems.add(new MenuItemProxy((String) args[2],
+ (String) args[3]));
+ }
+ return null;
+ }
+
+ public void dispose() {
+ // Nothing
+ }
+ });
+
+ browserRPC.addRPCHandler("status", new BrowserRPCHandler() {
+ public Object handle(Browser browser, Object[] args) {
+ if ("setMessage".equals(args[1])) {
+ IStatusLineManager slm = getEditorSite().getActionBars()
+ .getStatusLineManager();
+ slm.setMessage((String) args[2]);
+ } else if ("setDirty".equals(args[1])) {
+ isDirty = ((Boolean) args[2]).booleanValue();
+ firePropertyChange(PROP_DIRTY);
+ }
+ return null;
+ }
+
+ public void dispose() {
+ // Nothing
+ }
+ });
+
+ browserRPC.addRPCHandler("saveable", new BrowserRPCHandler() {
+ public Object handle(Browser browser, Object[] args) {
+ if ("promptToSaveOnClose".equals(args[1])) {
+ saveable.setPromptCallback((String) args[2]);
+ } else if ("doSave".equals(args[1])) {
+ saveable.setDoSaveCallback((String) args[2]);
+ }
+ return null;
+ }
+
+ public void dispose() {
+ // Nothing
+ }
+ });
+ configureBrowser(browser);
+
+ // context menu
+ hookContextMenu();
+ }
+
+ protected void configureBrowser(Browser b) {
+ }
+
+ protected BrowserEditorPart openWindow(WindowEvent event) {
+ BrowserEditorPart view = null;
+ try {
+ view = (BrowserEditorPart) getEditorSite().getPage()
+ .openEditor(getNewWindowEditorInput(event),
+ getNewWindowEditorId(event));
+ } catch (PartInitException e) {
+ e.printStackTrace();
+ }
+ return view;
+ }
+
+ protected String getNewWindowEditorId(WindowEvent event) {
+ return getSite().getId();
+ }
+
+ protected abstract IEditorInput getNewWindowEditorInput(WindowEvent event);
+
+ public void setUrl(String url) {
+ browser.setUrl(url);
+ }
+
+ public Browser getBrowser() {
+ return browser;
+ }
+
+ public void setFocus() {
+ browser.setFocus();
+ }
+
+ private void hookContextMenu() {
+ MenuManager menuMgr = new MenuManager("#PopupMenu");
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ // fill context menu
+ Iterator itr = menuItems.iterator();
+ while (itr.hasNext()) {
+ final MenuItemProxy mi = (MenuItemProxy) itr.next();
+ Action action = new Action(mi.getLabel()) {
+ public void run() {
+ browser.execute(mi.getCallback());
+ }
+ };
+ manager.add(action);
+ }
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(browser);
+ browser.setMenu(menu);
+
+ // TODO implement a selection provider wrapper for browser
+ // getSite().registerContextMenu(menuMgr, browser);
+ }
+
+ public int promptToSaveOnClose() {
+ return saveable.promptToSaveOnClose();
+ }
+
+ public void doSave(IProgressMonitor monitor) {
+ saveable.doSave(monitor);
+ }
+
+ public void doSaveAs() {
+ }
+
+ public boolean isDirty() {
+ return isDirty;
+ }
+
+ public boolean isSaveAsAllowed() {
+ return false;
+ }
+
+ public boolean isSaveOnCloseNeeded() {
+ return isDirty();
+ }
+
+ private class MenuItemProxy {
+ private String label;
+ private String callback;
+
+ public MenuItemProxy(String label, String callback) {
+ this.label = label;
+ this.callback = callback;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public String getCallback() {
+ return callback;
+ }
+ }
+
+ private class SaveableProxy {
+ private String promptCallback;
+ private String dosaveCallback;
+ private Browser browser;
+
+ public SaveableProxy(Browser browser) {
+ this.browser = browser;
+ }
+
+ public void setPromptCallback(String promptCallback) {
+ this.promptCallback = promptCallback;
+ }
+
+ public void setDoSaveCallback(String dosaveCallback) {
+ this.dosaveCallback = dosaveCallback;
+ }
+
+ public int promptToSaveOnClose() {
+ if (promptCallback != null) {
+ Double i = (Double) browser.evaluate(promptCallback);
+ if (i != null) {
+ return i.intValue();
+ }
+ }
+ return ISaveablePart2.DEFAULT;
+ }
+
+ public void doSave(IProgressMonitor monitor) {
+ if (dosaveCallback != null) {
+ browser.execute(dosaveCallback);
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserRPC.java b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserRPC.java
new file mode 100644
index 0000000..040b1b9
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserRPC.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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:
+ * Matthew Hatem, IBM Corporation - initial API and implementation
+ * Benjamin Cabe <BCabe@sierrawireless.com> - ongoing enhancements
+ *******************************************************************************/
+package org.eclipse.e4.ui.web;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.e4.ui.internal.web.E4BrowserUtil;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.BrowserFunction;
+import org.eclipse.swt.browser.LocationEvent;
+import org.eclipse.swt.browser.LocationListener;
+import org.eclipse.swt.browser.ProgressEvent;
+import org.eclipse.swt.browser.ProgressListener;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+
+public class BrowserRPC {
+
+ private static final String UNDEFINED = "undefined";
+
+ private BrowserFunction rpcFunction;
+
+ private Map/* String, BrowserRPCHandler */handlers = new HashMap();
+
+ private Browser browser;
+
+ public BrowserRPC(Browser browser) {
+ this.browser = browser;
+ final String e4Script;
+ try {
+ e4Script = new String(E4BrowserUtil.getBytesFromStream(getClass()
+ .getClassLoader().getResourceAsStream("js/e4.js")),
+ "ISO-8859-1");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ // we need to register the ipc each time
+ // the location for the browser changes
+ browser.addLocationListener(new LocationListener() {
+ public void changed(LocationEvent event) {
+ registerRPC();
+ }
+
+ public void changing(LocationEvent event) {
+ }
+ });
+ registerRPC();
+ browser.addProgressListener(new ProgressListener() {
+ public void completed(ProgressEvent event) {
+ if (!BrowserRPC.this.browser.execute(e4Script)) {
+ MessageDialog.openError(BrowserRPC.this.browser.getShell(),
+ "Error", "Error executing e4 script");
+ }
+ }
+
+ public void changed(ProgressEvent event) {
+ }
+ });
+ browser.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ removeAllRPCHandlers();
+ }
+ });
+ }
+
+ private void registerRPC() {
+ if (rpcFunction != null) {
+ rpcFunction.dispose();
+ }
+ rpcFunction = new BrowserFunction(browser, "e4RPC") {
+ public Object function(Object[] arguments) {
+ BrowserRPCHandler handler = (BrowserRPCHandler) handlers
+ .get(arguments[0]);
+ if (handler != null) {
+ return handler.handle(browser, arguments);
+ }
+ return UNDEFINED;
+ }
+ };
+ }
+
+ public void addRPCHandler(String function, BrowserRPCHandler handler) {
+ if (handlers.get(function) != null) {
+ throw new IllegalArgumentException();
+ }
+ handlers.put(function, handler);
+ }
+
+ public void removeRPCHandler(String function) {
+ BrowserRPCHandler oldHandler = (BrowserRPCHandler) handlers
+ .remove(function);
+ if (oldHandler != null) {
+ oldHandler.dispose();
+ }
+ }
+
+ private void removeAllRPCHandlers() {
+ String[] handlerFunction = (String[]) handlers.keySet().toArray(
+ new String[0]);
+ for (int i = 0; i < handlerFunction.length; i++) {
+ removeRPCHandler(handlerFunction[i]);
+ }
+
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserRPCHandler.java b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserRPCHandler.java
new file mode 100644
index 0000000..c065362
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserRPCHandler.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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:
+ * Matthew Hatem, IBM Corporation - initial API and implementation
+ * Benjamin Cabe <BCabe@sierrawireless.com> - ongoing enhancements
+ *******************************************************************************/
+package org.eclipse.e4.ui.web;
+
+import org.eclipse.swt.browser.Browser;
+
+public interface BrowserRPCHandler {
+
+ public Object handle(final Browser browser, final Object[] arguments);
+
+ public void dispose();
+
+}
diff --git a/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserViewPart.java b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserViewPart.java
new file mode 100644
index 0000000..bb1fbae
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.web/src/org/eclipse/e4/ui/web/BrowserViewPart.java
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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:
+ * Matthew Hatem, IBM Corporation - initial API and implementation
+ * Benjamin Cabe <BCabe@sierrawireless.com> - ongoing enhancements
+ *******************************************************************************/
+package org.eclipse.e4.ui.web;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.e4.ui.internal.web.Base64;
+import org.eclipse.e4.ui.internal.web.E4BrowserUtil;
+import org.eclipse.jface.action.*;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.*;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.*;
+import org.eclipse.ui.part.ViewPart;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+public abstract class BrowserViewPart extends ViewPart implements ISaveablePart2 {
+
+ protected Browser browser;
+ private BrowserRPC browserRPC;
+ private boolean isDirty;
+ private List menuItems = new ArrayList(3);
+ private SaveableProxy saveable;
+
+ public void createPartControl(Composite parent) {
+ parent.setLayout(new FillLayout());
+ browser = new Browser(parent, SWT.NONE);
+ browserRPC = new BrowserRPC(browser);
+ saveable = new SaveableProxy(browser);
+ browser.addOpenWindowListener(new OpenWindowListener() {
+ public void open(WindowEvent event) {
+ BrowserViewPart view = openWindow(event);
+ if (view != null) {
+ event.browser = view.getBrowser();
+ event.required = true;
+ }
+ }
+ });
+
+ browser.addCloseWindowListener(new CloseWindowListener() {
+ public void close(WindowEvent event) {
+ isDirty = false;
+ getViewSite().getPage().hideView(BrowserViewPart.this);
+ }
+ });
+
+ browserRPC.addRPCHandler("dialogs", new BrowserRPCHandler() {
+ public Object handle(Browser browser, Object[] args) {
+ if ("confirm".equals(args[1])) {
+ IViewSite site = getViewSite();
+ String title = "Confirmation - " + BrowserViewPart.this.getTitle();
+ return Boolean.valueOf(MessageDialog.openConfirm(site.getShell(), title, (String) args[2]));
+ }
+ return null;
+ }
+
+ public void dispose() {
+ // Nothing
+ }
+ });
+
+ browserRPC.addRPCHandler("clipboard", new BrowserRPCHandler() {
+ public Object handle(Browser browser, Object[] args) {
+ if ("getContents".equals(args[1])) {
+ Clipboard cb = new Clipboard(browser.getDisplay());
+ FileTransfer ft = FileTransfer.getInstance();
+ String[] files = (String[]) cb.getContents(ft);
+ if (files.length > 0) {
+ File file = new File(files[0]);
+ if (file.exists()) {
+ byte[] data;
+ try {
+ data = E4BrowserUtil.getBytesFromFile(file);
+ byte[] encoded = Base64.encode(data);
+ return new String(encoded);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public void dispose() {
+ // Nothing
+ }
+ });
+
+ browserRPC.addRPCHandler("log", new BrowserRPCHandler() {
+ public Object handle(Browser browser, Object[] args) {
+ int statusSeverity = IStatus.INFO;
+ if ("info".equals(args[1]))
+ statusSeverity = IStatus.INFO;
+ else if ("warning".equals(args[1]))
+ statusSeverity = IStatus.WARNING;
+ else if ("error".equals(args[1]))
+ statusSeverity = IStatus.ERROR;
+
+ if ("info".equals(args[1])) {
+ StatusManager.getManager().handle(new Status(statusSeverity, "opensocial-demo", (String) args[2]));
+ }
+ return null;
+ }
+
+ public void dispose() {
+ // Nothing
+ }
+ });
+
+ browserRPC.addRPCHandler("menus", new BrowserRPCHandler() {
+ public Object handle(Browser browser, Object[] args) {
+ if ("addContextMenuItem".equals(args[1])) {
+ menuItems.add(new MenuItemProxy((String) args[2], (String) args[3]));
+ }
+ return null;
+ }
+
+ public void dispose() {
+ // Nothing
+ }
+ });
+
+ browserRPC.addRPCHandler("status", new BrowserRPCHandler() {
+ public Object handle(Browser browser, Object[] args) {
+ if ("setMessage".equals(args[1])) {
+ IStatusLineManager slm = getViewSite().getActionBars().getStatusLineManager();
+ slm.setMessage((String) args[2]);
+ } else if ("setDirty".equals(args[1])) {
+ isDirty = ((Boolean) args[2]).booleanValue();
+ firePropertyChange(PROP_DIRTY);
+ }
+ return null;
+ }
+
+ public void dispose() {
+ // Nothing
+ }
+ });
+
+ browserRPC.addRPCHandler("saveable", new BrowserRPCHandler() {
+ public Object handle(Browser browser, Object[] args) {
+ if ("promptToSaveOnClose".equals(args[1])) {
+ saveable.setPromptCallback((String) args[2]);
+ } else if ("doSave".equals(args[1])) {
+ saveable.setDoSaveCallback((String) args[2]);
+ }
+ return null;
+ }
+
+ public void dispose() {
+ // Nothing
+ }
+ });
+
+ configureBrowser(browser);
+ // context menu
+ // hookContextMenu();
+ }
+
+ abstract protected void configureBrowser(Browser browser);
+
+ protected abstract String getNewWindowViewId();
+
+ protected BrowserViewPart openWindow(WindowEvent event) {
+ BrowserViewPart view = null;
+ try {
+ view = (BrowserViewPart) getViewSite().getPage().showView(getNewWindowViewId(), String.valueOf(System.currentTimeMillis()), IWorkbenchPage.VIEW_ACTIVATE);
+ } catch (PartInitException e) {
+ e.printStackTrace();
+ }
+ return view;
+ }
+
+ public void setUrl(String url) {
+ browser.setUrl(url);
+ }
+
+ public Browser getBrowser() {
+ return browser;
+ }
+
+ public void setFocus() {
+ browser.setFocus();
+ }
+
+ void hookContextMenu() {
+ MenuManager menuMgr = new MenuManager("#PopupMenu");
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ // fill context menu
+ Iterator itr = menuItems.iterator();
+ while (itr.hasNext()) {
+ final MenuItemProxy mi = (MenuItemProxy) itr.next();
+ Action action = new Action(mi.getLabel()) {
+ public void run() {
+ browser.execute(mi.getCallback());
+ }
+ };
+ manager.add(action);
+ }
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(browser);
+ browser.setMenu(menu);
+
+ // TODO implement a selection provider wrapper for browser
+ // getSite().registerContextMenu(menuMgr, browser);
+ }
+
+ public int promptToSaveOnClose() {
+ return saveable.promptToSaveOnClose();
+ }
+
+ public void doSave(IProgressMonitor monitor) {
+ saveable.doSave(monitor);
+ }
+
+ public void doSaveAs() {
+ }
+
+ public boolean isDirty() {
+ return isDirty;
+ }
+
+ public boolean isSaveAsAllowed() {
+ return false;
+ }
+
+ public boolean isSaveOnCloseNeeded() {
+ return isDirty();
+ }
+
+ private class MenuItemProxy {
+ private String label;
+ private String callback;
+
+ public MenuItemProxy(String label, String callback) {
+ this.label = label;
+ this.callback = callback;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public String getCallback() {
+ return callback;
+ }
+ }
+
+ private class SaveableProxy {
+ private String promptCallback;
+ private String dosaveCallback;
+ private Browser browser;
+
+ public SaveableProxy(Browser browser) {
+ this.browser = browser;
+ }
+
+ public void setPromptCallback(String promptCallback) {
+ this.promptCallback = promptCallback;
+ }
+
+ public void setDoSaveCallback(String dosaveCallback) {
+ this.dosaveCallback = dosaveCallback;
+ }
+
+ public int promptToSaveOnClose() {
+ if (promptCallback != null) {
+ Double i = (Double) browser.evaluate(promptCallback);
+ if (i != null) {
+ return i.intValue();
+ }
+ }
+ return ISaveablePart2.DEFAULT;
+ }
+
+ public void doSave(IProgressMonitor monitor) {
+ if (dosaveCallback != null) {
+ browser.execute(dosaveCallback);
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/.classpath b/bundles/org.eclipse.e4.ui.workbench.fragment/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/.cvsignore b/bundles/org.eclipse.e4.ui.workbench.fragment/.cvsignore
new file mode 100644
index 0000000..ba077a4
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/.project b/bundles/org.eclipse.e4.ui.workbench.fragment/.project
new file mode 100644
index 0000000..52bfeae
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.ui.workbench.fragment</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..3e499cf
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,354 @@
+#Fri Apr 03 07:41:10 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=error
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=error
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=80
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.launching.prefs b/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.launching.prefs
new file mode 100644
index 0000000..93cdd49
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.launching.prefs
@@ -0,0 +1,3 @@
+#Wed Dec 03 10:31:31 EST 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..0308585
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,63 @@
+#Fri Jun 12 14:32:58 EDT 2009
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile
+formatter_settings_version=11
+internal.default.compliance=user
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.javadoc=true
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return Returns the ${bare_field_name}.\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} The ${bare_field_name} to set.\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/*******************************************************************************\n * Copyright (c) ${year} IBM Corporation and others.\n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n * IBM Corporation - initial API and implementation\n ******************************************************************************/\n</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @since 3.3\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template></templates>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=false
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.pde.prefs b/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.pde.prefs
new file mode 100644
index 0000000..7f9ef27
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,14 @@
+#Tue Nov 23 11:21:27 EST 2004
+compilers.p.unused-element-or-attribute=1
+compilers.p.unresolved-ex-points=0
+compilers.p.deprecated=0
+compilers.p.unknown-element=1
+compilers.p.unknown-resource=1
+compilers.p.unknown-class=1
+compilers.p.unknown-attribute=0
+compilers.p.no-required-att=0
+eclipse.preferences.version=1
+compilers.p.unresolved-import=0
+compilers.p.not-externalized-att=0
+compilers.p.illegal-att-value=0
+compilers.use-project=true
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/Application.xmi b/bundles/org.eclipse.e4.ui.workbench.fragment/Application.xmi
new file mode 100644
index 0000000..f202148
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/Application.xmi
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="ASCII"?>
+<org.eclipse.e4.ui.model.application:MApplication xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:org.eclipse.e4.ui.model.application="http://www.eclipse.org/ui/2008/Application" xsi:schemaLocation="http://www.eclipse.org/ui/2008/Application ../org.eclipse.e4.ui.model.workbench/model/Application.ecore">
+ <windows x="100" y="100" width="800" height="600">
+ <menu>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" name="File">
+ <menu>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" id="" name="Do Nothing"/>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" iconURI="" name="---" separator="true"/>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" iconURI="" name="Exit" command="//@command.0"/>
+ </menu>
+ </items>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" name="Edit">
+ <menu>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" iconURI="" name="Exit" command="//@command.0"/>
+ </menu>
+ </items>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" name="Help">
+ <menu>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" iconURI="" name="Exit" command="//@command.0"/>
+ </menu>
+ </items>
+ </menu>
+ <children policy="VerticalComposite">
+ <toolBar>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MToolBarItem" name="You Are Seeing The Default Application.xmi"/>
+ </toolBar>
+ <children xsi:type="org.eclipse.e4.ui.model.application:MSashForm" policy="HorizontalSash">
+ <children xsi:type="org.eclipse.e4.ui.model.application:MSashForm" policy="VerticalSash">
+ <children xsi:type="org.eclipse.e4.ui.model.application:MStack">
+ <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Library" tooltip="" URI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.workbench.ui.internal.parts.SampleView"/>
+ </children>
+ </children>
+ <children xsi:type="org.eclipse.e4.ui.model.application:MSashForm" policy="VerticalSash">
+ <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Preview" URI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.workbench.ui.internal.parts.SampleView"/>
+ <children xsi:type="org.eclipse.e4.ui.model.application:MStack">
+ <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Thumbnails" URI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.workbench.ui.internal.parts.SampleView"/>
+ <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Exif" tooltip="" URI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.workbench.ui.internal.parts.SampleView"/>
+ </children>
+ <weights>70</weights>
+ <weights>30</weights>
+ </children>
+ <weights>30</weights>
+ <weights>70</weights>
+ </children>
+ </children>
+ <handlers URI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.workbench.ui.internal.ExitHandler" command="//@command.0"/>
+ </windows>
+ <command id="org.eclipse.e4.ui.workbench.exit" name="Exit"/>
+</org.eclipse.e4.ui.model.application:MApplication>
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.ui.workbench.fragment/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..a7e5dc3
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/META-INF/MANIFEST.MF
@@ -0,0 +1,26 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %fragmentName
+Bundle-SymbolicName: org.eclipse.e4.ui.workbench.fragment;singleton:=true
+Bundle-Version: 0.9.1.qualifier
+Bundle-Vendor: %providerName
+Fragment-Host: org.eclipse.ui.workbench;bundle-version="[3.0.0,4.0.0)"
+Bundle-Localization: fragment-compatibility
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ClassPath: e4-workbench.jar
+Require-Bundle: org.eclipse.e4.ui.workbench;bundle-version="0.9.0",
+ org.eclipse.core.runtime;bundle-version="3.4.100",
+ org.eclipse.e4.core.services;bundle-version="0.9.0",
+ org.eclipse.e4.ui.workbench.renderers.swt,
+ org.eclipse.e4.ui.workbench.swt,
+ org.eclipse.e4.ui.services;bundle-version="0.9.0",
+ org.eclipse.e4.ui.widgets;bundle-version="0.9.0",
+ org.eclipse.e4.ui.model.workbench;bundle-version="0.9.0",
+ org.eclipse.e4.core.commands;bundle-version="0.9.0"
+Export-Package: org.eclipse.e4.compatibility,
+ org.eclipse.e4.extensions,
+ org.eclipse.e4.workbench.ui.api,
+ org.eclipse.e4.workbench.ui.menus,
+ org.eclipse.ui,
+ org.eclipse.ui.internal;x-internal:=true,
+ org.eclipse.ui.part
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/about.html b/bundles/org.eclipse.e4.ui.workbench.fragment/about.html
new file mode 100644
index 0000000..4602330
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 2, 2006</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/build.properties b/bundles/org.eclipse.e4.ui.workbench.fragment/build.properties
new file mode 100644
index 0000000..a8878ad
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/build.properties
@@ -0,0 +1,18 @@
+###############################################################################
+# Copyright (c) 2003, 2008 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
+###############################################################################
+
+source.e4-workbench.jar=src/
+src.includes=about.html
+bin.includes = fragment-compatibility.properties,\
+ about.html,\
+ e4-workbench.jar,\
+ META-INF/,\
+ fragment.xml
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/fragment-compatibility.properties b/bundles/org.eclipse.e4.ui.workbench.fragment/fragment-compatibility.properties
new file mode 100644
index 0000000..f5c8844
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/fragment-compatibility.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2003, 2005 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
+###############################################################################
+providerName=Eclipse.org
+fragmentName=Workbench Compatibility (Incubation)
+
+perspective.name.f0 = Compatibility Test Perspective
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/fragment.xml b/bundles/org.eclipse.e4.ui.workbench.fragment/fragment.xml
new file mode 100644
index 0000000..9441a04
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/fragment.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<fragment>
+
+</fragment>
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/Activator.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/Activator.java
new file mode 100644
index 0000000..fe84207
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/Activator.java
@@ -0,0 +1,50 @@
+package org.eclipse.e4.compatibility;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.e4.compatibility"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/LegacyEditor.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/LegacyEditor.java
new file mode 100644
index 0000000..e92b87f
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/LegacyEditor.java
@@ -0,0 +1,280 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 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.e4.compatibility;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.extensions.ExtensionUtils;
+import org.eclipse.e4.extensions.ModelEditorReference;
+import org.eclipse.e4.ui.internal.workbench.Trackable;
+import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.widgets.CTabFolder;
+import org.eclipse.e4.ui.widgets.CTabItem;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.SubActionBars;
+import org.eclipse.ui.internal.EditorActionBars;
+import org.eclipse.ui.internal.EditorActionBuilder;
+import org.eclipse.ui.internal.EditorSite;
+import org.eclipse.ui.internal.ViewSite;
+import org.eclipse.ui.internal.WorkbenchPage;
+import org.eclipse.ui.internal.registry.EditorDescriptor;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+
+/**
+ * This class is an implementation of an MPart that can be used to host a 3.x
+ * EditorPart into an Eclipse 4.0 application.
+ *
+ * @since 4.0
+ *
+ */
+public class LegacyEditor {
+ public final static String LEGACY_VIEW_URI = "bundleclass://org.eclipse.ui.workbench/org.eclipse.e4.compatibility.LegacyEditor"; //$NON-NLS-1$
+
+ private static final String IS_DIRTY = "isDirty"; //$NON-NLS-1$
+ private static final String EDITOR_DISPOSED = "editorDisposed"; //$NON-NLS-1$
+
+ private MPart editorPart;
+ private IEditorPart editorWBPart;
+
+ private Map<IEditorPart, Trackable> trackables = new HashMap<IEditorPart, Trackable>();
+
+ /**
+ * Create and initialize a 3.x editor from an e4 contribution
+ *
+ * @param parent
+ * The SWT parent for the editor
+ * @param context
+ * The context under which this part is being created
+ * @param part
+ * The MPart representing the editor
+ */
+ public LegacyEditor(final Composite parent, IEclipseContext context,
+ final MPart part) {
+ editorPart = part;
+
+ IConfigurationElement editorElement = findEditorConfig(part.getId());
+
+ EditorDescriptor desc = new EditorDescriptor(part.getId(),
+ editorElement);
+
+ parent.setLayout(new FillLayout());
+
+ // Convert the relative path into a bundle URI
+ String imagePath = editorElement.getAttribute("icon"); //$NON-NLS-1$
+ String imageURI = imagePath;
+ if (!imagePath.startsWith("platform:")) { //$NON-NLS-1$
+ imagePath = imagePath.replace("$nl$", ""); //$NON-NLS-1$//$NON-NLS-2$
+ if (imagePath.charAt(0) != '/') {
+ imagePath = '/' + imagePath;
+ }
+ String bundleId = editorElement.getContributor().getName();
+ imageURI = "platform:/plugin/" + bundleId + imagePath; //$NON-NLS-1$
+ }
+
+ part.setIconURI(imageURI);
+
+ try {
+ editorWBPart = desc.createEditor();
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+
+ if (editorWBPart == null)
+ return;
+
+ try {
+ final IEclipseContext localContext = part.getContext();
+ IEclipseContext parentContext = (IEclipseContext) localContext
+ .get(IContextConstants.PARENT);
+
+ localContext.set(IContextConstants.DEBUG_STRING, "Legacy Editor(" //$NON-NLS-1$
+ + desc.getLabel() + ")"); //$NON-NLS-1$
+ parentContext.set(IContextConstants.ACTIVE_CHILD, localContext);
+
+ part.setObject(editorWBPart);
+ // Assign a 'site' for the newly instantiated part
+ WorkbenchPage page = (WorkbenchPage) localContext
+ .get(WorkbenchPage.class.getName());
+ ModelEditorReference ref = new ModelEditorReference(part, page);
+ EditorSite site = new EditorSite(ref, editorWBPart, page);
+ EditorActionBars bars = getEditorActionBars(desc, page,
+ page.getWorkbenchWindow(), part.getId());
+ site.setActionBars(bars);
+ site.setConfigurationElement(editorElement);
+ editorWBPart.init(site, (IEditorInput) localContext
+ .get(IEditorInput.class.getName()));
+
+ editorWBPart.createPartControl(parent);
+ localContext.set(MPart.class.getName(), part);
+
+ // HACK!! presumes it's the -last- child of the parent
+ if (parent.getChildren().length > 0) {
+ Control newCtrl = parent.getChildren()[parent.getChildren().length - 1];
+ newCtrl.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ disposeEditor(editorPart);
+ }
+ });
+ }
+
+ // Manage the 'dirty' state
+ final IEditorPart implementation = editorWBPart;
+ localContext.set(IS_DIRTY, implementation.isDirty());
+ localContext.set(EDITOR_DISPOSED, Boolean.FALSE);
+
+ Trackable updateDirty = new Trackable(localContext) {
+ private CTabItem findItemForPart(CTabFolder ctf) {
+ CTabItem[] items = ctf.getItems();
+ for (int i = 0; i < items.length; i++) {
+ if (items[i].getData(AbstractPartRenderer.OWNING_ME) == part) {
+ return items[i];
+ }
+ }
+
+ return null;
+ }
+
+ public void run() {
+ if (!participating) {
+ return;
+ }
+ trackingContext.get(EDITOR_DISPOSED);
+ boolean dirty = (Boolean) trackingContext.get(IS_DIRTY);
+ if (parent instanceof CTabFolder) {
+ CTabFolder ctf = (CTabFolder) parent;
+ CTabItem partItem = findItemForPart(ctf);
+ if (partItem == null)
+ return;
+
+ String itemText = partItem.getText();
+ if (dirty && itemText.indexOf('*') != 0) {
+ itemText = '*' + itemText;
+ } else if (itemText.indexOf('*') == 0) {
+ itemText = itemText.substring(1);
+ }
+ partItem.setText(itemText);
+ }
+ }
+ };
+ trackables.put(implementation, updateDirty);
+ localContext.runAndTrack(updateDirty);
+ editorWBPart.addPropertyListener(new IPropertyListener() {
+ public void propertyChanged(Object source, int propId) {
+ localContext.set(IS_DIRTY, implementation.isDirty());
+ }
+ });
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ protected void disposeEditor(MPart part) {
+ Object obj = part.getObject();
+ if (!(obj instanceof IWorkbenchPart))
+ return;
+
+ if (obj instanceof IEditorPart) {
+ Activator.trace(Policy.DEBUG_RENDERER,
+ "Disposing tracker for " + obj, null); //$NON-NLS-1$
+ Trackable t = trackables.remove(obj);
+ t.participating = false;
+ part.getContext().set(EDITOR_DISPOSED, Boolean.TRUE);
+ }
+ ((IWorkbenchPart) obj).dispose();
+ if (obj instanceof IEditorPart) {
+ EditorSite site = (EditorSite) ((IEditorPart) obj).getEditorSite();
+ disposeEditorActionBars((EditorActionBars) site.getActionBars());
+ site.dispose();
+ } else if (obj instanceof IViewPart) {
+ ViewSite site = (ViewSite) ((IViewPart) obj).getViewSite();
+ SubActionBars bars = (SubActionBars) site.getActionBars();
+ bars.dispose();
+ site.dispose();
+ }
+ part.setObject(null);
+ }
+
+ Map<String, EditorActionBars> actionCache = new HashMap<String, EditorActionBars>();
+
+ private EditorActionBars getEditorActionBars(EditorDescriptor desc,
+ WorkbenchPage page, IWorkbenchWindow workbenchWindow, String type) {
+ // Get the editor type.
+
+ // If an action bar already exists for this editor type return it.
+ EditorActionBars actionBars = actionCache.get(type);
+ if (actionBars != null) {
+ actionBars.addRef();
+ return actionBars;
+ }
+
+ // Create a new action bar set.
+ actionBars = new EditorActionBars(page, workbenchWindow, type);
+ actionBars.addRef();
+ actionCache.put(type, actionBars);
+
+ // Read base contributor.
+ IEditorActionBarContributor contr = desc.createActionBarContributor();
+ if (contr != null) {
+ actionBars.setEditorContributor(contr);
+ contr.init(actionBars, page);
+ }
+
+ // Read action extensions.
+ EditorActionBuilder builder = new EditorActionBuilder();
+ contr = builder.readActionExtensions(desc);
+ if (contr != null) {
+ actionBars.setExtensionContributor(contr);
+ contr.init(actionBars, page);
+ }
+
+ // Return action bars.
+ return actionBars;
+ }
+
+ private void disposeEditorActionBars(EditorActionBars actionBars) {
+ actionBars.removeRef();
+ if (actionBars.getRef() <= 0) {
+ String type = actionBars.getEditorType();
+ actionCache.remove(type);
+ actionBars.dispose();
+ }
+ }
+
+ private IConfigurationElement findEditorConfig(String id) {
+ IConfigurationElement[] editors = ExtensionUtils
+ .getExtensions(IWorkbenchRegistryConstants.PL_EDITOR);
+ IConfigurationElement editorContribution = ExtensionUtils
+ .findExtension(editors, id);
+ return editorContribution;
+ }
+
+ /**
+ * @return The client implementation of their 3.x part
+ */
+ public IEditorPart getEditorWBPart() {
+ return editorWBPart;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/LegacyView.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/LegacyView.java
new file mode 100644
index 0000000..cd98b2e
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/compatibility/LegacyView.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 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.e4.compatibility;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.extensions.ExtensionUtils;
+import org.eclipse.e4.extensions.ModelViewReference;
+import org.eclipse.e4.ui.model.application.MApplicationFactory;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
+import org.eclipse.e4.ui.model.application.ui.menu.MToolBar;
+import org.eclipse.e4.workbench.ui.menus.MenuHelper;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.internal.ViewSite;
+import org.eclipse.ui.internal.WorkbenchPage;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.menus.IMenuService;
+
+/**
+ * This class is an implementation of an MPart that can be used to host a 3.x
+ * ViewPart into an Eclipse 4.0 org.eclipse.e4.ui.model.application.
+ *
+ * @since 4.0
+ *
+ */
+public class LegacyView {
+ public final static String LEGACY_VIEW_URI = "bundleclass://org.eclipse.ui.workbench/org.eclipse.e4.compatibility.LegacyView"; //$NON-NLS-1$
+ private IViewPart impl;
+
+ public LegacyView(Composite parent, IEclipseContext context, MPart part) {
+ // KLUDGE: the progress view assumes a grid layout, we should fix that
+ // in 3.6
+ Set kludge = new HashSet();
+ kludge.add("org.eclipse.ui.views.ProgressView"); //$NON-NLS-1$
+ kludge.add("org.eclipse.pde.runtime.LogView"); //$NON-NLS-1$
+ if (kludge.contains(part.getId())) {
+ parent.setLayout(new GridLayout());
+ } else {
+ parent.setLayout(new FillLayout());
+ }
+
+ // Button btn = new Button(parent, SWT.BORDER);
+ // btn.setText(part.getName());
+ // if (btn != null)
+ // return;
+ String viewId = part.getId();
+ IConfigurationElement viewContribution = findViewConfig(viewId);
+ try {
+ impl = (IViewPart) viewContribution
+ .createExecutableExtension("class"); //$NON-NLS-1$
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+ if (impl == null)
+ return;
+
+ try {
+ final IEclipseContext localContext = part.getContext();
+ localContext.set(IContextConstants.DEBUG_STRING, "Legacy View(" //$NON-NLS-1$
+ + part.getName() + ")"); //$NON-NLS-1$
+
+ part.setObject(this);
+ // Assign a 'site' for the newly instantiated part
+ WorkbenchPage page = (WorkbenchPage) localContext
+ .get(WorkbenchPage.class.getName());
+ ModelViewReference ref = new ModelViewReference(part, page);
+ ViewSite site = new ViewSite(ref, impl, page);
+ site.setConfigurationElement(viewContribution);
+ impl.init(site, null);
+ // final ToolBarManager tbm = (ToolBarManager) site.getActionBars()
+ // .getToolBarManager();
+ // if (parent instanceof CTabFolder) {
+ // final ToolBar tb = tbm.createControl(parent);
+ // ((CTabFolder) parent).setTopRight(tb);
+ // }
+
+ // We need to create the actual TB (some parts call 'getControl')
+ ToolBarManager tbMgr = (ToolBarManager) site.getActionBars()
+ .getToolBarManager();
+ tbMgr.createControl(parent);
+
+ impl.createPartControl(parent);
+
+ localContext.set(MPart.class.getName(), part);
+
+ // Populate and scrape the old-style contributions...
+ IMenuService menuSvc = (IMenuService) localContext
+ .get(IMenuService.class.getName());
+
+ String tbURI = "toolbar:" + part.getId(); //$NON-NLS-1$
+ menuSvc.populateContributionManager(tbMgr, tbURI);
+ MToolBar viewTB = MApplicationFactory.eINSTANCE.createToolBar();
+ MenuHelper.processToolbarManager(localContext, viewTB,
+ tbMgr.getItems());
+ part.setToolbar(viewTB);
+ tbMgr.getControl().dispose();
+
+ String menuURI = "menu:" + part.getId(); //$NON-NLS-1$
+ MenuManager menuMgr = (MenuManager) site.getActionBars()
+ .getMenuManager();
+ menuSvc.populateContributionManager(menuMgr, menuURI);
+ MMenu viewMenu = MApplicationFactory.eINSTANCE.createMenu();
+ viewMenu.setId(menuURI);
+ MenuHelper.processMenuManager(localContext, viewMenu,
+ menuMgr.getItems());
+ part.getMenus().add(viewMenu);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * @return The implementation of the cient's 3.x view part
+ */
+ public IViewPart getViewPart() {
+ return impl;
+ }
+
+ private IConfigurationElement findViewConfig(String id) {
+ IConfigurationElement[] views = ExtensionUtils
+ .getExtensions(IWorkbenchRegistryConstants.PL_VIEWS);
+ IConfigurationElement viewContribution = ExtensionUtils.findExtension(
+ views, id);
+ return viewContribution;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ExtensionUtils.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ExtensionUtils.java
new file mode 100644
index 0000000..2061a5f
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ExtensionUtils.java
@@ -0,0 +1,31 @@
+package org.eclipse.e4.extensions;
+
+import org.eclipse.core.internal.runtime.InternalPlatform;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+
+public class ExtensionUtils {
+ public static IConfigurationElement[] getExtensions(String extensionId) {
+ IExtensionRegistry registry = InternalPlatform.getDefault().getRegistry();
+ String extId = "org.eclipse.ui." + extensionId; //$NON-NLS-1$
+ IConfigurationElement[] exts = registry.getConfigurationElementsFor(extId);
+ return exts;
+ }
+
+ public static IConfigurationElement findExtension(IConfigurationElement[] extensions, String attId, String id) {
+ if (id == null || id.length() == 0)
+ return null;
+
+ for (int i = 0; i < extensions.length; i++) {
+ String extId = extensions[i].getAttribute(attId);
+ if (id.equals(extId))
+ return extensions[i];
+ }
+
+ return null;
+ }
+
+ public static IConfigurationElement findExtension(IConfigurationElement[] extensions, String id) {
+ return findExtension(extensions, "id", id); //$NON-NLS-1$
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelEditorReference.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelEditorReference.java
new file mode 100644
index 0000000..9e92df9
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelEditorReference.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * 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.e4.extensions;
+
+import org.eclipse.e4.ui.model.application.MPart;
+
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.internal.WorkbenchPage;
+
+/**
+ */
+public class ModelEditorReference extends ModelReference implements
+ IEditorReference {
+
+ /**
+ * @param model
+ * @param page
+ */
+ public ModelEditorReference(MPart model, WorkbenchPage page) {
+ super(model, page);
+ // TODO Auto-generated constructor stub
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IEditorReference#getEditor(boolean)
+ */
+ public IEditorPart getEditor(boolean restore) {
+ return (IEditorPart) getPart(restore);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IEditorReference#getEditorInput()
+ */
+ public IEditorInput getEditorInput() {
+ // the "compatibility" way
+ Object object = getPart(false);
+ if (object instanceof IEditorPart)
+ return ((IEditorPart) object).getEditorInput();
+ // the E4 way
+ return (IEditorInput) getModel().getContext().get(
+ IEditorInput.class.getName());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IEditorReference#getFactoryId()
+ */
+ public String getFactoryId() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IEditorReference#getName()
+ */
+ public String getName() {
+ return getModel().getName();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IEditorReference#isPinned()
+ */
+ public boolean isPinned() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelReference.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelReference.java
new file mode 100644
index 0000000..83c242d
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelReference.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * 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.e4.extensions;
+
+import org.eclipse.e4.ui.model.application.MPart;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import org.eclipse.e4.workbench.ui.internal.Activator;
+import org.eclipse.e4.workbench.ui.internal.Policy;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.internal.WorkbenchPage;
+
+/**
+ *
+ */
+public class ModelReference implements IWorkbenchPartReference {
+
+ private MPart modelPart;
+ private WorkbenchPage page;
+ private Image titleImage;
+
+ public ModelReference(MPart model, WorkbenchPage page) {
+ modelPart = model;
+ this.page = page;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.IWorkbenchPartReference#addPartPropertyListener(org.eclipse
+ * .jface.util.IPropertyChangeListener)
+ */
+ public void addPartPropertyListener(IPropertyChangeListener listener) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.IWorkbenchPartReference#addPropertyListener(org.eclipse
+ * .ui.IPropertyListener)
+ */
+ public void addPropertyListener(IPropertyListener listener) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPartReference#getContentDescription()
+ */
+ public String getContentDescription() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPartReference#getId()
+ */
+ public String getId() {
+ return modelPart.getId();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPartReference#getPage()
+ */
+ public IWorkbenchPage getPage() {
+ return page;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPartReference#getPart(boolean)
+ */
+ public IWorkbenchPart getPart(boolean restore) {
+ Object object = modelPart.getObject();
+ if (object instanceof IWorkbenchPart)
+ return (IWorkbenchPart) object;
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPartReference#getPartName()
+ */
+ public String getPartName() {
+ return modelPart.getName();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.IWorkbenchPartReference#getPartProperty(java.lang.String)
+ */
+ public String getPartProperty(String key) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPartReference#getTitle()
+ */
+ public String getTitle() {
+ return modelPart.getName();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPartReference#getTitleImage()
+ */
+ public Image getTitleImage() {
+ if (titleImage != null) {
+ return titleImage;
+ }
+ if (modelPart.getIconURI() != null) {
+ try {
+ titleImage = JFaceResources.getResources().createImage(
+ ImageDescriptor.createFromURL(new URL(modelPart
+ .getIconURI())));
+ return titleImage;
+ } catch (MalformedURLException e) {
+ Activator.trace(Policy.DEBUG_WORKBENCH, "Failed to get image", //$NON-NLS-1$
+ e);
+ }
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPartReference#getTitleToolTip()
+ */
+ public String getTitleToolTip() {
+ return modelPart.getName();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPartReference#isDirty()
+ */
+ public boolean isDirty() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.IWorkbenchPartReference#removePartPropertyListener(org
+ * .eclipse.jface.util.IPropertyChangeListener)
+ */
+ public void removePartPropertyListener(IPropertyChangeListener listener) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.IWorkbenchPartReference#removePropertyListener(org.eclipse
+ * .ui.IPropertyListener)
+ */
+ public void removePropertyListener(IPropertyListener listener) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public MPart getModel() {
+ return modelPart;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelViewReference.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelViewReference.java
new file mode 100644
index 0000000..ba689db
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/ModelViewReference.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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.e4.extensions;
+
+import org.eclipse.e4.ui.model.application.MPart;
+
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.internal.WorkbenchPage;
+
+/**
+ * @since 3.3
+ *
+ */
+public class ModelViewReference extends ModelReference implements
+ IViewReference {
+
+ /**
+ * @param model
+ * @param page
+ */
+ public ModelViewReference(MPart model, WorkbenchPage page) {
+ super(model, page);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IViewReference#getSecondaryId()
+ */
+ public String getSecondaryId() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IViewReference#getView(boolean)
+ */
+ public IViewPart getView(boolean restore) {
+ return (IViewPart) getPart(restore);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IViewReference#isFastView()
+ */
+ public boolean isFastView() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/LegacySelectionService.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/LegacySelectionService.java
new file mode 100644
index 0000000..cbeae1c
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/LegacySelectionService.java
@@ -0,0 +1,227 @@
+/*******************************************************************************
+ * 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.e4.workbench.ui.api;
+
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.IContextConstants;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.INullSelectionListener;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.ISelectionService;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+
+/**
+ * @since 3.3
+ *
+ */
+public class LegacySelectionService implements ISelectionService {
+
+ ListenerList selectionListeners = new ListenerList(ListenerList.IDENTITY);
+ ListenerList postSelectionListeners = new ListenerList(
+ ListenerList.IDENTITY);
+
+ private IEclipseContext windowContext;
+
+ public LegacySelectionService(IEclipseContext context) {
+ windowContext = context;
+ windowContext.runAndTrack(new Runnable() {
+
+ public void run() {
+ fireSelectionChange();
+ }
+
+ /*
+ * for debugging purposes only
+ */
+ @Override
+ public String toString() {
+ return IServiceConstants.SELECTION;
+ }
+ });
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.ISelectionService#addPostSelectionListener(org.eclipse
+ * .ui.ISelectionListener)
+ */
+ public void addPostSelectionListener(ISelectionListener listener) {
+ postSelectionListeners.add(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.ISelectionService#addPostSelectionListener(java.lang.String
+ * , org.eclipse.ui.ISelectionListener)
+ */
+ public void addPostSelectionListener(String partId,
+ ISelectionListener listener) {
+ postSelectionListeners.add(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.ISelectionService#addSelectionListener(org.eclipse.ui.
+ * ISelectionListener)
+ */
+ public void addSelectionListener(ISelectionListener listener) {
+ selectionListeners.add(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.ISelectionService#addSelectionListener(java.lang.String,
+ * org.eclipse.ui.ISelectionListener)
+ */
+ public void addSelectionListener(String partId, ISelectionListener listener) {
+ selectionListeners.add(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.ISelectionService#getSelection()
+ */
+ public ISelection getSelection() {
+ Object obj = windowContext.get(IServiceConstants.SELECTION);
+ if (obj instanceof ISelection) {
+ return (ISelection) obj;
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.ISelectionService#getSelection(java.lang.String)
+ */
+ public ISelection getSelection(String partId) {
+ return getSelection();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.ISelectionService#removePostSelectionListener(org.eclipse
+ * .ui.ISelectionListener)
+ */
+ public void removePostSelectionListener(ISelectionListener listener) {
+ postSelectionListeners.remove(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.ISelectionService#removePostSelectionListener(java.lang
+ * .String, org.eclipse.ui.ISelectionListener)
+ */
+ public void removePostSelectionListener(String partId,
+ ISelectionListener listener) {
+ postSelectionListeners.remove(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.ISelectionService#removeSelectionListener(org.eclipse.
+ * ui.ISelectionListener)
+ */
+ public void removeSelectionListener(ISelectionListener listener) {
+ selectionListeners.remove(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.ISelectionService#removeSelectionListener(java.lang.String
+ * , org.eclipse.ui.ISelectionListener)
+ */
+ public void removeSelectionListener(String partId,
+ ISelectionListener listener) {
+ selectionListeners.remove(listener);
+ }
+
+ protected void fireSelectionChange() {
+ fireSelection(getActivePart(), getSelection());
+ firePostSelection(getActivePart(), getSelection());
+ }
+
+ private IWorkbenchPart getActivePart() {
+ IEclipseContext currentActive = windowContext;
+ IEclipseContext child;
+ while ((child = (IEclipseContext) currentActive
+ .get(IContextConstants.ACTIVE_CHILD)) != null
+ && child != currentActive) {
+ currentActive = child;
+ }
+ if (child != null) {
+ MPart p = (MPart) child.get(MPart.class.getName());
+ if (p == null)
+ return null;
+ Object object = p.getObject();
+ if (object == null)
+ return null;
+ if (object instanceof IWorkbenchPart)
+ return (IWorkbenchPart) p.getObject();
+ }
+ return null;
+ }
+
+ protected void fireSelection(final IWorkbenchPart part, final ISelection sel) {
+ Object[] array = selectionListeners.getListeners();
+ for (int i = 0; i < array.length; i++) {
+ final ISelectionListener l = (ISelectionListener) array[i];
+ if ((part != null && sel != null)
+ || l instanceof INullSelectionListener) {
+
+ try {
+ l.selectionChanged(part, sel);
+ } catch (Exception e) {
+ WorkbenchPlugin.log(e);
+ }
+ }
+ }
+ }
+
+ protected void firePostSelection(final IWorkbenchPart part,
+ final ISelection sel) {
+ Object[] array = postSelectionListeners.getListeners();
+ for (int i = 0; i < array.length; i++) {
+ final ISelectionListener l = (ISelectionListener) array[i];
+ if ((part != null && sel != null)
+ || l instanceof INullSelectionListener) {
+
+ try {
+ l.selectionChanged(part, sel);
+ } catch (Exception e) {
+ WorkbenchPlugin.log(e);
+ }
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledFolderLayout.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledFolderLayout.java
new file mode 100644
index 0000000..d3e9093
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledFolderLayout.java
@@ -0,0 +1,18 @@
+package org.eclipse.e4.workbench.ui.api;
+
+import org.eclipse.e4.ui.model.application.MView;
+import org.eclipse.e4.ui.model.application.MViewStack;
+
+import org.eclipse.ui.IFolderLayout;
+
+public class ModeledFolderLayout extends ModeledPlaceholderFolderLayout
+ implements IFolderLayout {
+ public ModeledFolderLayout(MViewStack stackModel) {
+ super(stackModel);
+ }
+
+ public void addView(String viewId) {
+ MView viewModel = ModeledPageLayout.createViewModel(viewId, true);
+ folderModel.getChildren().add(viewModel);
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledPageLayout.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledPageLayout.java
new file mode 100644
index 0000000..ac3f605
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledPageLayout.java
@@ -0,0 +1,442 @@
+package org.eclipse.e4.workbench.ui.api;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.e4.compatibility.LegacyView;
+import org.eclipse.e4.extensions.ExtensionUtils;
+import org.eclipse.e4.ui.model.application.MApplicationFactory;
+import org.eclipse.e4.ui.model.application.MEditorSashContainer;
+import org.eclipse.e4.ui.model.application.MEditorStack;
+import org.eclipse.e4.ui.model.application.MElementContainer;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MPerspective;
+import org.eclipse.e4.ui.model.application.MUIElement;
+import org.eclipse.e4.ui.model.application.MView;
+import org.eclipse.e4.ui.model.application.MViewSashContainer;
+import org.eclipse.e4.ui.model.application.MViewStack;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.IPlaceholderFolderLayout;
+import org.eclipse.ui.IViewLayout;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+
+public class ModeledPageLayout implements IPageLayout {
+
+ private MPerspective perspModel;
+ private IPerspectiveDescriptor descriptor;
+ private ArrayList newWizardShortcuts = new ArrayList();
+ private ArrayList perspectiveShortcut = new ArrayList();
+ private ArrayList showInPart = new ArrayList();
+ private ArrayList showViewShortcut = new ArrayList();
+ private ArrayList actionSet = new ArrayList();
+
+ public ModeledPageLayout(MPerspective perspModel) {
+ // Create the editor area stack
+ this.perspModel = perspModel;
+
+ MEditorSashContainer esc = MApplicationFactory.eINSTANCE
+ .createEditorSashContainer();
+ MEditorStack editorArea = MApplicationFactory.eINSTANCE
+ .createEditorStack();
+ esc.getChildren().add(editorArea);
+ editorArea.setId(getEditorArea());
+ esc.setId(getEditorArea());
+
+ // editorArea.setName("Editor Area");
+
+ // perspModel.getChildren().add(esc);
+ }
+
+ public MPerspective getModel() {
+ return perspModel;
+ }
+
+ public void addActionSet(String actionSetId) {
+ actionSet.add(actionSetId);
+ }
+
+ public void addFastView(String viewId) {
+ }
+
+ public void addFastView(String viewId, float ratio) {
+ }
+
+ public void addNewWizardShortcut(String id) {
+ newWizardShortcuts.add(id);
+ }
+
+ public void addPerspectiveShortcut(String id) {
+ perspectiveShortcut.add(id);
+ }
+
+ public void addPlaceholder(String viewId, int relationship, float ratio,
+ String refId) {
+ insertView(viewId, relationship, ratio, refId, false, true);
+ }
+
+ public void addShowInPart(String id) {
+ showInPart.add(id);
+ }
+
+ public void addShowViewShortcut(String id) {
+ showViewShortcut.add(id);
+ }
+
+ public void addStandaloneView(String viewId, boolean showTitle,
+ int relationship, float ratio, String refId) {
+ MView viewModel = insertView(viewId, relationship, ratio, refId, true,
+ false);
+
+ // Set the state
+ if (viewModel != null) {
+ // viewModel.setShowTitle(showTitle);
+ }
+ }
+
+ public void addStandaloneViewPlaceholder(String viewId, int relationship,
+ float ratio, String refId, boolean showTitle) {
+ MView viewModel = insertView(viewId, relationship, ratio, refId, false,
+ false);
+
+ // Set the state
+ if (viewModel != null) {
+ // viewModel.setShowTitle(showTitle);
+ }
+ }
+
+ public void addView(String viewId, int relationship, float ratio,
+ String refId) {
+ insertView(viewId, relationship, ratio, refId, true, true);
+ }
+
+ public IFolderLayout createFolder(String folderId, int relationship,
+ float ratio, String refId) {
+ MViewStack stack = insertStack(folderId, relationship, ratio, refId,
+ true);
+ return new ModeledFolderLayout(stack);
+ }
+
+ public IPlaceholderFolderLayout createPlaceholderFolder(String folderId,
+ int relationship, float ratio, String refId) {
+ MViewStack Stack = insertStack(folderId, relationship, ratio, refId,
+ false);
+ return new ModeledPlaceholderFolderLayout(Stack);
+ }
+
+ public void setDescriptor(IPerspectiveDescriptor desc) {
+ descriptor = desc;
+ }
+
+ public IPerspectiveDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+ public static String internalGetEditorArea() {
+ return IPageLayout.ID_EDITOR_AREA;
+ }
+
+ public String getEditorArea() {
+ return internalGetEditorArea();
+ }
+
+ public int getEditorReuseThreshold() {
+ return 0;
+ }
+
+ public IPlaceholderFolderLayout getFolderForView(String id) {
+ MPart view = findPart(perspModel, id);
+ if (view == null || !(view instanceof MView))
+ return null;
+
+ MUIElement stack = view.getParent();
+ if (stack == null || !(stack instanceof MViewStack))
+ return null;
+
+ return new ModeledPlaceholderFolderLayout((MViewStack) stack);
+ }
+
+ public IViewLayout getViewLayout(String id) {
+ MPart view = findPart(perspModel, id);
+ if (view == null || !(view instanceof MView))
+ return null;
+
+ return new ModeledViewLayout((MView) view);
+ }
+
+ public boolean isEditorAreaVisible() {
+ return true;
+ }
+
+ public boolean isFixed() {
+ return false;
+ }
+
+ public void setEditorAreaVisible(boolean showEditorArea) {
+ }
+
+ public void setEditorReuseThreshold(int openEditors) {
+ }
+
+ public void setFixed(boolean isFixed) {
+ // perspModel.setFixed(isFixed);
+ }
+
+ private static int plRelToSwt(int rel) {
+ switch (rel) {
+ case IPageLayout.BOTTOM:
+ return SWT.BOTTOM;
+ case IPageLayout.LEFT:
+ return SWT.LEFT;
+ case IPageLayout.RIGHT:
+ return SWT.RIGHT;
+ case IPageLayout.TOP:
+ return SWT.TOP;
+ default:
+ return 0;
+ }
+ }
+
+ public static MView createViewModel(String id, boolean visible) {
+ MView viewModel = MApplicationFactory.eINSTANCE.createView();
+
+ // HACK!! allow Contributed parts in a perspective
+ if (id.indexOf("platform:") >= 0) { //$NON-NLS-1$
+ viewModel.setURI(id);
+ viewModel.setName("Contrib View"); //$NON-NLS-1$
+ return viewModel;
+ }
+
+ viewModel.setURI(LegacyView.LEGACY_VIEW_URI);
+ viewModel.setId(id);
+
+ // Get the actual view name from the extension registry
+ IConfigurationElement[] views = ExtensionUtils
+ .getExtensions(IWorkbenchRegistryConstants.PL_VIEWS);
+ IConfigurationElement viewContribution = ExtensionUtils.findExtension(
+ views, id);
+ if (viewContribution != null) {
+ viewModel.setName(viewContribution.getAttribute("name")); //$NON-NLS-1$
+
+ // Convert the relative path into a bundle URI
+ String imagePath = viewContribution.getAttribute("icon"); //$NON-NLS-1$
+ if (imagePath != null) {
+ imagePath = imagePath.replace("$nl$", ""); //$NON-NLS-1$//$NON-NLS-2$
+ if (imagePath.charAt(0) != '/') {
+ imagePath = '/' + imagePath;
+ }
+ String bundleId = viewContribution.getContributor().getName();
+ String imageURI = "platform:/plugin/" + bundleId + imagePath; //$NON-NLS-1$
+ viewModel.setIconURI(imageURI);
+ }
+ } else
+ viewModel.setName(id); // No registered view, create error part?
+
+ // sets its visibility (false == placeholder)
+ viewModel.setVisible(visible);
+
+ return viewModel;
+ }
+
+ public static MViewStack createStack(String id, boolean visible) {
+ MViewStack newStack = MApplicationFactory.eINSTANCE.createViewStack();
+ newStack.setId(id);
+ newStack.setVisible(visible);
+ return newStack;
+ }
+
+ private MView insertView(String viewId, int relationship, float ratio,
+ String refId, boolean visible, boolean withStack) {
+ MUIElement refModel = findPart(perspModel, refId);
+ if (refModel == null || !(refModel instanceof MPart))
+ return null;
+
+ MView viewModel = createViewModel(viewId, visible);
+
+ if (withStack) {
+ String stackId = viewId + "MStack"; // Default id...basically unusable //$NON-NLS-1$
+ MViewStack stack = insertStack(stackId, relationship, ratio, refId,
+ visible);
+ stack.getChildren().add(viewModel);
+ } else {
+ insert(viewModel, (MPart) refModel, plRelToSwt(relationship), ratio);
+ }
+
+ return viewModel;
+ }
+
+ private MViewStack insertStack(String stackId, int relationship,
+ float ratio, String refId, boolean visible) {
+ MUIElement refModel = findPart(perspModel, refId);
+ if (refModel == null || !(refModel instanceof MPart))
+ return null;
+
+ // If the 'refModel' is -not- a stack then find one
+ // This covers cases where the defining layout is adding
+ // Views relative to other views and relying on the stacks
+ // being automatically created.
+ if (!(refModel instanceof MViewStack)) {
+ while (refModel.getParent() != null) {
+ refModel = refModel.getParent();
+ if (refModel instanceof MViewStack)
+ break;
+ }
+ if (!(refModel instanceof MViewStack))
+ return null;
+ }
+
+ MViewStack stack = createStack(stackId, visible);
+ insert(stack, (MPart) refModel, plRelToSwt(relationship), ratio);
+
+ return stack;
+ }
+
+ public static void replace(MUIElement relTo,
+ MElementContainer<MUIElement> newParent) {
+ if (relTo == null || newParent == null)
+ return;
+
+ MElementContainer<MUIElement> parent = relTo.getParent();
+ if (parent == null)
+ return;
+
+ List kids = parent.getChildren();
+ if (kids == null)
+ return;
+
+ kids.add(kids.indexOf(relTo), newParent);
+ kids.remove(relTo);
+ }
+
+ public static void insertParent(MElementContainer<MUIElement> newParent,
+ MUIElement relTo) {
+ if (newParent == null || relTo == null)
+ return;
+
+ MPart curParent = (MPart) relTo.getParent();
+ if (curParent != null) {
+ replace(relTo, newParent);
+ }
+
+ // Move the child under the new parent
+ newParent.getChildren().add(relTo);
+ }
+
+ public static void insert(MUIElement toInsert, MUIElement relTo,
+ int swtSide, int ratio) {
+ if (toInsert == null || relTo == null)
+ return;
+
+ MElementContainer<MUIElement> relParent = relTo.getParent();
+
+ boolean isStack = true;
+
+ // Create the new sash if we're going to need one
+ MViewSashContainer newSash = null;
+ if ((swtSide == SWT.TOP || swtSide == SWT.BOTTOM) && !isStack) {
+ newSash = MApplicationFactory.eINSTANCE.createViewSashContainer();
+ String label = "Vertical Sash[" + toInsert.getId() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+ newSash.setId(label);
+ newSash.setHorizontal(false);
+ } else if ((swtSide == SWT.LEFT || swtSide == SWT.RIGHT) && !isStack) {
+ newSash = MApplicationFactory.eINSTANCE.createViewSashContainer();
+ String label = "Horizontal Sash[" + toInsert.getId() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+ newSash.setId(label);
+ newSash.setHorizontal(true);
+ }
+
+ List parts;
+ if (newSash == null && relParent != null) {
+ parts = relParent.getChildren();
+ } else {
+ MUIElement vscElement = newSash;
+ MElementContainer<MUIElement> container = (MElementContainer<MUIElement>) vscElement;
+ insertParent(container, relTo);
+ parts = newSash.getChildren();
+
+ List<Integer> weights = newSash.getWeights();
+ weights.add(ratio);
+ weights.add(100 - ratio);
+ }
+
+ // Insert the part in the correct location
+ int index = parts.indexOf(relTo);
+ if (swtSide == SWT.BOTTOM || swtSide == SWT.RIGHT) {
+ index++;
+
+ }
+
+ parts.add(index, toInsert);
+ }
+
+ public static void insert(MUIElement toInsert, MUIElement relTo,
+ int swtSide, float ratio) {
+ int pct = (int) (ratio * 100);
+ insert(toInsert, relTo, swtSide, pct);
+ }
+
+ public static MUIElement findElementById(MUIElement element, String id) {
+ if (id == null || id.length() == 0)
+ return null;
+
+ // is it me?
+ if (id.equals(element.getId()))
+ return element;
+
+ // Recurse if this is a container
+ if (element instanceof MElementContainer) {
+ EList<MUIElement> children = ((MElementContainer<MUIElement>) element)
+ .getChildren();
+ MUIElement foundElement = null;
+ for (MUIElement childME : children) {
+ foundElement = findElementById(childME, id);
+ if (foundElement != null)
+ return foundElement;
+ }
+ }
+
+ return null;
+ }
+
+ public static MPart findPart(MUIElement toSearch, String id) {
+ if (toSearch == null)
+ return null;
+
+ MUIElement found = findElementById(toSearch, id);
+ if (found instanceof MPart)
+ return (MPart) found;
+
+ return null;
+ }
+
+ /**
+ * @return
+ */
+ public ArrayList getNewWizardShortcuts() {
+ return newWizardShortcuts;
+ }
+
+ /**
+ * @return
+ */
+ public ArrayList getShowViewShortcuts() {
+ return showViewShortcut;
+ }
+
+ /**
+ * @return
+ */
+ public ArrayList getPerspectiveShortcuts() {
+ return perspectiveShortcut;
+ }
+
+ /**
+ * @return
+ */
+ public ArrayList getShowInPartIds() {
+ return showInPart;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledPlaceholderFolderLayout.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledPlaceholderFolderLayout.java
new file mode 100644
index 0000000..e59b2f7
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledPlaceholderFolderLayout.java
@@ -0,0 +1,30 @@
+package org.eclipse.e4.workbench.ui.api;
+
+import org.eclipse.e4.ui.model.application.MView;
+import org.eclipse.e4.ui.model.application.MViewStack;
+
+import org.eclipse.ui.IPlaceholderFolderLayout;
+
+public class ModeledPlaceholderFolderLayout implements IPlaceholderFolderLayout {
+
+ protected MViewStack folderModel;
+
+ public ModeledPlaceholderFolderLayout(MViewStack stackModel) {
+ folderModel = stackModel;
+ }
+
+ public void addPlaceholder(String viewId) {
+ MView viewModel = ModeledPageLayout.createViewModel(viewId, false);
+ folderModel.getChildren().add(viewModel);
+ }
+
+ public String getProperty(String id) {
+ Object propVal = null;
+ return propVal == null ? "" : propVal.toString(); //$NON-NLS-1$
+ }
+
+ public void setProperty(String id, String value) {
+ // folderModel.setProperty(id, value);
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledViewLayout.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledViewLayout.java
new file mode 100644
index 0000000..4d452b3
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/api/ModeledViewLayout.java
@@ -0,0 +1,39 @@
+package org.eclipse.e4.workbench.ui.api;
+
+import org.eclipse.e4.ui.model.application.MView;
+
+import org.eclipse.ui.IViewLayout;
+
+public class ModeledViewLayout implements IViewLayout {
+
+ // private MContributedPart viewME;
+
+ public ModeledViewLayout(MView view) {
+ // viewME = view;
+ }
+
+ public boolean getShowTitle() {
+ return true;// viewME.getShowTitle();
+ }
+
+ public boolean isCloseable() {
+ return true;// viewME.isCloseable();
+ }
+
+ public boolean isMoveable() {
+ return true;// viewME.isMoveable();
+ }
+
+ public boolean isStandalone() {
+ return false;// viewME.isStandAlone();
+ }
+
+ public void setCloseable(boolean closeable) {
+ // viewME.setCloseable(closeable);
+ }
+
+ public void setMoveable(boolean moveable) {
+ // viewME.setMoveable(moveable);
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/ActionSet.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/ActionSet.java
new file mode 100644
index 0000000..92f8dda
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/ActionSet.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * 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.e4.workbench.ui.menus;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.ui.model.application.MHandledItem;
+import org.eclipse.e4.ui.model.application.MMenu;
+import org.eclipse.e4.ui.model.application.MMenuItem;
+import org.eclipse.e4.workbench.ui.internal.Activator;
+import org.eclipse.e4.workbench.ui.internal.Policy;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+
+/**
+ *
+ */
+public class ActionSet {
+ private IEclipseContext context;
+ private IConfigurationElement config;
+ private boolean visible = true;
+
+ private List<MHandledItem> items = new ArrayList<MHandledItem>();
+
+ public ActionSet(IEclipseContext context, IConfigurationElement element) {
+ this.context = context;
+ config = element;
+ }
+
+ public boolean merge(MMenu menu) {
+ IConfigurationElement[] menus = config
+ .getChildren(IWorkbenchRegistryConstants.TAG_MENU);
+ for (IConfigurationElement element : menus) {
+ addMenu(menu, element);
+ }
+ IConfigurationElement[] actions = config
+ .getChildren(IWorkbenchRegistryConstants.TAG_ACTION);
+ for (IConfigurationElement element : actions) {
+ addAction(menu, element);
+ }
+ return true;
+ }
+
+ /**
+ * @param menu
+ * @param element
+ */
+ private void addAction(MMenu menu, IConfigurationElement element) {
+ final String elementId = MenuHelper.getId(element);
+ String path = element
+ .getAttribute(IWorkbenchRegistryConstants.ATT_MENUBAR_PATH);
+ if (path == null) {
+ return;
+ }
+ Path menuPath = new Path(path);
+ MMenu parentMenu = findMenuFromPath(menu, menuPath, 0);
+ if (parentMenu == null) {
+ Activator
+ .trace(
+ Policy.DEBUG_MENUS,
+ "Failed to find menu for action " + elementId + ':' + path, null); //$NON-NLS-1$
+ return;
+ }
+ int idx = MenuHelper.indexForId(parentMenu, menuPath.lastSegment());
+ if (idx == -1) {
+ idx = MenuHelper.indexForId(parentMenu,
+ IWorkbenchActionConstants.MB_ADDITIONS);
+ }
+ if (idx == -1) {
+ Activator
+ .trace(
+ Policy.DEBUG_MENUS,
+ "Failed to find group for action " + elementId + ':' + path, null); //$NON-NLS-1$
+ return;
+ }
+ MMenuItem item = createActionElement(element);
+ parentMenu.getChildren().add(idx, item);
+ }
+
+ /**
+ * @param menu
+ * @param element
+ */
+ private void addMenu(MMenu menu, IConfigurationElement element) {
+ final String elementId = MenuHelper.getId(element);
+ String path = element
+ .getAttribute(IWorkbenchRegistryConstants.ATT_PATH);
+ if (path == null || path.length() == 0) {
+ path = IWorkbenchActionConstants.MB_ADDITIONS;
+ }
+ Path menuPath = new Path(path);
+ MMenu parentMenu = menu;
+ if (menuPath.segmentCount() > 1) {
+ parentMenu = findMenuFromPath(menu, menuPath, 0);
+ }
+ if (parentMenu == menu) {
+ Activator
+ .trace(
+ Policy.DEBUG_MENUS,
+ "Using parent menu for menu " + elementId + ':' + path, null); //$NON-NLS-1$
+ }
+ String id = MenuHelper.getId(element);
+ MMenuItem item = null;
+ final int itemIdx = MenuHelper.indexForId(parentMenu, id);
+ if (itemIdx == -1) {
+ int idx = MenuHelper.indexForId(parentMenu, menuPath.lastSegment());
+ if (idx == -1) {
+ idx = MenuHelper.indexForId(parentMenu,
+ IWorkbenchActionConstants.MB_ADDITIONS);
+ }
+ if (idx == -1) {
+ Activator
+ .trace(
+ Policy.DEBUG_MENUS,
+ "Failed to find group for menu " + elementId + ':' + path, null); //$NON-NLS-1$
+ return;
+ }
+ item = createMenuElement(element);
+ parentMenu.getChildren().add(idx + 1, item);
+ } else {
+ item = parentMenu.getChildren().get(itemIdx);
+ }
+ processGroups(item, element);
+ }
+
+ /**
+ * @param menu
+ * @param element
+ */
+ private void processGroups(MMenu menu, IConfigurationElement element) {
+ IConfigurationElement[] children = element.getChildren();
+ for (IConfigurationElement child : children) {
+ String name = child
+ .getAttribute(IWorkbenchRegistryConstants.ATT_NAME);
+ if (MenuHelper.indexForId(menu, name) == -1) {
+ MenuHelper.addSeparator(menu, name, true);
+ }
+ }
+ }
+
+ /**
+ * @param menu
+ * @param path
+ * @return
+ */
+ private MMenu findMenuFromPath(MMenu menu, Path menuPath, int segment) {
+ int idx = MenuHelper.indexForId(menu, menuPath.segment(segment));
+ if (idx == -1) {
+ if (segment + 1 < menuPath.segmentCount()
+ || !menuPath.hasTrailingSeparator()) {
+ return null;
+ }
+ return menu;
+ }
+ MMenuItem item = menu.getChildren().get(idx);
+ if (item.getChildren().size() == 0) {
+ if (segment + 1 == menuPath.segmentCount()) {
+ return menu;
+ } else {
+ return null;
+ }
+ }
+ return findMenuFromPath(item, menuPath, segment + 1);
+ }
+
+ private MMenuItem createMenuElement(IConfigurationElement element) {
+ String imagePath = MenuHelper.getImageUrl(MenuHelper
+ .getIconDescriptor(element));
+ String id = MenuHelper.getId(element);
+ String label = MenuHelper.getLabel(element);
+ MMenuItem item = MenuHelper.createMenuItem(context, label, imagePath,
+ id, null);
+ return item;
+ }
+
+ private MMenuItem createActionElement(IConfigurationElement element) {
+ String imagePath = MenuHelper.getImageUrl(MenuHelper
+ .getIconDescriptor(element));
+ String cmdId = MenuHelper.getActionSetCommandId(element);
+ String id = MenuHelper.getId(element);
+ String label = MenuHelper.getLabel(element);
+ // int style = MenuHelper.getStyle(element);
+ // if (style == CommandContributionItem.STYLE_PULLDOWN) {
+ // IWorkbenchWindow window = (IWorkbenchWindow) context
+ // .get(IWorkbenchWindow.class.getName());
+ // // we need to treat a pulldown action as a renderer, since the
+ // // action
+ // // itself contains the rendering code
+ // ActionDescriptor desc = new ActionDescriptor(element,
+ // ActionDescriptor.T_WORKBENCH_PULLDOWN, window);
+ // final ActionContributionItem item = new ActionContributionItem(desc
+ // .getAction());
+ // MMenuItemRenderer r = WorkbenchFactory.eINSTANCE
+ // .createMMenuItemRenderer();
+ // r.setId(item.getId() == null ? "item:" + id : item.getId()); //$NON-NLS-1$
+ // r.setRenderer(item);
+ // return r;
+ // }
+ if (label == null) {
+ if (cmdId == null) {
+ label = "none:" + id; //$NON-NLS-1$
+ } else {
+ ICommandService cs = (ICommandService) context
+ .get(ICommandService.class.getName());
+ Command cmd = cs.getCommand(cmdId);
+ if (cmd.isDefined()) {
+ try {
+ label = cmd.getName();
+ } catch (NotDefinedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ MMenuItem item = MenuHelper.createMenuItem(context, label, imagePath,
+ id, cmdId);
+ // items.add(item);
+ return item;
+ }
+
+ public void setVisible(boolean v) {
+ if (v == visible) {
+ return;
+ }
+ visible = v;
+ for (MHandledItem item : items) {
+ item.setVisible(visible);
+ }
+ }
+
+ public String getId() {
+ return MenuHelper.getId(config);
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/MenuContribution.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/MenuContribution.java
new file mode 100644
index 0000000..baf85e5
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/MenuContribution.java
@@ -0,0 +1,324 @@
+/*******************************************************************************
+ * 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.e4.workbench.ui.menus;
+
+import java.util.ArrayList;
+import java.util.Map;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.expressions.EvaluationResult;
+import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.expressions.ExpressionConverter;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.ui.model.application.MApplicationFactory;
+import org.eclipse.e4.ui.model.application.MMenu;
+import org.eclipse.e4.ui.model.application.MMenuItem;
+import org.eclipse.e4.workbench.ui.internal.Activator;
+import org.eclipse.e4.workbench.ui.internal.Policy;
+import org.eclipse.e4.workbench.ui.internal.Trackable;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.ui.IWindowListener;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.LegacyEvalContext;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.internal.menus.MenuLocationURI;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.internal.util.Util;
+
+/**
+ * @since 3.3
+ *
+ */
+public class MenuContribution {
+ /**
+ *
+ */
+ private static final String WINDOW_IS_CLOSED = "MenuContribution.window.isClosed"; //$NON-NLS-1$
+ private IConfigurationElement config;
+ private IEclipseContext context;
+ private MenuLocationURI uri;
+ private MMenu model;
+ private ArrayList<TrackVisible> trackers = new ArrayList<TrackVisible>();
+
+ public MenuContribution(IEclipseContext context,
+ IConfigurationElement element) {
+ this.context = context;
+ window = (IWorkbenchWindow) context.get(IWorkbenchWindow.class
+ .getName());
+ context.set(WINDOW_IS_CLOSED, Boolean.FALSE);
+ config = element;
+ uri = new MenuLocationURI(config
+ .getAttribute(IWorkbenchRegistryConstants.TAG_LOCATION_URI));
+ window.getWorkbench().addWindowListener(new IWindowListener() {
+
+ public void windowOpened(IWorkbenchWindow window) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void windowDeactivated(IWorkbenchWindow window) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void windowClosed(IWorkbenchWindow window) {
+ if (window == MenuContribution.this.window) {
+ cleanUp();
+ }
+ }
+
+ public void windowActivated(IWorkbenchWindow window) {
+ // TODO Auto-generated method stub
+
+ }
+ });
+ }
+
+ public MenuLocationURI getURI() {
+ return uri;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return MenuContribution.class.getName() + ": " //$NON-NLS-1$
+ + getURI();
+ }
+
+ public boolean merge(MMenu menu) {
+ String locationID = getURI().getPath();
+ if (locationID.equals(menu.getId())) {
+ loadModel();
+ return mergeModel(menu);
+ }
+ return false;
+ }
+
+ private boolean mergeModel(MMenu menu) {
+ int idx = getInsertionIndex(menu);
+ if (idx == -1) {
+ return false;
+ }
+ return mergeModel(idx, menu, model);
+ }
+
+ private boolean mergeModel(int idx, MMenu menu, MMenu toInsert) {
+ EList<MMenuItem> items = menu.getChildren();
+ MMenuItem[] modelItems = toInsert.getChildren().toArray(
+ new MMenuItem[toInsert.getChildren().size()]);
+ for (int i = 0; i < modelItems.length; i++) {
+ MMenuItem modelItem = modelItems[i];
+ if (modelItem.getChildren().size() > 0) {
+ int tmpIdx = MenuHelper.indexForId(menu, modelItem.getId());
+ if (tmpIdx == -1) {
+ items.add(idx++, modelItem);
+ } else {
+ mergeModel(0, items.get(tmpIdx), modelItem);
+ }
+ } else {
+ items.add(idx++, modelItem);
+ }
+ }
+ return true;
+
+ }
+
+ private int getInsertionIndex(MMenu menu) {
+ int additionsIndex = -1;
+ String query = getURI().getQuery();
+ if (query.length() == 0 || query.equals("after=additions")) { //$NON-NLS-1$
+ additionsIndex = MenuHelper.indexForId(menu, "additions"); //$NON-NLS-1$
+ if (additionsIndex == -1) {
+ additionsIndex = menu.getChildren().size();
+ } else {
+ additionsIndex++;
+ }
+ } else {
+ String[] queryParts = Util.split(query, '=');
+ if (queryParts.length > 1 && queryParts[1].length() > 0) {
+ additionsIndex = MenuHelper.indexForId(menu, queryParts[1]);
+ if (additionsIndex != -1 && queryParts[0].equals("after")) //$NON-NLS-1$
+ additionsIndex++;
+ }
+ }
+ return additionsIndex;
+ }
+
+ private void loadModel() {
+ model = MApplicationFactory.eINSTANCE.createMenu();
+ loadModel(config, model);
+ }
+
+ private void loadModel(IConfigurationElement menuElement, MMenu menu) {
+ IConfigurationElement[] children = menuElement.getChildren();
+ for (IConfigurationElement element : children) {
+ String elementType = element.getName();
+ if (IWorkbenchRegistryConstants.TAG_COMMAND.equals(elementType)) {
+ MMenuItem item = createCommandElement(element);
+ menu.getChildren().add(item);
+ } else if (IWorkbenchRegistryConstants.TAG_MENU.equals(elementType)) {
+ MMenuItem item = createMenuElement(element);
+ menu.getChildren().add(item);
+ } else if (IWorkbenchRegistryConstants.TAG_SEPARATOR
+ .equals(elementType)) {
+ MenuHelper.addSeparator(menu, MenuHelper.getId(element), true);
+ } else if (IWorkbenchRegistryConstants.TAG_DYNAMIC
+ .equals(elementType)) {
+ addRenderer(menu, element);
+ }
+ }
+ }
+
+ /**
+ * @param menu
+ * @param element
+ */
+ private void addRenderer(MMenu menu, IConfigurationElement element) {
+ // ContributionItem i = (ContributionItem) Util
+ // .safeLoadExecutableExtension(element,
+ // IWorkbenchRegistryConstants.ATT_CLASS,
+ // ContributionItem.class);
+ // if (i instanceof IWorkbenchContribution) {
+ // ((IWorkbenchContribution) i).initialize(window);
+ // }
+ // MMenuItemRenderer renderer = MenuHelper.addMenuRenderer(context,
+ // menu,
+ // i);
+ // associateVisibleWhen(element, renderer);
+ }
+
+ private IWorkbenchWindow window;
+
+ /**
+ * @param element
+ * @return
+ */
+ private MMenuItem createMenuElement(IConfigurationElement element) {
+ String imagePath = MenuHelper.getImageUrl(MenuHelper
+ .getIconDescriptor(element));
+ String id = MenuHelper.getId(element);
+ String label = MenuHelper.getLabel(element);
+ MMenuItem item = MenuHelper.createMenuItem(context, label, imagePath,
+ id, null);
+ loadModel(element, item);
+ return item;
+ }
+
+ private MMenuItem createCommandElement(IConfigurationElement element) {
+ String imagePath = MenuHelper.getImageUrl(MenuHelper
+ .getIconDescriptor(element));
+ String cmdId = MenuHelper.getCommandId(element);
+ String id = MenuHelper.getId(element);
+ String label = MenuHelper.getLabel(element);
+ ICommandService cs = (ICommandService) context
+ .get(ICommandService.class.getName());
+ Command cmd = cs.getCommand(cmdId);
+ if (label == null) {
+ if (cmd.isDefined()) {
+ try {
+ label = cmd.getName();
+ } catch (NotDefinedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ final MMenuItem item = MenuHelper.createMenuItem(context, label,
+ imagePath, id, cmdId);
+ final Map<String, String> parms = MenuHelper.getParameters(element);
+ if (!parms.isEmpty()) {
+ // final EList<MParameter> modelParms = item.getParameters();
+ // for (Map.Entry<String, String> entry : parms.entrySet()) {
+ // MParameter p = ApplicationFactory.eINSTANCE.createMParameter();
+ // p.setName(entry.getKey());
+ // p.setValue(entry.getValue());
+ // modelParms.add(p);
+ // }
+ }
+
+ associateVisibleWhen(element, item);
+ return item;
+ }
+
+ class TrackVisible extends Trackable {
+ private MMenuItem item;
+ private LegacyEvalContext legacyEvalContext;
+ private Expression visWhen;
+ boolean participating = true;
+
+ public TrackVisible(MMenuItem item, IEclipseContext context,
+ Expression visWhen) {
+ super(context);
+ this.item = item;
+ this.legacyEvalContext = new LegacyEvalContext(trackingContext);
+ this.visWhen = visWhen;
+ }
+
+ public void run() {
+ if (!participating) {
+ return;
+ }
+ trackingContext.get(WINDOW_IS_CLOSED);
+ boolean visible = true;
+ try {
+ visible = visWhen.evaluate(legacyEvalContext) != EvaluationResult.FALSE;
+ } catch (CoreException e) {
+ Activator.trace(Policy.DEBUG_MENUS,
+ "Failed to evaluate visibleWhen", e); //$NON-NLS-1$
+ }
+ Activator.trace(Policy.DEBUG_MENUS,
+ "visibleWhen set to " + visible, null); //$NON-NLS-1$
+
+ item.setVisible(visible);
+ }
+ }
+
+ /**
+ * @param element
+ * @param item
+ */
+ private void associateVisibleWhen(final IConfigurationElement element,
+ final MMenuItem item) {
+ IConfigurationElement[] visibleWhen = element
+ .getChildren(IWorkbenchRegistryConstants.TAG_VISIBLE_WHEN);
+ if (visibleWhen.length > 0) {
+ IConfigurationElement[] visibleChild = visibleWhen[0].getChildren();
+ if (visibleChild.length > 0) {
+ try {
+ final Expression visWhen = ExpressionConverter.getDefault()
+ .perform(visibleChild[0]);
+ TrackVisible runnable = new TrackVisible(item, context,
+ visWhen);
+ trackers.add(runnable);
+ context.runAndTrack(runnable);
+ } catch (CoreException e) {
+ Activator.trace(Policy.DEBUG_MENUS,
+ "Failed to parse visibleWhen", e); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+
+ void cleanUp() {
+ for (TrackVisible tracker : trackers) {
+ tracker.participating = false;
+ }
+ context.set(WINDOW_IS_CLOSED, Boolean.TRUE);
+ trackers.clear();
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/MenuHelper.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/MenuHelper.java
new file mode 100644
index 0000000..a68b5f4
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/workbench/ui/menus/MenuHelper.java
@@ -0,0 +1,737 @@
+/*******************************************************************************
+ * 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.e4.workbench.ui.menus;
+
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.extensions.ExtensionUtils;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.MApplicationFactory;
+import org.eclipse.e4.ui.model.application.MCommand;
+import org.eclipse.e4.ui.model.application.MMenu;
+import org.eclipse.e4.ui.model.application.MMenuItem;
+import org.eclipse.e4.ui.model.application.MToolBar;
+import org.eclipse.e4.ui.model.application.MToolItem;
+import org.eclipse.e4.workbench.ui.internal.Activator;
+import org.eclipse.e4.workbench.ui.internal.Policy;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.commands.ActionHandler;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.LegacyHandlerService;
+import org.eclipse.ui.commands.ICommandImageService;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.internal.Workbench;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.menus.CommandContributionItem;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+public class MenuHelper {
+
+ public static final String ACTION_SET_CMD_PREFIX = "AS::"; //$NON-NLS-1$
+ public static final String MAIN_MENU_ID = "org.eclipse.ui.main.menu"; //$NON-NLS-1$
+ private static Field urlField;
+
+ public static void loadMainMenu(IEclipseContext context, MMenu menuModel,
+ MenuManager barManager) {
+ // traceMenuModel(menuModel);
+ processMenuManager(context, menuModel, barManager.getItems());
+ MenuContribution[] contributions = loadMenuContributions(context);
+ processMenuContributions(context, menuModel, contributions);
+ // processActionSets(context, menuModel);
+ }
+
+ /**
+ * @param context
+ * @param menuModel
+ */
+ public static ActionSet[] processActionSets(IEclipseContext context,
+ MMenu menuModel) {
+ ActionSet[] sets = loadActionSets(context, menuModel);
+ for (ActionSet actionSet : sets) {
+ actionSet.merge(menuModel);
+ }
+ return sets;
+ }
+
+ /**
+ * @param context
+ * @param menuModel
+ */
+ private static ActionSet[] loadActionSets(IEclipseContext context,
+ MMenu menuModel) {
+ ArrayList<ActionSet> contributions = new ArrayList<ActionSet>();
+ IConfigurationElement[] elements = ExtensionUtils
+ .getExtensions(IWorkbenchRegistryConstants.PL_ACTION_SETS);
+ for (IConfigurationElement element : elements) {
+ contributions.add(new ActionSet(context, element));
+ }
+ return contributions.toArray(new ActionSet[contributions.size()]);
+ }
+
+ public static int indexForId(MMenu parentMenu, String id) {
+ if (id == null || id.length() == 0) {
+ return -1;
+ }
+ int i = 0;
+ for (MMenuItem item : parentMenu.getChildren()) {
+ if (id.equals(item.getId())) {
+ return i;
+ }
+ i++;
+ }
+ return -1;
+ }
+
+ public static String getActionSetCommandId(IConfigurationElement element) {
+ String id = MenuHelper.getDefinitionId(element);
+ if (id != null) {
+ return id;
+ }
+ id = MenuHelper.getId(element);
+ String actionSetId = null;
+ Object obj = element.getParent();
+ while (obj instanceof IConfigurationElement && actionSetId == null) {
+ IConfigurationElement parent = (IConfigurationElement) obj;
+ if (parent.getName().equals(
+ IWorkbenchRegistryConstants.TAG_ACTION_SET)) {
+ actionSetId = MenuHelper.getId(parent);
+ }
+ obj = parent.getParent();
+ }
+ return ACTION_SET_CMD_PREFIX + actionSetId + '/' + id;
+ }
+
+ /**
+ * @param context
+ * @param menuModel
+ */
+ static void processMenuContributions(IEclipseContext context,
+ MMenu menuBar, MenuContribution[] contributions) {
+ HashSet<MenuContribution> processedContributions = new HashSet<MenuContribution>();
+ int size = -1;
+ while (size != processedContributions.size()) {
+ size = processedContributions.size();
+ for (MenuContribution contribution : contributions) {
+ if (!processedContributions.contains(contribution)) {
+ if (contribution.merge(menuBar)) {
+ processedContributions.add(contribution);
+ }
+ }
+ }
+ }
+ // now, what about sub menus
+ EList<MMenuItem> items = menuBar.getChildren();
+ for (MMenuItem menuItem : items) {
+ if (menuItem.getChildren().size() > 0) {
+ processMenuContributions(context, menuItem, contributions);
+ }
+ }
+ }
+
+ /**
+ * @param context
+ */
+ static MenuContribution[] loadMenuContributions(IEclipseContext context) {
+ ArrayList<MenuContribution> contributions = new ArrayList<MenuContribution>();
+ IConfigurationElement[] elements = ExtensionUtils
+ .getExtensions(IWorkbenchRegistryConstants.PL_MENUS);
+ for (IConfigurationElement element : elements) {
+ if (element.getName().equals(
+ IWorkbenchRegistryConstants.PL_MENU_CONTRIBUTION)) {
+ contributions.add(new MenuContribution(context, element));
+ }
+ }
+ return contributions
+ .toArray(new MenuContribution[contributions.size()]);
+ }
+
+ static abstract class ProcessItem {
+ static final ProcessItem MENU = new ProcessMenuItem();
+ static final ProcessItem TOOLBAR = new ProcessToolBarItem();
+
+ public void process(IEclipseContext context,
+ CommandContributionItem cci, Object modelParent) {
+ String id = cci.getCommand().getId();
+ ICommandService cs = (ICommandService) context
+ .get(ICommandService.class.getName());
+ Command cmd = cs.getCommand(id);
+ if (cmd.isDefined()) {
+ ICommandImageService cis = (ICommandImageService) context
+ .get(ICommandImageService.class.getName());
+ String imageURL = getImageUrl(cis.getImageDescriptor(cmd
+ .getId(), ICommandImageService.TYPE_DEFAULT));
+ try {
+ addModelItem(context, modelParent, cmd.getName(), imageURL,
+ cci.getId(), id);
+ } catch (NotDefinedException e) {
+ // This should not happen
+ e.printStackTrace();
+ }
+ } else {
+ addModelItem(context, modelParent,
+ "unloaded:" + id, null, cci.getId(), id); //$NON-NLS-1$
+ }
+ }
+
+ public void process(IEclipseContext context,
+ ActionContributionItem aci, Object modelParent) {
+ IAction action = aci.getAction();
+ String commandID = action.getActionDefinitionId();
+ if (commandID == null)
+ commandID = aci.getId();
+ if (commandID == null) {
+ commandID = action.getId();
+ }
+ if (commandID == null) {
+ // last resort, this is goofy
+ commandID = "GEN::" + System.identityHashCode(aci); //$NON-NLS-1$
+ }
+
+ if (action.getActionDefinitionId() == null && commandID != null) {
+ // check that we have a command; create it if necessary
+ Workbench legacyWB = (Workbench) context.get(Workbench.class
+ .getName());
+ String label = action.getText();
+ if (label == null) {
+ label = action.getToolTipText();
+ }
+ if (label == null) {
+ label = "label for " + commandID; //$NON-NLS-1$
+ }
+ legacyWB.addCommand(commandID, label);
+
+ // create handler
+ IHandler handler = new ActionHandler(action);
+ LegacyHandlerService.registerLegacyHandler(context, commandID,
+ commandID, handler, null);
+
+ // update action definition if needed
+ if (action.getActionDefinitionId() == null)
+ action.setActionDefinitionId(commandID);
+ }
+ addModelItem(context, modelParent, action, aci.getId());
+ }
+
+ public void addModelItem(IEclipseContext context, Object modelParent,
+ IAction action, String id) {
+ String imageURL = getImageUrl(action.getImageDescriptor());
+
+ addModelItem(context, modelParent, action.getText(), imageURL, id,
+ action.getActionDefinitionId());
+ }
+
+ public abstract void addModelItem(IEclipseContext context,
+ Object modelParent, String label, String imageURL, String id,
+ String cmdId);
+
+ static class ProcessToolBarItem extends ProcessItem {
+
+ @Override
+ public void addModelItem(IEclipseContext context,
+ Object modelParent, String label, String imageURL,
+ String id, String cmdId) {
+ MToolItem newItem = createToolbarItem(context, label, imageURL,
+ id, cmdId);
+ MToolBar tbModel = (MToolBar) modelParent;
+ tbModel.getChildren().add(newItem);
+ }
+
+ }
+
+ static class ProcessMenuItem extends ProcessItem {
+ @Override
+ public void addModelItem(IEclipseContext context,
+ Object modelParent, String label, String imageURL,
+ String id, String cmdId) {
+ MMenu menu = (MMenu) modelParent;
+ addMenuItem(context, menu, label, null, imageURL, id, cmdId);
+ }
+ }
+ }
+
+ /**
+ * @param menu
+ * @param manager
+ */
+ public static void processMenuManager(IEclipseContext context, MMenu menu,
+ IContributionItem[] items) {
+
+ if (items.length == 0) {
+ addMenuItem(context, menu, "Test Item", null, null, //$NON-NLS-1$
+ "test.id", "test.action.id"); //$NON-NLS-1$//$NON-NLS-2$
+ }
+ for (int i = 0; i < items.length; i++) {
+ IContributionItem item = items[i];
+ if (item instanceof MenuManager) {
+ MenuManager m = (MenuManager) item;
+ MMenuItem menu1 = addMenu(context, menu, m.getMenuText(), null,
+ null, m.getId(), null);
+ processMenuManager(context, menu1, m.getItems());
+ } else if (item instanceof ActionContributionItem) {
+ ActionContributionItem aci = (ActionContributionItem) item;
+ if ((aci.getAction().getStyle() | IAction.AS_DROP_DOWN_MENU) == 0) {
+ ProcessItem.MENU.process(context, aci, menu);
+ } else {
+ // addMenuRenderer(context, menu, item);
+ }
+ } else if (item instanceof CommandContributionItem) {
+ CommandContributionItem cci = (CommandContributionItem) item;
+ ProcessItem.MENU.process(context, cci, menu);
+ } else if (item instanceof Separator) {
+ addSeparator(menu, item.getId(), true);
+ } else if (item instanceof GroupMarker) {
+ addSeparator(menu, item.getId(), false);
+ } else {
+ Activator.trace(Policy.DEBUG_MENUS,
+ "ICI: " + item.getClass().getName(), null); //$NON-NLS-1$
+ // addMenuRenderer(context, menu, item);
+ }
+ }
+ }
+
+ /**
+ * @param context
+ * @param menu
+ * @param item
+ */
+ // public static MMenuItemRenderer addMenuRenderer(IEclipseContext context,
+ // MMenu menu, IContributionItem item) {
+ // MMenuItemRenderer r = WorkbenchFactory.eINSTANCE
+ // .createMMenuItemRenderer();
+ // r.setId(item.getId() == null ? "item:" + menu.getId() : item.getId()); //$NON-NLS-1$
+ // r.setRenderer(item);
+ // menu.getChildren().add(r);
+ // return r;
+ // }
+ //
+ // public static MToolItemRenderer addToolRenderer(IEclipseContext context,
+ // MToolBar bar, IContributionItem item) {
+ // MToolItemRenderer r = WorkbenchFactory.eINSTANCE
+ // .createMToolItemRenderer();
+ // r.setId(item.getId() == null ? "item:" + bar.getId() : item.getId()); //$NON-NLS-1$
+ // r.setRenderer(item);
+ // bar.getChildren().add(r);
+ // return r;
+ // }
+
+ /**
+ * @param menu
+ * @param manager
+ */
+ public static void processToolbarManager(IEclipseContext context,
+ MToolBar tbModel, IContributionItem[] items) {
+
+ if (items.length == 0) {
+ addToolbarItem(tbModel, "Test Item", null, null, //$NON-NLS-1$
+ "test.id", "test.action.id"); //$NON-NLS-1$//$NON-NLS-2$
+ }
+ for (int i = 0; i < items.length; i++) {
+ IContributionItem item = items[i];
+ if (item instanceof MenuManager) {
+ Activator
+ .trace(Policy.DEBUG_MENUS, "Tb has a MenuManger", null); //$NON-NLS-1$
+ // MenuManager m = (MenuManager) item;
+ // MMenuItem menu1 = addMenu(context, menu, m.getMenuText(),
+ // null,
+ // null, m.getId(), null);
+ // processMenuManager(context, menu1.getMenu(),
+ // m.getChildren());
+ } else if (item instanceof ActionContributionItem) {
+ ActionContributionItem aci = (ActionContributionItem) item;
+ if ((aci.getAction().getStyle() | IAction.AS_DROP_DOWN_MENU) == 0) {
+ ProcessItem.TOOLBAR.process(context, aci, tbModel);
+ } else {
+ // addToolRenderer(context, tbModel, item);
+ }
+ } else if (item instanceof CommandContributionItem) {
+ CommandContributionItem cci = (CommandContributionItem) item;
+ ProcessItem.TOOLBAR.process(context, cci, tbModel);
+ } else if (item instanceof Separator) {
+ // addSeparator(menu, item.getId());
+ } else if (item instanceof GroupMarker) {
+ // addSeparator(menu, item.getId());
+ } else {
+ Activator.trace(Policy.DEBUG_MENUS,
+ "unknown tool item: " + item.getClass().getName() //$NON-NLS-1$
+ + " in " + context, null); //$NON-NLS-1$
+ // addToolRenderer(context, tbModel, item);
+ }
+ }
+ }
+
+ /**
+ * @param imageDescriptor
+ * @return
+ */
+ public static String getImageUrl(ImageDescriptor imageDescriptor) {
+ if (imageDescriptor == null)
+ return null;
+ Class idc = imageDescriptor.getClass();
+ if (idc.getName().endsWith("URLImageDescriptor")) { //$NON-NLS-1$
+ URL url = getUrl(idc, imageDescriptor);
+ return url.toExternalForm();
+ }
+ return null;
+ }
+
+ private static URL getUrl(Class idc, ImageDescriptor imageDescriptor) {
+ try {
+ if (urlField == null) {
+ urlField = idc.getDeclaredField("url"); //$NON-NLS-1$
+ urlField.setAccessible(true);
+ }
+ return (URL) urlField.get(imageDescriptor);
+ } catch (SecurityException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (NoSuchFieldException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IllegalArgumentException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ private static MCommand getCommandById(IEclipseContext context, String cmdId) {
+ if (context == null)
+ return null;
+
+ MApplication app = (MApplication) context.get(MApplication.class
+ .getName());
+ final EList<MCommand> cmds = app.getCommands();
+ for (MCommand cmd : cmds) {
+ if (cmdId.equals(cmd.getId())) {
+ return cmd;
+ }
+ }
+ return null;
+ }
+
+ public static MMenuItem createMenuItem(IEclipseContext context,
+ String label, String imgPath, String id, String cmdId) {
+ MMenuItem newItem = MApplicationFactory.eINSTANCE.createMenuItem();
+ newItem.setId(id);
+ newItem.setName(label);
+ newItem.setIconURI(imgPath);
+ if (cmdId != null) {
+ MCommand mcmd = getCommandById(context, cmdId);
+ if (mcmd != null) {
+ // newItem.setCommand(mcmd);
+ } else {
+ // System.err.println("No MCommand defined for " + cmdId); //$NON-NLS-1$
+ }
+ } else {
+ // System.err.println("No command id for " + id); //$NON-NLS-1$
+ }
+ return newItem;
+ }
+
+ public static MToolItem createToolbarItem(IEclipseContext context,
+ String label, String imgPath, String id, String cmdId) {
+ MToolItem newItem = MApplicationFactory.eINSTANCE.createToolItem();
+ newItem.setId(id);
+ newItem.setTooltip(label);
+ newItem.setIconURI(imgPath);
+ Activator.trace(Policy.DEBUG_MENUS, "createToolbarItem: " + id //$NON-NLS-1$
+ + ": " + label + ": " + cmdId, null); //$NON-NLS-1$//$NON-NLS-2$
+ if (cmdId != null) {
+ MCommand mcmd = getCommandById(context, cmdId);
+ if (mcmd != null) {
+ // newItem.setCommand(mcmd);
+ } else {
+ // System.err.println("No MCommand defined for " + cmdId); //$NON-NLS-1$
+ }
+ } else {
+ // System.err.println("No command id for " + id); //$NON-NLS-1$
+ }
+ return newItem;
+ }
+
+ private static MToolItem createTBItem(String ttip, String imgPath,
+ String id, String cmdId) {
+ MToolItem newItem = MApplicationFactory.eINSTANCE.createToolItem();
+ newItem.setId(id);
+ newItem.setTooltip(ttip);
+ newItem.setIconURI(imgPath);
+
+ return newItem;
+ }
+
+ public static MMenuItem addMenu(IEclipseContext context, MMenu parentMenu,
+ String label, String plugin, String imgPath, String id, String cmdId) {
+ // Sub-menus are implemented as an item with a menu... ??
+ MMenuItem newItem = createMenuItem(context, label, imgPath, id, cmdId);
+ parentMenu.getChildren().add(newItem);
+
+ return newItem;
+ }
+
+ public static MMenuItem addMenu(MMenuItem parentMenuItem, String label,
+ String plugin, String imgPath, String id, String cmdId) {
+ MMenu parentMenu = parentMenuItem;
+ return addMenu(null, parentMenu, label, plugin, imgPath, id, cmdId);
+ }
+
+ public static void addMenuItem(MMenuItem parentMenuItem, String label,
+ String plugin, String imgPath, String id, String cmdId) {
+ MMenuItem newItem = createMenuItem(null, label, imgPath, id, cmdId);
+ MMenu parentMenu = parentMenuItem;
+ parentMenu.getChildren().add(newItem);
+ }
+
+ public static void addToolbarItem(MToolBar tbModel, String label,
+ String plugin, String imgPath, String id, String cmdId) {
+ MToolItem newItem = createToolbarItem(null, label, imgPath, id, cmdId);
+ tbModel.getChildren().add(newItem);
+ }
+
+ public static void addMenuItem(IEclipseContext context, MMenu parentMenu,
+ String label, String plugin, String imgPath, String id, String cmdId) {
+ MMenuItem newItem = createMenuItem(context, label, imgPath, id, cmdId);
+ parentMenu.getChildren().add(newItem);
+ }
+
+ public static void addSeparator(MMenuItem parentMenuItem, String id) {
+ if (id != null)
+ return;
+ MMenuItem newItem = MApplicationFactory.eINSTANCE.createMenuItem();
+ newItem.setId(id);
+ newItem.setSeparator(true);
+ // newItem.setVisible(id == null);
+ parentMenuItem.getChildren().add(newItem);
+ }
+
+ public static void addSeparator(MMenu menu, String id, boolean visible) {
+ MMenuItem newItem = MApplicationFactory.eINSTANCE.createMenuItem();
+ if (id != null) {
+ newItem.setId(id);
+ }
+ newItem.setSeparator(true);
+ newItem.setVisible(visible);
+
+ menu.getChildren().add(newItem);
+ }
+
+ public static void loadToolbar(MToolBar tbModel) {
+ MToolItem tbItem = createTBItem("&New Alt+Shift+N", null, //$NON-NLS-1$
+ "cmdId.New", "cmdId.New"); //$NON-NLS-1$//$NON-NLS-2$
+ tbModel.getChildren().add(tbItem);
+
+ tbItem = createTBItem(
+ "&Save", //$NON-NLS-1$
+ "platform:/plugin/org.eclipse.ui/icons/full/etool16/save_edit.gif", //$NON-NLS-1$
+ "cmdId.Save", "cmdId.Save"); //$NON-NLS-1$//$NON-NLS-2$
+ tbModel.getChildren().add(tbItem);
+
+ tbItem = createTBItem(
+ "&Print", //$NON-NLS-1$
+ "platform:/plugin/org.eclipse.ui/icons/full/etool16/print_edit.gif", //$NON-NLS-1$
+ "cmdId.Print", "cmdId.Print"); //$NON-NLS-1$//$NON-NLS-2$
+ tbModel.getChildren().add(tbItem);
+ }
+
+ static boolean getVisibleEnabled(IConfigurationElement element) {
+ IConfigurationElement[] children = element
+ .getChildren(IWorkbenchRegistryConstants.TAG_VISIBLE_WHEN);
+ String checkEnabled = null;
+
+ if (children.length > 0) {
+ checkEnabled = children[0]
+ .getAttribute(IWorkbenchRegistryConstants.ATT_CHECK_ENABLED);
+ }
+
+ return checkEnabled != null && checkEnabled.equalsIgnoreCase("true"); //$NON-NLS-1$
+ }
+
+ /*
+ * Support Utilities
+ */
+ public static String getId(IConfigurationElement element) {
+ String id = element.getAttribute(IWorkbenchRegistryConstants.ATT_ID);
+
+ // For sub-menu management -all- items must be id'd so enforce this
+ // here (we could optimize by checking the 'name' of the config
+ // element == "menu"
+ if (id == null || id.length() == 0) {
+ id = getCommandId(element);
+ }
+ if (id == null || id.length() == 0) {
+ id = element.toString();
+ }
+
+ return id;
+ }
+
+ public static boolean getRetarget(IConfigurationElement element) {
+ String r = element
+ .getAttribute(IWorkbenchRegistryConstants.ATT_RETARGET);
+ return Boolean.valueOf(r);
+ }
+
+ public static String getName(IConfigurationElement element) {
+ return element.getAttribute(IWorkbenchRegistryConstants.ATT_NAME);
+ }
+
+ public static int getMode(IConfigurationElement element) {
+ if ("FORCE_TEXT".equals(element.getAttribute(IWorkbenchRegistryConstants.ATT_MODE))) { //$NON-NLS-1$
+ return CommandContributionItem.MODE_FORCE_TEXT;
+ }
+ return 0;
+ }
+
+ public static String getLabel(IConfigurationElement element) {
+ return element.getAttribute(IWorkbenchRegistryConstants.ATT_LABEL);
+ }
+
+ public static String getMnemonic(IConfigurationElement element) {
+ return element.getAttribute(IWorkbenchRegistryConstants.ATT_MNEMONIC);
+ }
+
+ public static String getTooltip(IConfigurationElement element) {
+ return element.getAttribute(IWorkbenchRegistryConstants.ATT_TOOLTIP);
+ }
+
+ public static String getIconPath(IConfigurationElement element) {
+ return element.getAttribute(IWorkbenchRegistryConstants.ATT_ICON);
+ }
+
+ public static String getDisabledIconPath(IConfigurationElement element) {
+ return element
+ .getAttribute(IWorkbenchRegistryConstants.ATT_DISABLEDICON);
+ }
+
+ public static String getHoverIconPath(IConfigurationElement element) {
+ return element.getAttribute(IWorkbenchRegistryConstants.ATT_HOVERICON);
+ }
+
+ public static ImageDescriptor getIconDescriptor(
+ IConfigurationElement element) {
+ String extendingPluginId = element.getDeclaringExtension()
+ .getContributor().getName();
+
+ String iconPath = getIconPath(element);
+ if (iconPath != null) {
+ return AbstractUIPlugin.imageDescriptorFromPlugin(
+ extendingPluginId, iconPath);
+ }
+ return null;
+ }
+
+ public static ImageDescriptor getDisabledIconDescriptor(
+ IConfigurationElement element) {
+ String extendingPluginId = element.getDeclaringExtension()
+ .getContributor().getName();
+
+ String iconPath = getDisabledIconPath(element);
+ if (iconPath != null) {
+ return AbstractUIPlugin.imageDescriptorFromPlugin(
+ extendingPluginId, iconPath);
+ }
+ return null;
+ }
+
+ public static ImageDescriptor getHoverIconDescriptor(
+ IConfigurationElement element) {
+ String extendingPluginId = element.getDeclaringExtension()
+ .getContributor().getName();
+
+ String iconPath = getHoverIconPath(element);
+ if (iconPath != null) {
+ return AbstractUIPlugin.imageDescriptorFromPlugin(
+ extendingPluginId, iconPath);
+ }
+ return null;
+ }
+
+ public static String getHelpContextId(IConfigurationElement element) {
+ return element
+ .getAttribute(IWorkbenchRegistryConstants.ATT_HELP_CONTEXT_ID);
+ }
+
+ public static boolean isSeparatorVisible(IConfigurationElement element) {
+ String val = element
+ .getAttribute(IWorkbenchRegistryConstants.ATT_VISIBLE);
+ return Boolean.valueOf(val).booleanValue();
+ }
+
+ public static String getClassSpec(IConfigurationElement element) {
+ return element.getAttribute(IWorkbenchRegistryConstants.ATT_CLASS);
+ }
+
+ public static String getCommandId(IConfigurationElement element) {
+ return element.getAttribute(IWorkbenchRegistryConstants.ATT_COMMAND_ID);
+ }
+
+ public static String getDefinitionId(IConfigurationElement element) {
+ return element
+ .getAttribute(IWorkbenchRegistryConstants.ATT_DEFINITION_ID);
+ }
+
+ public static int getStyle(IConfigurationElement element) {
+ String style = element
+ .getAttribute(IWorkbenchRegistryConstants.ATT_STYLE);
+ if (style == null || style.length() == 0) {
+ return CommandContributionItem.STYLE_PUSH;
+ }
+ if (IWorkbenchRegistryConstants.STYLE_TOGGLE.equals(style)) {
+ return CommandContributionItem.STYLE_CHECK;
+ }
+ if (IWorkbenchRegistryConstants.STYLE_RADIO.equals(style)) {
+ return CommandContributionItem.STYLE_RADIO;
+ }
+ if (IWorkbenchRegistryConstants.STYLE_PULLDOWN.equals(style)) {
+ return CommandContributionItem.STYLE_PULLDOWN;
+ }
+ return CommandContributionItem.STYLE_PUSH;
+ }
+
+ /**
+ * @param element
+ * @return A map of parameters names to parameter values. All Strings. The
+ * map may be empty.
+ */
+ public static Map<String, String> getParameters(
+ IConfigurationElement element) {
+ HashMap<String, String> map = new HashMap<String, String>();
+ IConfigurationElement[] parameters = element
+ .getChildren(IWorkbenchRegistryConstants.TAG_PARAMETER);
+ for (int i = 0; i < parameters.length; i++) {
+ String name = parameters[i]
+ .getAttribute(IWorkbenchRegistryConstants.ATT_NAME);
+ String value = parameters[i]
+ .getAttribute(IWorkbenchRegistryConstants.ATT_VALUE);
+ if (name != null && value != null) {
+ map.put(name, value);
+ }
+ }
+ return map;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/LegacyEvalContext.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/LegacyEvalContext.java
new file mode 100644
index 0000000..cd1d368
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/LegacyEvalContext.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * 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.ui;
+
+import java.util.Collections;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+
+/**
+ *
+ */
+public class LegacyEvalContext implements IEvaluationContext {
+ public IEclipseContext eclipseContext = null;
+ private boolean allowActivation;
+
+ public LegacyEvalContext(IEclipseContext context) {
+ eclipseContext = context;
+ }
+
+ public void setAllowPluginActivation(boolean value) {
+ allowActivation = value;
+ }
+
+ public Object resolveVariable(String name, Object[] args)
+ throws CoreException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Object removeVariable(String name) {
+ Object o = eclipseContext.get(name);
+ eclipseContext.remove(name);
+ return o;
+ }
+
+ public Object getVariable(String name) {
+ final Object obj = eclipseContext.get(name);
+ return obj == null ? IEvaluationContext.UNDEFINED_VARIABLE : obj;
+ }
+
+ public IEvaluationContext getRoot() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public IEvaluationContext getParent() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Object getDefaultVariable() {
+ final Object obj = eclipseContext
+ .get(ISources.ACTIVE_CURRENT_SELECTION_NAME);
+ return obj == null ? Collections.EMPTY_LIST : obj;
+ }
+
+ public boolean getAllowPluginActivation() {
+ return allowActivation;
+ }
+
+ public void addVariable(String name, Object value) {
+ eclipseContext.set(name, value);
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/LegacyHandlerService.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/LegacyHandlerService.java
new file mode 100644
index 0000000..b1be89e
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/LegacyHandlerService.java
@@ -0,0 +1,709 @@
+/*******************************************************************************
+ * 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.ui;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.NotEnabledException;
+import org.eclipse.core.commands.NotHandledException;
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.expressions.ElementHandler;
+import org.eclipse.core.expressions.EvaluationResult;
+import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.expressions.ExpressionConverter;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.e4.core.commands.ECommandService;
+import org.eclipse.e4.core.commands.EHandlerService;
+import org.eclipse.e4.core.services.context.EclipseContextFactory;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.extensions.ExtensionUtils;
+import org.eclipse.e4.ui.model.application.MContext;
+import org.eclipse.e4.ui.workbench.swt.internal.AbstractPartRenderer;
+import org.eclipse.e4.workbench.ui.internal.Activator;
+import org.eclipse.e4.workbench.ui.internal.Policy;
+import org.eclipse.e4.workbench.ui.internal.UISchedulerStrategy;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.ui.handlers.IHandlerActivation;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.internal.expressions.AndExpression;
+import org.eclipse.ui.internal.expressions.WorkbenchWindowExpression;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.internal.services.SourcePriorityNameMapping;
+
+public class LegacyHandlerService implements IHandlerService {
+ private static final String PARM_MAP = "legacyParameterMap"; //$NON-NLS-1$
+ private static final String HANDLER_PREFIX = "HDL_"; //$NON-NLS-1$
+
+ public static class HandlerProxy {
+ IHandler handler = null;
+ Command command;
+ EHandlerActivation activation = null;
+
+ public HandlerProxy(Command command, IHandler handler) {
+ this.command = command;
+ this.handler = handler;
+ }
+
+ public boolean canExecute(IEclipseContext context) {
+ return handler.isEnabled();
+ }
+
+ public void execute(IEclipseContext context) {
+ Activator.trace(Policy.DEBUG_CMDS, "execute " + command + " and " //$NON-NLS-1$ //$NON-NLS-2$
+ + handler + " with: " + context, null); //$NON-NLS-1$
+ LegacyEvalContext legacy = new LegacyEvalContext(context);
+ ExecutionEvent event = new ExecutionEvent(command, (Map) context
+ .get(PARM_MAP), null, legacy);
+ try {
+ handler.execute(event);
+ } catch (ExecutionException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public IHandler getHandler() {
+ return handler;
+ }
+ }
+
+ static class EHandlerActivation implements IHandlerActivation, Runnable {
+
+ IEclipseContext context;
+ private String commandId;
+ private IHandler handler;
+ HandlerProxy proxy;
+ Expression activeWhen;
+ boolean active;
+ int sourcePriority;
+ boolean participating = true;
+
+ /**
+ * @param context
+ * @param cmdId
+ * @param handler
+ * @param handlerProxy
+ */
+ public EHandlerActivation(IEclipseContext context, String cmdId,
+ IHandler handler, HandlerProxy handlerProxy, Expression expr) {
+ this.context = context;
+ this.commandId = cmdId;
+ this.handler = handler;
+ this.proxy = handlerProxy;
+ this.activeWhen = expr;
+ this.sourcePriority = SourcePriorityNameMapping
+ .computeSourcePriority(activeWhen);
+ proxy.activation = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.handlers.IHandlerActivation#clearActive()
+ */
+ public void clearActive() {
+ active = true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.handlers.IHandlerActivation#getCommandId()
+ */
+ public String getCommandId() {
+ return commandId;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.handlers.IHandlerActivation#getDepth()
+ */
+ public int getDepth() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.handlers.IHandlerActivation#getHandler()
+ */
+ public IHandler getHandler() {
+ return handler;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.handlers.IHandlerActivation#getHandlerService()
+ */
+ public IHandlerService getHandlerService() {
+ return (IHandlerService) context.get(IHandlerService.class
+ .getName());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.handlers.IHandlerActivation#isActive(org.eclipse.core
+ * .expressions.IEvaluationContext)
+ */
+ public boolean isActive(IEvaluationContext context) {
+ return active;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.internal.services.IEvaluationResultCache#clearResult()
+ */
+ public void clearResult() {
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.internal.services.IEvaluationResultCache#evaluate(
+ * org.eclipse.core.expressions.IEvaluationContext)
+ */
+ public boolean evaluate(IEvaluationContext context) {
+ if (activeWhen == null) {
+ active = true;
+ } else {
+ try {
+ active = activeWhen.evaluate(context) != EvaluationResult.FALSE;
+ } catch (CoreException e) {
+ Activator.trace(Policy.DEBUG_CMDS,
+ "Failed to calculate active", e); //$NON-NLS-1$
+ }
+ }
+ return active;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.internal.services.IEvaluationResultCache#getExpression
+ * ()
+ */
+ public Expression getExpression() {
+ return activeWhen;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.internal.services.IEvaluationResultCache#getSourcePriority
+ * ()
+ */
+ public int getSourcePriority() {
+ return sourcePriority;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.internal.services.IEvaluationResultCache#setResult
+ * (boolean)
+ */
+ public void setResult(boolean result) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(Object o) {
+ EHandlerActivation activation = (EHandlerActivation) o;
+ int difference;
+
+ // Check the priorities
+ int thisPriority = this.getSourcePriority();
+ int thatPriority = activation.getSourcePriority();
+
+ // rogue bit problem - ISources.ACTIVE_MENU
+ int thisLsb = 0;
+ int thatLsb = 0;
+
+ if (((thisPriority & ISources.ACTIVE_MENU) | (thatPriority & ISources.ACTIVE_MENU)) != 0) {
+ thisLsb = thisPriority & 1;
+ thisPriority = (thisPriority >> 1) & 0x7fffffff;
+ thatLsb = thatPriority & 1;
+ thatPriority = (thatPriority >> 1) & 0x7fffffff;
+ }
+
+ difference = thisPriority - thatPriority;
+ if (difference != 0) {
+ return difference;
+ }
+
+ // if all of the higher bits are the same, check the
+ // difference of the LSB
+ difference = thisLsb - thatLsb;
+ if (difference != 0) {
+ return difference;
+ }
+
+ // Check depth
+ final int thisDepth = this.getDepth();
+ final int thatDepth = activation.getDepth();
+ difference = thisDepth - thatDepth;
+ return difference;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "EHA: " + active + ":" + sourcePriority + ":" + commandId + ": " + proxy //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ + ": " + handler + ": " + context; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Runnable#run()
+ */
+ public void run() {
+ if (!participating) {
+ return;
+ }
+ final EHandlerService hs = (EHandlerService) context
+ .get(EHandlerService.class.getName());
+ Object obj = context.get(HANDLER_PREFIX + commandId);
+
+ if (evaluate(new LegacyEvalContext(context))) {
+ if (obj instanceof HandlerProxy) {
+ final EHandlerActivation bestActivation = ((HandlerProxy) obj).activation;
+ final int comparison = bestActivation.compareTo(this);
+ if (comparison < 0) {
+ hs.activateHandler(commandId, proxy);
+ }
+ } else if (obj == null) {
+ hs.activateHandler(commandId, proxy);
+ }
+ } else {
+ if (obj == proxy) {
+ hs.deactivateHandler(commandId, proxy);
+ }
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.application.IActionBarConfigurer#registerGlobalAction(
+ * org.eclipse.jface.action.IAction)
+ */
+ public static IHandlerActivation registerLegacyHandler(
+ final IEclipseContext context, String id, final String cmdId,
+ IHandler handler, Expression activeWhen) {
+
+ ECommandService cs = (ECommandService) context
+ .get(ECommandService.class.getName());
+ Command command = cs.getCommand(cmdId);
+ HandlerProxy handlerProxy = new HandlerProxy(command, handler);
+ final EHandlerActivation activation = new EHandlerActivation(context,
+ cmdId, handler, handlerProxy, activeWhen);
+ context.runAndTrack(activation);
+ return activation;
+ }
+
+ private IEclipseContext eclipseContext;
+ private IEvaluationContext evalContext;
+ private Expression defaultExpression = null;
+
+ public LegacyHandlerService(IEclipseContext context) {
+ eclipseContext = context;
+ evalContext = new LegacyEvalContext(eclipseContext);
+ IWorkbenchWindow window = (IWorkbenchWindow) eclipseContext
+ .get(IWorkbenchWindow.class.getName());
+ if (window != null) {
+ defaultExpression = new WorkbenchWindowExpression(window);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.handlers.IHandlerService#activateHandler(org.eclipse.ui
+ * .handlers.IHandlerActivation)
+ */
+ public IHandlerActivation activateHandler(IHandlerActivation activation) {
+ EHandlerActivation eActivation = (EHandlerActivation) activation;
+ eActivation.participating = true;
+ eActivation.context.runAndTrack(eActivation);
+ return activation;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.handlers.IHandlerService#activateHandler(java.lang.String,
+ * org.eclipse.core.commands.IHandler)
+ */
+ public IHandlerActivation activateHandler(String commandId, IHandler handler) {
+ return registerLegacyHandler(eclipseContext, commandId, commandId,
+ handler, defaultExpression);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.handlers.IHandlerService#activateHandler(java.lang.String,
+ * org.eclipse.core.commands.IHandler,
+ * org.eclipse.core.expressions.Expression)
+ */
+ public IHandlerActivation activateHandler(String commandId,
+ IHandler handler, Expression expression) {
+ return activateHandler(commandId, handler, expression, false);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.handlers.IHandlerService#activateHandler(java.lang.String,
+ * org.eclipse.core.commands.IHandler,
+ * org.eclipse.core.expressions.Expression, boolean)
+ */
+ public IHandlerActivation activateHandler(String commandId,
+ IHandler handler, Expression expression, boolean global) {
+ if (global || defaultExpression == null) {
+ return registerLegacyHandler(eclipseContext, commandId, commandId,
+ handler, expression);
+ }
+ AndExpression andExpr = new AndExpression();
+ andExpr.add(expression);
+ andExpr.add(defaultExpression);
+ return registerLegacyHandler(eclipseContext, commandId, commandId,
+ handler, andExpr);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.handlers.IHandlerService#activateHandler(java.lang.String,
+ * org.eclipse.core.commands.IHandler,
+ * org.eclipse.core.expressions.Expression, int)
+ */
+ public IHandlerActivation activateHandler(String commandId,
+ IHandler handler, Expression expression, int sourcePriorities) {
+ return activateHandler(commandId, handler, expression, false);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.handlers.IHandlerService#createContextSnapshot(boolean)
+ */
+ public IEvaluationContext createContextSnapshot(boolean includeSelection) {
+ return new LegacyEvalContext(EclipseContextFactory.create(
+ getFocusContext(PlatformUI.getWorkbench().getDisplay()),
+ UISchedulerStrategy.getInstance()));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.handlers.IHandlerService#createExecutionEvent(org.eclipse
+ * .core.commands.Command, org.eclipse.swt.widgets.Event)
+ */
+ public ExecutionEvent createExecutionEvent(Command command, Event event) {
+ LegacyEvalContext legacy = new LegacyEvalContext(
+ getFocusContext(PlatformUI.getWorkbench().getDisplay()));
+ ExecutionEvent e = new ExecutionEvent(command, Collections.EMPTY_MAP,
+ event, legacy);
+ return e;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.handlers.IHandlerService#createExecutionEvent(org.eclipse
+ * .core.commands.ParameterizedCommand, org.eclipse.swt.widgets.Event)
+ */
+ public ExecutionEvent createExecutionEvent(ParameterizedCommand command,
+ Event event) {
+ LegacyEvalContext legacy = new LegacyEvalContext(
+ getFocusContext(PlatformUI.getWorkbench().getDisplay()));
+ ExecutionEvent e = new ExecutionEvent(command.getCommand(), command
+ .getParameterMap(), event, legacy);
+ return e;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.handlers.IHandlerService#deactivateHandler(org.eclipse
+ * .ui.handlers.IHandlerActivation)
+ */
+ public void deactivateHandler(IHandlerActivation activation) {
+ EHandlerActivation eActivation = (EHandlerActivation) activation;
+ eActivation.participating = false;
+ EHandlerService hs = (EHandlerService) eActivation.context
+ .get(EHandlerService.class.getName());
+ hs.deactivateHandler(eActivation.getCommandId(), eActivation.proxy);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.handlers.IHandlerService#deactivateHandlers(java.util.
+ * Collection)
+ */
+ public void deactivateHandlers(Collection activations) {
+ Object[] array = activations.toArray();
+ for (int i = 0; i < array.length; i++) {
+ deactivateHandler((IHandlerActivation) array[i]);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.handlers.IHandlerService#executeCommand(java.lang.String,
+ * org.eclipse.swt.widgets.Event)
+ */
+ public Object executeCommand(String commandId, Event event)
+ throws ExecutionException, NotDefinedException,
+ NotEnabledException, NotHandledException {
+ ECommandService cs = (ECommandService) getFocusContext(
+ PlatformUI.getWorkbench().getDisplay()).get(
+ ECommandService.class.getName());
+ final Command command = cs.getCommand(commandId);
+ return executeCommand(ParameterizedCommand.generateCommand(command,
+ null), event);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.handlers.IHandlerService#executeCommand(org.eclipse.core
+ * .commands.ParameterizedCommand, org.eclipse.swt.widgets.Event)
+ */
+ public Object executeCommand(ParameterizedCommand command, Event event)
+ throws ExecutionException, NotDefinedException,
+ NotEnabledException, NotHandledException {
+ EHandlerService hs = (EHandlerService) getFocusContext(
+ PlatformUI.getWorkbench().getDisplay()).get(
+ EHandlerService.class.getName());
+ hs.getContext().set(PARM_MAP, command.getParameterMap());
+ return hs.executeHandler(command);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.handlers.IHandlerService#executeCommandInContext(org.eclipse
+ * .core.commands.ParameterizedCommand, org.eclipse.swt.widgets.Event,
+ * org.eclipse.core.expressions.IEvaluationContext)
+ */
+ public Object executeCommandInContext(ParameterizedCommand command,
+ Event event, IEvaluationContext context) throws ExecutionException,
+ NotDefinedException, NotEnabledException, NotHandledException {
+ if (context instanceof LegacyEvalContext) {
+ EHandlerService hs = (EHandlerService) ((LegacyEvalContext) context).eclipseContext
+ .get(EHandlerService.class.getName());
+ return hs.executeHandler(command);
+ }
+ return executeCommand(command, event);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.handlers.IHandlerService#getCurrentState()
+ */
+ public IEvaluationContext getCurrentState() {
+ return evalContext;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.handlers.IHandlerService#readRegistry()
+ */
+ public void readRegistry() {
+ readDefaultHandlers();
+ readHandlers();
+ }
+
+ private void readHandlers() {
+ IConfigurationElement[] elements = ExtensionUtils
+ .getExtensions(IWorkbenchRegistryConstants.PL_HANDLERS);
+ for (IConfigurationElement configElement : elements) {
+ String commandId = configElement
+ .getAttribute(IWorkbenchRegistryConstants.ATT_COMMAND_ID);
+ if (commandId == null || commandId.length() == 0) {
+ continue;
+ }
+ String defaultHandler = configElement
+ .getAttribute(IWorkbenchRegistryConstants.ATT_CLASS);
+ if ((defaultHandler == null)
+ && (configElement
+ .getChildren(IWorkbenchRegistryConstants.TAG_CLASS).length == 0)) {
+ continue;
+ }
+ Expression activeWhen = null;
+ final IConfigurationElement[] awChildren = configElement
+ .getChildren(IWorkbenchRegistryConstants.TAG_ACTIVE_WHEN);
+ if (awChildren.length > 0) {
+ final IConfigurationElement[] subChildren = awChildren[0]
+ .getChildren();
+ if (subChildren.length != 1) {
+ Activator.trace(Policy.DEBUG_CMDS,
+ "Incorrect activeWhen element " + commandId, null); //$NON-NLS-1$
+ continue;
+ }
+ final ElementHandler elementHandler = ElementHandler
+ .getDefault();
+ final ExpressionConverter converter = ExpressionConverter
+ .getDefault();
+ try {
+ activeWhen = elementHandler.create(converter,
+ subChildren[0]);
+ } catch (CoreException e) {
+ Activator.trace(Policy.DEBUG_CMDS,
+ "Incorrect activeWhen element " + commandId, e); //$NON-NLS-1$
+ }
+ }
+ registerLegacyHandler(eclipseContext, commandId, commandId,
+ new org.eclipse.ui.internal.handlers.HandlerProxy(
+ commandId, configElement,
+ IWorkbenchRegistryConstants.ATT_CLASS), activeWhen);
+ }
+ }
+
+ private void readDefaultHandlers() {
+ IConfigurationElement[] elements = ExtensionUtils
+ .getExtensions(IWorkbenchRegistryConstants.PL_COMMANDS);
+ for (IConfigurationElement configElement : elements) {
+ String id = configElement
+ .getAttribute(IWorkbenchRegistryConstants.ATT_ID);
+ if (id == null || id.length() == 0) {
+ continue;
+ }
+ String defaultHandler = configElement
+ .getAttribute(IWorkbenchRegistryConstants.ATT_DEFAULT_HANDLER);
+ if ((defaultHandler == null)
+ && (configElement
+ .getChildren(IWorkbenchRegistryConstants.TAG_DEFAULT_HANDLER).length == 0)) {
+ continue;
+ }
+ registerLegacyHandler(eclipseContext, id, id,
+ new org.eclipse.ui.internal.handlers.HandlerProxy(id,
+ configElement,
+ IWorkbenchRegistryConstants.ATT_DEFAULT_HANDLER),
+ null);
+
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.handlers.IHandlerService#setHelpContextId(org.eclipse.
+ * core.commands.IHandler, java.lang.String)
+ */
+ public void setHelpContextId(IHandler handler, String helpContextId) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.services.IServiceWithSources#addSourceProvider(org.eclipse
+ * .ui.ISourceProvider)
+ */
+ public void addSourceProvider(ISourceProvider provider) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.services.IServiceWithSources#removeSourceProvider(org.
+ * eclipse.ui.ISourceProvider)
+ */
+ public void removeSourceProvider(ISourceProvider provider) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.services.IDisposable#dispose()
+ */
+ public void dispose() {
+ // TODO Auto-generated method stub
+
+ }
+
+ private IEclipseContext getFocusContext(Display display) {
+ // find the first useful part in the model
+ Control control = display.getFocusControl();
+ Object modelObj = null;
+ while (control != null) {
+ modelObj = control.getData(AbstractPartRenderer.OWNING_ME);
+ if (modelObj instanceof MContext)
+ return ((MContext) modelObj).getContext();
+ control = control.getParent();
+ }
+ return eclipseContext;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/actions/ContributedAction.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/actions/ContributedAction.java
new file mode 100644
index 0000000..da33322
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/actions/ContributedAction.java
@@ -0,0 +1,286 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 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.ui.actions;
+
+import java.util.Collections;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.IHandler2;
+import org.eclipse.core.commands.NotEnabledException;
+import org.eclipse.core.commands.NotHandledException;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.expressions.EvaluationContext;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.LegacyHandlerService;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.internal.PartSite;
+import org.eclipse.ui.internal.actions.CommandAction;
+import org.eclipse.ui.internal.handlers.ActionDelegateHandlerProxy;
+import org.eclipse.ui.internal.handlers.HandlerService;
+import org.eclipse.ui.internal.handlers.IActionCommandMappingService;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.internal.services.IWorkbenchLocationService;
+import org.eclipse.ui.part.MultiPageEditorSite;
+import org.eclipse.ui.services.IServiceLocator;
+
+/**
+ * For a declarative editor action, see if we can link it to a command.
+ * <p>
+ * This is a legacy bridge class, and should not be used outside of the Eclipse
+ * SDK. Please use menu contributions to display a command in a menu or toolbar.
+ * </p>
+ * <p>
+ * <b>Note:</b> Clients may instantiate.
+ * </p>
+ *
+ * @since 3.3
+ */
+public final class ContributedAction extends CommandAction {
+ private IEvaluationContext appContext;
+
+ private IHandler partHandler;
+
+ private boolean localHandler = false;
+
+ private IPartListener partListener;
+
+ /**
+ * Create an action that can call a command.
+ *
+ * @param locator
+ * The appropriate service locator to use. If you use a part site
+ * as your locator, this action will be tied to your part.
+ * @param element
+ * the contributed action element
+ */
+ public ContributedAction(IServiceLocator locator,
+ IConfigurationElement element) throws CommandNotMappedException {
+
+ String actionId = element
+ .getAttribute(IWorkbenchRegistryConstants.ATT_ID);
+ String commandId = element
+ .getAttribute(IWorkbenchRegistryConstants.ATT_DEFINITION_ID);
+
+ // TODO throw some more exceptions here :-)
+
+ String contributionId = null;
+ if (commandId == null) {
+
+ Object obj = element.getParent();
+ if (obj instanceof IConfigurationElement) {
+ contributionId = ((IConfigurationElement) obj)
+ .getAttribute(IWorkbenchRegistryConstants.ATT_ID);
+ if (contributionId == null) {
+ throw new CommandNotMappedException("Action " //$NON-NLS-1$
+ + actionId + " configuration element invalid"); //$NON-NLS-1$
+ }
+ }
+ // legacy bridge part
+ IActionCommandMappingService mapping = (IActionCommandMappingService) locator
+ .getService(IActionCommandMappingService.class);
+ if (mapping == null) {
+ throw new CommandNotMappedException(
+ "No action mapping service available"); //$NON-NLS-1$
+ }
+
+ commandId = mapping.getCommandId(mapping.getGeneratedCommandId(
+ contributionId, actionId));
+ }
+ // what, still no command?
+ if (commandId == null) {
+ throw new CommandNotMappedException("Action " + actionId //$NON-NLS-1$
+ + " in contribution " + contributionId //$NON-NLS-1$
+ + " not mapped to a command"); //$NON-NLS-1$
+ }
+
+ init(locator, commandId, null);
+
+ if (locator instanceof IWorkbenchPartSite) {
+ updateSiteAssociations((IWorkbenchPartSite) locator, commandId,
+ actionId, element);
+ }
+
+ setId(actionId);
+ }
+
+ private void updateSiteAssociations(IWorkbenchPartSite site,
+ String commandId, String actionId, IConfigurationElement element) {
+ IWorkbenchLocationService wls = (IWorkbenchLocationService) site
+ .getService(IWorkbenchLocationService.class);
+ IWorkbench workbench = wls.getWorkbench();
+ IWorkbenchWindow window = wls.getWorkbenchWindow();
+ IHandlerService serv = (IHandlerService) workbench
+ .getService(IHandlerService.class);
+ appContext = new EvaluationContext(serv.getCurrentState(),
+ Collections.EMPTY_LIST);
+
+ // set up the appContext as we would want it.
+ appContext.addVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME,
+ StructuredSelection.EMPTY);
+ appContext.addVariable(ISources.ACTIVE_PART_NAME, site.getPart());
+ appContext.addVariable(ISources.ACTIVE_PART_ID_NAME, site.getId());
+ appContext.addVariable(ISources.ACTIVE_SITE_NAME, site);
+ if (site instanceof IEditorSite) {
+ appContext.addVariable(ISources.ACTIVE_EDITOR_NAME, site.getPart());
+ appContext
+ .addVariable(ISources.ACTIVE_EDITOR_ID_NAME, site.getId());
+ }
+ appContext.addVariable(ISources.ACTIVE_WORKBENCH_WINDOW_NAME, window);
+ appContext.addVariable(ISources.ACTIVE_WORKBENCH_WINDOW_SHELL_NAME,
+ window.getShell());
+
+ // E4MOD --- modified for E4 due to the downcast to HandlerService:
+ if (serv instanceof HandlerService) {
+ // 3.x processing: notice downcast to HandlerService
+ HandlerService realService = (HandlerService) serv;
+ partHandler = realService.findHandler(commandId, appContext);
+ } else if (site instanceof PartSite) { // E4 processing
+ IEclipseContext context = ((PartSite) site).getContext();
+ Object handler = context.get(commandId, new Object[] { "handler" }); //$NON-NLS-1$
+ if (handler instanceof IHandler)
+ partHandler = (IHandler) handler;
+ else if (handler instanceof LegacyHandlerService.HandlerProxy)
+ partHandler = ((LegacyHandlerService.HandlerProxy) handler)
+ .getHandler();
+ }
+ // E4MOD --- end of modified part
+ if (partHandler == null) {
+ localHandler = true;
+ // if we can't find the handler, then at least we can
+ // call the action delegate run method
+ partHandler = new ActionDelegateHandlerProxy(element,
+ IWorkbenchRegistryConstants.ATT_CLASS, actionId,
+ getParameterizedCommand(), site.getWorkbenchWindow(), null,
+ null, null);
+ }
+ if (site instanceof MultiPageEditorSite) {
+ IHandlerService siteServ = (IHandlerService) site
+ .getService(IHandlerService.class);
+ siteServ.activateHandler(commandId, partHandler);
+ }
+
+ if (getParameterizedCommand() != null) {
+ getParameterizedCommand().getCommand().removeCommandListener(
+ getCommandListener());
+ }
+ site.getPage().addPartListener(getPartListener());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.internal.actions.CommandAction#runWithEvent(org.eclipse
+ * .swt.widgets.Event)
+ */
+ public void runWithEvent(Event event) {
+ if (partHandler != null && getParameterizedCommand() != null) {
+ IHandler oldHandler = getParameterizedCommand().getCommand()
+ .getHandler();
+ try {
+ getParameterizedCommand().getCommand().setHandler(partHandler);
+ getParameterizedCommand().executeWithChecks(event, appContext);
+ } catch (ExecutionException e) {
+ // TODO some logging, perhaps?
+ } catch (NotDefinedException e) {
+ // TODO some logging, perhaps?
+ } catch (NotEnabledException e) {
+ // TODO some logging, perhaps?
+ } catch (NotHandledException e) {
+ // TODO some logging, perhaps?
+ } finally {
+ getParameterizedCommand().getCommand().setHandler(oldHandler);
+ }
+ } else {
+ super.runWithEvent(event);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.action.Action#isEnabled()
+ */
+ public boolean isEnabled() {
+ if (partHandler != null) {
+ if (partHandler instanceof IHandler2) {
+ ((IHandler2) partHandler).setEnabled(appContext);
+ }
+ return partHandler.isEnabled();
+ }
+ return false;
+ }
+
+ private IPartListener getPartListener() {
+ if (partListener == null) {
+ final IWorkbenchPartSite site = (IWorkbenchPartSite) appContext
+ .getVariable(ISources.ACTIVE_SITE_NAME);
+
+ final IWorkbenchPart currentPart;
+ if (site instanceof MultiPageEditorSite) {
+ currentPart = ((MultiPageEditorSite) site).getMultiPageEditor();
+ } else {
+ currentPart = site.getPart();
+ }
+
+ partListener = new IPartListener() {
+ public void partActivated(IWorkbenchPart part) {
+ }
+
+ public void partBroughtToTop(IWorkbenchPart part) {
+ }
+
+ public void partClosed(IWorkbenchPart part) {
+ if (part == currentPart) {
+ ContributedAction.this.disposeAction();
+ }
+ }
+
+ public void partDeactivated(IWorkbenchPart part) {
+ }
+
+ public void partOpened(IWorkbenchPart part) {
+ }
+ };
+ }
+ return partListener;
+ }
+
+ // TODO make public in 3.4
+ private void disposeAction() {
+ if (appContext != null) {
+ if (localHandler) {
+ partHandler.dispose();
+ }
+ if (partListener != null) {
+ IWorkbenchPartSite site = (IWorkbenchPartSite) appContext
+ .getVariable(ISources.ACTIVE_SITE_NAME);
+ site.getPage().removePartListener(partListener);
+ partListener = null;
+ }
+ appContext = null;
+ partHandler = null;
+ }
+ dispose();
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/EditorSite.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/EditorSite.java
new file mode 100644
index 0000000..79a10dd
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/EditorSite.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.ui.internal;
+
+import java.util.ArrayList;
+
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.ui.IActionBars2;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.SubActionBars;
+import org.eclipse.ui.SubActionBars2;
+import org.eclipse.ui.dnd.IDragAndDropService;
+
+/**
+ * An editor container manages the services for an editor.
+ */
+public class EditorSite extends PartSite implements IEditorSite {
+ /* package */// static final int PROP_REUSE_EDITOR = -0x101;
+
+ // private ListenerList propChangeListeners = new ListenerList(1);
+
+ private SubActionBars ab = null;
+
+ /**
+ * Constructs an EditorSite for an editor.
+ */
+ public EditorSite(IEditorReference ref, IEditorPart editor,
+ WorkbenchPage page) {
+ super(ref, editor, page);
+
+ // Initialize the services specific to this editor site.
+ initializeDefaultServices();
+ }
+
+ /**
+ * Initialize the local services.
+ */
+ private void initializeDefaultServices() {
+ // Register an implementation of the service appropriate for the
+ // EditorSite.
+ final IDragAndDropService editorDTService = new EditorSiteDragAndDropServiceImpl();
+ serviceLocator.registerService(IDragAndDropService.class,
+ editorDTService);
+ }
+
+ public void setActionBars(SubActionBars bars) {
+ super.setActionBars(bars);
+
+ if (bars instanceof IActionBars2) {
+ ab = new SubActionBars2((IActionBars2) bars, this);
+ } else {
+ ab = new SubActionBars(bars, this);
+ }
+ }
+
+ public void activateActionBars(boolean forceVisibility) {
+ if (ab != null) {
+ ab.activate(forceVisibility);
+ }
+ super.activateActionBars(forceVisibility);
+ }
+
+ public void deactivateActionBars(boolean forceHide) {
+ if (ab != null) {
+ ab.deactivate(forceHide);
+ }
+ super.deactivateActionBars(forceHide);
+ }
+
+ /**
+ * Returns the editor action bar contributor for this editor.
+ * <p>
+ * An action contributor is responsable for the creation of actions. By
+ * design, this contributor is used for one or more editors of the same
+ * type. Thus, the contributor returned by this method is not owned
+ * completely by the editor. It is shared.
+ * </p>
+ *
+ * @return the editor action bar contributor
+ */
+ public IEditorActionBarContributor getActionBarContributor() {
+ EditorActionBars bars = (EditorActionBars) getActionBars();
+ if (bars != null) {
+ return bars.getEditorContributor();
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the extension editor action bar contributor for this editor.
+ */
+ public IEditorActionBarContributor getExtensionActionBarContributor() {
+ EditorActionBars bars = (EditorActionBars) getActionBars();
+ if (bars != null) {
+ return bars.getExtensionContributor();
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the editor
+ */
+ public IEditorPart getEditorPart() {
+ return (IEditorPart) getPart();
+ }
+
+ protected String getInitialScopeId() {
+ return "org.eclipse.ui.textEditorScope"; //$NON-NLS-1$
+ }
+
+ public void dispose() {
+ super.dispose();
+
+ if (ab != null) {
+ ab.dispose();
+ }
+ }
+
+ public final void registerContextMenu(final MenuManager menuManager,
+ final ISelectionProvider selectionProvider,
+ final boolean includeEditorInput) {
+ registerContextMenu(getId(), menuManager, selectionProvider,
+ includeEditorInput);
+ }
+
+ public final void registerContextMenu(final String menuId,
+ final MenuManager menuManager,
+ final ISelectionProvider selectionProvider,
+ final boolean includeEditorInput) {
+ if (menuExtenders == null) {
+ menuExtenders = new ArrayList(1);
+ }
+
+ PartSite.registerContextMenu(menuId, menuManager, selectionProvider,
+ includeEditorInput, getPart(), menuExtenders);
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ModelExtensionProcessor.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ModelExtensionProcessor.java
new file mode 100644
index 0000000..52bfc33
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ModelExtensionProcessor.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * 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.ui.internal;
+
+import java.util.ArrayList;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IContributor;
+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.services.Logger;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.ui.model.application.MElementContainer;
+import org.eclipse.e4.ui.model.application.MUIElement;
+import org.eclipse.e4.ui.model.application.MWindow;
+import org.eclipse.e4.workbench.ui.api.ModeledPageLayout;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+
+// TBD this should be incorporated into both E4 and legacy processing
+
+/**
+ * Process extensions to E4 model contributed via extensions.
+ */
+public class ModelExtensionProcessor {
+
+ final private static String extensionPointID = "org.eclipse.e4.workbench.model"; //$NON-NLS-1$
+
+ /**
+ * Preferred default parent ID, if none specified
+ */
+ final private static String preferredID1 = "Horizontal Sash[right]"; //$NON-NLS-1$
+
+ /**
+ * Alternative preferred default parent ID, if none specified
+ */
+ final private static String preferredID2 = "bottom"; //$NON-NLS-1$
+
+ /**
+ * Model extensions as described by the extension registry
+ */
+ private class ModelExtension {
+ private String uri;
+ private String parentID;
+ private IContributor contributor;
+
+ public ModelExtension(String uri, String parentID,
+ IContributor contributor) {
+ super();
+ this.uri = uri;
+ this.parentID = parentID;
+ this.contributor = contributor;
+ }
+
+ public URI getURI() {
+ if (uri == null)
+ return null;
+ String bundleName = contributor.getName();
+ String path = bundleName + '/' + uri;
+ try {
+ return URI.createPlatformPluginURI(path, false);
+ } catch (RuntimeException e) {
+ log("Model extension has invalid location", e); //$NON-NLS-1$
+ return null;
+ }
+ }
+
+ public String getParentID() {
+ return parentID;
+ }
+
+ }
+
+ private MWindow e4Window;
+
+ /**
+ * Constructs processor for the model extensions on the MWindow
+ *
+ * @param e4Window
+ */
+ public ModelExtensionProcessor(MWindow e4Window) {
+ this.e4Window = e4Window;
+ }
+
+ /**
+ * Add extensions to the specified window.
+ */
+ public void addModelExtensions() {
+ ModelExtension[] extensions = readExtensionRegistry();
+ for (ModelExtension extension : extensions) {
+ URI uri = extension.getURI();
+ if (uri == null) {
+ log("Unable to find location for the model extension \"{0}\"", //$NON-NLS-1$
+ extension.contributor.getName());
+ continue;
+ }
+ Resource resource;
+ try {
+ resource = new ResourceSetImpl().getResource(uri, true);
+ } catch (RuntimeException e) {
+ log("Unable to read model extension", e); //$NON-NLS-1$
+ continue;
+ }
+ EList contents = resource.getContents();
+ if (contents.isEmpty())
+ continue;
+ Object extensionRoot = contents.get(0);
+ if (!(extensionRoot instanceof MUIElement)) {
+ log("Unable to create model extension \"{0}\"", //$NON-NLS-1$
+ extension.contributor.getName());
+ continue;
+ }
+
+ MUIElement root = (MUIElement) extensionRoot;
+ MElementContainer<MUIElement> parentElement = null;
+ if (root instanceof MWindow)
+ parentElement = (MElementContainer<MUIElement>) ((MUIElement) e4Window);
+ else
+ parentElement = findDefaultParent(extension.getParentID());
+ if (parentElement != null)
+ parentElement.getChildren().add(root);
+ }
+ }
+
+ private MElementContainer<MUIElement> findDefaultParent(String parentID) {
+ MUIElement defaultElement = null;
+ // Try the specified ID
+ if (parentID != null) {
+ defaultElement = ModeledPageLayout.findElementById(e4Window,
+ parentID);
+ if (defaultElement != null)
+ return (MElementContainer<MUIElement>) defaultElement;
+ }
+
+ // Try first preferred ID
+ defaultElement = ModeledPageLayout.findElementById(e4Window,
+ preferredID1);
+ if (defaultElement != null)
+ return (MElementContainer<MUIElement>) defaultElement;
+
+ // Try second preferred ID - parent of "bottom"
+ defaultElement = ModeledPageLayout.findPart(e4Window, preferredID2);
+ if (defaultElement != null)
+ return defaultElement.getParent();
+
+ return null;
+ }
+
+ private ModelExtension[] readExtensionRegistry() {
+ IExtensionRegistry registry = RegistryFactory.getRegistry();
+ IExtensionPoint extPoint = registry.getExtensionPoint(extensionPointID);
+ IExtension[] extensions = extPoint.getExtensions();
+ ArrayList<ModelExtension> result = new ArrayList();
+ for (IExtension extension : extensions) {
+ IConfigurationElement[] ces = extension.getConfigurationElements();
+ for (IConfigurationElement ce : ces) {
+ if (!"model".equals(ce.getName())) //$NON-NLS-1$
+ continue;
+ String attrURI = ce.getAttribute("location"); //$NON-NLS-1$
+ String attrParent = ce.getAttribute("parentID"); //$NON-NLS-1$
+ IContributor contributor = ce.getContributor();
+ ModelExtension modelExt = new ModelExtension(attrURI,
+ attrParent, contributor);
+ result.add(modelExt);
+ }
+ }
+ ModelExtension[] typedResult = new ModelExtension[result.size()];
+ result.toArray(typedResult);
+ return typedResult;
+ }
+
+ private void log(String msg, Exception e) {
+ IEclipseContext context = e4Window.getContext();
+ Logger logger = (Logger) context.get(Logger.class.getName());
+ if (logger == null)
+ e.printStackTrace();
+ else
+ logger.error(e, msg);
+ }
+
+ private void log(String msg, String arg) {
+ IEclipseContext context = e4Window.getContext();
+ Logger logger = (Logger) context.get(Logger.class.getName());
+ if (logger == null)
+ System.err.println(msg);
+ else
+ logger.error(msg, arg);
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartService.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartService.java
new file mode 100644
index 0000000..138177a
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartService.java
@@ -0,0 +1,304 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2008 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.ui.internal;
+
+import java.util.ArrayList;
+import org.eclipse.jface.dialogs.PageChangedEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IPartListener2;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.internal.misc.UIListenerLogging;
+
+public class PartService implements IPartService {
+ private static Point ZERO = new Point(0, 0);
+
+ private PartListenerList listeners = new PartListenerList();
+
+ private PartListenerList2 listeners2 = new PartListenerList2();
+ private IWorkbenchPartReference activePart = null;
+
+ private String debugListenersKey;
+ private String debugListeners2Key;
+
+ private ArrayList activeControlJobs = new ArrayList();
+
+ public PartService(String debugListenersKey, String debugListeners2Key) {
+ this.debugListeners2Key = debugListeners2Key;
+ this.debugListenersKey = debugListenersKey;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IPartService
+ */
+ public void addPartListener(IPartListener l) {
+ listeners.addPartListener(l);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IPartService
+ */
+ public void addPartListener(IPartListener2 l) {
+ listeners2.addPartListener(l);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IPartService
+ */
+ public void removePartListener(IPartListener l) {
+ listeners.removePartListener(l);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IPartService
+ */
+ public void removePartListener(IPartListener2 l) {
+ listeners2.removePartListener(l);
+ }
+
+ private abstract class PartJob {
+ IWorkbenchPartReference ref;
+ Control control;
+
+ public PartJob(IWorkbenchPartReference ref, Control c) {
+ this.ref = ref;
+ this.control = c;
+ }
+
+ abstract void fire();
+ }
+
+ private class PartListener implements Listener {
+ public void handleEvent(Event event) {
+ processPartJobs();
+ }
+ }
+
+ private PartListener partListener = new PartListener();
+
+ private class PartActivated extends PartJob {
+ public PartActivated(IWorkbenchPartReference ref, Control c) {
+ super(ref, c);
+ }
+
+ void fire() {
+ firePartActivated(ref);
+ }
+ }
+
+ private class PartVisible extends PartJob {
+ public PartVisible(IWorkbenchPartReference ref, Control c) {
+ super(ref, c);
+ }
+
+ void fire() {
+ firePartVisible(ref);
+ }
+ }
+
+ private class PartTop extends PartJob {
+ public PartTop(IWorkbenchPartReference ref, Control c) {
+ super(ref, c);
+ }
+
+ void fire() {
+ firePartBroughtToTop(ref);
+ }
+ }
+
+ private Control deferControl(IWorkbenchPartReference ref) {
+ return null;
+ }
+
+ private void addControlListener(Control control, PartJob listener) {
+ control.addListener(SWT.Resize, partListener);
+ control.addListener(SWT.Activate, partListener);
+ control.addListener(SWT.Dispose, partListener);
+ activeControlJobs.add(listener);
+ }
+
+ void processPartJobs() {
+ if (activeControlJobs.isEmpty()) {
+ return;
+ }
+
+ ArrayList toRemove = new ArrayList();
+ PartJob[] jobs = (PartJob[]) activeControlJobs
+ .toArray(new PartJob[activeControlJobs.size()]);
+ for (int i = 0; i < jobs.length; i++) {
+ PartJob job = jobs[i];
+ Control control = job.control;
+ if (!control.isDisposed() && !control.getSize().equals(ZERO)
+ && control.isVisible()) {
+ toRemove.add(job);
+ control.removeListener(SWT.Resize, partListener);
+ control.removeListener(SWT.Activate, partListener);
+ control.removeListener(SWT.Dispose, partListener);
+ job.fire();
+ } else if (control.isDisposed()) {
+ toRemove.add(job);
+ }
+ }
+
+ if (toRemove.isEmpty()) {
+ return;
+ }
+
+ activeControlJobs.removeAll(toRemove);
+ }
+
+ /**
+ * @param ref
+ */
+ private void firePartActivated(IWorkbenchPartReference ref) {
+ IWorkbenchPart part = ref.getPart(false);
+ if (part != null) {
+ Control control = deferControl(ref);
+ if (control != null) {
+ addControlListener(control, new PartActivated(ref, control));
+ return;
+ }
+ UIListenerLogging.logPartListenerEvent(debugListenersKey, this,
+ part, UIListenerLogging.PE_ACTIVATED);
+ listeners.firePartActivated(part);
+ }
+
+ UIListenerLogging.logPartListener2Event(debugListeners2Key, this, ref,
+ UIListenerLogging.PE2_ACTIVATED);
+ listeners2.firePartActivated(ref);
+ }
+
+ /**
+ * @param ref
+ */
+ public void firePartBroughtToTop(IWorkbenchPartReference ref) {
+ IWorkbenchPart part = ref.getPart(false);
+ if (part != null) {
+ Control control = deferControl(ref);
+ if (control != null) {
+ addControlListener(control, new PartTop(ref, control));
+ return;
+ }
+ UIListenerLogging.logPartListenerEvent(debugListenersKey, this,
+ part, UIListenerLogging.PE_PART_BROUGHT_TO_TOP);
+ listeners.firePartBroughtToTop(part);
+ }
+ UIListenerLogging.logPartListener2Event(debugListeners2Key, this, ref,
+ UIListenerLogging.PE2_PART_BROUGHT_TO_TOP);
+ listeners2.firePartBroughtToTop(ref);
+ }
+
+ /**
+ * @param ref
+ */
+ public void firePartClosed(IWorkbenchPartReference ref) {
+ IWorkbenchPart part = ref.getPart(false);
+ if (part != null) {
+ UIListenerLogging.logPartListenerEvent(debugListenersKey, this,
+ part, UIListenerLogging.PE_PART_CLOSED);
+ listeners.firePartClosed(part);
+ }
+ UIListenerLogging.logPartListener2Event(debugListeners2Key, this, ref,
+ UIListenerLogging.PE2_PART_CLOSED);
+ listeners2.firePartClosed(ref);
+ }
+
+ /**
+ * @param ref
+ */
+ private void firePartDeactivated(IWorkbenchPartReference ref) {
+ IWorkbenchPart part = ref.getPart(false);
+ if (part != null) {
+ UIListenerLogging.logPartListenerEvent(debugListenersKey, this,
+ part, UIListenerLogging.PE_PART_DEACTIVATED);
+ listeners.firePartDeactivated(part);
+ }
+ UIListenerLogging.logPartListener2Event(debugListeners2Key, this, ref,
+ UIListenerLogging.PE2_PART_DEACTIVATED);
+ listeners2.firePartDeactivated(ref);
+ }
+
+ public void firePartVisible(IWorkbenchPartReference ref) {
+ Control control = deferControl(ref);
+ if (control != null) {
+ addControlListener(control, new PartVisible(ref, control));
+ return;
+ }
+ UIListenerLogging.logPartListener2Event(debugListeners2Key, this, ref,
+ UIListenerLogging.PE2_PART_VISIBLE);
+ listeners2.firePartVisible(ref);
+ }
+
+ public void firePartHidden(IWorkbenchPartReference ref) {
+ UIListenerLogging.logPartListener2Event(debugListeners2Key, this, ref,
+ UIListenerLogging.PE2_PART_HIDDEN);
+ listeners2.firePartHidden(ref);
+ }
+
+ public void firePartInputChanged(IWorkbenchPartReference ref) {
+ UIListenerLogging.logPartListener2Event(debugListeners2Key, this, ref,
+ UIListenerLogging.PE2_PART_INPUT_CHANGED);
+ listeners2.firePartInputChanged(ref);
+ }
+
+ /**
+ * @param ref
+ */
+ public void firePartOpened(IWorkbenchPartReference ref) {
+ IWorkbenchPart part = ref.getPart(false);
+ if (part != null) {
+ UIListenerLogging.logPartListenerEvent(debugListenersKey, this,
+ part, UIListenerLogging.PE_PART_OPENED);
+ listeners.firePartOpened(part);
+ }
+ UIListenerLogging.logPartListener2Event(debugListeners2Key, this, ref,
+ UIListenerLogging.PE2_PART_OPENED);
+ listeners2.firePartOpened(ref);
+ }
+
+ public IWorkbenchPart getActivePart() {
+ return activePart == null ? null : activePart.getPart(false);
+ }
+
+ public IWorkbenchPartReference getActivePartReference() {
+ return activePart;
+ }
+
+ public void setActivePart(IWorkbenchPartReference ref) {
+ IWorkbenchPartReference oldRef = activePart;
+
+ // Filter out redundant activation events
+ if (oldRef == ref) {
+ return;
+ }
+
+ if (oldRef != null && oldRef.getPart(false) != null) {
+ firePartDeactivated(oldRef);
+ }
+
+ activePart = ref;
+
+ if (ref != null) {
+ firePartActivated(ref);
+ }
+ }
+
+ public void firePageChanged(PageChangedEvent event) {
+ listeners2.firePageChanged(event);
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartSite.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartSite.java
new file mode 100644
index 0000000..92587cf
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartSite.java
@@ -0,0 +1,557 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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
+ * Dan Rubel (dan_rubel@instantiations.com) - accessor to get context menu ids
+ *******************************************************************************/
+package org.eclipse.ui.internal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.ContextFunction;
+import org.eclipse.e4.extensions.ModelReference;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IKeyBindingService;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.LegacyHandlerService;
+import org.eclipse.ui.SubActionBars;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.internal.progress.WorkbenchSiteProgressService;
+import org.eclipse.ui.internal.services.IServiceLocatorCreator;
+import org.eclipse.ui.internal.services.IWorkbenchLocationService;
+import org.eclipse.ui.internal.services.ServiceLocator;
+import org.eclipse.ui.internal.services.WorkbenchLocationService;
+import org.eclipse.ui.internal.testing.WorkbenchPartTestable;
+import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.services.IServiceScopes;
+import org.eclipse.ui.testing.IWorkbenchPartTestable;
+
+/**
+ * <code>PartSite</code> is the general implementation for an
+ * <code>IWorkbenchPartSite</code>. A site maintains the context for a part,
+ * including the part, its pane, active contributions, selection provider, etc.
+ * Together, these components make up the complete behavior for a part as if it
+ * was implemented by one person.
+ *
+ * The <code>PartSite</code> lifecycle is as follows ..
+ *
+ * <ol>
+ * <li>a site is constructed</li>
+ * <li>a part is constructed and stored in the part</li>
+ * <li>the site calls part.init()</li>
+ * <li>a pane is constructed and stored in the site</li>
+ * <li>the action bars for a part are constructed and stored in the site</li>
+ * <li>the pane is added to a presentation</li>
+ * <li>the SWT widgets for the pane and part are created</li>
+ * <li>the site is activated, causing the actions to become visible</li>
+ * </ol>
+ */
+public abstract class PartSite implements IWorkbenchPartSite {
+
+ /**
+ * This is a helper method for the register context menu functionality. It
+ * is provided so that different implementations of the
+ * <code>IWorkbenchPartSite</code> interface don't have to worry about how
+ * context menus should work.
+ *
+ * @param menuId
+ * the menu id
+ * @param menuManager
+ * the menu manager
+ * @param selectionProvider
+ * the selection provider
+ * @param includeEditorInput
+ * whether editor inputs should be included in the structured
+ * selection when calculating contributions
+ * @param part
+ * the part for this site
+ * @param menuExtenders
+ * the collection of menu extenders for this site
+ * @see IWorkbenchPartSite#registerContextMenu(MenuManager,
+ * ISelectionProvider)
+ */
+ public static final void registerContextMenu(final String menuId,
+ final MenuManager menuManager,
+ final ISelectionProvider selectionProvider,
+ final boolean includeEditorInput, final IWorkbenchPart part,
+ final Collection menuExtenders) {
+ /*
+ * Check to see if the same menu manager and selection provider have
+ * already been used. If they have, then we can just add another menu
+ * identifier to the existing PopupMenuExtender.
+ */
+ final Iterator extenderItr = menuExtenders.iterator();
+ boolean foundMatch = false;
+ while (extenderItr.hasNext()) {
+ final PopupMenuExtender existingExtender = (PopupMenuExtender) extenderItr
+ .next();
+ if (existingExtender.matches(menuManager, selectionProvider, part)) {
+ existingExtender.addMenuId(menuId);
+ foundMatch = true;
+ break;
+ }
+ }
+
+ if (!foundMatch) {
+ menuExtenders.add(new PopupMenuExtender(menuId, menuManager,
+ selectionProvider, part, includeEditorInput));
+ }
+ }
+
+ private IWorkbenchPartReference partReference;
+
+ private IWorkbenchPart part;
+
+ private IWorkbenchPage page;
+
+ private String extensionID;
+
+ private String pluginID;
+
+ private String extensionName;
+
+ private SubActionBars actionBars;
+
+ private KeyBindingService keyBindingService;
+
+ protected ArrayList menuExtenders;
+
+ private WorkbenchSiteProgressService progressService;
+
+ protected final ServiceLocator serviceLocator;
+
+ final protected IEclipseContext e4Context;
+
+ /**
+ * Build the part site.
+ *
+ * @param ref
+ * the part reference
+ * @param part
+ * the part
+ * @param page
+ * the page it belongs to
+ */
+ public PartSite(IWorkbenchPartReference ref, IWorkbenchPart part,
+ IWorkbenchPage page) {
+ this.partReference = ref;
+ this.part = part;
+ this.page = page;
+ extensionID = "org.eclipse.ui.UnknownID"; //$NON-NLS-1$
+ extensionName = "Unknown Name"; //$NON-NLS-1$
+
+ // Initialize the service locator.
+ final WorkbenchWindow workbenchWindow = (WorkbenchWindow) page
+ .getWorkbenchWindow();
+ IServiceLocatorCreator slc = (IServiceLocatorCreator) workbenchWindow
+ .getService(IServiceLocatorCreator.class);
+ this.serviceLocator = (ServiceLocator) slc.createServiceLocator(
+ workbenchWindow, null, new IDisposable() {
+ public void dispose() {
+ final Control control = getPane().getControl();
+ if (control != null && !control.isDisposed()) {
+ getPane().doHide();
+ }
+ }
+ });
+ e4Context = ((ModelReference) partReference).getModel().getContext();
+ this.serviceLocator.setContext(e4Context);
+
+ initializeDefaultServices();
+ }
+
+ /**
+ * Initialize the local services.
+ */
+ private void initializeDefaultServices() {
+ serviceLocator.registerService(IWorkbenchLocationService.class,
+ new WorkbenchLocationService(IServiceScopes.PARTSITE_SCOPE,
+ getWorkbenchWindow().getWorkbench(),
+ getWorkbenchWindow(), this, null, null, 2));
+
+ // local handler service for local handlers
+ IHandlerService handlerService = new LegacyHandlerService(e4Context);
+ serviceLocator.registerService(IHandlerService.class, handlerService);
+
+ // added back for legacy reasons
+ serviceLocator.registerService(IWorkbenchPartSite.class, this);
+ e4Context.set(IWorkbenchSiteProgressService.class.getName(),
+ new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context,
+ Object[] arguments) {
+ if (progressService == null) {
+ progressService = new WorkbenchSiteProgressService(
+ PartSite.this);
+ }
+ return progressService;
+ }
+ });
+ e4Context.set(IKeyBindingService.class.getName(),
+ new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context,
+ Object[] arguments) {
+ if (keyBindingService == null) {
+ keyBindingService = new KeyBindingService(
+ PartSite.this);
+ }
+
+ return keyBindingService;
+ }
+ });
+ }
+
+ /**
+ * Dispose the contributions.
+ */
+ public void dispose() {
+ if (menuExtenders != null) {
+ HashSet managers = new HashSet(menuExtenders.size());
+ for (int i = 0; i < menuExtenders.size(); i++) {
+ PopupMenuExtender ext = (PopupMenuExtender) menuExtenders
+ .get(i);
+ managers.add(ext.getManager());
+ ext.dispose();
+ }
+ if (managers.size() > 0) {
+ for (Iterator iterator = managers.iterator(); iterator
+ .hasNext();) {
+ MenuManager mgr = (MenuManager) iterator.next();
+ mgr.dispose();
+ }
+ }
+ menuExtenders = null;
+ }
+
+ if (keyBindingService != null) {
+ keyBindingService.dispose();
+ keyBindingService = null;
+ }
+
+ if (progressService != null) {
+ progressService.dispose();
+ progressService = null;
+ }
+
+ if (serviceLocator != null) {
+ serviceLocator.dispose();
+ }
+ part = null;
+ }
+
+ /**
+ * Returns the action bars for the part. If this part is a view then it has
+ * exclusive use of the action bars. If this part is an editor then the
+ * action bars are shared among this editor and other editors of the same
+ * type.
+ */
+ public IActionBars getActionBars() {
+ return actionBars;
+ }
+
+ /**
+ * Returns the part registry extension ID.
+ *
+ * @return the registry extension ID
+ */
+ public String getId() {
+ return extensionID;
+ }
+
+ /**
+ * Returns the page containing this workbench site's part.
+ *
+ * @return the page containing this part
+ */
+ public IWorkbenchPage getPage() {
+ return page;
+ }
+
+ /**
+ * Gets the part pane.
+ */
+ public PartPane getPane() {
+ return null;
+ }
+
+ /**
+ * Returns the part.
+ */
+ public IWorkbenchPart getPart() {
+ return part;
+ }
+
+ /**
+ * Returns the part reference.
+ */
+ public IWorkbenchPartReference getPartReference() {
+ return partReference;
+ }
+
+ /**
+ * Returns the part registry plugin ID. It cannot be <code>null</code>.
+ *
+ * @return the registry plugin ID
+ */
+ public String getPluginId() {
+ return pluginID;
+ }
+
+ /**
+ * Returns the registered name for this part.
+ */
+ public String getRegisteredName() {
+ return extensionName;
+ }
+
+ /**
+ * Returns the selection provider for a part.
+ */
+ public ISelectionProvider getSelectionProvider() {
+ return (ISelectionProvider) e4Context.get(ISelectionProvider.class
+ .getName());
+ }
+
+ /**
+ * Returns the shell containing this part.
+ *
+ * @return the shell containing this part
+ */
+ public Shell getShell() {
+ return page.getWorkbenchWindow().getShell();
+ }
+
+ /**
+ * Returns the workbench window containing this part.
+ *
+ * @return the workbench window containing this part
+ */
+ public IWorkbenchWindow getWorkbenchWindow() {
+ return page.getWorkbenchWindow();
+ }
+
+ /**
+ * Register a popup menu for extension.
+ */
+ public void registerContextMenu(String menuID, MenuManager menuMgr,
+ ISelectionProvider selProvider) {
+ if (menuExtenders == null) {
+ menuExtenders = new ArrayList(1);
+ }
+
+ registerContextMenu(menuID, menuMgr, selProvider, true, getPart(),
+ menuExtenders);
+ }
+
+ /**
+ * Register a popup menu with the default id for extension.
+ */
+ public void registerContextMenu(MenuManager menuMgr,
+ ISelectionProvider selProvider) {
+ registerContextMenu(getId(), menuMgr, selProvider);
+ }
+
+ // getContextMenuIds() added by Dan Rubel (dan_rubel@instantiations.com)
+ /**
+ * Get the registered popup menu identifiers
+ */
+ public String[] getContextMenuIds() {
+ if (menuExtenders == null) {
+ return new String[0];
+ }
+ ArrayList menuIds = new ArrayList(menuExtenders.size());
+ for (Iterator iter = menuExtenders.iterator(); iter.hasNext();) {
+ final PopupMenuExtender extender = (PopupMenuExtender) iter.next();
+ menuIds.addAll(extender.getMenuIds());
+ }
+ return (String[]) menuIds.toArray(new String[menuIds.size()]);
+ }
+
+ /**
+ * Sets the action bars for the part.
+ */
+ public void setActionBars(SubActionBars bars) {
+ e4Context.set(IActionBars.class.getName(), bars);
+ actionBars = bars;
+ }
+
+ /**
+ * Sets the configuration element for a part.
+ */
+ public void setConfigurationElement(IConfigurationElement configElement) {
+
+ // Get extension ID.
+ extensionID = configElement.getAttribute("id"); //$NON-NLS-1$
+
+ // Get plugin ID.
+ pluginID = configElement.getNamespace();
+
+ // Get extension name.
+ String name = configElement.getAttribute("name"); //$NON-NLS-1$
+ if (name != null) {
+ extensionName = name;
+ }
+ }
+
+ protected void setPluginId(String pluginId) {
+ this.pluginID = pluginId;
+ }
+
+ /**
+ * Sets the part registry extension ID.
+ *
+ * @param id
+ * the registry extension ID
+ */
+ protected void setId(String id) {
+ extensionID = id;
+ }
+
+ /**
+ * Sets the part.
+ */
+ public void setPart(IWorkbenchPart newPart) {
+ part = newPart;
+ }
+
+ /**
+ * Sets the registered name for this part.
+ *
+ * @param name
+ * the registered name
+ */
+ protected void setRegisteredName(String name) {
+ extensionName = name;
+ }
+
+ /**
+ * Set the selection provider for a part.
+ */
+ public void setSelectionProvider(ISelectionProvider provider) {
+ e4Context.set(ISelectionProvider.class.getName(), provider);
+ if (provider != null) {
+ provider
+ .addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ e4Context.modify(IServiceConstants.SELECTION, event
+ .getSelection());
+ }
+ });
+ }
+ }
+
+ /*
+ * @see IWorkbenchPartSite#getKeyBindingService()
+ */
+ public IKeyBindingService getKeyBindingService() {
+ return (IKeyBindingService) e4Context.get(IKeyBindingService.class
+ .getName());
+ }
+
+ protected String getInitialScopeId() {
+ return null;
+ }
+
+ /**
+ * Get an adapter for this type.
+ *
+ * @param adapter
+ * @return
+ */
+ public final Object getAdapter(Class adapter) {
+
+ if (IWorkbenchSiteProgressService.class == adapter) {
+ return getSiteProgressService();
+ }
+
+ if (IWorkbenchPartTestable.class == adapter) {
+ return new WorkbenchPartTestable(this);
+ }
+
+ return Platform.getAdapterManager().getAdapter(this, adapter);
+ }
+
+ public void activateActionBars(boolean forceVisibility) {
+ if (serviceLocator != null) {
+ serviceLocator.activate();
+ }
+
+ if (actionBars != null) {
+ actionBars.activate(forceVisibility);
+ }
+ }
+
+ public void deactivateActionBars(boolean forceHide) {
+ if (actionBars != null) {
+ actionBars.deactivate(forceHide);
+ }
+ if (serviceLocator != null) {
+ serviceLocator.deactivate();
+ }
+ }
+
+ /**
+ * Get a progress service for the receiver.
+ *
+ * @return WorkbenchSiteProgressService
+ */
+ WorkbenchSiteProgressService getSiteProgressService() {
+ return (WorkbenchSiteProgressService) e4Context
+ .get(IWorkbenchSiteProgressService.class.getName());
+ }
+
+ public final Object getService(final Class key) {
+ return serviceLocator.getService(key);
+ }
+
+ public final boolean hasService(final Class key) {
+ return serviceLocator.hasService(key);
+ }
+
+ /**
+ * Prints out the identifier, the plug-in identifier and the registered
+ * name. This is for debugging purposes only.
+ *
+ * @since 3.2
+ */
+ public String toString() {
+ final StringBuffer buffer = new StringBuffer();
+ buffer.append("PartSite(id="); //$NON-NLS-1$
+ buffer.append(getId());
+ buffer.append(",pluginId="); //$NON-NLS-1$
+ buffer.append(getPluginId());
+ buffer.append(",registeredName="); //$NON-NLS-1$
+ buffer.append(getRegisteredName());
+ buffer.append(",hashCode="); //$NON-NLS-1$
+ buffer.append(hashCode());
+ buffer.append(')');
+ return buffer.toString();
+ }
+
+ public IEclipseContext getContext() {
+ return e4Context;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartsEventTransformer.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartsEventTransformer.java
new file mode 100644
index 0000000..e16dfe5
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartsEventTransformer.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * 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.ui.internal;
+
+import org.eclipse.e4.ui.model.application.MApplicationPackage;
+import org.eclipse.e4.ui.model.application.MEditorStack;
+import org.eclipse.e4.ui.model.application.MElementContainer;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MPerspective;
+import org.eclipse.e4.ui.model.application.MViewStack;
+
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.util.EContentAdapter;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.ISaveablesLifecycleListener;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.SubActionBars;
+
+/**
+ * Transforms E4 MPart events into 3.x legacy events.
+ */
+public class PartsEventTransformer extends EContentAdapter {
+
+ final private IEclipseContext e4Context;
+ final private WorkbenchPagePartList partList;
+
+ /**
+ * Constructor.
+ *
+ * @param e4Context
+ * @param partList
+ */
+ public PartsEventTransformer(IEclipseContext e4Context,
+ WorkbenchPagePartList partList) {
+ this.e4Context = e4Context;
+ this.partList = partList;
+ }
+
+ public void notifyChanged(Notification notification) {
+ super.notifyChanged(notification);
+
+ /*
+ * We create partOpened / partClosed events based on both MPartWidget
+ * events.
+ *
+ * The initial MPartVisible events are sent early and don't have the
+ * actual implementation included. The MPartWidget events are sent as a
+ * final step of "part is created" and therefore we use it to create
+ * partOpened events. When the part is closed the widget is set to null.
+ */
+ if (MApplicationPackage.Literals.UI_ELEMENT__WIDGET.equals(notification
+ .getFeature())) {
+ if (notification.getEventType() != Notification.SET)
+ return;
+ if (notification.getOldValue() == notification.getNewValue())
+ return; // avoid extra notifications
+ Object part = notification.getNotifier();
+ if (part instanceof MPart) {
+ IWorkbenchPartReference ref = toPartRef((MPart) part);
+ if (ref != null) {
+ boolean isVisible = ((MPart) part).isVisible();
+ if (isVisible) {
+ if (notification.getNewValue() == null) {
+ /*
+ * not sure if this is the right place to fix bug
+ * 283922 but if there is no widget and
+ * isVisible==true, we must be shutting down, and we
+ * should not send partOpened notifications.
+ */
+ return;
+ }
+ SaveablesList modelManager = (SaveablesList) ref
+ .getPart(true).getSite().getService(
+ ISaveablesLifecycleListener.class);
+ modelManager.postOpen(ref.getPart(true));
+ partList.firePartOpened(ref);
+ }
+ }
+ }
+ return;
+ }
+
+ // Interpret E4 activation events:
+ if (!MApplicationPackage.Literals.ELEMENT_CONTAINER__ACTIVE_CHILD
+ .equals(notification.getFeature()))
+ return;
+
+ // at this time we only interpreting SET events
+ if (notification.getEventType() != Notification.SET
+ || notification.getEventType() != Notification.CREATE)
+ return;
+
+ // make sure something actually changed
+ Object oldPart = notification.getOldValue();
+ Object newPart = notification.getNewValue();
+
+ // create 3.x visibility events
+ if ((newPart != oldPart) && (oldPart instanceof MPart)
+ && (newPart instanceof MPart))
+ changeVisibility((MPart) oldPart, (MPart) newPart);
+
+ // create 3.x activation events
+ final Object object = e4Context.get(IServiceConstants.ACTIVE_PART);
+ if ((newPart != oldPart) && newPart instanceof MPerspective) {
+ // let legacy Workbench know about perspective activation
+ IWorkbenchPage page = (IWorkbenchPage) e4Context
+ .get(IWorkbenchPage.class.getName());
+ if (page != null) {
+ String id = ((MPerspective) newPart).getId();
+ IPerspectiveDescriptor[] descriptors = page
+ .getOpenPerspectives();
+ for (IPerspectiveDescriptor desc : descriptors) {
+ if (!id.equals(desc.getId()))
+ continue;
+ page.setPerspective(desc);
+ }
+ }
+ }
+ if (object instanceof MPart) {
+ IWorkbenchPartReference ref = toPartRef((MPart) object);
+ if (ref != null) {
+ // set the Focus to the newly active part
+ IWorkbenchPart part = ref.getPart(true);
+ part.setFocus();
+ // Update the action bars
+ SubActionBars bars = (SubActionBars) ((PartSite) part.getSite())
+ .getActionBars();
+ bars.partChanged(part);
+ partList.setActivePart(ref);
+ if (ref instanceof IEditorReference) {
+ IEditorReference editorReference = (IEditorReference) ref;
+ partList.setActiveEditor(editorReference);
+ final IEditorPart editor = editorReference.getEditor(true);
+ e4Context.set(ISources.ACTIVE_EDITOR_NAME, editor);
+ e4Context.set(ISources.ACTIVE_EDITOR_ID_NAME, editor
+ .getSite().getId());
+ e4Context.set(ISources.ACTIVE_EDITOR_INPUT_NAME, editor
+ .getEditorInput());
+ }
+ }
+ } else {
+ partList.setActiveEditor(null);
+ e4Context.set(ISources.ACTIVE_EDITOR_NAME, null);
+ e4Context.set(ISources.ACTIVE_EDITOR_ID_NAME, null);
+ e4Context.set(ISources.ACTIVE_EDITOR_INPUT_NAME, null);
+ partList.setActivePart(null);
+ }
+ }
+
+ // TBD default hidden/shown state
+ private void changeVisibility(MPart oldPart, MPart newPart) {
+ // TBD old parent vs new parent: should we apply the same logic to both?
+ // if parent was a stack: hide the previously active part
+ MElementContainer oldParent = oldPart.getParent();
+ if (oldParent instanceof MViewStack
+ || oldParent instanceof MEditorStack)
+ visiblityChange(oldPart, false);
+ // show new part
+ visiblityChange(newPart, true);
+ }
+
+ private void visiblityChange(MPart part, boolean visible) {
+ IWorkbenchPartReference partRef = toPartRef(part);
+ if (visible) {
+ // TBD do we need to make children/parents visible or will there be
+ // separate notifications?
+ if (partRef != null)
+ partList.firePartVisible(partRef); // make this part visible
+ } else {
+ if (partRef != null)
+ partList.firePartHidden(partRef); // hide this part
+ }
+ }
+
+ // TBD is this the best method?
+ // TBD this should be a general utility method somewhere in the fragment
+ private IWorkbenchPartReference toPartRef(MPart part) {
+ if (part == null)
+ return null;
+ Object impl = part.getObject();
+ if (!(impl instanceof IWorkbenchPart))
+ return null;
+ PartSite site = (PartSite) ((IWorkbenchPart) impl).getSite();
+ return site.getPartReference();
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/Perspective.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/Perspective.java
new file mode 100644
index 0000000..02e05f9
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/Perspective.java
@@ -0,0 +1,2611 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * Markus Alexander Kuppe, Versant GmbH - bug 215797
+ *******************************************************************************/
+
+package org.eclipse.ui.internal;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.e4.compatibility.LegacyView;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.extensions.ExtensionUtils;
+import org.eclipse.e4.extensions.ModelViewReference;
+import org.eclipse.e4.ui.model.application.MApplicationFactory;
+import org.eclipse.e4.ui.model.application.MElementContainer;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MPerspective;
+import org.eclipse.e4.ui.model.application.MPerspectiveStack;
+import org.eclipse.e4.ui.model.application.MUIElement;
+import org.eclipse.e4.ui.model.application.MView;
+import org.eclipse.e4.ui.model.application.MViewSashContainer;
+import org.eclipse.e4.ui.model.application.MViewStack;
+import org.eclipse.e4.ui.model.application.MWindow;
+import org.eclipse.e4.workbench.ui.api.ModeledPageLayout;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.Geometry;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.IPerspectiveFactory;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.IWorkbenchPreferenceConstants;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.XMLMemento;
+import org.eclipse.ui.contexts.IContextService;
+import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
+import org.eclipse.ui.internal.intro.IIntroConstants;
+import org.eclipse.ui.internal.layout.ITrimManager;
+import org.eclipse.ui.internal.layout.IWindowTrim;
+import org.eclipse.ui.internal.layout.TrimLayout;
+import org.eclipse.ui.internal.misc.StatusUtil;
+import org.eclipse.ui.internal.registry.ActionSetRegistry;
+import org.eclipse.ui.internal.registry.IActionSetDescriptor;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.internal.registry.PerspectiveDescriptor;
+import org.eclipse.ui.internal.registry.PerspectiveExtensionReader;
+import org.eclipse.ui.internal.registry.PerspectiveRegistry;
+import org.eclipse.ui.internal.util.PrefUtil;
+import org.eclipse.ui.presentations.AbstractPresentationFactory;
+import org.eclipse.ui.presentations.IStackPresentationSite;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.ui.views.IStickyViewDescriptor;
+import org.eclipse.ui.views.IViewDescriptor;
+import org.eclipse.ui.views.IViewRegistry;
+
+/**
+ * The ViewManager is a factory for workbench views.
+ */
+public class Perspective {
+ protected PerspectiveDescriptor descriptor;
+
+ protected WorkbenchPage page;
+
+ // Editor Area management
+ protected LayoutPart editorArea;
+ protected PartPlaceholder editorHolder;
+ protected boolean editorHidden = false;
+ protected boolean editorAreaRestoreOnUnzoom = false;
+ protected int editorAreaState = IStackPresentationSite.STATE_RESTORED;
+
+ private ViewFactory viewFactory;
+
+ protected ArrayList alwaysOnActionSets;
+
+ protected ArrayList alwaysOffActionSets;
+
+ protected ArrayList newWizardShortcuts;
+
+ protected ArrayList showViewShortcuts;
+
+ protected ArrayList perspectiveShortcuts;
+
+ /** IDs of menu items the user has chosen to hide */
+ protected Collection hideMenuIDs;
+
+ /** IDs of toolbar items the user has chosen to hide */
+ protected Collection hideToolBarIDs;
+
+ // private List fastViews;
+ protected FastViewManager fastViewManager = null;
+
+ private Map mapIDtoViewLayoutRec;
+
+ protected boolean fixed;
+
+ protected ArrayList showInPartIds;
+
+ protected HashMap showInTimes = new HashMap();
+
+ private IViewReference activeFastView;
+
+ protected IMemento memento;
+
+ protected PerspectiveHelper presentation;
+
+ final static private String VERSION_STRING = "0.016";//$NON-NLS-1$
+
+ private FastViewPane fastViewPane = new FastViewPane();
+
+ // fields used by fast view resizing via a sash
+ private static final int FASTVIEW_HIDE_STEPS = 5;
+
+ /**
+ * Reference to the part that was previously active when this perspective
+ * was deactivated.
+ */
+ private IWorkbenchPartReference oldPartRef = null;
+
+ protected boolean shouldHideEditorsOnActivate = false;
+
+ protected ModeledPageLayout layout;
+
+ /**
+ * ViewManager constructor comment.
+ */
+ public Perspective(PerspectiveDescriptor desc, WorkbenchPage page)
+ throws WorkbenchException {
+ this(page);
+ descriptor = desc;
+ if (desc != null) {
+ createPresentation(desc);
+ }
+ }
+
+ /**
+ * ViewManager constructor comment.
+ */
+ protected Perspective(WorkbenchPage page) throws WorkbenchException {
+ this.page = page;
+ this.viewFactory = page.getViewFactory();
+ alwaysOnActionSets = new ArrayList(2);
+ alwaysOffActionSets = new ArrayList(2);
+ hideMenuIDs = new HashSet();
+ hideToolBarIDs = new HashSet();
+
+ // We'll only make a FastView Manager if there's a
+ // Trim manager in the WorkbenchWindow
+ IWorkbenchWindow wbw = page.getWorkbenchWindow();
+ if (wbw instanceof WorkbenchWindow) {
+ if (((WorkbenchWindow) wbw).getTrimManager() != null)
+ fastViewManager = new FastViewManager(this, page);
+ }
+
+ mapIDtoViewLayoutRec = new HashMap();
+ }
+
+ /**
+ * Sets the fast view attribute. Note: The page is expected to update action
+ * bars.
+ */
+ public void makeFastView(IViewReference ref) {
+ addFastView(ref, true);
+ }
+
+ /**
+ * Sets the fast view attribute. Note: The page is expected to update action
+ * bars.
+ */
+ public void addFastView(IViewReference ref, boolean handleLayout) {
+ ViewPane pane = (ViewPane) ((WorkbenchPartReference) ref).getPane();
+ if (!isFastView(ref)) {
+ if (handleLayout) {
+ // Only remove the part from the presentation if it
+ // is actually in the presentation.
+ if (presentation.hasPlaceholder(ref.getId(), ref
+ .getSecondaryId())
+ || pane.getContainer() != null) {
+ presentation.removePart(pane);
+ }
+ }
+
+ // We are drag-enabling the pane because it has been disabled
+ // when it was removed from the perspective presentation.
+ pane.setFast(true);
+ Control ctrl = pane.getControl();
+ if (ctrl != null) {
+ ctrl.setEnabled(false); // Remove focus support.
+ }
+ }
+ }
+
+ /**
+ * Moves a part forward in the Z order of a perspective so it is visible.
+ *
+ * @param part
+ * the part to bring to move forward
+ * @return true if the part was brought to top, false if not.
+ */
+ public boolean bringToTop(IViewReference ref) {
+ if (isFastView(ref)) {
+ setActiveFastView(ref);
+ return true;
+ } else {
+ return presentation.bringPartToTop(getPane(ref));
+ }
+ }
+
+ /**
+ * Returns whether a view exists within the perspective.
+ */
+ public boolean containsView(IViewPart view) {
+ IViewSite site = view.getViewSite();
+ IViewReference ref = findView(site.getId(), site.getSecondaryId());
+ if (ref == null) {
+ return false;
+ }
+ return (view == ref.getPart(false));
+ }
+
+ /**
+ * Create the initial list of action sets.
+ */
+ protected void createInitialActionSets(List outputList, List stringList) {
+ ActionSetRegistry reg = WorkbenchPlugin.getDefault()
+ .getActionSetRegistry();
+ Iterator iter = stringList.iterator();
+ while (iter.hasNext()) {
+ String id = (String) iter.next();
+ IActionSetDescriptor desc = reg.findActionSet(id);
+ if (desc != null) {
+ outputList.add(desc);
+ } else {
+ WorkbenchPlugin.log("Unable to find Action Set: " + id);//$NON-NLS-1$
+ }
+ }
+ }
+
+ /**
+ * Create a presentation for a perspective.
+ */
+ private void createPresentation(PerspectiveDescriptor persp)
+ throws WorkbenchException {
+ if (persp.hasCustomDefinition()) {
+ loadCustomPersp(persp);
+ } else {
+ loadPredefinedPersp(persp);
+ }
+ }
+
+ /**
+ * Dispose the perspective and all views contained within.
+ */
+ public void dispose() {
+ // Get rid of presentation.
+ if (presentation == null) {
+ disposeViewRefs();
+ return;
+ }
+
+ presentation.deactivate();
+ presentation.dispose();
+
+ fastViewPane.dispose();
+
+ // Release each view.
+ IViewReference refs[] = getViewReferences();
+ for (int i = 0, length = refs.length; i < length; i++) {
+ getViewFactory().releaseView(refs[i]);
+ }
+
+ mapIDtoViewLayoutRec.clear();
+ }
+
+ private void disposeViewRefs() {
+ if (memento == null) {
+ return;
+ }
+ IMemento views[] = memento.getChildren(IWorkbenchConstants.TAG_VIEW);
+ for (int x = 0; x < views.length; x++) {
+ // Get the view details.
+ IMemento childMem = views[x];
+ String id = childMem.getString(IWorkbenchConstants.TAG_ID);
+ // skip creation of the intro reference - it's handled elsewhere.
+ if (id.equals(IIntroConstants.INTRO_VIEW_ID)) {
+ continue;
+ }
+
+ String secondaryId = ViewFactory.extractSecondaryId(id);
+ if (secondaryId != null) {
+ id = ViewFactory.extractPrimaryId(id);
+ }
+ // Create and open the view.
+
+ if (!"true".equals(childMem.getString(IWorkbenchConstants.TAG_REMOVED))) { //$NON-NLS-1$
+ IViewReference ref = viewFactory.getView(id, secondaryId);
+ if (ref != null) {
+ viewFactory.releaseView(ref);
+ }
+ }
+
+ }
+ }
+
+ /**
+ * Finds the view with the given ID that is open in this page, or
+ * <code>null</code> if not found.
+ *
+ * @param viewId
+ * the view ID
+ */
+ public IViewReference findView(String viewId) {
+ return findView(viewId, null);
+ }
+
+ /**
+ * Finds the view with the given id and secondary id that is open in this
+ * page, or <code>null</code> if not found.
+ *
+ * @param viewId
+ * the view ID
+ * @param secondaryId
+ * the secondary ID
+ */
+ public IViewReference findView(String id, String secondaryId) {
+ IViewReference refs[] = getViewReferences();
+ for (int i = 0; i < refs.length; i++) {
+ IViewReference ref = refs[i];
+ if (id.equals(ref.getId())
+ && (secondaryId == null ? ref.getSecondaryId() == null
+ : secondaryId.equals(ref.getSecondaryId()))) {
+ return ref;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the window's client composite widget which views and editor area
+ * will be parented.
+ */
+ public Composite getClientComposite() {
+ return page.getClientComposite();
+ }
+
+ /**
+ * Returns the perspective.
+ */
+ public IPerspectiveDescriptor getDesc() {
+ return descriptor;
+ }
+
+ /**
+ * Returns the bounds of the given fast view.
+ */
+ /* package */Rectangle getFastViewBounds(IViewReference ref) {
+ // Copy the bounds of the page composite
+ Rectangle bounds = page.getClientComposite().getBounds();
+ // get the width ratio of the fast view
+ float ratio = getFastViewWidthRatio(ref);
+ // Compute the actual width of the fast view.
+ bounds.width = (int) (ratio * getClientComposite().getSize().x);
+ return bounds;
+ }
+
+ /**
+ * Returns the docked views.
+ */
+ public IViewReference[] getFastViews() {
+ if (fastViewManager == null)
+ return new IViewReference[0];
+
+ List trueFVBRefs = fastViewManager
+ .getFastViews(FastViewBar.FASTVIEWBAR_ID);
+ IViewReference array[] = new IViewReference[trueFVBRefs.size()];
+ trueFVBRefs.toArray(array);
+ return array;
+ }
+
+ /**
+ * Returns the new wizard shortcuts associated with this perspective.
+ *
+ * @return an array of new wizard identifiers
+ */
+ public String[] getNewWizardShortcuts() {
+ return (String[]) newWizardShortcuts
+ .toArray(new String[newWizardShortcuts.size()]);
+ }
+
+ /**
+ * Returns the pane for a view reference.
+ */
+ protected ViewPane getPane(IViewReference ref) {
+ return null;
+ }
+
+ /**
+ * Returns the perspective shortcuts associated with this perspective.
+ *
+ * @return an array of perspective identifiers
+ */
+ public String[] getPerspectiveShortcuts() {
+ return (String[]) perspectiveShortcuts
+ .toArray(new String[perspectiveShortcuts.size()]);
+ }
+
+ /**
+ * Returns the presentation.
+ */
+ public PerspectiveHelper getPresentation() {
+ return presentation;
+ }
+
+ /**
+ * Retrieves the fast view width ratio for the given view. If the ratio is
+ * not known, the default ratio for the view is assigned and returned.
+ */
+ public float getFastViewWidthRatio(IViewReference ref) {
+ ViewLayoutRec rec = getViewLayoutRec(ref, true);
+ if (rec.fastViewWidthRatio == IPageLayout.INVALID_RATIO) {
+ IViewRegistry reg = WorkbenchPlugin.getDefault().getViewRegistry();
+ IViewDescriptor desc = reg.find(ref.getId());
+ rec.fastViewWidthRatio = (desc != null ? desc
+ .getFastViewWidthRatio()
+ : IPageLayout.DEFAULT_FASTVIEW_RATIO);
+ }
+ return rec.fastViewWidthRatio;
+ }
+
+ /**
+ * Returns the ids of the parts to list in the Show In... dialog. This is a
+ * List of Strings.
+ */
+ public ArrayList getShowInPartIds() {
+ return showInPartIds;
+ }
+
+ /**
+ * Returns the time at which the last Show In was performed for the given
+ * target part, or 0 if unknown.
+ */
+ public long getShowInTime(String partId) {
+ Long t = (Long) showInTimes.get(partId);
+ return t == null ? 0L : t.longValue();
+ }
+
+ /**
+ * Returns the show view shortcuts associated with this perspective.
+ *
+ * @return an array of view identifiers
+ */
+ public String[] getShowViewShortcuts() {
+ return (String[]) showViewShortcuts
+ .toArray(new String[showViewShortcuts.size()]);
+ }
+
+ /**
+ * Returns the view factory.
+ */
+ public ViewFactory getViewFactory() {
+ return viewFactory;
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public IViewReference[] getViewReferences() {
+ // Get normal views.
+ if (presentation == null) {
+ return new IViewReference[0];
+ }
+
+ List panes = new ArrayList(5);
+ presentation.collectViewPanes(panes);
+
+ List fastViews = (fastViewManager != null) ? fastViewManager
+ .getFastViews(null) : new ArrayList();
+ IViewReference[] resultArray = new IViewReference[panes.size()
+ + fastViews.size()];
+
+ // Copy fast views.
+ int nView = 0;
+ for (int i = 0; i < fastViews.size(); i++) {
+ resultArray[nView] = (IViewReference) fastViews.get(i);
+ ++nView;
+ }
+
+ // Copy normal views.
+ for (int i = 0; i < panes.size(); i++) {
+ ViewPane pane = (ViewPane) panes.get(i);
+ resultArray[nView] = pane.getViewReference();
+ ++nView;
+ }
+
+ return resultArray;
+ }
+
+ /**
+ * Hide the editor area if visible
+ */
+ protected void hideEditorArea() {
+ if (!isEditorAreaVisible()) {
+ return;
+ }
+
+ // Show the editor in the appropriate location
+ if (useNewMinMax(this)) {
+ // If it's the currently maximized part we have to restore first
+ if (getPresentation().getMaximizedStack() instanceof EditorStack) {
+ getPresentation().getMaximizedStack().setState(
+ IStackPresentationSite.STATE_RESTORED);
+ }
+
+ boolean isMinimized = editorAreaState == IStackPresentationSite.STATE_MINIMIZED;
+ if (!isMinimized)
+ hideEditorAreaLocal();
+ else
+ setEditorAreaTrimVisibility(false);
+ } else {
+ hideEditorAreaLocal();
+ }
+
+ editorHidden = true;
+ }
+
+ /**
+ * Hide the editor area if visible
+ */
+ protected void hideEditorAreaLocal() {
+ if (editorHolder != null) {
+ return;
+ }
+
+ // Replace the editor area with a placeholder so we
+ // know where to put it back on show editor area request.
+ editorHolder = new PartPlaceholder(editorArea.getID());
+ presentation.getLayout().replace(editorArea, editorHolder);
+ }
+
+ /**
+ * Hides a fast view. The view shrinks equally <code>steps</code> times
+ * before disappearing completely.
+ */
+ private void hideFastView(IViewReference ref, int steps) {
+ setFastViewIconSelection(ref, false);
+
+ // Note: We always do at least one step of the animation.
+ // Note: This doesn't take into account the overhead of doing
+ if (ref == activeFastView) {
+ saveFastViewWidthRatio();
+ fastViewPane.hideView();
+ }
+ }
+
+ /**
+ * Hides the fast view sash for zooming in a fast view.
+ */
+ void hideFastViewSash() {
+ fastViewPane.hideFastViewSash();
+ }
+
+ public boolean hideView(IViewReference ref) {
+ // If the view is locked just return.
+ ModelViewReference mvr = (ModelViewReference) ref;
+ mvr.getModel().setVisible(false);
+ return true;
+ }
+
+ /*
+ * Return whether the editor area is visible or not.
+ */
+ protected boolean isEditorAreaVisible() {
+ return !editorHidden;
+ }
+
+ /**
+ * Returns true if a view is fast.
+ */
+ public boolean isFastView(IViewReference ref) {
+ if (fastViewManager == null)
+ return false;
+
+ return fastViewManager.isFastView(ref);
+ }
+
+ /**
+ * Returns the view layout rec for the given view reference, or null if not
+ * found. If create is true, it creates the record if not already created.
+ */
+ public ViewLayoutRec getViewLayoutRec(IViewReference ref, boolean create) {
+ ViewLayoutRec result = getViewLayoutRec(ViewFactory.getKey(ref), create);
+ if (result == null && create == false) {
+ result = getViewLayoutRec(ref.getId(), false);
+ }
+ return result;
+ }
+
+ /**
+ * Returns the view layout record for the given view id or null if not
+ * found. If create is true, it creates the record if not already created.
+ */
+ private ViewLayoutRec getViewLayoutRec(String viewId, boolean create) {
+ ViewLayoutRec rec = (ViewLayoutRec) mapIDtoViewLayoutRec.get(viewId);
+ if (rec == null && create) {
+ rec = new ViewLayoutRec();
+ mapIDtoViewLayoutRec.put(viewId, rec);
+ }
+ return rec;
+ }
+
+ /**
+ * Returns true if a layout or perspective is fixed.
+ */
+ public boolean isFixedLayout() {
+ // @issue is there a difference between a fixed
+ // layout and a fixed perspective?? If not the API
+ // may need some polish, WorkbenchPage, PageLayout
+ // and Perspective all have isFixed methods.
+ // PageLayout and Perspective have their own fixed
+ // attribute, we are assuming they are always in sync.
+ // WorkbenchPage delegates to the perspective.
+ return fixed;
+ }
+
+ /**
+ * Returns true if a view is standalone.
+ *
+ * @since 3.0
+ */
+ public boolean isStandaloneView(IViewReference ref) {
+ ViewLayoutRec rec = getViewLayoutRec(ref, false);
+ return rec != null && rec.isStandalone;
+ }
+
+ /**
+ * Returns whether the title for a view should be shown. This applies only
+ * to standalone views.
+ *
+ * @since 3.0
+ */
+ public boolean getShowTitleView(IViewReference ref) {
+ ViewLayoutRec rec = getViewLayoutRec(ref, false);
+ return rec != null && rec.showTitle;
+ }
+
+ /**
+ * Creates a new presentation from a persistence file. Note: This method
+ * should not modify the current state of the perspective.
+ */
+ private void loadCustomPersp(PerspectiveDescriptor persp) {
+ // get the layout from the registry
+ PerspectiveRegistry perspRegistry = (PerspectiveRegistry) WorkbenchPlugin
+ .getDefault().getPerspectiveRegistry();
+ try {
+ IMemento memento = perspRegistry.getCustomPersp(persp.getId());
+ // Restore the layout state.
+ MultiStatus status = new MultiStatus(
+ PlatformUI.PLUGIN_ID,
+ IStatus.OK,
+ NLS
+ .bind(
+ WorkbenchMessages.Perspective_unableToRestorePerspective,
+ persp.getLabel()), null);
+ status.merge(restoreState(memento));
+ status.merge(restoreState());
+ if (status.getSeverity() != IStatus.OK) {
+ unableToOpenPerspective(persp, status);
+ }
+ } catch (IOException e) {
+ unableToOpenPerspective(persp, null);
+ } catch (WorkbenchException e) {
+ unableToOpenPerspective(persp, e.getStatus());
+ }
+ }
+
+ private void unableToOpenPerspective(PerspectiveDescriptor persp,
+ IStatus status) {
+ PerspectiveRegistry perspRegistry = (PerspectiveRegistry) WorkbenchPlugin
+ .getDefault().getPerspectiveRegistry();
+ perspRegistry.deletePerspective(persp);
+ // If this is a predefined perspective, we will not be able to delete
+ // the perspective (we wouldn't want to). But make sure to delete the
+ // customized portion.
+ persp.deleteCustomDefinition();
+ String title = WorkbenchMessages.Perspective_problemRestoringTitle;
+ String msg = WorkbenchMessages.Perspective_errorReadingState;
+ if (status == null) {
+ MessageDialog.openError((Shell) null, title, msg);
+ } else {
+ ErrorDialog.openError((Shell) null, title, msg, status);
+ }
+ }
+
+ /**
+ * Create a presentation for a perspective. Note: This method should not
+ * modify the current state of the perspective.
+ */
+ protected void loadPredefinedPersp(PerspectiveDescriptor persp)
+ throws WorkbenchException {
+ // Create layout engine.
+ IPerspectiveFactory factory = null;
+ try {
+ factory = persp.createFactory();
+ } catch (CoreException e) {
+ throw new WorkbenchException(NLS.bind(
+ WorkbenchMessages.Perspective_unableToLoad, persp.getId()));
+ }
+
+ /*
+ * IPerspectiveFactory#createFactory() can return null
+ */
+ if (factory == null) {
+ throw new WorkbenchException(NLS.bind(
+ WorkbenchMessages.Perspective_unableToLoad, persp.getId()));
+ }
+
+ MWindow e4Window = page.getModelWindow();
+
+ EList e4Kids = e4Window.getChildren();
+ if (e4Kids.size() == 0) {
+ createLegacyWBModel(e4Window);
+ }
+
+ // Add the new perspective to its stack
+ MElementContainer<MUIElement> perspStack = (MElementContainer<MUIElement>) ModeledPageLayout
+ .findElementById(e4Window, "PerspectiveStack"); //$NON-NLS-1$
+
+ // Is it already there?
+ MPerspective perspModel = (MPerspective) ModeledPageLayout.findPart(
+ perspStack, persp.getId());
+ if (perspModel != null) {
+ if (!perspModel.isVisible())
+ perspModel.setVisible(true);
+ perspStack.setActiveChild(perspModel);
+ return;
+ }
+
+ // Not there, create it
+ perspModel = MApplicationFactory.eINSTANCE.createPerspective();
+ perspModel.setId(persp.getId());
+
+ IConfigurationElement element = persp.getConfigElement();
+ if (element != null) {
+ // Convert the relative path into a bundle URI
+ String imagePath = element.getAttribute("icon"); //$NON-NLS-1$
+ if (imagePath != null) {
+ imagePath = imagePath.replace("$nl$", ""); //$NON-NLS-1$//$NON-NLS-2$
+ if (imagePath.charAt(0) != '/') {
+ imagePath = '/' + imagePath;
+ }
+ String bundleId = element.getContributor().getName();
+ String imageURI = "platform:/plugin/" + bundleId + imagePath; //$NON-NLS-1$
+ perspModel.setIconURI(imageURI);
+ }
+ }
+
+ // e4Window.getChildren().add(persModel);
+ perspModel.setName(persp.getLabel());
+ layout = new ModeledPageLayout(perspModel);
+ ((ModeledPageLayout) layout).setDescriptor(descriptor);
+ newWizardShortcuts = layout.getNewWizardShortcuts();
+ showViewShortcuts = layout.getShowViewShortcuts();
+ perspectiveShortcuts = layout.getPerspectiveShortcuts();
+ showInPartIds = layout.getShowInPartIds();
+ // hideMenuIDs = layout.getHiddenMenuItems();
+ // hideToolBarIDs = layout.getHiddenToolBarItems();
+ layout.setFixed(descriptor.getFixed());
+
+ // add the placeholders for the sticky folders and their contents
+
+ // Run layout engine.
+ factory.createInitialLayout(layout);
+ loadExtensions(perspModel, ((ModeledPageLayout) layout));
+ // MPart ea = ModeledPageLayout.findPart(persModel, "bottom"); //$NON-NLS-1$
+ // if (ea == null) {
+ // layout
+ // .createPlaceholderFolder(
+ // "bottom", IPageLayout.BOTTOM, 0.2f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
+ // }
+ perspStack.getChildren().add(perspModel);
+ perspStack.setActiveChild(perspModel);
+
+ final IEclipseContext perspContext = perspModel.getContext();
+ // Manage the 'close' button
+ // final MPerspective thePerspModel = perspModel;
+ // final PerspectiveDescriptor theDesc = descriptor;
+ // IValueFunction closeFunc = new IValueFunction() {
+ // public Object getValue() {
+ // if (page.getOpenPerspectives().length == 1)
+ // return false;
+ //
+ // ArrayList<IEditorReference> result = new
+ // ArrayList<IEditorReference>();
+ // page.getContainedEditorRefs(result, thePerspModel);
+ // IEditorReference[] openEditors = new IEditorReference[result
+ // .size()];
+ // result.toArray(openEditors);
+ // boolean okToClose = page.closeEditors(openEditors, true);
+ // if (okToClose) {
+ // // Explicitly 'dispose' all created views
+ // List<MStack> stacks = new ArrayList<MStack>();
+ // gatherStacks(thePerspModel, stacks);
+ // for (Iterator iterator = stacks.iterator(); iterator
+ // .hasNext();) {
+ // MStack mStack = (MStack) iterator.next();
+ // String policy = mStack.getPolicy();
+ // if (policy == null)
+ // continue;
+ // if (policy.indexOf("ViewStack") >= 0) { //$NON-NLS-1$
+ // EList<MItemPart<?>> vsKids = mStack.getChildren();
+ // for (Iterator iterator2 = vsKids.iterator(); iterator2
+ // .hasNext();) {
+ // MContributedPart<MPart<?>> view = (MContributedPart<MPart<?>>)
+ // iterator2
+ // .next();
+ // if (view.getObject() instanceof IViewPart) {
+ // Control ctrl = (Control) view.getWidget();
+ // if (ctrl.getMenu() != null)
+ // ctrl.setMenu(null);
+ // IViewPart vp = (IViewPart) view.getObject();
+ // vp.dispose();
+ // }
+ // }
+ // }
+ // }
+ // page.closePerspective(theDesc, true, false);
+ // }
+ // return okToClose;
+ // }
+ // };
+ // perspContext.set("canCloseFunc", closeFunc); //$NON-NLS-1$
+ perspContext.set(Perspective.class.getName(), this);
+
+ // Always show the progress view since we don't have progress trim yet
+ MPart prgViewPart = ModeledPageLayout.findPart(perspModel,
+ "org.eclipse.ui.views.ProgressView"); //$NON-NLS-1$
+ if (prgViewPart != null) {
+ prgViewPart.setVisible(true);
+ }
+ // prgViewPart.getParent().setActiveChild(prgViewPart);
+ //showView("org.eclipse.ui.views.ProgressView", null); //$NON-NLS-1$
+ }
+
+ /**
+ * @param e4Window
+ */
+ private void createLegacyWBModel(MWindow e4Window) {
+ // MTrimStructure<MUIElement> trim = MApplicationFactory.eINSTANCE
+ // .createTrimStructure();
+
+ // Add a 'stickyRight' stack and populate it
+ MViewSashContainer mainSash = MApplicationFactory.eINSTANCE
+ .createViewSashContainer();
+ mainSash.setHorizontal(true);
+
+ MPerspectiveStack perspStack = MApplicationFactory.eINSTANCE
+ .createPerspectiveStack();
+ perspStack.setId("PerspectiveStack"); //$NON-NLS-1$
+
+ mainSash.getChildren().add(perspStack);
+
+ MViewStack stickyRight = MApplicationFactory.eINSTANCE
+ .createViewStack();
+ stickyRight.setId("stickyRight"); //$NON-NLS-1$
+ stickyRight.setVisible(false);
+ IStickyViewDescriptor[] descs = WorkbenchPlugin.getDefault()
+ .getViewRegistry().getStickyViews();
+ for (int i = 0; i < descs.length; i++) {
+ IStickyViewDescriptor stickyViewDescriptor = descs[i];
+ String id = stickyViewDescriptor.getId();
+ switch (stickyViewDescriptor.getLocation()) {
+ case IPageLayout.RIGHT:
+ MView view = ModeledPageLayout.createViewModel(id, false);
+ stickyRight.getChildren().add(view);
+ break;
+ }
+ }
+ mainSash.getChildren().add(stickyRight);
+ // trim.getChildren().add(mainSash);
+ e4Window.getChildren().add(mainSash);
+ }
+
+ private void loadExtensions(MPerspective perspModel,
+ ModeledPageLayout layout) {
+ String perspId = perspModel.getId();
+ if (perspId == null)
+ return;
+
+ IConfigurationElement[] perspExts = ExtensionUtils
+ .getExtensions(IWorkbenchRegistryConstants.PL_PERSPECTIVE_EXTENSIONS);
+ for (int i = 0; i < perspExts.length; i++) {
+ String extTarget = perspExts[i]
+ .getAttribute(IWorkbenchRegistryConstants.ATT_TARGET_ID);
+ if (perspId.equals(extTarget)) {
+ IConfigurationElement[] viewExts = perspExts[i]
+ .getChildren(IWorkbenchRegistryConstants.TAG_VIEW);
+ for (int j = 0; j < viewExts.length; j++) {
+ if (viewExts[j] == null)
+ continue; // this view has already being created
+ addView(j, viewExts, perspModel);
+ }
+ }
+ }
+ }
+
+ private MPart addView(int position, IConfigurationElement[] viewExts,
+ MPerspective perspModel) {
+ String id = viewExts[position]
+ .getAttribute(IWorkbenchRegistryConstants.ATT_ID);
+ // String relationship =
+ // viewExts[j].getAttribute("relationship");
+ String relative = viewExts[position]
+ .getAttribute(IWorkbenchRegistryConstants.ATT_RELATIVE);
+ String visible = viewExts[position]
+ .getAttribute(IWorkbenchRegistryConstants.ATT_VISIBLE);
+ // String closeable = viewExts[j].getAttribute("closeable");
+ // String showTitle = viewExts[j].getAttribute("showTitle");
+
+ MPart relPart = ModeledPageLayout.findPart(perspModel, relative);
+ if (relPart == null) { // is it declared later in the extensions?
+ for (int i = position + 1; i < viewExts.length; i++) {
+ if (viewExts[i] == null)
+ continue; // this view has already being created
+ String otherID = viewExts[i]
+ .getAttribute(IWorkbenchRegistryConstants.ATT_ID);
+ if (otherID == null)
+ continue;
+ if (otherID.equals(relative)) {
+ relPart = addView(i, viewExts, perspModel);
+ if (relPart != null)
+ break;
+ }
+ }
+ }
+ MViewStack sm;
+ if (relPart instanceof MView) {
+ MUIElement rp = relPart.getParent();
+ sm = (MViewStack) rp;
+ } else { // get a default stack
+ sm = getDefaultStack(perspModel);
+ }
+
+ MView viewModel = ModeledPageLayout.createViewModel(id, Boolean
+ .parseBoolean(visible));
+ sm.getChildren().add(viewModel);
+ viewExts[position] = null; // only create once
+ return viewModel;
+ }
+
+ private MViewStack getDefaultStack(MElementContainer<?> container) {
+ // TBD is there a better approach in 3.x?
+ // find any stack in the perspective's ascendants
+ for (MUIElement child : container.getChildren()) {
+ if (child instanceof MViewStack)
+ return (MViewStack) child;
+ if (child instanceof MElementContainer<?>) {
+ MViewStack result = getDefaultStack((MElementContainer<?>) child);
+ if (result != null)
+ return result;
+ }
+ }
+ return null;
+ }
+
+ private void removeAlwaysOn(IActionSetDescriptor descriptor) {
+ if (descriptor == null) {
+ return;
+ }
+ if (!alwaysOnActionSets.contains(descriptor)) {
+ return;
+ }
+
+ alwaysOnActionSets.remove(descriptor);
+ if (page != null) {
+ page.perspectiveActionSetChanged(this, descriptor,
+ ActionSetManager.CHANGE_HIDE);
+ }
+ }
+
+ protected void addAlwaysOff(IActionSetDescriptor descriptor) {
+ if (descriptor == null) {
+ return;
+ }
+ if (alwaysOffActionSets.contains(descriptor)) {
+ return;
+ }
+ alwaysOffActionSets.add(descriptor);
+ if (page != null) {
+ page.perspectiveActionSetChanged(this, descriptor,
+ ActionSetManager.CHANGE_MASK);
+ }
+ removeAlwaysOn(descriptor);
+ }
+
+ protected void addAlwaysOn(IActionSetDescriptor descriptor) {
+ if (descriptor == null) {
+ return;
+ }
+ if (alwaysOnActionSets.contains(descriptor)) {
+ return;
+ }
+ alwaysOnActionSets.add(descriptor);
+ if (page != null) {
+ page.perspectiveActionSetChanged(this, descriptor,
+ ActionSetManager.CHANGE_SHOW);
+ }
+ removeAlwaysOff(descriptor);
+ }
+
+ private void removeAlwaysOff(IActionSetDescriptor descriptor) {
+ if (descriptor == null) {
+ return;
+ }
+ if (!alwaysOffActionSets.contains(descriptor)) {
+ return;
+ }
+ alwaysOffActionSets.remove(descriptor);
+ if (page != null) {
+ page.perspectiveActionSetChanged(this, descriptor,
+ ActionSetManager.CHANGE_UNMASK);
+ }
+ }
+
+ /**
+ * activate.
+ */
+ protected void onActivate() {
+ // Update editor area state.
+
+ }
+
+ /**
+ * deactivate.
+ */
+ protected void onDeactivate() {
+ presentation.deactivate();
+ setActiveFastView(null);
+ setAllPinsVisible(false);
+
+ // Update fast views.
+ if (fastViewManager != null) {
+ List fastViews = fastViewManager.getFastViews(null);
+ for (int i = 0; i < fastViews.size(); i++) {
+ ViewPane pane = getPane((IViewReference) fastViews.get(i));
+ if (pane != null) {
+ Control ctrl = pane.getControl();
+ if (ctrl != null) {
+ ctrl.setEnabled(true); // Add focus support.
+ }
+ }
+ }
+
+ fastViewManager.deActivate();
+ }
+
+ // Ensure that the editor area trim is hidden as well
+ setEditorAreaTrimVisibility(false);
+ }
+
+ /**
+ * Notifies that a part has been activated.
+ */
+ public void partActivated(IWorkbenchPart activePart) {
+ // If a fastview is open close it.
+ if (activeFastView != null
+ && activeFastView.getPart(false) != activePart) {
+ setActiveFastView(null);
+ }
+ }
+
+ /**
+ * The user successfully performed a Show In... action on the specified
+ * part. Update the history.
+ */
+ public void performedShowIn(String partId) {
+ showInTimes.put(partId, new Long(System.currentTimeMillis()));
+ }
+
+ /**
+ * Sets the fast view attribute. Note: The page is expected to update action
+ * bars.
+ */
+ public void removeFastView(IViewReference ref) {
+ removeFastView(ref, true);
+ }
+
+ /**
+ * Sets the fast view attribute. Note: The page is expected to update action
+ * bars.
+ */
+ public void removeFastView(IViewReference ref, boolean handleLayout) {
+ ViewPane pane = getPane(ref);
+
+ if (activeFastView == ref) {
+ setActiveFastView(null);
+ }
+
+ pane.setFast(false);
+ Control ctrl = pane.getControl();
+ if (ctrl != null) {
+ ctrl.setEnabled(true); // Modify focus support.
+ }
+
+ if (handleLayout) {
+ // We are disabling the pane because it will be enabled when it
+ // is added to the presentation. When a pane is enabled a drop
+ // listener is added to it, and we do not want to have multiple
+ // listeners for a pane
+ presentation.addPart(pane);
+ }
+ }
+
+ /**
+ * Fills a presentation with layout data. Note: This method should not
+ * modify the current state of the perspective.
+ */
+ public IStatus restoreState(IMemento memento) {
+ MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
+ WorkbenchMessages.Perspective_problemsRestoringPerspective,
+ null);
+
+ // Create persp descriptor.
+ descriptor = new PerspectiveDescriptor(null, null, null);
+ result.add(descriptor.restoreState(memento));
+ PerspectiveDescriptor desc = (PerspectiveDescriptor) WorkbenchPlugin
+ .getDefault().getPerspectiveRegistry().findPerspectiveWithId(
+ descriptor.getId());
+ if (desc != null) {
+ descriptor = desc;
+ }
+
+ this.memento = memento;
+ // Add the visible views.
+ IMemento views[] = memento.getChildren(IWorkbenchConstants.TAG_VIEW);
+ result.merge(createReferences(views));
+
+ memento = memento.getChild(IWorkbenchConstants.TAG_FAST_VIEWS);
+ if (memento != null) {
+ views = memento.getChildren(IWorkbenchConstants.TAG_VIEW);
+ result.merge(createReferences(views));
+ }
+ return result;
+ }
+
+ IStatus createReferences(IMemento views[]) {
+ MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
+ WorkbenchMessages.Perspective_problemsRestoringViews, null);
+
+ for (int x = 0; x < views.length; x++) {
+ // Get the view details.
+ IMemento childMem = views[x];
+ String id = childMem.getString(IWorkbenchConstants.TAG_ID);
+ // skip creation of the intro reference - it's handled elsewhere.
+ if (id.equals(IIntroConstants.INTRO_VIEW_ID)) {
+ continue;
+ }
+
+ String secondaryId = ViewFactory.extractSecondaryId(id);
+ if (secondaryId != null) {
+ id = ViewFactory.extractPrimaryId(id);
+ }
+ // Create and open the view.
+ try {
+ if (!"true".equals(childMem.getString(IWorkbenchConstants.TAG_REMOVED))) { //$NON-NLS-1$
+ viewFactory.createView(id, secondaryId);
+ }
+ } catch (PartInitException e) {
+ childMem.putString(IWorkbenchConstants.TAG_REMOVED, "true"); //$NON-NLS-1$
+ result.add(StatusUtil.newStatus(IStatus.ERROR,
+ e.getMessage() == null ? "" : e.getMessage(), //$NON-NLS-1$
+ e));
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Fills a presentation with layout data. Note: This method should not
+ * modify the current state of the perspective.
+ */
+ public IStatus restoreState() {
+ if (this.memento == null) {
+ return new Status(IStatus.OK, PlatformUI.PLUGIN_ID, 0, "", null); //$NON-NLS-1$
+ }
+
+ MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
+ WorkbenchMessages.Perspective_problemsRestoringPerspective,
+ null);
+
+ IMemento memento = this.memento;
+ this.memento = null;
+
+ final IMemento boundsMem = memento
+ .getChild(IWorkbenchConstants.TAG_WINDOW);
+ if (boundsMem != null) {
+ final Rectangle r = new Rectangle(0, 0, 0, 0);
+ r.x = boundsMem.getInteger(IWorkbenchConstants.TAG_X).intValue();
+ r.y = boundsMem.getInteger(IWorkbenchConstants.TAG_Y).intValue();
+ r.height = boundsMem.getInteger(IWorkbenchConstants.TAG_HEIGHT)
+ .intValue();
+ r.width = boundsMem.getInteger(IWorkbenchConstants.TAG_WIDTH)
+ .intValue();
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() throws Throwable {
+ if (page.getWorkbenchWindow().getPages().length == 0) {
+ page.getWorkbenchWindow().getShell().setBounds(r);
+ }
+ }
+ });
+
+ }
+
+ // Create an empty presentation..
+ final PerspectiveHelper[] presArray = new PerspectiveHelper[1];
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() throws Throwable {
+ ViewSashContainer mainLayout = new ViewSashContainer(page,
+ getClientComposite());
+ presArray[0] = new PerspectiveHelper(page, mainLayout,
+ Perspective.this);
+ }
+ });
+ final PerspectiveHelper pres = presArray[0];
+
+ // Read the layout.
+ result.merge(pres.restoreState(memento
+ .getChild(IWorkbenchConstants.TAG_LAYOUT)));
+
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() throws Throwable {
+ // Add the editor workbook. Do not hide it now.
+ pres.replacePlaceholderWithPart(editorArea);
+ }
+ });
+
+ // Add the visible views.
+ IMemento[] views = memento.getChildren(IWorkbenchConstants.TAG_VIEW);
+
+ for (int x = 0; x < views.length; x++) {
+ // Get the view details.
+ IMemento childMem = views[x];
+ String id = childMem.getString(IWorkbenchConstants.TAG_ID);
+ String secondaryId = ViewFactory.extractSecondaryId(id);
+ if (secondaryId != null) {
+ id = ViewFactory.extractPrimaryId(id);
+ }
+
+ // skip the intro as it is restored higher up in workbench.
+ if (id.equals(IIntroConstants.INTRO_VIEW_ID)) {
+ continue;
+ }
+
+ // Create and open the view.
+ IViewReference viewRef = viewFactory.getView(id, secondaryId);
+ WorkbenchPartReference ref = (WorkbenchPartReference) viewRef;
+
+ // report error
+ if (ref == null) {
+ String key = ViewFactory.getKey(id, secondaryId);
+ result.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0,
+ NLS.bind(WorkbenchMessages.Perspective_couldNotFind,
+ key), null));
+ continue;
+ }
+ boolean willPartBeVisible = pres.willPartBeVisible(ref.getId(),
+ secondaryId);
+ if (willPartBeVisible) {
+ IViewPart view = (IViewPart) ref.getPart(true);
+ if (view != null) {
+ ViewSite site = (ViewSite) view.getSite();
+ ViewPane pane = (ViewPane) site.getPane();
+ pres.replacePlaceholderWithPart(pane);
+ }
+ } else {
+ pres.replacePlaceholderWithPart(ref.getPane());
+ }
+ }
+
+ // Load the fast views
+ if (fastViewManager != null)
+ fastViewManager.restoreState(memento, result);
+
+ // Load the view layout recs
+ IMemento[] recMementos = memento
+ .getChildren(IWorkbenchConstants.TAG_VIEW_LAYOUT_REC);
+ for (int i = 0; i < recMementos.length; i++) {
+ IMemento recMemento = recMementos[i];
+ String compoundId = recMemento
+ .getString(IWorkbenchConstants.TAG_ID);
+ if (compoundId != null) {
+ ViewLayoutRec rec = getViewLayoutRec(compoundId, true);
+ if (IWorkbenchConstants.FALSE.equals(recMemento
+ .getString(IWorkbenchConstants.TAG_CLOSEABLE))) {
+ rec.isCloseable = false;
+ }
+ if (IWorkbenchConstants.FALSE.equals(recMemento
+ .getString(IWorkbenchConstants.TAG_MOVEABLE))) {
+ rec.isMoveable = false;
+ }
+ if (IWorkbenchConstants.TRUE.equals(recMemento
+ .getString(IWorkbenchConstants.TAG_STANDALONE))) {
+ rec.isStandalone = true;
+ rec.showTitle = !IWorkbenchConstants.FALSE
+ .equals(recMemento
+ .getString(IWorkbenchConstants.TAG_SHOW_TITLE));
+ }
+ }
+ }
+
+ final IContextService service = (IContextService) page
+ .getWorkbenchWindow().getService(IContextService.class);
+ try { // one big try block, don't kill me here
+ // defer context events
+ if (service != null) {
+ service.deferUpdates(true);
+ }
+
+ HashSet knownActionSetIds = new HashSet();
+
+ // Load the always on action sets.
+ IMemento[] actions = memento
+ .getChildren(IWorkbenchConstants.TAG_ALWAYS_ON_ACTION_SET);
+ for (int x = 0; x < actions.length; x++) {
+ String actionSetID = actions[x]
+ .getString(IWorkbenchConstants.TAG_ID);
+ final IActionSetDescriptor d = WorkbenchPlugin.getDefault()
+ .getActionSetRegistry().findActionSet(actionSetID);
+ if (d != null) {
+ StartupThreading
+ .runWithoutExceptions(new StartupRunnable() {
+ public void runWithException() throws Throwable {
+ addAlwaysOn(d);
+ }
+ });
+
+ knownActionSetIds.add(actionSetID);
+ }
+ }
+
+ // Load the always off action sets.
+ actions = memento
+ .getChildren(IWorkbenchConstants.TAG_ALWAYS_OFF_ACTION_SET);
+ for (int x = 0; x < actions.length; x++) {
+ String actionSetID = actions[x]
+ .getString(IWorkbenchConstants.TAG_ID);
+ final IActionSetDescriptor d = WorkbenchPlugin.getDefault()
+ .getActionSetRegistry().findActionSet(actionSetID);
+ if (d != null) {
+ StartupThreading
+ .runWithoutExceptions(new StartupRunnable() {
+ public void runWithException() throws Throwable {
+ addAlwaysOff(d);
+ }
+ });
+ knownActionSetIds.add(actionSetID);
+ }
+ }
+
+ // Load "show view actions".
+ actions = memento
+ .getChildren(IWorkbenchConstants.TAG_SHOW_VIEW_ACTION);
+ showViewShortcuts = new ArrayList(actions.length);
+ for (int x = 0; x < actions.length; x++) {
+ String id = actions[x].getString(IWorkbenchConstants.TAG_ID);
+ showViewShortcuts.add(id);
+ }
+
+ // Load "show in times".
+ actions = memento.getChildren(IWorkbenchConstants.TAG_SHOW_IN_TIME);
+ for (int x = 0; x < actions.length; x++) {
+ String id = actions[x].getString(IWorkbenchConstants.TAG_ID);
+ String timeStr = actions[x]
+ .getString(IWorkbenchConstants.TAG_TIME);
+ if (id != null && timeStr != null) {
+ try {
+ long time = Long.parseLong(timeStr);
+ showInTimes.put(id, new Long(time));
+ } catch (NumberFormatException e) {
+ // skip this one
+ }
+ }
+ }
+
+ // Load "show in parts" from registry, not memento
+ showInPartIds = getShowInIdsFromRegistry();
+
+ // Load "new wizard actions".
+ actions = memento
+ .getChildren(IWorkbenchConstants.TAG_NEW_WIZARD_ACTION);
+ newWizardShortcuts = new ArrayList(actions.length);
+ for (int x = 0; x < actions.length; x++) {
+ String id = actions[x].getString(IWorkbenchConstants.TAG_ID);
+ newWizardShortcuts.add(id);
+ }
+
+ // Load "perspective actions".
+ actions = memento
+ .getChildren(IWorkbenchConstants.TAG_PERSPECTIVE_ACTION);
+ perspectiveShortcuts = new ArrayList(actions.length);
+ for (int x = 0; x < actions.length; x++) {
+ String id = actions[x].getString(IWorkbenchConstants.TAG_ID);
+ perspectiveShortcuts.add(id);
+ }
+
+ // Load hidden menu item ids
+ actions = memento.getChildren(IWorkbenchConstants.TAG_HIDE_MENU);
+ hideMenuIDs = new HashSet();
+ for (int x = 0; x < actions.length; x++) {
+ String id = actions[x].getString(IWorkbenchConstants.TAG_ID);
+ hideMenuIDs.add(id);
+ }
+ actions = memento.getChildren(IWorkbenchConstants.TAG_HIDE_TOOLBAR);
+ hideToolBarIDs = new HashSet();
+ for (int x = 0; x < actions.length; x++) {
+ String id = actions[x].getString(IWorkbenchConstants.TAG_ID);
+ hideToolBarIDs.add(id);
+ }
+
+ ArrayList extActionSets = getPerspectiveExtensionActionSets();
+ for (int i = 0; i < extActionSets.size(); i++) {
+ String actionSetID = (String) extActionSets.get(i);
+ if (knownActionSetIds.contains(actionSetID)) {
+ continue;
+ }
+ final IActionSetDescriptor d = WorkbenchPlugin.getDefault()
+ .getActionSetRegistry().findActionSet(actionSetID);
+ if (d != null) {
+ StartupThreading
+ .runWithoutExceptions(new StartupRunnable() {
+ public void runWithException() throws Throwable {
+ addAlwaysOn(d);
+ }
+ });
+ knownActionSetIds.add(d.getId());
+ }
+ }
+
+ // Add the visible set of action sets to our knownActionSetIds
+ // Now go through the registry to ensure we pick up any new action
+ // sets
+ // that have been added but not yet considered by this perspective.
+ ActionSetRegistry reg = WorkbenchPlugin.getDefault()
+ .getActionSetRegistry();
+ IActionSetDescriptor[] array = reg.getActionSets();
+ int count = array.length;
+ for (int i = 0; i < count; i++) {
+ IActionSetDescriptor desc = array[i];
+ if ((!knownActionSetIds.contains(desc.getId()))
+ && (desc.isInitiallyVisible())) {
+ addActionSet(desc);
+ }
+ }
+ } finally {
+ // restart context changes
+ if (service != null) {
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+ public void runWithException() throws Throwable {
+ service.deferUpdates(false);
+ }
+ });
+ }
+ }
+
+ // Save presentation.
+ presentation = pres;
+
+ // Hide the editor area if needed. Need to wait for the
+ // presentation to be fully setup first.
+ Integer areaVisible = memento
+ .getInteger(IWorkbenchConstants.TAG_AREA_VISIBLE);
+ // Rather than hiding the editors now we must wait until after their
+ // controls
+ // are created. This ensures that if an editor is instantiated,
+ // createPartControl
+ // is also called. See bug 20166.
+ shouldHideEditorsOnActivate = (areaVisible != null && areaVisible
+ .intValue() == 0);
+
+ // Restore the trim state of the editor area
+ IPreferenceStore preferenceStore = PrefUtil.getAPIPreferenceStore();
+ boolean useNewMinMax = preferenceStore
+ .getBoolean(IWorkbenchPreferenceConstants.ENABLE_NEW_MIN_MAX);
+ if (useNewMinMax) {
+ Integer trimStateInt = memento
+ .getInteger(IWorkbenchConstants.TAG_AREA_TRIM_STATE);
+ if (trimStateInt != null) {
+ editorAreaState = trimStateInt.intValue() & 0x3; // low order
+ // two bits
+ // contain
+ // the state
+ editorAreaRestoreOnUnzoom = (trimStateInt.intValue() & 4) != 0;
+ }
+ }
+
+ // restore the fixed state
+ Integer isFixed = memento.getInteger(IWorkbenchConstants.TAG_FIXED);
+ fixed = (isFixed != null && isFixed.intValue() == 1);
+
+ return result;
+ }
+
+ /**
+ * Restores a fast view to its corrent presentation structure. This method
+ * is pubilc because the FastViewManager uses it to reconstruct it minimized
+ * stacks on startup.
+ *
+ * @param fvMemento
+ * The mement containing the fast view info
+ * @param result
+ * The result status
+ * @return The reference to the restored view
+ */
+ public IViewReference restoreFastView(IMemento fvMemento, MultiStatus result) {
+ String viewID = fvMemento.getString(IWorkbenchConstants.TAG_ID);
+ String secondaryId = ViewFactory.extractSecondaryId(viewID);
+ if (secondaryId != null) {
+ viewID = ViewFactory.extractPrimaryId(viewID);
+ }
+
+ IViewReference viewRef = getViewFactory().getView(viewID, secondaryId);
+ if (viewRef == null) {
+ String key = ViewFactory.getKey(viewID, secondaryId);
+ WorkbenchPlugin.log("Could not create view: '" + key + "'."); //$NON-NLS-1$ //$NON-NLS-2$
+ result.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, NLS
+ .bind(WorkbenchMessages.Perspective_couldNotFind, key),
+ null));
+ return null;
+ }
+
+ // Restore fast view width ratio
+ Float ratio = fvMemento.getFloat(IWorkbenchConstants.TAG_RATIO);
+ if (ratio == null) {
+ Integer viewWidth = fvMemento
+ .getInteger(IWorkbenchConstants.TAG_WIDTH);
+ if (viewWidth == null) {
+ ratio = new Float(IPageLayout.DEFAULT_FASTVIEW_RATIO);
+ } else {
+ ratio = new Float((float) viewWidth.intValue()
+ / (float) getClientComposite().getSize().x);
+ }
+ }
+ ViewLayoutRec rec = getViewLayoutRec(viewRef, true);
+ rec.fastViewWidthRatio = ratio.floatValue();
+
+ return viewRef;
+ }
+
+ /**
+ * Returns the ActionSets read from perspectiveExtensions in the registry.
+ */
+ protected ArrayList getPerspectiveExtensionActionSets() {
+ PerspectiveExtensionReader reader = new PerspectiveExtensionReader();
+ reader
+ .setIncludeOnlyTags(new String[] { IWorkbenchRegistryConstants.TAG_ACTION_SET });
+ PageLayout layout = new PageLayout();
+ reader.extendLayout(null, descriptor.getOriginalId(), layout);
+ return layout.getActionSets();
+ }
+
+ /**
+ * Returns the Show In... part ids read from the registry.
+ */
+ protected ArrayList getShowInIdsFromRegistry() {
+ PerspectiveExtensionReader reader = new PerspectiveExtensionReader();
+ reader
+ .setIncludeOnlyTags(new String[] { IWorkbenchRegistryConstants.TAG_SHOW_IN_PART });
+ PageLayout layout = new PageLayout();
+ reader.extendLayout(null, descriptor.getOriginalId(), layout);
+ return layout.getShowInPartIds();
+ }
+
+ /**
+ * Save the layout.
+ */
+ public void saveDesc() {
+ saveDescAs(descriptor);
+ }
+
+ /**
+ * Save the layout.
+ */
+ public void saveDescAs(IPerspectiveDescriptor desc) {
+ PerspectiveDescriptor realDesc = (PerspectiveDescriptor) desc;
+ // get the layout from the registry
+ PerspectiveRegistry perspRegistry = (PerspectiveRegistry) WorkbenchPlugin
+ .getDefault().getPerspectiveRegistry();
+ // Capture the layout state.
+ XMLMemento memento = XMLMemento.createWriteRoot("perspective");//$NON-NLS-1$
+ IStatus status = saveState(memento, realDesc, false);
+ if (status.getSeverity() == IStatus.ERROR) {
+ ErrorDialog.openError((Shell) null,
+ WorkbenchMessages.Perspective_problemSavingTitle,
+ WorkbenchMessages.Perspective_problemSavingMessage, status);
+ return;
+ }
+ // save it to the preference store
+ try {
+ perspRegistry.saveCustomPersp(realDesc, memento);
+ descriptor = realDesc;
+ } catch (IOException e) {
+ perspRegistry.deletePerspective(realDesc);
+ MessageDialog.openError((Shell) null,
+ WorkbenchMessages.Perspective_problemSavingTitle,
+ WorkbenchMessages.Perspective_problemSavingMessage);
+ }
+ }
+
+ /**
+ * Save the layout.
+ */
+ public IStatus saveState(IMemento memento) {
+ MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
+ WorkbenchMessages.Perspective_problemsSavingPerspective, null);
+
+ result.merge(saveState(memento, descriptor, true));
+
+ return result;
+ }
+
+ /**
+ * Save the layout.
+ */
+ private IStatus saveState(IMemento memento, PerspectiveDescriptor p,
+ boolean saveInnerViewState) {
+ MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
+ WorkbenchMessages.Perspective_problemsSavingPerspective, null);
+
+ if (this.memento != null) {
+ memento.putMemento(this.memento);
+ return result;
+ }
+
+ // Save the version number.
+ memento.putString(IWorkbenchConstants.TAG_VERSION, VERSION_STRING);
+ result.add(p.saveState(memento));
+ if (!saveInnerViewState) {
+ Rectangle bounds = page.getWorkbenchWindow().getShell().getBounds();
+ IMemento boundsMem = memento
+ .createChild(IWorkbenchConstants.TAG_WINDOW);
+ boundsMem.putInteger(IWorkbenchConstants.TAG_X, bounds.x);
+ boundsMem.putInteger(IWorkbenchConstants.TAG_Y, bounds.y);
+ boundsMem.putInteger(IWorkbenchConstants.TAG_HEIGHT, bounds.height);
+ boundsMem.putInteger(IWorkbenchConstants.TAG_WIDTH, bounds.width);
+ }
+
+ // Save the "always on" action sets.
+ Iterator itr = alwaysOnActionSets.iterator();
+ while (itr.hasNext()) {
+ IActionSetDescriptor desc = (IActionSetDescriptor) itr.next();
+ IMemento child = memento
+ .createChild(IWorkbenchConstants.TAG_ALWAYS_ON_ACTION_SET);
+ child.putString(IWorkbenchConstants.TAG_ID, desc.getId());
+ }
+
+ // Save the "always off" action sets.
+ itr = alwaysOffActionSets.iterator();
+ while (itr.hasNext()) {
+ IActionSetDescriptor desc = (IActionSetDescriptor) itr.next();
+ IMemento child = memento
+ .createChild(IWorkbenchConstants.TAG_ALWAYS_OFF_ACTION_SET);
+ child.putString(IWorkbenchConstants.TAG_ID, desc.getId());
+ }
+
+ // Save "show view actions"
+ itr = showViewShortcuts.iterator();
+ while (itr.hasNext()) {
+ String str = (String) itr.next();
+ IMemento child = memento
+ .createChild(IWorkbenchConstants.TAG_SHOW_VIEW_ACTION);
+ child.putString(IWorkbenchConstants.TAG_ID, str);
+ }
+
+ // Save "show in times"
+ itr = showInTimes.keySet().iterator();
+ while (itr.hasNext()) {
+ String id = (String) itr.next();
+ Long time = (Long) showInTimes.get(id);
+ IMemento child = memento
+ .createChild(IWorkbenchConstants.TAG_SHOW_IN_TIME);
+ child.putString(IWorkbenchConstants.TAG_ID, id);
+ child.putString(IWorkbenchConstants.TAG_TIME, time.toString());
+ }
+
+ // Save "new wizard actions".
+ itr = newWizardShortcuts.iterator();
+ while (itr.hasNext()) {
+ String str = (String) itr.next();
+ IMemento child = memento
+ .createChild(IWorkbenchConstants.TAG_NEW_WIZARD_ACTION);
+ child.putString(IWorkbenchConstants.TAG_ID, str);
+ }
+
+ // Save "perspective actions".
+ itr = perspectiveShortcuts.iterator();
+ while (itr.hasNext()) {
+ String str = (String) itr.next();
+ IMemento child = memento
+ .createChild(IWorkbenchConstants.TAG_PERSPECTIVE_ACTION);
+ child.putString(IWorkbenchConstants.TAG_ID, str);
+ }
+
+ // Save hidden menu item ids
+ itr = hideMenuIDs.iterator();
+ while (itr.hasNext()) {
+ String str = (String) itr.next();
+ IMemento child = memento
+ .createChild(IWorkbenchConstants.TAG_HIDE_MENU);
+ child.putString(IWorkbenchConstants.TAG_ID, str);
+ }
+ itr = hideToolBarIDs.iterator();
+ while (itr.hasNext()) {
+ String str = (String) itr.next();
+ IMemento child = memento
+ .createChild(IWorkbenchConstants.TAG_HIDE_TOOLBAR);
+ child.putString(IWorkbenchConstants.TAG_ID, str);
+ }
+
+ // Get visible views.
+ List viewPanes = new ArrayList(5);
+ presentation.collectViewPanes(viewPanes);
+
+ // Save the views.
+ itr = viewPanes.iterator();
+ int errors = 0;
+ while (itr.hasNext()) {
+ ViewPane pane = (ViewPane) itr.next();
+ IViewReference ref = pane.getViewReference();
+ boolean restorable = page.getViewFactory().getViewRegistry().find(
+ ref.getId()).isRestorable();
+ if (restorable) {
+ IMemento viewMemento = memento
+ .createChild(IWorkbenchConstants.TAG_VIEW);
+ viewMemento.putString(IWorkbenchConstants.TAG_ID, ViewFactory
+ .getKey(ref));
+ }
+ }
+
+ // save all fastview state
+ if (fastViewManager != null)
+ fastViewManager.saveState(memento);
+
+ // Save the view layout recs.
+ for (Iterator i = mapIDtoViewLayoutRec.keySet().iterator(); i.hasNext();) {
+ String compoundId = (String) i.next();
+ ViewLayoutRec rec = (ViewLayoutRec) mapIDtoViewLayoutRec
+ .get(compoundId);
+ if (rec != null
+ && (!rec.isCloseable || !rec.isMoveable || rec.isStandalone)) {
+ IMemento layoutMemento = memento
+ .createChild(IWorkbenchConstants.TAG_VIEW_LAYOUT_REC);
+ layoutMemento.putString(IWorkbenchConstants.TAG_ID, compoundId);
+ if (!rec.isCloseable) {
+ layoutMemento.putString(IWorkbenchConstants.TAG_CLOSEABLE,
+ IWorkbenchConstants.FALSE);
+ }
+ if (!rec.isMoveable) {
+ layoutMemento.putString(IWorkbenchConstants.TAG_MOVEABLE,
+ IWorkbenchConstants.FALSE);
+ }
+ if (rec.isStandalone) {
+ layoutMemento.putString(IWorkbenchConstants.TAG_STANDALONE,
+ IWorkbenchConstants.TRUE);
+ layoutMemento.putString(IWorkbenchConstants.TAG_SHOW_TITLE,
+ String.valueOf(rec.showTitle));
+ }
+ }
+ }
+
+ if (errors > 0) {
+ String message = WorkbenchMessages.Perspective_multipleErrors;
+ if (errors == 1) {
+ message = WorkbenchMessages.Perspective_oneError;
+ }
+ MessageDialog.openError(null, WorkbenchMessages.Error, message);
+ }
+
+ // Save the layout.
+ IMemento childMem = memento.createChild(IWorkbenchConstants.TAG_LAYOUT);
+ result.add(presentation.saveState(childMem));
+
+ // Save the editor visibility state
+ if (isEditorAreaVisible()) {
+ memento.putInteger(IWorkbenchConstants.TAG_AREA_VISIBLE, 1);
+ } else {
+ memento.putInteger(IWorkbenchConstants.TAG_AREA_VISIBLE, 0);
+ }
+
+ // Save the trim state of the editor area if using the new min/max
+ IPreferenceStore preferenceStore = PrefUtil.getAPIPreferenceStore();
+ boolean useNewMinMax = preferenceStore
+ .getBoolean(IWorkbenchPreferenceConstants.ENABLE_NEW_MIN_MAX);
+ if (useNewMinMax) {
+ int trimState = editorAreaState;
+ trimState |= editorAreaRestoreOnUnzoom ? 4 : 0;
+ memento.putInteger(IWorkbenchConstants.TAG_AREA_TRIM_STATE,
+ trimState);
+ }
+
+ // Save the fixed state
+ if (fixed) {
+ memento.putInteger(IWorkbenchConstants.TAG_FIXED, 1);
+ } else {
+ memento.putInteger(IWorkbenchConstants.TAG_FIXED, 0);
+ }
+
+ return result;
+ }
+
+ public void turnOnActionSets(IActionSetDescriptor[] newArray) {
+ for (int i = 0; i < newArray.length; i++) {
+ IActionSetDescriptor descriptor = newArray[i];
+
+ addAlwaysOn(descriptor);
+ }
+ }
+
+ public void turnOffActionSets(IActionSetDescriptor[] toDisable) {
+ for (int i = 0; i < toDisable.length; i++) {
+ IActionSetDescriptor descriptor = toDisable[i];
+
+ turnOffActionSet(descriptor);
+ }
+ }
+
+ public void turnOffActionSet(IActionSetDescriptor toDisable) {
+ addAlwaysOff(toDisable);
+ }
+
+ /**
+ * Return the active fast view or null if there are no fast views or if
+ * there are all minimized.
+ */
+ public IViewReference getActiveFastView() {
+ return activeFastView;
+ }
+
+ /**
+ * Sets the active fast view. If a different fast view is already open, it
+ * shrinks equally <code>steps</code> times before disappearing completely.
+ * Then, <code>view</code> becomes active and is shown.
+ */
+ /* package */void setActiveFastView(IViewReference ref, int steps) {
+ if (activeFastView == ref) {
+ return;
+ }
+
+ if (activeFastView != null) {
+ ViewPane pane = getPane(activeFastView);
+ if (pane != null) {
+ if (pane.isZoomed()) {
+ presentation.zoomOut();
+ }
+ hideFastView(activeFastView, steps);
+ }
+ }
+ activeFastView = ref;
+ try {
+ if (activeFastView != null) {
+ if (!showFastView(activeFastView)) {
+ activeFastView = null;
+ }
+ }
+ } catch (RuntimeException e) {
+ activeFastView = null;
+ }
+ }
+
+ /**
+ * Sets the active fast view.
+ */
+ /* package */void setActiveFastView(IViewReference ref) {
+ setActiveFastView(ref, FASTVIEW_HIDE_STEPS);
+ }
+
+ /**
+ * Sets the visibility of all fast view pins.
+ */
+ protected void setAllPinsVisible(boolean visible) {
+ if (fastViewManager == null)
+ return;
+
+ Iterator iter = fastViewManager.getFastViews(null).iterator();
+ while (iter.hasNext()) {
+ ViewPane pane = getPane((IViewReference) iter.next());
+ if (pane != null) {
+ pane.setFast(visible);
+ }
+ }
+ }
+
+ /**
+ * Sets the selection for the shortcut bar icon representing the givevn fast
+ * view.
+ */
+ private void setFastViewIconSelection(IViewReference ref, boolean selected) {
+ if (fastViewManager == null)
+ return;
+
+ fastViewManager.setFastViewIconSelection(ref, selected);
+ }
+
+ /**
+ * Sets the new wizard actions for the page. This is List of Strings.
+ */
+ public void setNewWizardActionIds(ArrayList newList) {
+ newWizardShortcuts = newList;
+ }
+
+ /**
+ * Sets the perspective actions for this page. This is List of Strings.
+ */
+ public void setPerspectiveActionIds(ArrayList list) {
+ perspectiveShortcuts = list;
+ }
+
+ /**
+ * Sets the ids of the parts to list in the Show In... prompter. This is a
+ * List of Strings.
+ */
+ public void setShowInPartIds(ArrayList list) {
+ showInPartIds = list;
+ }
+
+ /**
+ * Sets the ids of the views to list in the Show View shortcuts. This is a
+ * List of Strings.
+ */
+ public void setShowViewActionIds(ArrayList list) {
+ showViewShortcuts = list;
+ }
+
+ /**
+ * Show the editor area if not visible
+ */
+ protected void showEditorArea() {
+ if (isEditorAreaVisible()) {
+ return;
+ }
+
+ editorHidden = false;
+
+ // Show the editor in the appropriate location
+ if (useNewMinMax(this)) {
+ boolean isMinimized = editorAreaState == IStackPresentationSite.STATE_MINIMIZED;
+ if (!isMinimized) {
+ // If the editor area is going to show then we have to restore
+ if (getPresentation().getMaximizedStack() != null)
+ getPresentation().getMaximizedStack().setState(
+ IStackPresentationSite.STATE_RESTORED);
+
+ showEditorAreaLocal();
+ } else
+ setEditorAreaTrimVisibility(true);
+ } else {
+ showEditorAreaLocal();
+ }
+ }
+
+ /**
+ * Show the editor area if not visible
+ */
+ protected void showEditorAreaLocal() {
+ if (editorHolder == null || editorHidden) {
+ return;
+ }
+
+ // Replace the part holder with the editor area.
+ presentation.getLayout().replace(editorHolder, editorArea);
+ editorHolder = null;
+ }
+
+ private EditorAreaTrimToolBar getEditorAreaTrim(boolean createIfNecessary) {
+ WorkbenchWindow wbw = (WorkbenchWindow) page.getWorkbenchWindow();
+ ITrimManager tbm = wbw.getTrimManager();
+ if (tbm == null)
+ return null;
+
+ // Create if necesary
+ EditorAreaTrimToolBar editorAreaTrim = (EditorAreaTrimToolBar) tbm
+ .getTrim(IPageLayout.ID_EDITOR_AREA);
+ if (editorAreaTrim == null && createIfNecessary) {
+ int suggestedSide = SWT.RIGHT;
+ int cachedSide = ((TrimLayout) tbm)
+ .getPreferredArea(IPageLayout.ID_EDITOR_AREA);
+ if (cachedSide != -1)
+ suggestedSide = cachedSide;
+
+ IWindowTrim beforeMe = ((TrimLayout) tbm)
+ .getPreferredLocation(IPageLayout.ID_EDITOR_AREA);
+
+ // Gain access to the trim manager
+ editorAreaTrim = new EditorAreaTrimToolBar(wbw, editorArea);
+ editorAreaTrim.dock(suggestedSide);
+ tbm.addTrim(suggestedSide, editorAreaTrim, beforeMe);
+ }
+
+ return editorAreaTrim;
+ }
+
+ public void setEditorAreaState(int newState) {
+ if (newState == editorAreaState)
+ return;
+
+ editorAreaState = newState;
+
+ // reset the restore flag if we're not minimized
+ if (newState != IStackPresentationSite.STATE_MINIMIZED)
+ editorAreaRestoreOnUnzoom = false;
+
+ refreshEditorAreaVisibility();
+ }
+
+ public int getEditorAreaState() {
+ return editorAreaState;
+ }
+
+ /**
+ *
+ */
+ public void refreshEditorAreaVisibility() {
+ // Nothing shows up if the editor area isn't visible at all
+ if (editorHidden) {
+ hideEditorAreaLocal();
+ setEditorAreaTrimVisibility(false);
+ return;
+ }
+
+ EditorStack editorStack = ((EditorSashContainer) editorArea)
+ .getUpperRightEditorStack(null);
+ if (editorStack == null)
+ return;
+
+ // Whatever we're doing, make the current editor stack match it
+ editorStack.setStateLocal(editorAreaState);
+
+ // If it's minimized then it's in the trim
+ if (editorAreaState == IStackPresentationSite.STATE_MINIMIZED) {
+ // Hide the editor area and show its trim
+ hideEditorAreaLocal();
+ setEditorAreaTrimVisibility(true);
+ } else {
+ // Show the editor area and hide its trim
+ setEditorAreaTrimVisibility(false);
+ showEditorAreaLocal();
+
+ if (editorAreaState == IStackPresentationSite.STATE_MAXIMIZED)
+ getPresentation().setMaximizedStack(editorStack);
+ }
+ }
+
+ protected EditorAreaTrimToolBar setEditorAreaTrimVisibility(boolean visible) {
+ WorkbenchWindow wbw = (WorkbenchWindow) page.getWorkbenchWindow();
+ ITrimManager tbm = wbw.getTrimManager();
+ if (tbm == null)
+ return null;
+
+ // Only create the trim element if it's going to be visible
+ EditorAreaTrimToolBar editorAreaTrim = getEditorAreaTrim(visible);
+ if (editorAreaTrim == null)
+ return null;
+
+ tbm.setTrimVisible(editorAreaTrim, visible);
+ tbm.forceLayout();
+
+ return editorAreaTrim;
+ }
+
+ /**
+ * Shows a fast view.
+ *
+ * @return whether the view was successfully shown
+ */
+ boolean showFastView(IViewReference ref) {
+ if (fastViewManager == null)
+ return false;
+
+ // Make sure the part is restored.
+ IWorkbenchPart refPart = ref.getPart(true);
+ if (refPart == null) {
+ return false;
+ }
+
+ ViewPane pane = getPane(ref);
+ if (pane == null) {
+ return false;
+ }
+
+ saveFastViewWidthRatio();
+
+ // Special check to ensure that a 'minimized' intro view shows
+ // as 'standby'
+ if (ref.getId().equals("org.eclipse.ui.internal.introview")) { //$NON-NLS-1$
+ if (refPart instanceof ViewIntroAdapterPart) {
+ ((ViewIntroAdapterPart) refPart).setStandby(true);
+ }
+ }
+
+ // Determine the display orientation
+ int side = fastViewManager.getViewSide(ref);
+ fastViewPane.showView(getClientComposite(), pane, side,
+ getFastViewWidthRatio(ref));
+
+ setFastViewIconSelection(ref, true);
+
+ return true;
+ }
+
+ private void saveFastViewWidthRatio() {
+ ViewPane pane = fastViewPane.getCurrentPane();
+ if (pane != null) {
+ ViewLayoutRec rec = getViewLayoutRec(pane.getViewReference(), true);
+ rec.fastViewWidthRatio = fastViewPane.getCurrentRatio();
+ }
+ }
+
+ /**
+ * Resolves a view's id into its reference, creating the view if necessary.
+ *
+ * @param viewId
+ * The primary id of the view (must not be <code>null</code>
+ * @param secondaryId
+ * The secondary id of a multiple-instance view (may be
+ * <code>null</code>).
+ *
+ * @return The reference to the specified view. This may be null if the view
+ * fails to create (i.e. thrown a PartInitException)
+ */
+ public IViewReference getViewReference(String viewId, String secondaryId) {
+ IViewReference ref = page.findViewReference(viewId, secondaryId);
+ if (ref == null) {
+ ViewFactory factory = getViewFactory();
+ try {
+ ref = factory.createView(viewId, secondaryId);
+ } catch (PartInitException e) {
+ IStatus status = StatusUtil.newStatus(IStatus.ERROR, e
+ .getMessage() == null ? "" : e.getMessage(), //$NON-NLS-1$
+ e);
+ StatusUtil.handleStatus(status,
+ "Failed to create view: id=" + viewId, //$NON-NLS-1$
+ StatusManager.LOG);
+ }
+ }
+ return ref;
+ }
+
+ private MElementContainer<MUIElement> findBottomStack(MPerspective persp) {
+ List stacks = new ArrayList();
+ gatherStacks(persp, stacks);
+ if (stacks.size() > 0)
+ return (MElementContainer<MUIElement>) stacks
+ .get(stacks.size() - 1);
+ return null;
+ }
+
+ /**
+ * @param persp
+ * @param stacks
+ */
+ private void gatherStacks(MElementContainer<? extends MUIElement> persp,
+ List stacks) {
+ for (MUIElement kid : persp.getChildren()) {
+ if (kid instanceof ViewStack) {
+ stacks.add(kid);
+ }
+ if (kid instanceof MElementContainer<?>)
+ gatherStacks((MElementContainer<? extends MUIElement>) kid,
+ stacks);
+ }
+ }
+
+ /**
+ * Shows the view with the given id and secondary id.
+ */
+ public IViewPart showView(String viewId, String secondaryId)
+ throws PartInitException {
+ // Is it already there?
+ MWindow e4Window = page.getModelWindow();
+ MPerspectiveStack perspStack = (MPerspectiveStack) ModeledPageLayout
+ .findElementById(e4Window, "PerspectiveStack"); //$NON-NLS-1$
+ final MPerspective perspectiveModel = (MPerspective) perspStack
+ .getActiveChild();
+ MView view = (MView) ModeledPageLayout.findPart(perspectiveModel,
+ viewId);
+
+ // also check 'stickyRight' since it's not in a perspective
+ if (view == null) {
+ ViewStack stickyRight = (ViewStack) ModeledPageLayout
+ .findElementById(e4Window, "stickyRight"); //$NON-NLS-1$
+ view = (MView) ModeledPageLayout.findElementById(
+ (MUIElement) stickyRight, viewId);
+ }
+ boolean doLayout = false;
+
+ // if not, add it
+ MElementContainer<MUIElement> theStack = null;
+ if (view == null) {
+ // Place it in the 'bottom' stack
+ theStack = (MElementContainer<MUIElement>) ModeledPageLayout
+ .findElementById(perspectiveModel, "bottom"); //$NON-NLS-1$
+ if (theStack == null)
+ theStack = findBottomStack(perspectiveModel);
+
+ // If the stack is hidden, show it
+ if (!theStack.isVisible()) {
+ theStack.setVisible(true);
+ doLayout = true;
+ }
+
+ view = ModeledPageLayout.createViewModel(viewId, true);
+ theStack.getChildren().add(view);
+ } else {
+ // Its stack is where it already is
+ theStack = view.getParent();
+
+ // If the stack is hidden, show it
+ if (!theStack.isVisible()) {
+ theStack.setVisible(true);
+ doLayout = true;
+ }
+
+ // create it if necessary
+ if (!view.isVisible()) {
+ // Move it to the end of the stack
+ theStack.getChildren().remove(view);
+ theStack.getChildren().add(view);
+ view.setVisible(true);
+ }
+ }
+
+ if (doLayout && theStack.getParent().getWidget() instanceof Composite) {
+ Composite comp = (Composite) theStack.getParent().getWidget();
+ comp.layout(true);
+ }
+
+ // OK, make it active
+ theStack.setActiveChild(view);
+
+ LegacyView lView = (LegacyView) view.getObject();
+ return lView != null ? lView.getViewPart() : null;
+ }
+
+ /**
+ * Toggles the visibility of a fast view. If the view is active it is
+ * deactivated. Otherwise, it is activated.
+ */
+ public void toggleFastView(IViewReference ref) {
+ if (ref == activeFastView) {
+ setActiveFastView(null);
+ } else {
+ setActiveFastView(ref);
+ }
+ }
+
+ /**
+ * Returns the old part reference. Returns null if there was no previously
+ * active part.
+ *
+ * @return the old part reference or <code>null</code>
+ */
+ public IWorkbenchPartReference getOldPartRef() {
+ return oldPartRef;
+ }
+
+ /**
+ * Sets the old part reference.
+ *
+ * @param oldPartRef
+ * The old part reference to set, or <code>null</code>
+ */
+ public void setOldPartRef(IWorkbenchPartReference oldPartRef) {
+ this.oldPartRef = oldPartRef;
+ }
+
+ // for dynamic UI
+ protected void addActionSet(IActionSetDescriptor newDesc) {
+ IContextService service = (IContextService) page.getWorkbenchWindow()
+ .getService(IContextService.class);
+ try {
+ service.deferUpdates(true);
+ for (int i = 0; i < alwaysOnActionSets.size(); i++) {
+ IActionSetDescriptor desc = (IActionSetDescriptor) alwaysOnActionSets
+ .get(i);
+ if (desc.getId().equals(newDesc.getId())) {
+ removeAlwaysOn(desc);
+ removeAlwaysOff(desc);
+ break;
+ }
+ }
+ addAlwaysOn(newDesc);
+ } finally {
+ service.deferUpdates(false);
+ }
+ }
+
+ // for dynamic UI
+ /* package */void removeActionSet(String id) {
+ IContextService service = (IContextService) page.getWorkbenchWindow()
+ .getService(IContextService.class);
+ try {
+ service.deferUpdates(true);
+ for (int i = 0; i < alwaysOnActionSets.size(); i++) {
+ IActionSetDescriptor desc = (IActionSetDescriptor) alwaysOnActionSets
+ .get(i);
+ if (desc.getId().equals(id)) {
+ removeAlwaysOn(desc);
+ break;
+ }
+ }
+
+ for (int i = 0; i < alwaysOffActionSets.size(); i++) {
+ IActionSetDescriptor desc = (IActionSetDescriptor) alwaysOffActionSets
+ .get(i);
+ if (desc.getId().equals(id)) {
+ removeAlwaysOff(desc);
+ break;
+ }
+ }
+ } finally {
+ service.deferUpdates(false);
+ }
+ }
+
+ void removeActionSet(IActionSetDescriptor toRemove) {
+ removeAlwaysOn(toRemove);
+ removeAlwaysOff(toRemove);
+ }
+
+ public void setFastViewState(int newState) {
+ fastViewPane.setState(newState);
+ }
+
+ public int getFastViewState() {
+ return fastViewPane.getState();
+ }
+
+ /**
+ * Returns whether the given view is closeable in this perspective.
+ *
+ * @since 3.0
+ */
+ public boolean isCloseable(IViewReference reference) {
+ ViewLayoutRec rec = getViewLayoutRec(reference, false);
+ if (rec != null) {
+ return rec.isCloseable;
+ }
+ return true;
+ }
+
+ /**
+ * Returns whether the given view is moveable in this perspective.
+ *
+ * @since 3.0
+ */
+ public boolean isMoveable(IViewReference reference) {
+ ViewLayoutRec rec = getViewLayoutRec(reference, false);
+ if (rec != null) {
+ return rec.isMoveable;
+ }
+ return true;
+ }
+
+ /**
+ * Writes a description of the layout to the given string buffer. This is
+ * used for drag-drop test suites to determine if two layouts are the same.
+ * Like a hash code, the description should compare as equal iff the layouts
+ * are the same. However, it should be user-readable in order to help debug
+ * failed tests. Although these are english readable strings, they should
+ * not be translated or equality tests will fail.
+ * <p>
+ * This is only intended for use by test suites.
+ * </p>
+ *
+ * @param buf
+ */
+ public void describeLayout(StringBuffer buf) {
+ IViewReference[] fastViews = getFastViews();
+
+ if (fastViews.length != 0) {
+ buf.append("fastviews ("); //$NON-NLS-1$
+ for (int idx = 0; idx < fastViews.length; idx++) {
+ IViewReference ref = fastViews[idx];
+
+ if (idx > 0) {
+ buf.append(", "); //$NON-NLS-1$
+ }
+
+ buf.append(ref.getPartName());
+ }
+ buf.append("), "); //$NON-NLS-1$
+ }
+
+ getPresentation().describeLayout(buf);
+ }
+
+ /**
+ * Sanity-checks the LayoutParts in this perspective. Throws an Assertation
+ * exception if an object's internal state is invalid.
+ */
+ public void testInvariants() {
+ getPresentation().getLayout().testInvariants();
+ }
+
+ public IActionSetDescriptor[] getAlwaysOnActionSets() {
+ return (IActionSetDescriptor[]) alwaysOnActionSets
+ .toArray(new IActionSetDescriptor[alwaysOnActionSets.size()]);
+ }
+
+ public IActionSetDescriptor[] getAlwaysOffActionSets() {
+ return (IActionSetDescriptor[]) alwaysOffActionSets
+ .toArray(new IActionSetDescriptor[alwaysOffActionSets.size()]);
+ }
+
+ /* package */FastViewPane getFastViewPane() {
+ return fastViewPane;
+ }
+
+ /**
+ * Restores a part in the trim to the actual layout
+ *
+ * @param part
+ * The part to restore
+ */
+ public void restoreTrimPart(LayoutPart part) {
+ if (fastViewManager == null)
+ return;
+
+ // Remove any current fastview
+ setActiveFastView(null);
+
+ // Set the part's state to place it back in the layout
+ if (part instanceof ViewStack) {
+ ViewStack vs = (ViewStack) part;
+ fastViewManager.restoreToPresentation(vs.getID());
+ }
+
+ if (part == editorArea) {
+ setEditorAreaState(IStackPresentationSite.STATE_RESTORED);
+ editorAreaRestoreOnUnzoom = false;
+ }
+ }
+
+ /**
+ * Determine the correct side to initially dock a new trim part on. We do
+ * this by checking its rect against the editor area.
+ *
+ * @param stackBounds
+ * The bounds of the stack we want to create trim for
+ * @return the SWT side to dock the trim element on
+ */
+ public int calcStackSide(Rectangle stackBounds) {
+ // Where is the stack in relation to the EditorArea?
+ Rectangle editorAreaBounds = editorArea.getBounds();
+
+ // Is this the Editor Area
+ if (editorAreaBounds.equals(stackBounds))
+ return SWT.TOP;
+
+ Point stackCenter = Geometry.centerPoint(stackBounds);
+ Point editorAreaCenter = Geometry.centerPoint(editorAreaBounds);
+
+ int dx = editorAreaCenter.x - stackCenter.x;
+ int dy = editorAreaCenter.y - stackCenter.y;
+
+ if (Math.abs(dx) > Math.abs(dy)) {
+ return (dx > 0) ? SWT.LEFT : SWT.RIGHT;
+ }
+
+ if (dy > 0) {
+ return (dx > 0) ? SWT.LEFT : SWT.RIGHT;
+ }
+
+ return SWT.BOTTOM;
+ }
+
+ /**
+ * Restore any parts that are showing in the trim as a result of a 'zoom'
+ * operation
+ */
+ public void restoreZoomedParts() {
+ if (fastViewManager == null)
+ return;
+
+ // Remove any current fastview
+ setActiveFastView(null);
+
+ // have the layout restore the parts
+ fastViewManager.restoreZoomedViewStacks();
+
+ if (editorAreaRestoreOnUnzoom) {
+ restoreTrimPart(editorArea);
+ }
+ }
+
+ /**
+ * @return Returns the fastViewManager.
+ */
+ public FastViewManager getFastViewManager() {
+ return fastViewManager;
+ }
+
+ /**
+ * Sets the restore on unzoom state for the editor area
+ *
+ * @param restore
+ * the new state
+ */
+ public void setEditorAreaRestoreOnUnzoom(boolean restore) {
+ editorAreaRestoreOnUnzoom = restore;
+ }
+
+ /**
+ * @return the restore on unzoom state
+ */
+ public boolean getEditorAreaRestoreOnUnzoom() {
+ return editorAreaRestoreOnUnzoom;
+ }
+
+ /**
+ * Used to restrict the use of the new min/max behavior to envoronments in
+ * which it has a chance of working...
+ *
+ * @param activePerspective
+ * We pass this in as an arg so others won't have to check it for
+ * 'null' (which is one of the failure cases)
+ *
+ */
+ public static boolean useNewMinMax(Perspective activePerspective) {
+ // We need to have an active perspective
+ if (activePerspective == null)
+ return false;
+
+ // We need to have a trim manager (if we don't then we
+ // don't create a FastViewManager because it'd be useless)
+ if (activePerspective.getFastViewManager() == null)
+ return false;
+
+ // Make sure we don't NPE anyplace
+ WorkbenchWindow wbw = (WorkbenchWindow) activePerspective.page
+ .getWorkbenchWindow();
+ if (wbw == null)
+ return false;
+
+ WorkbenchWindowConfigurer configurer = wbw.getWindowConfigurer();
+ if (configurer == null)
+ return false;
+
+ AbstractPresentationFactory factory = configurer
+ .getPresentationFactory();
+ if (factory == null)
+ return false;
+
+ // Ok, we should be good to go, return the pref
+ IPreferenceStore preferenceStore = PrefUtil.getAPIPreferenceStore();
+ boolean useNewMinMax = preferenceStore
+ .getBoolean(IWorkbenchPreferenceConstants.ENABLE_NEW_MIN_MAX);
+ return useNewMinMax;
+ }
+
+ /** @return a Collection of IDs of items to be hidden from the menu bar */
+ public Collection getHiddenMenuItems() {
+ return hideMenuIDs;
+ }
+
+ /** @return a Collection of IDs of items to be hidden from the tool bar */
+ public Collection getHiddenToolbarItems() {
+ return hideToolBarIDs;
+ }
+
+ public void updateActionBars() {
+ page.getActionBars().getMenuManager().updateAll(true);
+ page.resetToolBarLayout();
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ViewIntroAdapterPart.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ViewIntroAdapterPart.java
new file mode 100644
index 0000000..6b286ce
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ViewIntroAdapterPart.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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.ui.internal;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.internal.intro.IntroMessages;
+import org.eclipse.ui.intro.IIntroPart;
+import org.eclipse.ui.intro.IIntroSite;
+import org.eclipse.ui.part.ViewPart;
+
+/**
+ * Simple view that will wrap an <code>IIntroPart</code>.
+ *
+ * e4: hacked to remove reference to
+ * WorkbenchPartReference.addInternalPropertyListener
+ *
+ * @since 3.0
+ */
+public final class ViewIntroAdapterPart extends ViewPart {
+
+ private boolean handleZoomEvents = true;
+
+ private IIntroPart introPart;
+
+ private IIntroSite introSite;
+
+ private Composite parentControl;
+
+ /**
+ * Adds a listener that toggles standby state if the view pane is zoomed.
+ */
+ private void addPaneListener() {
+ // e4: switch from using internal property listener
+ parentControl.addControlListener(new ControlAdapter() {
+ boolean isInitialized = false;
+ boolean isStandby = false;
+
+ @Override
+ public void controlResized(ControlEvent e) {
+ if (handleZoomEvents) {
+ // put view in standby mode if smaller than a certain size
+ boolean newStandby = parentControl.getBounds().width < 600;
+ if (!isInitialized || newStandby != isStandby) {
+ isInitialized = true;
+ isStandby = newStandby;
+ setStandby(newStandby);
+ }
+ }
+ }
+ });
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets
+ * .Composite)
+ */
+ public void createPartControl(Composite parent) {
+ this.parentControl = parent;
+ addPaneListener();
+ introPart.createPartControl(parent);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPart#dispose()
+ */
+ public void dispose() {
+ setBarVisibility(true);
+ super.dispose();
+ getSite().getWorkbenchWindow().getWorkbench().getIntroManager()
+ .closeIntro(introPart);
+ introPart.dispose();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ public Object getAdapter(Class adapter) {
+ return introPart.getAdapter(adapter);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.part.WorkbenchPart#getTitle()
+ */
+ public String getTitle() {
+ // this method is called eagerly before our init method is called (and
+ // therefore before our intropart is created). By default return
+ // the view title from the view declaration. We will fire a property
+ // change to set the title to the proper value in the init method.
+ return introPart == null ? super.getTitle() : introPart.getTitle();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPart#getTitleImage()
+ */
+ public Image getTitleImage() {
+ return introPart.getTitleImage();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite,
+ * org.eclipse.ui.IMemento)
+ */
+ public void init(IViewSite site, IMemento memento) throws PartInitException {
+ super.init(site);
+ Workbench workbench = (Workbench) site.getWorkbenchWindow()
+ .getWorkbench();
+ try {
+ introPart = workbench.getWorkbenchIntroManager()
+ .createNewIntroPart();
+ // reset the part name of this view to be that of the intro title
+ setPartName(introPart.getTitle());
+ introPart.addPropertyListener(new IPropertyListener() {
+ public void propertyChanged(Object source, int propId) {
+ firePropertyChange(propId);
+ }
+ });
+ introSite = new ViewIntroAdapterSite(site, workbench
+ .getIntroDescriptor());
+ introPart.init(introSite, memento);
+
+ } catch (CoreException e) {
+ WorkbenchPlugin.log(IntroMessages.Intro_could_not_create_proxy,
+ new Status(IStatus.ERROR, WorkbenchPlugin.PI_WORKBENCH,
+ IStatus.ERROR,
+ IntroMessages.Intro_could_not_create_proxy, e));
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IViewPart#saveState(org.eclipse.ui.IMemento)
+ */
+ public void saveState(IMemento memento) {
+ introPart.saveState(memento);
+ }
+
+ /**
+ * Sets whether the CoolBar/PerspectiveBar should be visible.
+ *
+ * @param visible
+ * whether the CoolBar/PerspectiveBar should be visible
+ * @since 3.1
+ */
+ private void setBarVisibility(final boolean visible) {
+ WorkbenchWindow window = (WorkbenchWindow) getSite()
+ .getWorkbenchWindow();
+
+ final boolean layout = (visible != window.getCoolBarVisible())
+ || (visible != window.getPerspectiveBarVisible()); // don't
+ // layout unless things have actually changed
+ if (visible) {
+ window.setCoolBarVisible(true);
+ window.setPerspectiveBarVisible(true);
+ } else {
+ window.setCoolBarVisible(false);
+ window.setPerspectiveBarVisible(false);
+ }
+
+ if (layout) {
+ window.getShell().layout();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPart#setFocus()
+ */
+ public void setFocus() {
+ introPart.setFocus();
+ }
+
+ /**
+ * Toggles handling of zoom events.
+ *
+ * @param handle
+ * whether to handle zoom events
+ */
+ public void setHandleZoomEvents(boolean handle) {
+ handleZoomEvents = handle;
+ }
+
+ /**
+ * Forces the standby state of the intro part.
+ *
+ * @param standby
+ * update the standby state
+ */
+ public void setStandby(final boolean standby) {
+ final Control control = parentControl;
+ if (control == null || control.isDisposed())
+ return;
+ BusyIndicator.showWhile(control.getDisplay(), new Runnable() {
+ public void run() {
+ try {
+ control.setRedraw(false);
+ introPart.standbyStateChanged(standby);
+ } finally {
+ control.setRedraw(true);
+ }
+
+ setBarVisibility(standby);
+ }
+ });
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ViewSite.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ViewSite.java
new file mode 100644
index 0000000..3509af1
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ViewSite.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.ui.internal;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.internal.provisional.action.ToolBarManager2;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.SubActionBars;
+
+/**
+ * A view container manages the services for a view.
+ */
+public class ViewSite extends PartSite implements IViewSite {
+
+ /**
+ * @param ref
+ * @param part
+ * @param page
+ */
+ public ViewSite(IViewReference ref, IWorkbenchPart part, IWorkbenchPage page) {
+ super(ref, part, page);
+ SubActionBars bars = new SubActionBars(((WorkbenchPage) page)
+ .getActionBars(), serviceLocator) {
+ private IToolBarManager tbMgr;
+ private MenuManager menuMgr;
+
+ @Override
+ public IToolBarManager getToolBarManager() {
+ if (tbMgr == null) {
+ tbMgr = new ToolBarManager2();
+ }
+ return tbMgr;
+ }
+
+ @Override
+ public IMenuManager getMenuManager() {
+ if (menuMgr == null) {
+ menuMgr = new MenuManager();
+ }
+ return menuMgr;
+ }
+ };
+ setActionBars(bars);
+ }
+
+ /**
+ * Returns the secondary id or <code>null</code>.
+ */
+ public String getSecondaryId() {
+ return ((IViewReference) getPartReference()).getSecondaryId();
+ }
+
+ /**
+ * Returns the view.
+ */
+ public IViewPart getViewPart() {
+ return (IViewPart) getPart();
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/Workbench.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/Workbench.java
new file mode 100644
index 0000000..ce0a3ff
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/Workbench.java
@@ -0,0 +1,3935 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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
+ * Francis Upton - <francisu@ieee.org> -
+ * Fix for Bug 217777 [Workbench] Workbench event loop does not terminate if Display is closed
+ *******************************************************************************/
+
+package org.eclipse.ui.internal;
+
+import com.ibm.icu.util.ULocale;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.Category;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.CommandManager;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.common.EventManager;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.commands.contexts.ContextManager;
+import org.eclipse.core.databinding.observable.Realm;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProduct;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IRegistryChangeEvent;
+import org.eclipse.core.runtime.IRegistryChangeListener;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.e4.core.commands.ECommandService;
+import org.eclipse.e4.core.contexts.ContextFunction;
+import org.eclipse.e4.core.contexts.EclipseContextFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.extensions.ExtensionUtils;
+import org.eclipse.e4.ui.internal.workbench.swt.ResourceUtility;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.MApplicationFactory;
+import org.eclipse.e4.ui.model.application.commands.MCommand;
+import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
+import org.eclipse.e4.ui.services.EContextService;
+import org.eclipse.e4.workbench.ui.menus.MenuHelper;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.ExternalActionManager;
+import org.eclipse.jface.action.ExternalActionManager.CommandCallback;
+import org.eclipse.jface.action.ExternalActionManager.IActiveChecker;
+import org.eclipse.jface.action.ExternalActionManager.IExecuteApplicable;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.LegacyActionTools;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.bindings.BindingManager;
+import org.eclipse.jface.bindings.BindingManagerEvent;
+import org.eclipse.jface.bindings.IBindingManagerListener;
+import org.eclipse.jface.databinding.swt.SWTObservables;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.ModalContext;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceManager;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.util.OpenStrategy;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.window.IShellProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.window.WindowManager;
+import org.eclipse.osgi.service.datalocation.Location;
+import org.eclipse.osgi.service.runnable.StartupMonitor;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.DeviceData;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IDecoratorManager;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IElementFactory;
+import org.eclipse.ui.ILocalWorkingSetManager;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.IPerspectiveRegistry;
+import org.eclipse.ui.ISaveableFilter;
+import org.eclipse.ui.ISaveablePart;
+import org.eclipse.ui.ISaveablesLifecycleListener;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.ISourceProvider;
+import org.eclipse.ui.ISourceProviderListener;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.IWindowListener;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchListener;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPreferenceConstants;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.LegacyHandlerService;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.Saveable;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.XMLMemento;
+import org.eclipse.ui.activities.IWorkbenchActivitySupport;
+import org.eclipse.ui.application.IWorkbenchConfigurer;
+import org.eclipse.ui.application.WorkbenchAdvisor;
+import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
+import org.eclipse.ui.commands.ICommandImageService;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.commands.IWorkbenchCommandSupport;
+import org.eclipse.ui.contexts.IContextService;
+import org.eclipse.ui.contexts.IWorkbenchContextSupport;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.help.IWorkbenchHelpSystem;
+import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
+import org.eclipse.ui.internal.actions.CommandAction;
+import org.eclipse.ui.internal.activities.ws.WorkbenchActivitySupport;
+import org.eclipse.ui.internal.browser.WorkbenchBrowserSupport;
+import org.eclipse.ui.internal.commands.CommandImageManager;
+import org.eclipse.ui.internal.commands.CommandImageService;
+import org.eclipse.ui.internal.commands.CommandService;
+import org.eclipse.ui.internal.commands.WorkbenchCommandSupport;
+import org.eclipse.ui.internal.contexts.ActiveContextSourceProvider;
+import org.eclipse.ui.internal.contexts.ContextService;
+import org.eclipse.ui.internal.contexts.WorkbenchContextSupport;
+import org.eclipse.ui.internal.dialogs.PropertyPageContributorManager;
+import org.eclipse.ui.internal.help.WorkbenchHelpSystem;
+import org.eclipse.ui.internal.intro.IIntroRegistry;
+import org.eclipse.ui.internal.intro.IntroDescriptor;
+import org.eclipse.ui.internal.keys.BindingService;
+import org.eclipse.ui.internal.menus.FocusControlSourceProvider;
+import org.eclipse.ui.internal.menus.WorkbenchMenuService;
+import org.eclipse.ui.internal.misc.Policy;
+import org.eclipse.ui.internal.misc.StatusUtil;
+import org.eclipse.ui.internal.misc.UIStats;
+import org.eclipse.ui.internal.model.ContributionService;
+import org.eclipse.ui.internal.progress.ProgressManager;
+import org.eclipse.ui.internal.registry.IActionSetDescriptor;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.internal.registry.UIExtensionTracker;
+import org.eclipse.ui.internal.services.ActionSetSourceProvider;
+import org.eclipse.ui.internal.services.EvaluationService;
+import org.eclipse.ui.internal.services.IServiceLocatorCreator;
+import org.eclipse.ui.internal.services.IWorkbenchLocationService;
+import org.eclipse.ui.internal.services.MenuSourceProvider;
+import org.eclipse.ui.internal.services.ServiceLocator;
+import org.eclipse.ui.internal.services.ServiceLocatorCreator;
+import org.eclipse.ui.internal.services.SourceProviderService;
+import org.eclipse.ui.internal.services.WorkbenchLocationService;
+import org.eclipse.ui.internal.splash.EclipseSplashHandler;
+import org.eclipse.ui.internal.splash.SplashHandlerFactory;
+import org.eclipse.ui.internal.testing.WorkbenchTestable;
+import org.eclipse.ui.internal.themes.ColorDefinition;
+import org.eclipse.ui.internal.themes.FontDefinition;
+import org.eclipse.ui.internal.themes.ThemeElementHelper;
+import org.eclipse.ui.internal.themes.WorkbenchThemeManager;
+import org.eclipse.ui.internal.tweaklets.GrabFocus;
+import org.eclipse.ui.internal.tweaklets.Tweaklets;
+import org.eclipse.ui.internal.util.PrefUtil;
+import org.eclipse.ui.internal.util.Util;
+import org.eclipse.ui.intro.IIntroManager;
+import org.eclipse.ui.keys.IBindingService;
+import org.eclipse.ui.menus.IMenuService;
+import org.eclipse.ui.model.IContributionService;
+import org.eclipse.ui.operations.IWorkbenchOperationSupport;
+import org.eclipse.ui.progress.IProgressService;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.services.IEvaluationService;
+import org.eclipse.ui.services.IServiceScopes;
+import org.eclipse.ui.services.ISourceProviderService;
+import org.eclipse.ui.splash.AbstractSplashHandler;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.ui.swt.IFocusService;
+import org.eclipse.ui.themes.IThemeManager;
+import org.eclipse.ui.views.IViewRegistry;
+import org.eclipse.ui.wizards.IWizardRegistry;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * The workbench class represents the top of the Eclipse user interface. Its
+ * primary responsibility is the management of workbench windows, dialogs,
+ * wizards, and other workbench-related windows.
+ * <p>
+ * Note that any code that is run during the creation of a workbench instance
+ * should not required access to the display.
+ * </p>
+ * <p>
+ * Note that this internal class changed significantly between 2.1 and 3.0.
+ * Applications that used to define subclasses of this internal class need to be
+ * rewritten to use the new workbench advisor API.
+ * </p>
+ */
+public final class Workbench extends EventManager implements IWorkbench {
+
+ private final class StartupProgressBundleListener implements
+ SynchronousBundleListener {
+
+ private final IProgressMonitor progressMonitor;
+
+ private final int maximumProgressCount;
+
+ // stack of names of bundles currently starting
+ private final List starting;
+
+ StartupProgressBundleListener(IProgressMonitor progressMonitor,
+ int maximumProgressCount) {
+ super();
+ this.progressMonitor = progressMonitor;
+ this.maximumProgressCount = maximumProgressCount;
+ this.starting = new ArrayList();
+ }
+
+ public void bundleChanged(BundleEvent event) {
+ int eventType = event.getType();
+ String bundleName;
+
+ synchronized (this) {
+ if (eventType == BundleEvent.STARTING) {
+ starting.add(bundleName = event.getBundle()
+ .getSymbolicName());
+ } else if (eventType == BundleEvent.STARTED) {
+ progressCount++;
+ if (progressCount <= maximumProgressCount) {
+ progressMonitor.worked(1);
+ }
+ int index = starting.lastIndexOf(event.getBundle()
+ .getSymbolicName());
+ if (index >= 0) {
+ starting.remove(index);
+ }
+ if (index != starting.size()) {
+ return; // not currently displayed
+ }
+ bundleName = index == 0 ? null : (String) starting
+ .get(index - 1);
+ } else {
+ return; // uninteresting event
+ }
+ }
+
+ String taskName;
+
+ if (bundleName == null) {
+ taskName = WorkbenchMessages.Startup_Loading_Workbench;
+ } else {
+ taskName = NLS.bind(WorkbenchMessages.Startup_Loading,
+ bundleName);
+ }
+
+ progressMonitor.subTask(taskName);
+ }
+ }
+
+ /**
+ * Family for the early startup job.
+ */
+ public static final String EARLY_STARTUP_FAMILY = "earlyStartup"; //$NON-NLS-1$
+
+ static final String VERSION_STRING[] = { "0.046", "2.0" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+ static final String DEFAULT_WORKBENCH_STATE_FILENAME = "workbench.xml"; //$NON-NLS-1$
+
+ /**
+ * Holds onto the only instance of Workbench.
+ */
+ private static Workbench instance;
+
+ /**
+ * The testable object facade.
+ *
+ * @since 3.0
+ */
+ private static WorkbenchTestable testableObject;
+
+ /**
+ * Signals that the workbench should create a splash implementation when
+ * instantiated. Intial value is <code>true</code>.
+ *
+ * @since 3.3
+ */
+ private static boolean createSplash = true;
+
+ /**
+ * The splash handler.
+ */
+ private static AbstractSplashHandler splash;
+
+ /**
+ * The display used for all UI interactions with this workbench.
+ *
+ * @since 3.0
+ */
+ private Display display;
+
+ private WindowManager windowManager;
+
+ private WorkbenchWindow activatedWindow;
+
+ private EditorHistory editorHistory;
+
+ private boolean runEventLoop = true;
+
+ private boolean isStarting = true;
+
+ private boolean isClosing = false;
+
+ /**
+ * PlatformUI return code (as opposed to IPlatformRunnable return code).
+ */
+ private int returnCode = PlatformUI.RETURN_UNSTARTABLE;
+
+ /**
+ * Advisor providing application-specific configuration and customization of
+ * the workbench.
+ *
+ * @since 3.0
+ */
+ private WorkbenchAdvisor advisor;
+
+ /**
+ * Object for configuring the workbench. Lazily initialized to an instance
+ * unique to the workbench instance.
+ *
+ * @since 3.0
+ */
+ private WorkbenchConfigurer workbenchConfigurer;
+
+ // for dynamic UI
+ /**
+ * ExtensionEventHandler handles extension life-cycle events.
+ */
+ private ExtensionEventHandler extensionEventHandler;
+
+ /**
+ * A count of how many large updates are going on. This tracks nesting of
+ * requests to disable services during a large update -- similar to the
+ * <code>setRedraw</code> functionality on <code>Control</code>. When this
+ * value becomes greater than zero, services are disabled. When this value
+ * becomes zero, services are enabled. Please see
+ * <code>largeUpdateStart()</code> and <code>largeUpdateEnd()</code>.
+ */
+ private int largeUpdates = 0;
+
+ /**
+ * The service locator maintained by the workbench. These services are
+ * initialized during workbench during the <code>init</code> method.
+ */
+ private final ServiceLocator serviceLocator;
+
+ /**
+ * A count of how many plug-ins were loaded while restoring the workbench
+ * state. Initially -1 for unknown number.
+ */
+ private int progressCount = -1;
+
+ /**
+ * Listener list for registered IWorkbenchListeners .
+ */
+ private ListenerList workbenchListeners = new ListenerList(
+ ListenerList.IDENTITY);
+
+ private ServiceTracker locationTracker;
+
+ private ISourceProviderListener sourceListener;
+
+ /**
+ * Creates a new workbench.
+ *
+ * @param display
+ * the display to be used for all UI interactions with the
+ * workbench
+ * @param advisor
+ * the application-specific advisor that configures and
+ * specializes this workbench instance
+ * @since 3.0
+ */
+ private Workbench(Display display, WorkbenchAdvisor advisor) {
+ super();
+ StartupThreading.setWorkbench(this);
+ if (instance != null && instance.isRunning()) {
+ throw new IllegalStateException(
+ WorkbenchMessages.Workbench_CreatingWorkbenchTwice);
+ }
+ Assert.isNotNull(display);
+ Assert.isNotNull(advisor);
+ this.advisor = advisor;
+ this.display = display;
+ Workbench.instance = this;
+
+ // hook in the e4 workbench
+ IEclipseContext serviceContext = EclipseContextFactory
+ .getServiceContext(Activator.getDefault().getContext());
+ IEclipseContext appContext = EclipseContextFactory.create(
+ serviceContext, null);
+ appContext.set(IContextConstants.DEBUG_STRING, "application"); //$NON-NLS-1$
+ Location instanceLocation = getInstanceLocation();
+ PackageAdmin packageAdmin = (PackageAdmin) appContext
+ .get(PackageAdmin.class.getName());
+ String engineURI = "bundleclass://org.eclipse.e4.ui.workbench.swt/"; //$NON-NLS-1$
+ engineURI += "org.eclipse.e4.ui.workbench.swt.internal.PartRenderingEngine"; //$NON-NLS-1$
+
+ e4Workbench = new org.eclipse.e4.workbench.ui.internal.Workbench(
+ instanceLocation, Platform.getExtensionRegistry(),
+ packageAdmin, appContext, new WorkbenchWindowHandler(),
+ engineURI);
+ e4Context = e4Workbench.getContext();
+ e4Context.set(getClass().getName(), this);
+ e4Context.set(IWorkbench.class.getName(), this);
+
+ IServiceLocatorCreator slc = new ServiceLocatorCreator();
+ serviceLocator = (ServiceLocator) slc.createServiceLocator(null, null,
+ new IDisposable() {
+ public void dispose() {
+ final Display display = getDisplay();
+ if (display != null && !display.isDisposed()) {
+ MessageDialog
+ .openInformation(
+ null,
+ WorkbenchMessages.Workbench_NeedsClose_Title,
+ WorkbenchMessages.Workbench_NeedsClose_Message);
+ close(PlatformUI.RETURN_RESTART, true);
+ }
+ }
+ });
+ serviceLocator.setContext(e4Context);
+ serviceLocator.registerService(IServiceLocatorCreator.class, slc);
+ serviceLocator.registerService(IWorkbenchLocationService.class,
+ new WorkbenchLocationService(IServiceScopes.WORKBENCH_SCOPE,
+ this, null, null, null, null, 0));
+ // added back for legacy reasons
+ serviceLocator.registerService(IWorkbench.class, this);
+ }
+
+ public Location getInstanceLocation() {
+ if (locationTracker == null) {
+ final BundleContext context = WorkbenchPlugin.getDefault()
+ .getBundleContext();
+ Filter filter = null;
+ try {
+ filter = context.createFilter(Location.INSTANCE_FILTER);
+ } catch (InvalidSyntaxException e) {
+ // ignore this. It should never happen as we have tested the
+ // above format.
+ }
+ locationTracker = new ServiceTracker(context, filter, null);
+ locationTracker.open();
+ }
+ return (Location) locationTracker.getService();
+ }
+
+ private MApplication createE4Model() {
+ MApplication app = MApplicationFactory.eINSTANCE.createApplication();
+ return app;
+ }
+
+ /**
+ * Returns the one and only instance of the workbench, if there is one.
+ *
+ * @return the workbench, or <code>null</code> if the workbench has not been
+ * created, or has been created and already completed
+ */
+ public static final Workbench getInstance() {
+ return instance;
+ }
+
+ /**
+ * Creates the workbench and associates it with the the given display and
+ * workbench advisor, and runs the workbench UI. This entails processing and
+ * dispatching events until the workbench is closed or restarted.
+ * <p>
+ * This method is intended to be called by <code>PlatformUI</code>. Fails if
+ * the workbench UI has already been created.
+ * </p>
+ * <p>
+ * The display passed in must be the default display.
+ * </p>
+ *
+ * @param display
+ * the display to be used for all UI interactions with the
+ * workbench
+ * @param advisor
+ * the application-specific advisor that configures and
+ * specializes the workbench
+ * @return return code {@link PlatformUI#RETURN_OK RETURN_OK}for normal
+ * exit; {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the
+ * workbench was terminated with a call to
+ * {@link IWorkbench#restart IWorkbench.restart}; other values
+ * reserved for future use
+ */
+ public static final int createAndRunWorkbench(final Display display,
+ final WorkbenchAdvisor advisor) {
+ final int[] returnCode = new int[1];
+ Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
+ public void run() {
+ ULocale.setDefault(new ULocale(Platform.getNL()
+ + Platform.getNLExtensions()));
+ // create the workbench instance
+ Workbench workbench = new Workbench(display, advisor);
+ // run the workbench event loop
+ returnCode[0] = workbench.runUI();
+ }
+ });
+ return returnCode[0];
+ }
+
+ /**
+ * Creates the <code>Display</code> to be used by the workbench.
+ *
+ * @return the display
+ */
+ public static Display createDisplay() {
+ // setup the application name used by SWT to lookup resources on some
+ // platforms
+ String applicationName = WorkbenchPlugin.getDefault().getAppName();
+ if (applicationName != null) {
+ Display.setAppName(applicationName);
+ }
+
+ // create the display
+ Display newDisplay = Display.getCurrent();
+ if (newDisplay == null) {
+ if (Policy.DEBUG_SWT_GRAPHICS || Policy.DEBUG_SWT_DEBUG) {
+ DeviceData data = new DeviceData();
+ if (Policy.DEBUG_SWT_GRAPHICS) {
+ data.tracking = true;
+ }
+ if (Policy.DEBUG_SWT_DEBUG) {
+ data.debug = true;
+ }
+ newDisplay = new Display(data);
+ } else {
+ newDisplay = new Display();
+ }
+ }
+
+ // workaround for 1GEZ9UR and 1GF07HN
+ newDisplay.setWarnings(false);
+
+ // Set the priority higher than normal so as to be higher
+ // than the JobManager.
+ Thread.currentThread().setPriority(
+ Math.min(Thread.MAX_PRIORITY, Thread.NORM_PRIORITY + 1));
+
+ initializeImages();
+
+ return newDisplay;
+ }
+
+ /**
+ * Create the splash wrapper and set it to work.
+ *
+ * @since 3.3
+ */
+ private void createSplashWrapper() {
+ final Display display = getDisplay();
+ String splashLoc = System
+ .getProperty("org.eclipse.equinox.launcher.splash.location"); //$NON-NLS-1$
+ final Image background = loadImage(splashLoc);
+
+ SafeRunnable run = new SafeRunnable() {
+
+ public void run() throws Exception {
+ if (!WorkbenchPlugin.isSplashHandleSpecified()) {
+ createSplash = false;
+ return;
+ }
+
+ // create the splash
+ getSplash();
+ if (splash == null) {
+ createSplash = false;
+ return;
+ }
+
+ Shell splashShell = splash.getSplash();
+ if (splashShell == null) {
+ splashShell = WorkbenchPlugin.getSplashShell(display);
+
+ if (splashShell == null)
+ return;
+ if (background != null)
+ splashShell.setBackgroundImage(background);
+ }
+
+ Dictionary properties = new Hashtable();
+ properties.put(Constants.SERVICE_RANKING, new Integer(
+ Integer.MAX_VALUE));
+ BundleContext context = WorkbenchPlugin.getDefault()
+ .getBundleContext();
+ final ServiceRegistration registration[] = new ServiceRegistration[1];
+ StartupMonitor startupMonitor = new StartupMonitor() {
+
+ public void applicationRunning() {
+ splash.dispose();
+ if (background != null)
+ background.dispose();
+ registration[0].unregister(); // unregister ourself
+ WorkbenchPlugin.unsetSplashShell(display);
+ }
+
+ public void update() {
+ // do nothing - we come into the picture far too late
+ // for this to be relevant
+ }
+ };
+ registration[0] = context.registerService(
+ StartupMonitor.class.getName(), startupMonitor,
+ properties);
+
+ splash.init(splashShell);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.util.SafeRunnable#handleException(java.lang
+ * .Throwable)
+ */
+ public void handleException(Throwable e) {
+ StatusManager.getManager().handle(
+ StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH,
+ "Could not instantiate splash", e)); //$NON-NLS-1$
+ createSplash = false;
+ splash = null;
+ if (background != null)
+ background.dispose();
+
+ }
+ };
+ SafeRunner.run(run);
+ }
+
+ /**
+ * Load an image from a filesystem path.
+ *
+ * @param splashLoc
+ * the location to load from
+ * @return the image or <code>null</code>
+ * @since 3.3
+ */
+ private Image loadImage(String splashLoc) {
+ Image background = null;
+ if (splashLoc != null) {
+ InputStream input = null;
+ try {
+ input = new BufferedInputStream(new FileInputStream(splashLoc));
+ background = new Image(display, input);
+ } catch (SWTException e) {
+ StatusManager.getManager().handle(
+ StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, e));
+ } catch (IOException e) {
+ StatusManager.getManager().handle(
+ StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, e));
+ } finally {
+ if (input != null) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ // he's done for
+ }
+ }
+ }
+ }
+ return background;
+ }
+
+ /**
+ * Return the splash handler for this application. If none is specifically
+ * provided the default Eclipse implementation is returned.
+ *
+ * @return the splash handler for this application or <code>null</code>
+ * @since 3.3
+ */
+ private static AbstractSplashHandler getSplash() {
+ if (!createSplash)
+ return null;
+
+ if (splash == null) {
+
+ IProduct product = Platform.getProduct();
+ if (product != null)
+ splash = SplashHandlerFactory.findSplashHandlerFor(product);
+
+ if (splash == null)
+ splash = new EclipseSplashHandler();
+ }
+ return splash;
+ }
+
+ /**
+ * Returns the testable object facade, for use by the test harness.
+ *
+ * @return the testable object facade
+ * @since 3.0
+ */
+ public static WorkbenchTestable getWorkbenchTestable() {
+ if (testableObject == null) {
+ testableObject = new WorkbenchTestable();
+ }
+ return testableObject;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ *
+ * @since 3.2
+ */
+ public void addWorkbenchListener(IWorkbenchListener listener) {
+ workbenchListeners.add(listener);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ *
+ * @since 3.2
+ */
+ public void removeWorkbenchListener(IWorkbenchListener listener) {
+ workbenchListeners.remove(listener);
+ }
+
+ /**
+ * Fire workbench preShutdown event, stopping at the first one to veto
+ *
+ * @param forced
+ * flag indicating whether the shutdown is being forced
+ * @return <code>true</code> to allow the workbench to proceed with
+ * shutdown, <code>false</code> to veto a non-forced shutdown
+ * @since 3.2
+ */
+ boolean firePreShutdown(final boolean forced) {
+ Object list[] = workbenchListeners.getListeners();
+ for (int i = 0; i < list.length; i++) {
+ final IWorkbenchListener l = (IWorkbenchListener) list[i];
+ final boolean[] result = new boolean[] { false };
+ SafeRunnable.run(new SafeRunnable() {
+ public void run() {
+ result[0] = l.preShutdown(Workbench.this, forced);
+ }
+ });
+ if (!result[0]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Fire workbench postShutdown event.
+ *
+ * @since 3.2
+ */
+ void firePostShutdown() {
+ Object list[] = workbenchListeners.getListeners();
+ for (int i = 0; i < list.length; i++) {
+ final IWorkbenchListener l = (IWorkbenchListener) list[i];
+ SafeRunnable.run(new SafeRunnable() {
+ public void run() {
+ l.postShutdown(Workbench.this);
+ }
+ });
+ }
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public void addWindowListener(IWindowListener l) {
+ addListenerObject(l);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public void removeWindowListener(IWindowListener l) {
+ removeListenerObject(l);
+ }
+
+ /**
+ * Fire window opened event.
+ *
+ * @param window
+ * The window which just opened; should not be <code>null</code>.
+ */
+ protected void fireWindowOpened(final IWorkbenchWindow window) {
+ Object list[] = getListeners();
+ for (int i = 0; i < list.length; i++) {
+ final IWindowListener l = (IWindowListener) list[i];
+ SafeRunner.run(new SafeRunnable() {
+ public void run() {
+ l.windowOpened(window);
+ }
+ });
+ }
+ }
+
+ /**
+ * Fire window closed event.
+ *
+ * @param window
+ * The window which just closed; should not be <code>null</code>.
+ */
+ protected void fireWindowClosed(final IWorkbenchWindow window) {
+ if (activatedWindow == window) {
+ // Do not hang onto it so it can be GC'ed
+ activatedWindow = null;
+ }
+
+ Object list[] = getListeners();
+ for (int i = 0; i < list.length; i++) {
+ final IWindowListener l = (IWindowListener) list[i];
+ SafeRunner.run(new SafeRunnable() {
+ public void run() {
+ l.windowClosed(window);
+ }
+ });
+ }
+ }
+
+ /**
+ * Fire window activated event.
+ *
+ * @param window
+ * The window which was just activated; should not be
+ * <code>null</code>.
+ */
+ protected void fireWindowActivated(final IWorkbenchWindow window) {
+ Object list[] = getListeners();
+ for (int i = 0; i < list.length; i++) {
+ final IWindowListener l = (IWindowListener) list[i];
+ SafeRunner.run(new SafeRunnable() {
+ public void run() {
+ l.windowActivated(window);
+ }
+ });
+ }
+ }
+
+ /**
+ * Fire window deactivated event.
+ *
+ * @param window
+ * The window which was just deactivated; should not be
+ * <code>null</code>.
+ */
+ protected void fireWindowDeactivated(final IWorkbenchWindow window) {
+ Object list[] = getListeners();
+ for (int i = 0; i < list.length; i++) {
+ final IWindowListener l = (IWindowListener) list[i];
+ SafeRunner.run(new SafeRunnable() {
+ public void run() {
+ l.windowDeactivated(window);
+ }
+ });
+ }
+ }
+
+ /**
+ * Closes the workbench. Assumes that the busy cursor is active.
+ *
+ * @param force
+ * true if the close is mandatory, and false if the close is
+ * allowed to fail
+ * @return true if the close succeeded, and false otherwise
+ */
+ private boolean busyClose(final boolean force) {
+
+ // notify the advisor of preShutdown and allow it to veto if not forced
+ isClosing = advisor.preShutdown();
+ if (!force && !isClosing) {
+ return false;
+ }
+
+ // notify regular workbench clients of preShutdown and allow them to
+ // veto if not forced
+ isClosing = firePreShutdown(force);
+ if (!force && !isClosing) {
+ return false;
+ }
+
+ // save any open editors if they are dirty
+ isClosing = saveAllEditors(!force);
+ if (!force && !isClosing) {
+ return false;
+ }
+
+ boolean closeEditors = !force
+ && PrefUtil.getAPIPreferenceStore().getBoolean(
+ IWorkbenchPreferenceConstants.CLOSE_EDITORS_ON_EXIT);
+ if (closeEditors) {
+ SafeRunner.run(new SafeRunnable() {
+ public void run() {
+ IWorkbenchWindow windows[] = getWorkbenchWindows();
+ for (int i = 0; i < windows.length; i++) {
+ IWorkbenchPage pages[] = windows[i].getPages();
+ for (int j = 0; j < pages.length; j++) {
+ isClosing = isClosing
+ && pages[j].closeAllEditors(false);
+ }
+ }
+ }
+ });
+ if (!force && !isClosing) {
+ return false;
+ }
+ }
+
+ if (getWorkbenchConfigurer().getSaveAndRestore()) {
+ SafeRunner.run(new SafeRunnable() {
+ public void run() {
+
+ org.eclipse.e4.workbench.ui.internal.Activator
+ .trace(org.eclipse.e4.workbench.ui.internal.Policy.DEBUG_WORKBENCH,
+ "saveing model to " + getXmiLocation(), null); //$NON-NLS-1$
+ try {
+ // because we created the model we need to set the
+ // resource correctly
+ Resource resource = new XMIResourceImpl();
+ resource.getContents().add(
+ (EObject) e4Workbench.getModel());
+ String resourceLoc = getXmiLocation();
+ resource.setURI(URI.createFileURI(resourceLoc));
+
+ resource.save(null);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ XMLMemento mem = recordWorkbenchState();
+ // Save the IMemento to a file.
+ saveMementoToFile(mem);
+ }
+
+ public void handleException(Throwable e) {
+ String message;
+ if (e.getMessage() == null) {
+ message = WorkbenchMessages.ErrorClosingNoArg;
+ } else {
+ message = NLS.bind(
+ WorkbenchMessages.ErrorClosingOneArg,
+ e.getMessage());
+ }
+
+ if (!MessageDialog.openQuestion(null,
+ WorkbenchMessages.Error, message)) {
+ isClosing = false;
+ }
+ }
+ });
+ }
+ if (!force && !isClosing) {
+ return false;
+ }
+
+ SafeRunner.run(new SafeRunnable(WorkbenchMessages.ErrorClosing) {
+ public void run() {
+ if (isClosing || force) {
+ isClosing = windowManager.close();
+ }
+ }
+ });
+
+ if (!force && !isClosing) {
+ return false;
+ }
+
+ shutdown();
+
+ runEventLoop = false;
+ return true;
+ }
+
+ private String getXmiLocation() {
+ return WorkbenchPlugin.getDefault().getDataLocation()
+ .append("workbench.xmi").toOSString(); //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbench#saveAllEditors(boolean)
+ */
+ public boolean saveAllEditors(boolean confirm) {
+ final boolean finalConfirm = confirm;
+ final boolean[] result = new boolean[1];
+ result[0] = true;
+
+ SafeRunner.run(new SafeRunnable(WorkbenchMessages.ErrorClosing) {
+ public void run() {
+ // Collect dirtyParts
+ ArrayList dirtyParts = new ArrayList();
+ ArrayList dirtyEditorsInput = new ArrayList();
+ IWorkbenchWindow windows[] = getWorkbenchWindows();
+ for (int i = 0; i < windows.length; i++) {
+ IWorkbenchPage pages[] = windows[i].getPages();
+ for (int j = 0; j < pages.length; j++) {
+ WorkbenchPage page = (WorkbenchPage) pages[j];
+
+ ISaveablePart[] parts = page.getDirtyParts();
+
+ for (int k = 0; k < parts.length; k++) {
+ ISaveablePart part = parts[k];
+
+ if (part.isSaveOnCloseNeeded()) {
+ if (part instanceof IEditorPart) {
+ IEditorPart editor = (IEditorPart) part;
+ if (!dirtyEditorsInput.contains(editor
+ .getEditorInput())) {
+ dirtyParts.add(editor);
+ dirtyEditorsInput.add(editor
+ .getEditorInput());
+ }
+ } else {
+ dirtyParts.add(part);
+ }
+ }
+ }
+ }
+ }
+ IShellProvider shellProvider;
+ IRunnableContext runnableContext;
+ IWorkbenchWindow w = getActiveWorkbenchWindow();
+ if (w == null && windows.length > 0) {
+ w = windows[0];
+ }
+ if (w != null) {
+ shellProvider = w;
+ runnableContext = w;
+ } else {
+ shellProvider = new IShellProvider() {
+ public Shell getShell() {
+ return null;
+ }
+ };
+ runnableContext = new ProgressMonitorDialog(null);
+ }
+ // The fourth parameter is true to also save saveables from
+ // non-part sources, see bug 139004.
+ result[0] = EditorManager.saveAll(dirtyParts, finalConfirm,
+ false, true, runnableContext, shellProvider);
+ }
+ });
+ return result[0];
+ }
+
+ /**
+ * Opens a new workbench window and page with a specific perspective.
+ *
+ * Assumes that busy cursor is active.
+ */
+ private IWorkbenchWindow busyOpenWorkbenchWindow(final String perspID,
+ final IAdaptable input) throws WorkbenchException {
+ // Create a workbench window (becomes active window)
+ final WorkbenchWindow newWindowArray[] = new WorkbenchWindow[1];
+ StartupThreading.runWithWorkbenchExceptions(new StartupRunnable() {
+ public void runWithException() {
+ newWindowArray[0] = newWorkbenchWindow();
+ }
+ });
+
+ final WorkbenchWindow newWindow = newWindowArray[0];
+
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ // newWindow.create(); // must be created before adding to
+ // window
+ // manager
+ }
+ });
+ windowManager.add(newWindow);
+
+ final WorkbenchException[] exceptions = new WorkbenchException[1];
+ // Create the initial page.
+ if (perspID != null) {
+ StartupThreading.runWithWorkbenchExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ try {
+ newWindow.busyOpenPage(perspID, input);
+ } catch (WorkbenchException e) {
+ windowManager.remove(newWindow);
+ exceptions[0] = e;
+ }
+ }
+ });
+ }
+ if (exceptions[0] != null)
+ throw exceptions[0];
+
+ // Open window after opening page, to avoid flicker.
+ StartupThreading.runWithWorkbenchExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ newWindow.open();
+ }
+ });
+
+ return newWindow;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public boolean close() {
+ return close(PlatformUI.RETURN_OK, false);
+ }
+
+ /**
+ * Closes the workbench, returning the given return code from the run
+ * method. If forced, the workbench is closed no matter what.
+ *
+ * @param returnCode
+ * {@link PlatformUI#RETURN_OK RETURN_OK}for normal exit;
+ * {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the
+ * workbench was terminated with a call to
+ * {@link IWorkbench#restart IWorkbench.restart};
+ * {@link PlatformUI#RETURN_EMERGENCY_CLOSE} for an emergency
+ * shutdown {@link PlatformUI#RETURN_UNSTARTABLE
+ * RETURN_UNSTARTABLE}if the workbench could not be started;
+ * other values reserved for future use
+ *
+ * @param force
+ * true to force the workbench close, and false for a "soft"
+ * close that can be canceled
+ * @return true if the close was successful, and false if the close was
+ * canceled
+ */
+ /* package */
+ boolean close(int returnCode, final boolean force) {
+ this.returnCode = returnCode;
+ final boolean[] ret = new boolean[1];
+ BusyIndicator.showWhile(null, new Runnable() {
+ public void run() {
+ ret[0] = busyClose(force);
+ }
+ });
+ return ret[0];
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public IWorkbenchWindow getActiveWorkbenchWindow() {
+ // Return null if called from a non-UI thread.
+ // This is not spec'ed behaviour and is misleading, however this is how
+ // it
+ // worked in 2.1 and we cannot change it now.
+ // For more details, see [Bug 57384] [RCP] Main window not active on
+ // startup
+ if (Display.getCurrent() == null) {
+ return null;
+ }
+
+ // Look at the current shell and up its parent
+ // hierarchy for a workbench window.
+ Control shell = display.getActiveShell();
+ while (shell != null) {
+ Object data = shell.getData();
+ if (data instanceof IWorkbenchWindow) {
+ return (IWorkbenchWindow) data;
+ }
+ shell = shell.getParent();
+ }
+
+ // Look for the window that was last known being
+ // the active one
+ WorkbenchWindow win = getActivatedWindow();
+ if (win != null) {
+ return win;
+ }
+
+ win = (WorkbenchWindow) e4Context
+ .get(ISources.ACTIVE_WORKBENCH_WINDOW_NAME);
+ if (win != null) {
+ return win;
+ }
+
+ // Look at all the shells and pick the first one
+ // that is a workbench window.
+ Shell shells[] = display.getShells();
+ for (int i = 0; i < shells.length; i++) {
+ Object data = shells[i].getData();
+ if (data instanceof IWorkbenchWindow) {
+ return (IWorkbenchWindow) data;
+ }
+ }
+
+ // Can't find anything!
+ return null;
+ }
+
+ /*
+ * Returns the editor history.
+ */
+ public EditorHistory getEditorHistory() {
+ return (EditorHistory) e4Context.get(EditorHistory.class.getName());
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public IEditorRegistry getEditorRegistry() {
+ return WorkbenchPlugin.getDefault().getEditorRegistry();
+ }
+
+ /*
+ * Returns the number for a new window. This will be the first number > 0
+ * which is not used to identify another window in the workbench.
+ */
+ private int getNewWindowNumber() {
+ // Get window list.
+ Window[] windows = windowManager.getWindows();
+ int count = windows.length;
+
+ // Create an array of booleans (size = window count).
+ // Cross off every number found in the window list.
+ boolean checkArray[] = new boolean[count];
+ for (int nX = 0; nX < count; nX++) {
+ if (windows[nX] instanceof WorkbenchWindow) {
+ WorkbenchWindow ww = (WorkbenchWindow) windows[nX];
+ int index = ww.getNumber() - 1;
+ if (index >= 0 && index < count) {
+ checkArray[index] = true;
+ }
+ }
+ }
+
+ // Return first index which is not used.
+ // If no empty index was found then every slot is full.
+ // Return next index.
+ for (int index = 0; index < count; index++) {
+ if (!checkArray[index]) {
+ return index + 1;
+ }
+ }
+ return count + 1;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public IWorkbenchOperationSupport getOperationSupport() {
+ return WorkbenchPlugin.getDefault().getOperationSupport();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public IPerspectiveRegistry getPerspectiveRegistry() {
+ return WorkbenchPlugin.getDefault().getPerspectiveRegistry();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public PreferenceManager getPreferenceManager() {
+ return WorkbenchPlugin.getDefault().getPreferenceManager();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public IPreferenceStore getPreferenceStore() {
+ return WorkbenchPlugin.getDefault().getPreferenceStore();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public ISharedImages getSharedImages() {
+ return WorkbenchPlugin.getDefault().getSharedImages();
+ }
+
+ /**
+ * Returns the window manager for this workbench.
+ *
+ * @return the window manager
+ */
+ /* package */
+ WindowManager getWindowManager() {
+ return windowManager;
+ }
+
+ /*
+ * Answer the workbench state file.
+ */
+ private File getWorkbenchStateFile() {
+ IPath path = WorkbenchPlugin.getDefault().getDataLocation();
+ if (path == null) {
+ return null;
+ }
+ path = path.append(DEFAULT_WORKBENCH_STATE_FILENAME);
+ return path.toFile();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public int getWorkbenchWindowCount() {
+ return windowManager.getWindowCount();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public IWorkbenchWindow[] getWorkbenchWindows() {
+ Window[] windows = windowManager.getWindows();
+ IWorkbenchWindow[] dwindows = new IWorkbenchWindow[windows.length];
+ System.arraycopy(windows, 0, dwindows, 0, windows.length);
+ return dwindows;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public IWorkingSetManager getWorkingSetManager() {
+ return WorkbenchPlugin.getDefault().getWorkingSetManager();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ILocalWorkingSetManager createLocalWorkingSetManager() {
+ return new LocalWorkingSetManager(WorkbenchPlugin.getDefault()
+ .getBundleContext());
+ }
+
+ private static final String APPLICATION_CSS_RESOURCES_ARG = "-applicationCSSResources"; //$NON-NLS-1$
+ private static final String APPLICATION_CSS_RESOURCES = "applicationCSSResources"; //$NON-NLS-1$
+ private static final String APPLICATION_CSS_ARG = "-applicationCSS"; //$NON-NLS-1$
+ private static final String APPLICATION_CSS = "applicationCSS"; //$NON-NLS-1$
+
+ private Map<String, String> processArgs(String[] args) {
+ HashMap<String, String> argsList = new HashMap<String, String>();
+ for (int i = 0; i < args.length; i++) {
+ if (APPLICATION_CSS_ARG.equals(args[i])) {
+ argsList.put(APPLICATION_CSS, args[++i]);
+ } else if (APPLICATION_CSS_RESOURCES_ARG.equals(args[i])) {
+ argsList.put(APPLICATION_CSS_RESOURCES, args[++i]);
+ }
+ }
+ return argsList;
+ }
+
+ /**
+ * Initializes the workbench now that the display is created.
+ *
+ * @return true if init succeeded.
+ */
+ private boolean init() {
+ // setup debug mode if required.
+ if (WorkbenchPlugin.getDefault().isDebugging()) {
+ WorkbenchPlugin.DEBUG = true;
+ ModalContext.setDebugMode(true);
+ }
+
+ // Set up the JFace preference store
+ JFaceUtil.initializeJFacePreferences();
+
+ MApplication model = createE4Model();
+ e4Workbench.setWorkbenchModel(model);
+
+ // create workbench window manager
+ windowManager = new WindowManager();
+
+ // BEGIN: early e4 services
+ final Map<String, String> argsList = processArgs(Platform
+ .getApplicationArgs());
+ String cssURIr = argsList.get(APPLICATION_CSS);
+ String cssResourcesURIr = argsList.get(APPLICATION_CSS_RESOURCES);
+ IProduct product = Platform.getProduct();
+ if (product != null) {
+ if (cssURIr == null) {
+ cssURIr = product.getProperty(APPLICATION_CSS);
+ }
+ if (cssResourcesURIr == null) {
+ cssResourcesURIr = product
+ .getProperty(APPLICATION_CSS_RESOURCES);
+ }
+ }
+ final String cssURI = cssURIr;
+ final String cssResourcesURI = cssResourcesURIr;
+
+ if (cssURI != null) {
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+ public void runWithException() {
+ CSSStylingSupport.initializeStyling(display, cssURI,
+ cssResourcesURI, e4Context);
+ }
+ });
+ }
+ final PackageAdmin packageAdmin = (PackageAdmin) e4Context
+ .get(PackageAdmin.class.getName());
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ e4Context.set(IResourceUtiltities.class.getName(),
+ new ResourceUtility(packageAdmin));
+ }
+ });
+ e4Context.set(IExtensionTracker.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ if (tracker == null) {
+ tracker = new UIExtensionTracker(getDisplay());
+ }
+ return tracker;
+ }
+ });
+ e4Context.set(IWorkbenchActivitySupport.class.getName(),
+ new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context,
+ Object[] arguments) {
+ if (workbenchActivitySupport == null) {
+ workbenchActivitySupport = new WorkbenchActivitySupport();
+ }
+ return workbenchActivitySupport;
+ }
+ });
+ // END: early e4 services
+
+ WorkbenchPlugin.getDefault().initializeContext(e4Context);
+
+ // TODO Correctly order service initialization
+ // there needs to be some serious consideration given to
+ // the services, and hooking them up in the correct order
+ final EvaluationService evaluationService = new EvaluationService();
+
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ serviceLocator.registerService(IEvaluationService.class,
+ evaluationService);
+ }
+ });
+
+ // Initialize the activity support.
+
+ activityHelper = ActivityPersistanceHelper.getInstance();
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ WorkbenchImages.getImageRegistry();
+ }
+ });
+ initializeDefaultServices();
+ initializeFonts();
+ initializeColors();
+ initializeApplicationColors();
+
+ // now that the workbench is sufficiently initialized, let the advisor
+ // have a turn.
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ advisor.internalBasicInitialize(getWorkbenchConfigurer());
+ }
+ });
+
+ // configure use of color icons in toolbars
+ boolean useColorIcons = PrefUtil.getInternalPreferenceStore()
+ .getBoolean(IPreferenceConstants.COLOR_ICONS);
+ ActionContributionItem.setUseColorIconsInToolbars(useColorIcons);
+
+ // initialize workbench single-click vs double-click behavior
+ initializeSingleClickOption();
+
+ initializeWorkbenchImages();
+
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ ((GrabFocus) Tweaklets.get(GrabFocus.KEY)).init(getDisplay());
+ }
+ });
+
+ // attempt to restore a previous workbench state
+ try {
+ UIStats.start(UIStats.RESTORE_WORKBENCH, "Workbench"); //$NON-NLS-1$
+
+ final boolean bail[] = new boolean[1];
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() throws Throwable {
+ advisor.preStartup();
+
+ if (isClosing() || !advisor.openWindows()) {
+ bail[0] = true;
+ }
+ }
+ });
+
+ if (bail[0])
+ return false;
+
+ } finally {
+ UIStats.end(UIStats.RESTORE_WORKBENCH, this, "Workbench"); //$NON-NLS-1$
+ }
+
+ forceOpenPerspective();
+
+ return true;
+ }
+
+ /**
+ *
+ */
+ private void initializeWorkbenchImages() {
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+ public void runWithException() {
+ WorkbenchImages.getDescriptors();
+ }
+ });
+ }
+
+ /**
+ * Establishes the relationship between JFace actions and the command
+ * manager.
+ */
+ private void initializeCommandResolver() {
+ ExternalActionManager.getInstance().setCallback(
+ new CommandCallback(bindingManager, commandManager,
+ new IActiveChecker() {
+ public final boolean isActive(final String commandId) {
+ return getActivitySupport()
+ .getActivityManager()
+ .getIdentifier(commandId).isEnabled();
+ }
+ }, new IExecuteApplicable() {
+ public boolean isApplicable(IAction action) {
+ return !(action instanceof CommandAction);
+ }
+ }));
+ }
+
+ /**
+ * Initialize colors defined by the new colorDefinitions extension point.
+ * Note this will be rolled into initializeColors() at some point.
+ *
+ * @since 3.0
+ */
+ private void initializeApplicationColors() {
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ ColorDefinition[] colorDefinitions = WorkbenchPlugin
+ .getDefault().getThemeRegistry().getColors();
+ ThemeElementHelper
+ .populateRegistry(
+ getThemeManager().getTheme(
+ IThemeManager.DEFAULT_THEME),
+ colorDefinitions,
+ PrefUtil.getInternalPreferenceStore());
+ }
+ });
+ }
+
+ private void initializeSingleClickOption() {
+ IPreferenceStore store = WorkbenchPlugin.getDefault()
+ .getPreferenceStore();
+ boolean openOnSingleClick = store
+ .getBoolean(IPreferenceConstants.OPEN_ON_SINGLE_CLICK);
+ boolean selectOnHover = store
+ .getBoolean(IPreferenceConstants.SELECT_ON_HOVER);
+ boolean openAfterDelay = store
+ .getBoolean(IPreferenceConstants.OPEN_AFTER_DELAY);
+ int singleClickMethod = openOnSingleClick ? OpenStrategy.SINGLE_CLICK
+ : OpenStrategy.DOUBLE_CLICK;
+ if (openOnSingleClick) {
+ if (selectOnHover) {
+ singleClickMethod |= OpenStrategy.SELECT_ON_HOVER;
+ }
+ if (openAfterDelay) {
+ singleClickMethod |= OpenStrategy.ARROW_KEYS_OPEN;
+ }
+ }
+ OpenStrategy.setOpenMethod(singleClickMethod);
+ }
+
+ /*
+ * Initializes the workbench fonts with the stored values.
+ */
+ private void initializeFonts() {
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ FontDefinition[] fontDefinitions = WorkbenchPlugin.getDefault()
+ .getThemeRegistry().getFonts();
+
+ ThemeElementHelper.populateRegistry(getThemeManager()
+ .getCurrentTheme(), fontDefinitions, PrefUtil
+ .getInternalPreferenceStore());
+ }
+ });
+ }
+
+ /*
+ * Initialize the workbench images.
+ *
+ * @param windowImages An array of the descriptors of the images to be used
+ * in the corner of each window, or <code>null</code> if none. It is
+ * expected that the array will contain the same icon, rendered at different
+ * sizes.
+ *
+ * @since 3.0
+ */
+ private static void initializeImages() {
+ ImageDescriptor[] windowImages = WorkbenchPlugin.getDefault()
+ .getWindowImages();
+ if (windowImages == null) {
+ return;
+ }
+
+ Image[] images = new Image[windowImages.length];
+ for (int i = 0; i < windowImages.length; ++i) {
+ images[i] = windowImages[i].createImage();
+ }
+ Window.setDefaultImages(images);
+ }
+
+ /*
+ * Take the workbenches' images out of the shared registry.
+ *
+ * @since 3.0
+ */
+ private void uninitializeImages() {
+ WorkbenchImages.dispose();
+ Image[] images = Window.getDefaultImages();
+ Window.setDefaultImage(null);
+ for (int i = 0; i < images.length; i++) {
+ images[i].dispose();
+ }
+ }
+
+ /*
+ * Initialize the workbench colors.
+ *
+ * @since 3.0
+ */
+ private void initializeColors() {
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+ public void runWithException() {
+ WorkbenchColors.startup();
+ }
+ });
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public boolean isClosing() {
+ return isClosing;
+ }
+
+ /**
+ * Initializes all of the default services for the workbench. For
+ * initializing the command-based services, this also parses the registry
+ * and hooks up all the required listeners.
+ */
+ private final void initializeDefaultServices() {
+ // BEGIN: some e4 services
+ e4Context.set(IWorkbenchBrowserSupport.class.getName(),
+ new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context,
+ Object[] arguments) {
+ return WorkbenchBrowserSupport.getInstance();
+ }
+ });
+ e4Context.set(EditorHistory.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ if (editorHistory == null) {
+ editorHistory = new EditorHistory();
+ }
+ return editorHistory;
+ }
+ });
+ e4Context.set(IWorkbenchHelpSystem.class.getName(),
+ new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context,
+ Object[] arguments) {
+ return WorkbenchHelpSystem.getInstance();
+ }
+ });
+ e4Context.set(IProgressService.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ return ProgressManager.getInstance();
+ }
+ });
+ e4Context.set(IThemeManager.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ return WorkbenchThemeManager.getInstance();
+ }
+ });
+ e4Context.set(WorkbenchIntroManager.class.getName(),
+ new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context,
+ Object[] arguments) {
+ if (introManager == null) {
+ introManager = new WorkbenchIntroManager(
+ Workbench.this);
+ }
+ return introManager;
+ }
+ });
+ e4Context.set(ISources.ACTIVE_WORKBENCH_WINDOW_NAME,
+ new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context,
+ Object[] arguments) {
+ IEclipseContext childContext = (IEclipseContext) context
+ .getLocal(IContextConstants.ACTIVE_CHILD);
+ if (childContext != null) {
+ return childContext
+ .get(ISources.ACTIVE_WORKBENCH_WINDOW_NAME);
+ }
+ return null;
+ }
+ });
+ e4Context.set(ISources.ACTIVE_ACTION_SETS_NAME, new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ IEclipseContext childContext = (IEclipseContext) context
+ .getLocal(IContextConstants.ACTIVE_CHILD);
+ if (childContext != null) {
+ return childContext.get(ISources.ACTIVE_ACTION_SETS_NAME);
+ }
+ return null;
+ }
+ });
+ e4Context.set(ISources.ACTIVE_PART_NAME, new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ IEclipseContext childContext = (IEclipseContext) context
+ .getLocal(IContextConstants.ACTIVE_CHILD);
+ if (childContext != null) {
+ return childContext.get(ISources.ACTIVE_PART_NAME);
+ }
+ return null;
+ }
+ });
+ e4Context.set(ISources.ACTIVE_SITE_NAME, new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ IEclipseContext childContext = (IEclipseContext) context
+ .getLocal(IContextConstants.ACTIVE_CHILD);
+ if (childContext != null) {
+ return childContext.get(ISources.ACTIVE_SITE_NAME);
+ }
+ return null;
+ }
+ });
+ e4Context.set(ISources.ACTIVE_WORKBENCH_WINDOW_IS_COOLBAR_VISIBLE_NAME,
+ new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context,
+ Object[] arguments) {
+ WorkbenchWindow window = (WorkbenchWindow) context
+ .get(ISources.ACTIVE_WORKBENCH_WINDOW_NAME);
+ return window == null ? false : window
+ .getCoolBarVisible();
+ }
+ });
+ e4Context
+ .set(ISources.ACTIVE_WORKBENCH_WINDOW_IS_PERSPECTIVEBAR_VISIBLE_NAME,
+ new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context,
+ Object[] arguments) {
+ WorkbenchWindow window = (WorkbenchWindow) context
+ .get(ISources.ACTIVE_WORKBENCH_WINDOW_NAME);
+ return window == null ? false : window
+ .getPerspectiveBarVisible();
+ }
+ });
+ e4Context.set(ISources.ACTIVE_WORKBENCH_WINDOW_ACTIVE_PERSPECTIVE_NAME,
+ new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context,
+ Object[] arguments) {
+ IEclipseContext childContext = (IEclipseContext) context
+ .getLocal(IContextConstants.ACTIVE_CHILD);
+ if (childContext != null) {
+ return childContext
+ .get(ISources.ACTIVE_WORKBENCH_WINDOW_ACTIVE_PERSPECTIVE_NAME);
+ }
+ MPerspective persp = (MPerspective) context
+ .get(MPerspective.class.getName());
+ final String perspId = persp == null ? null : persp
+ .getId();
+ org.eclipse.e4.workbench.ui.internal.Activator
+ .trace(org.eclipse.e4.workbench.ui.internal.Policy.DEBUG_CMDS,
+ "asked for perspective " + perspId, //$NON-NLS-1$
+ null);
+ return perspId;
+ }
+ });
+ // END: some e4 services
+
+ final IContributionService contributionService = new ContributionService(
+ getAdvisor());
+ serviceLocator.registerService(IContributionService.class,
+ contributionService);
+
+ // TODO Correctly order service initialization
+ // there needs to be some serious consideration given to
+ // the services, and hooking them up in the correct order
+ final IEvaluationService evaluationService = (IEvaluationService) serviceLocator
+ .getService(IEvaluationService.class);
+
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ serviceLocator.registerService(
+ ISaveablesLifecycleListener.class, new SaveablesList());
+ }
+ });
+
+ /*
+ * Phase 1 of the initialization of commands. When this phase completes,
+ * all the services and managers will exist, and be accessible via the
+ * getService(Object) method.
+ */
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ Command.DEBUG_COMMAND_EXECUTION = Policy.DEBUG_COMMANDS;
+ commandManager = (CommandManager) e4Context
+ .get(CommandManager.class.getName());
+ }
+ });
+
+ final CommandService[] commandService = new CommandService[1];
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ commandService[0] = new CommandService(commandManager);
+ commandService[0].readRegistry();
+ serviceLocator.registerService(ICommandService.class,
+ commandService[0]);
+
+ }
+ });
+
+ populateCommands();
+ populateActionSets();
+
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ ContextManager.DEBUG = Policy.DEBUG_CONTEXTS;
+ contextManager = (ContextManager) e4Context
+ .get(ContextManager.class.getName());
+ }
+ });
+
+ final IContextService contextService = new ContextService(
+ contextManager);
+
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ contextService.readRegistry();
+ }
+ });
+
+ EContextService ecs = (EContextService) e4Context
+ .get(EContextService.class.getName());
+ ecs.activateContext(IContextService.CONTEXT_ID_DIALOG_AND_WINDOW);
+
+ serviceLocator.registerService(IContextService.class, contextService);
+
+ final IBindingService[] bindingService = new BindingService[1];
+
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ BindingManager.DEBUG = Policy.DEBUG_KEY_BINDINGS;
+ bindingManager = new BindingManager(contextManager,
+ commandManager);
+ bindingService[0] = new BindingService(bindingManager,
+ commandService[0], Workbench.this);
+
+ }
+ });
+
+ bindingService[0].readRegistryAndPreferences(commandService[0]);
+ serviceLocator
+ .registerService(IBindingService.class, bindingService[0]);
+
+ final CommandImageManager commandImageManager = new CommandImageManager();
+ final CommandImageService commandImageService = new CommandImageService(
+ commandImageManager, commandService[0]);
+ commandImageService.readRegistry();
+ serviceLocator.registerService(ICommandImageService.class,
+ commandImageService);
+
+ final WorkbenchMenuService menuService = new WorkbenchMenuService(
+ serviceLocator);
+
+ serviceLocator.registerService(IMenuService.class, menuService);
+ // the service must be registered before it is initialized - its
+ // initialization uses the service locator to address a dependency on
+ // the menu service
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ menuService.readRegistry();
+ }
+ });
+
+ /*
+ * Phase 2 of the initialization of commands. The source providers that
+ * the workbench provides are creating and registered with the above
+ * services. These source providers notify the services when particular
+ * pieces of workbench state change.
+ */
+ final SourceProviderService sourceProviderService = new SourceProviderService(
+ serviceLocator);
+ serviceLocator.registerService(ISourceProviderService.class,
+ sourceProviderService);
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ // this currently instantiates all players ... sigh
+ sourceProviderService.readRegistry();
+ ISourceProvider[] sp = sourceProviderService
+ .getSourceProviders();
+ for (int i = 0; i < sp.length; i++) {
+ evaluationService.addSourceProvider(sp[i]);
+ if (!(sp[i] instanceof ActiveContextSourceProvider)) {
+ contextService.addSourceProvider(sp[i]);
+ }
+ }
+ }
+ });
+
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ // these guys are need to provide the variables they say
+ // they source
+ actionSetSourceProvider = (ActionSetSourceProvider) sourceProviderService
+ .getSourceProvider(ISources.ACTIVE_ACTION_SETS_NAME);
+
+ FocusControlSourceProvider focusControl = (FocusControlSourceProvider) sourceProviderService
+ .getSourceProvider(ISources.ACTIVE_FOCUS_CONTROL_ID_NAME);
+ serviceLocator.registerService(IFocusService.class,
+ focusControl);
+
+ menuSourceProvider = (MenuSourceProvider) sourceProviderService
+ .getSourceProvider(ISources.ACTIVE_MENU_NAME);
+ }
+ });
+
+ /*
+ * Phase 3 of the initialization of commands. This handles the creation
+ * of wrappers for legacy APIs. By the time this phase completes, any
+ * code trying to access commands through legacy APIs should work.
+ */
+ final IHandlerService[] handlerService = new IHandlerService[1];
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() {
+ handlerService[0] = new LegacyHandlerService(e4Context);
+ handlerService[0].readRegistry();
+ }
+ });
+ serviceLocator
+ .registerService(IHandlerService.class, handlerService[0]);
+ // BEGIN: e4 services
+ e4Context.set(IWorkbenchContextSupport.class.getName(),
+ new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context,
+ Object[] arguments) {
+ if (workbenchContextSupport == null) {
+ workbenchContextSupport = new WorkbenchContextSupport(
+ Workbench.this, contextManager);
+ }
+ return workbenchContextSupport;
+ }
+ });
+ e4Context.set(IWorkbenchCommandSupport.class.getName(),
+ new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context,
+ Object[] arguments) {
+ if (workbenchCommandSupport == null) {
+ workbenchCommandSupport = new WorkbenchCommandSupport(
+ bindingManager, commandManager,
+ contextManager, handlerService[0]);
+ }
+ return workbenchCommandSupport;
+ }
+ });
+
+ // TODO needs a replacement with the updated binding service and bridge
+ // EBindingService e4BindingService = new EBindingService() {
+ // public TriggerSequence getBestActiveBindingFor(
+ // ParameterizedCommand command) {
+ // if (bindingService[0] == null)
+ // return null;
+ // return bindingService[0].getBestActiveBindingFor(command);
+ // }
+ // };
+ // e4Context.set(EBindingService.class.getName(), e4BindingService);
+
+ final ISourceProvider showInProvider = sourceProviderService
+ .getSourceProvider(ISources.SHOW_IN_SELECTION);
+ showInProvider.addSourceProviderListener(getSourceListener());
+ final ISourceProvider focusProvider = sourceProviderService
+ .getSourceProvider(ISources.ACTIVE_FOCUS_CONTROL_ID_NAME);
+ focusProvider.addSourceProviderListener(getSourceListener());
+ // END: e4 services
+
+ initializeCommandResolver();
+
+ addWindowListener(windowListener);
+ bindingManager.addBindingManagerListener(bindingManagerListener);
+
+ serviceLocator.registerService(ISelectionConversionService.class,
+ new SelectionConversionService());
+ }
+
+ private ISourceProviderListener getSourceListener() {
+ if (sourceListener == null) {
+ sourceListener = new ISourceProviderListener() {
+ public void sourceChanged(int sourcePriority,
+ String sourceName, Object sourceValue) {
+ updateChangedVariable(sourceName, sourceValue);
+ }
+
+ public void sourceChanged(int sourcePriority,
+ Map sourceValuesByName) {
+ final Iterator i = sourceValuesByName.entrySet().iterator();
+ while (i.hasNext()) {
+ Map.Entry entry = (Map.Entry) i.next();
+ sourceChanged(0, (String) entry.getKey(),
+ entry.getValue());
+ }
+ }
+ };
+ }
+ return sourceListener;
+ }
+
+ void updateChangedVariable(String sourceName, Object sourceValue) {
+ boolean updated = updateVariable(ISources.SHOW_IN_INPUT, sourceName,
+ sourceValue);
+ if (!updated) {
+ updated = updateVariable(ISources.SHOW_IN_SELECTION, sourceName,
+ sourceValue);
+ }
+ if (!updated) {
+ updated = updateVariable(ISources.ACTIVE_FOCUS_CONTROL_ID_NAME,
+ sourceName, sourceValue);
+ }
+ if (!updated) {
+ updated = updateVariable(ISources.ACTIVE_FOCUS_CONTROL_NAME,
+ sourceName, sourceValue);
+ }
+ if (!updated) {
+ updated = updateVariable(ISources.ACTIVE_SHELL_NAME, sourceName,
+ sourceValue);
+ if (updated) {
+ org.eclipse.e4.workbench.ui.internal.Activator
+ .trace(org.eclipse.e4.workbench.ui.internal.Policy.DEBUG_WORKBENCH,
+ "activated shell: " + sourceValue, null); //$NON-NLS-1$
+ if (sourceValue instanceof Shell) {
+ activateShell((Shell) sourceValue);
+ }
+ }
+ }
+ }
+
+ boolean updateVariable(String name, String sourceName, Object sourceValue) {
+ if (name.equals(sourceName)) {
+ if (sourceValue == null
+ || sourceValue == IEvaluationContext.UNDEFINED_VARIABLE) {
+ e4Context.remove(name);
+ } else {
+ e4Context.set(name, sourceValue);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ void activateShell(final Shell shell) {
+ if (shell.getParent() instanceof Shell) {
+ final String localContext = "localContext"; //$NON-NLS-1$
+ Object obj = shell.getData(localContext);
+ if (obj instanceof IEclipseContext) {
+ e4Context.set(IContextConstants.ACTIVE_CHILD, obj);
+ } else {
+ final IEclipseContext shellContext = EclipseContextFactory
+ .create(e4Context, UISchedulerStrategy.getInstance());
+ shellContext.set(IContextConstants.DEBUG_STRING,
+ "Shell Context (" + shell + ")"); //$NON-NLS-1$//$NON-NLS-2$
+ shell.setData(localContext, shellContext);
+ e4Context.set(IContextConstants.ACTIVE_CHILD, shellContext);
+ shell.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ shell.setData(localContext, null);
+ if (shellContext instanceof org.eclipse.e4.core.services.IDisposable) {
+ ((org.eclipse.e4.core.services.IDisposable) shellContext)
+ .dispose();
+ }
+ }
+ });
+ }
+ } else {
+ if (shell.getData() instanceof WorkbenchWindow) {
+ e4Context.set(IContextConstants.ACTIVE_CHILD,
+ ((WorkbenchWindow) shell.getData()).getModelWindow()
+ .getContext());
+ }
+ }
+ }
+
+ static class MakeHandlersGo extends AbstractHandler {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands
+ * .ExecutionEvent)
+ */
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ org.eclipse.e4.workbench.ui.internal.Activator.trace(
+ org.eclipse.e4.workbench.ui.internal.Policy.DEBUG_CMDS,
+ "AllHandlerGo: not for executing", null); //$NON-NLS-1$
+ return null;
+ }
+
+ }
+
+ protected void populateCommands() {
+ MakeHandlersGo allHandlers = new MakeHandlersGo();
+ if (allHandlers != null)
+ return;
+ ECommandService cs = (ECommandService) e4Context
+ .get(ECommandService.class.getName());
+ MApplication app = (MApplication) e4Context.get(MApplication.class
+ .getName());
+ Command[] cmds = commandManager.getAllCommands();
+ for (int i = 0; i < cmds.length; i++) {
+ Command cmd = cmds[i];
+ final String cmdId = cmd.getId();
+ if (cmdId.contains("(")) { //$NON-NLS-1$
+ org.eclipse.e4.workbench.ui.internal.Activator.trace(
+ org.eclipse.e4.workbench.ui.internal.Policy.DEBUG_CMDS,
+ "Invalid command: " + cmd, null); //$NON-NLS-1$
+ continue;
+ }
+ cmd.setHandler(allHandlers);
+ cs.getCommand(cmdId);
+ MCommand mcmd = MApplicationFactory.eINSTANCE.createCommand();
+ mcmd.setId(cmdId);
+ try {
+ mcmd.setCommandName(cmd.getName());
+ } catch (NotDefinedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ app.getCommands().add(mcmd);
+ }
+ }
+
+ // TBD update to use #addCommand()
+ protected void populateActionSets() {
+ String hack = ""; //$NON-NLS-1$
+ if (hack.length() == 0)
+ return;
+
+ ECommandService cs = (ECommandService) e4Context
+ .get(ECommandService.class.getName());
+ Category category = cs
+ .getCategory(IWorkbenchRegistryConstants.PL_ACTION_SETS);
+ category.define("Action Sets", null); //$NON-NLS-1$
+ MApplication app = (MApplication) e4Context.get(MApplication.class
+ .getName());
+ IConfigurationElement[] actionSetElements = ExtensionUtils
+ .getExtensions(IWorkbenchRegistryConstants.PL_ACTION_SETS);
+ for (IConfigurationElement ase : actionSetElements) {
+ IConfigurationElement[] elements = ase
+ .getChildren(IWorkbenchRegistryConstants.TAG_ACTION);
+
+ for (IConfigurationElement element : elements) {
+ String id = MenuHelper.getActionSetCommandId(element);
+ if (id != null
+ && id.startsWith(MenuHelper.ACTION_SET_CMD_PREFIX)) {
+ MCommand mcmd = MApplicationFactory.eINSTANCE
+ .createCommand();
+ mcmd.setId(id);
+ mcmd.setCommandName(LegacyActionTools
+ .removeMnemonics(MenuHelper.getLabel(element)));
+ app.getCommands().add(mcmd);
+ Command command = cs.getCommand(id);
+ if (!command.isDefined()) {
+ command.define(mcmd.getCommandName(), null, category);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns true if the Workbench is in the process of starting.
+ *
+ * @return <code>true</code> if the Workbench is starting, but not yet
+ * running the event loop.
+ */
+ public boolean isStarting() {
+ return isStarting && isRunning();
+ }
+
+ /*
+ * Creates a new workbench window.
+ *
+ * @return the new workbench window
+ */
+ private WorkbenchWindow newWorkbenchWindow() {
+ WorkbenchWindow wbw = ((WorkbenchImplementation) Tweaklets
+ .get(WorkbenchImplementation.KEY))
+ .createWorkbenchWindow(getNewWindowNumber());
+ return wbw;
+ }
+
+ /*
+ * If a perspective was specified on the command line (-perspective) then
+ * force that perspective to open in the active window.
+ */
+ private void forceOpenPerspective() {
+ if (getWorkbenchWindowCount() == 0) {
+ // there should be an open window by now, bail out.
+ return;
+ }
+
+ String perspId = null;
+ String[] commandLineArgs = Platform.getCommandLineArgs();
+ for (int i = 0; i < commandLineArgs.length - 1; i++) {
+ if (commandLineArgs[i].equalsIgnoreCase("-perspective")) { //$NON-NLS-1$
+ perspId = commandLineArgs[i + 1];
+ break;
+ }
+ }
+ if (perspId == null) {
+ return;
+ }
+ IPerspectiveDescriptor desc = getPerspectiveRegistry()
+ .findPerspectiveWithId(perspId);
+ if (desc == null) {
+ return;
+ }
+
+ IWorkbenchWindow win = getActiveWorkbenchWindow();
+ if (win == null) {
+ win = getWorkbenchWindows()[0];
+ }
+
+ final String threadPerspId = perspId;
+ final IWorkbenchWindow threadWin = win;
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+ public void runWithException() throws Throwable {
+ try {
+ showPerspective(threadPerspId, threadWin);
+ } catch (WorkbenchException e) {
+ String msg = "Workbench exception showing specified command line perspective on startup."; //$NON-NLS-1$
+ WorkbenchPlugin.log(msg, new Status(IStatus.ERROR,
+ PlatformUI.PLUGIN_ID, 0, msg, e));
+ }
+ }
+ });
+ }
+
+ /**
+ * Opens the initial workbench window.
+ */
+ /* package */void openFirstTimeWindow() {
+ final boolean showProgress = PrefUtil.getAPIPreferenceStore()
+ .getBoolean(
+ IWorkbenchPreferenceConstants.SHOW_PROGRESS_ON_STARTUP);
+
+ if (!showProgress) {
+ doOpenFirstTimeWindow();
+ } else {
+ // We don't know how many plug-ins will be loaded,
+ // assume we are loading a tenth of the installed plug-ins.
+ // (The Eclipse SDK loads 7 of 86 plug-ins at startup as of
+ // 2005-5-20)
+ final int expectedProgressCount = Math.max(1, WorkbenchPlugin
+ .getDefault().getBundleCount() / 10);
+
+ runStartupWithProgress(expectedProgressCount, new Runnable() {
+ public void run() {
+ doOpenFirstTimeWindow();
+ }
+ });
+ }
+ }
+
+ private void runStartupWithProgress(final int expectedProgressCount,
+ final Runnable runnable) {
+ progressCount = 0;
+ final double cutoff = 0.95;
+
+ AbstractSplashHandler handler = getSplash();
+ IProgressMonitor progressMonitor = null;
+ if (handler != null)
+ progressMonitor = handler.getBundleProgressMonitor();
+
+ if (progressMonitor == null) {
+ // cannot report progress (e.g. if the splash screen is not showing)
+ // fall back to starting without showing progress.
+ runnable.run();
+ } else {
+ progressMonitor.beginTask("", expectedProgressCount); //$NON-NLS-1$
+ SynchronousBundleListener bundleListener = new StartupProgressBundleListener(
+ progressMonitor, (int) (expectedProgressCount * cutoff));
+ WorkbenchPlugin.getDefault().addBundleListener(bundleListener);
+ try {
+ runnable.run();
+ progressMonitor.subTask(WorkbenchMessages.Startup_Done);
+ int remainingWork = expectedProgressCount
+ - Math.min(progressCount,
+ (int) (expectedProgressCount * cutoff));
+ progressMonitor.worked(remainingWork);
+ progressMonitor.done();
+ } finally {
+ WorkbenchPlugin.getDefault().removeBundleListener(
+ bundleListener);
+ }
+ }
+ }
+
+ private void doOpenFirstTimeWindow() {
+ try {
+ final IAdaptable input[] = new IAdaptable[1];
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() throws Throwable {
+ input[0] = getDefaultPageInput();
+ }
+ });
+
+ busyOpenWorkbenchWindow(getPerspectiveRegistry()
+ .getDefaultPerspective(), input[0]);
+ } catch (final WorkbenchException e) {
+ // Don't use the window's shell as the dialog parent,
+ // as the window is not open yet (bug 76724).
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() throws Throwable {
+ ErrorDialog.openError(null,
+ WorkbenchMessages.Problems_Opening_Page,
+ e.getMessage(), e.getStatus());
+ }
+ });
+ }
+ }
+
+ /*
+ * Restores the workbench UI from the workbench state file (workbench.xml).
+ *
+ * @return a status object indicating OK if a window was opened,
+ * RESTORE_CODE_RESET if no window was opened but one should be, and
+ * RESTORE_CODE_EXIT if the workbench should close immediately
+ */
+ /* package */IStatus restoreState() {
+ // TBD the Save/Restore functionality is not implemented
+ String msg = WorkbenchMessages.Workbench_restoreDisabled;
+ return new Status(IStatus.WARNING, WorkbenchPlugin.PI_WORKBENCH,
+ IWorkbenchConfigurer.RESTORE_CODE_RESET, msg, null);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public IWorkbenchWindow openWorkbenchWindow(IAdaptable input)
+ throws WorkbenchException {
+ return openWorkbenchWindow(getPerspectiveRegistry()
+ .getDefaultPerspective(), input);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public IWorkbenchWindow openWorkbenchWindow(final String perspID,
+ final IAdaptable input) throws WorkbenchException {
+ // Run op in busy cursor.
+ final Object[] result = new Object[1];
+ BusyIndicator.showWhile(null, new Runnable() {
+ public void run() {
+ try {
+ result[0] = busyOpenWorkbenchWindow(perspID, input);
+ } catch (WorkbenchException e) {
+ result[0] = e;
+ }
+ }
+ });
+ if (result[0] instanceof IWorkbenchWindow) {
+ return (IWorkbenchWindow) result[0];
+ } else if (result[0] instanceof WorkbenchException) {
+ throw (WorkbenchException) result[0];
+ } else {
+ throw new WorkbenchException(
+ WorkbenchMessages.Abnormal_Workbench_Conditi);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.IWorkbench#restoreWorkbenchWindow(org.eclipse.ui.IMemento)
+ */
+ IWorkbenchWindow restoreWorkbenchWindow(IMemento memento)
+ throws WorkbenchException {
+ WorkbenchWindow newWindow = newWorkbenchWindow();
+ newWindow.create();
+
+ windowManager.add(newWindow);
+
+ // whether the window was opened
+ boolean opened = false;
+
+ try {
+ newWindow.restoreState(memento, null);
+ newWindow.fireWindowRestored();
+ newWindow.open();
+ opened = true;
+ } finally {
+ if (!opened) {
+ newWindow.close();
+ }
+ }
+
+ return newWindow;
+ }
+
+ /*
+ * Record the workbench UI in a document
+ */
+ private XMLMemento recordWorkbenchState() {
+ XMLMemento memento = XMLMemento
+ .createWriteRoot(IWorkbenchConstants.TAG_WORKBENCH);
+ final IStatus status = saveState(memento);
+ if (status.getSeverity() != IStatus.OK) {
+ // don't use newWindow as parent because it has not yet been opened
+ // (bug 76724)
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+
+ public void runWithException() throws Throwable {
+ ErrorDialog.openError(null,
+ WorkbenchMessages.Workbench_problemsSaving,
+ WorkbenchMessages.Workbench_problemsSavingMsg,
+ status);
+ }
+ });
+
+ }
+ return memento;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public boolean restart() {
+ // this is the return code from run() to trigger a restart
+ return close(PlatformUI.RETURN_RESTART, false);
+ }
+
+ /**
+ * Returns the ids of all plug-ins that extend the
+ * <code>org.eclipse.ui.startup</code> extension point.
+ *
+ * @return the ids of all plug-ins containing 1 or more startup extensions
+ */
+ public String[] getEarlyActivatedPlugins() {
+ IExtensionPoint point = Platform.getExtensionRegistry()
+ .getExtensionPoint(PlatformUI.PLUGIN_ID,
+ IWorkbenchRegistryConstants.PL_STARTUP);
+ IExtension[] extensions = point.getExtensions();
+ ArrayList pluginIds = new ArrayList(extensions.length);
+ for (int i = 0; i < extensions.length; i++) {
+ String id = extensions[i].getNamespace();
+ if (!pluginIds.contains(id)) {
+ pluginIds.add(id);
+ }
+ }
+ return (String[]) pluginIds.toArray(new String[pluginIds.size()]);
+ }
+
+ /**
+ * Returns the ids of the early activated plug-ins that have been disabled
+ * by the user.
+ *
+ * @return the ids of the early activated plug-ins that have been disabled
+ * by the user
+ */
+ public String[] getDisabledEarlyActivatedPlugins() {
+ String pref = PrefUtil.getInternalPreferenceStore().getString(
+ IPreferenceConstants.PLUGINS_NOT_ACTIVATED_ON_STARTUP);
+ return Util.getArrayFromList(pref, ";"); //$NON-NLS-1$
+ }
+
+ /*
+ * Starts all plugins that extend the <code> org.eclipse.ui.startup </code>
+ * extension point, and that the user has not disabled via the preference
+ * page.
+ */
+ private void startPlugins() {
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+
+ // bug 55901: don't use getConfigElements directly, for pre-3.0
+ // compat, make sure to allow both missing class
+ // attribute and a missing startup element
+ IExtensionPoint point = registry.getExtensionPoint(
+ PlatformUI.PLUGIN_ID, IWorkbenchRegistryConstants.PL_STARTUP);
+
+ final IExtension[] extensions = point.getExtensions();
+ if (extensions.length == 0) {
+ return;
+ }
+ Job job = new Job("Workbench early startup") { //$NON-NLS-1$
+ protected IStatus run(IProgressMonitor monitor) {
+ HashSet disabledPlugins = new HashSet(
+ Arrays.asList(getDisabledEarlyActivatedPlugins()));
+ monitor.beginTask(WorkbenchMessages.Workbench_startingPlugins,
+ extensions.length);
+ for (int i = 0; i < extensions.length; ++i) {
+ if (monitor.isCanceled() || !isRunning()) {
+ return Status.CANCEL_STATUS;
+ }
+ IExtension extension = extensions[i];
+
+ // if the plugin is not in the set of disabled plugins, then
+ // execute the code to start it
+ if (!disabledPlugins.contains(extension.getNamespace())) {
+ monitor.subTask(extension.getNamespace());
+ SafeRunner.run(new EarlyStartupRunnable(extension));
+ }
+ monitor.worked(1);
+ }
+ monitor.done();
+ return Status.OK_STATUS;
+ }
+
+ public boolean belongsTo(Object family) {
+ return EARLY_STARTUP_FAMILY.equals(family);
+ }
+ };
+ job.setSystem(true);
+ job.schedule();
+ }
+
+ /**
+ * Internal method for running the workbench UI. This entails processing and
+ * dispatching events until the workbench is closed or restarted.
+ *
+ * @return return code {@link PlatformUI#RETURN_OK RETURN_OK}for normal
+ * exit; {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the
+ * workbench was terminated with a call to
+ * {@link IWorkbench#restart IWorkbench.restart};
+ * {@link PlatformUI#RETURN_UNSTARTABLE RETURN_UNSTARTABLE}if the
+ * workbench could not be started; other values reserved for future
+ * use
+ * @since 3.0
+ */
+ private int runUI() {
+ UIStats.start(UIStats.START_WORKBENCH, "Workbench"); //$NON-NLS-1$
+
+ // deadlock code
+ boolean avoidDeadlock = true;
+
+ String[] commandLineArgs = Platform.getCommandLineArgs();
+ for (int i = 0; i < commandLineArgs.length; i++) {
+ if (commandLineArgs[i].equalsIgnoreCase("-allowDeadlock")) { //$NON-NLS-1$
+ avoidDeadlock = false;
+ }
+ }
+
+ final UISynchronizer synchronizer;
+
+ if (avoidDeadlock) {
+ UILockListener uiLockListener = new UILockListener(display);
+ Job.getJobManager().setLockListener(uiLockListener);
+ synchronizer = new UISynchronizer(display, uiLockListener);
+ display.setSynchronizer(synchronizer);
+ // declare the main thread to be a startup thread.
+ UISynchronizer.startupThread.set(Boolean.TRUE);
+ } else
+ synchronizer = null;
+
+ // prime the splash nice and early
+ if (createSplash)
+ createSplashWrapper();
+
+ // ModalContext should not spin the event loop (there is no UI yet to
+ // block)
+ ModalContext.setAllowReadAndDispatch(false);
+
+ // if the -debug command line argument is used and the event loop is
+ // being
+ // run while starting the Workbench, log a warning.
+ if (WorkbenchPlugin.getDefault().isDebugging()) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (isStarting()) {
+ WorkbenchPlugin.log(StatusUtil
+ .newStatus(
+ IStatus.WARNING,
+ "Event loop should not be run while the Workbench is starting.", //$NON-NLS-1$
+ new RuntimeException()));
+ }
+ }
+ });
+ }
+
+ Listener closeListener = new Listener() {
+ public void handleEvent(Event event) {
+ event.doit = close();
+ }
+ };
+
+ // Initialize an exception handler.
+ Window.IExceptionHandler handler = ExceptionHandler.getInstance();
+
+ try {
+ // react to display close event by closing workbench nicely
+ display.addListener(SWT.Close, closeListener);
+
+ // install backstop to catch exceptions thrown out of event loop
+ Window.setExceptionHandler(handler);
+
+ final boolean[] initOK = new boolean[1];
+
+ if (getSplash() != null) {
+
+ final boolean[] initDone = new boolean[] { false };
+ final Throwable[] error = new Throwable[1];
+ Thread initThread = new Thread() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Thread#run()
+ */
+ public void run() {
+ try {
+ // declare us to be a startup thread so that our
+ // syncs will be executed
+ UISynchronizer.startupThread.set(Boolean.TRUE);
+ initOK[0] = Workbench.this.init();
+ } catch (Throwable e) {
+ error[0] = e;
+ } finally {
+ initDone[0] = true;
+ display.wake();
+ }
+ }
+ };
+ initThread.start();
+ while (true) {
+ if (!display.readAndDispatch()) {
+ if (initDone[0])
+ break;
+ display.sleep();
+ }
+ }
+ Throwable throwable = error[0];
+ if (throwable != null) {
+ if (throwable instanceof Error)
+ throw (Error) throwable;
+ if (throwable instanceof Exception)
+ throw (Exception) throwable;
+
+ // how very exotic - something that isn't playing by the
+ // rules. Wrap it in an error and bail
+ throw new Error(throwable);
+ }
+ } else {
+ // initialize workbench and restore or open one window
+ initOK[0] = init();
+
+ }
+ // drop the splash screen now that a workbench window is up
+ Platform.endSplash();
+
+ // let the advisor run its start up code
+ if (initOK[0]) {
+ advisor.postStartup(); // may trigger a close/restart
+ }
+
+ if (initOK[0] && runEventLoop) {
+ // start eager plug-ins
+ startPlugins();
+ addStartupRegistryListener();
+
+ // WWinPluginAction.refreshActionList();
+
+ display.asyncExec(new Runnable() {
+ public void run() {
+ UIStats.end(UIStats.START_WORKBENCH, this, "Workbench"); //$NON-NLS-1$
+ UIStats.startupComplete();
+ }
+ });
+
+ getWorkbenchTestable().init(display, this);
+
+ // allow ModalContext to spin the event loop
+ ModalContext.setAllowReadAndDispatch(true);
+ isStarting = false;
+
+ if (synchronizer != null)
+ synchronizer.started();
+ // the event loop
+ runEventLoop(handler, display);
+ }
+
+ } catch (final Exception e) {
+ if (!display.isDisposed()) {
+ handler.handleException(e);
+ } else {
+ String msg = "Exception in Workbench.runUI after display was disposed"; //$NON-NLS-1$
+ WorkbenchPlugin.log(msg, new Status(IStatus.ERROR,
+ WorkbenchPlugin.PI_WORKBENCH, 1, msg, e));
+ }
+ } finally {
+ // mandatory clean up
+
+ // The runEventLoop flag may not have been cleared if an exception
+ // occurred
+ // Needs to be false to ensure PlatformUI.isWorkbenchRunning()
+ // returns false.
+ runEventLoop = false;
+
+ if (!display.isDisposed()) {
+ display.removeListener(SWT.Close, closeListener);
+ }
+ }
+
+ // restart or exit based on returnCode
+ return returnCode;
+ }
+
+ /*
+ * Runs an event loop for the workbench.
+ */
+ private void runEventLoop(Window.IExceptionHandler handler, Display display) {
+ runEventLoop = true;
+ while (runEventLoop) {
+ try {
+ if (!display.readAndDispatch()) {
+ getAdvisor().eventLoopIdle(display);
+ }
+ } catch (Throwable t) {
+ handler.handleException(t);
+ // In case Display was closed under us
+ if (display.isDisposed())
+ runEventLoop = false;
+ }
+ }
+ }
+
+ /*
+ * Saves the current state of the workbench so it can be restored later on
+ */
+ private IStatus saveState(IMemento memento) {
+ MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
+ WorkbenchMessages.Workbench_problemsSaving, null);
+
+ // Save the version number.
+ memento.putString(IWorkbenchConstants.TAG_VERSION, VERSION_STRING[1]);
+
+ // Save how many plug-ins were loaded while restoring the workbench
+ if (progressCount != -1) {
+ memento.putInteger(IWorkbenchConstants.TAG_PROGRESS_COUNT,
+ progressCount);
+ }
+
+ // Save the advisor state.
+ IMemento advisorState = memento
+ .createChild(IWorkbenchConstants.TAG_WORKBENCH_ADVISOR);
+ result.add(getAdvisor().saveState(advisorState));
+
+ // Save the workbench windows.
+ IWorkbenchWindow[] windows = getWorkbenchWindows();
+ for (int nX = 0; nX < windows.length; nX++) {
+ WorkbenchWindow window = (WorkbenchWindow) windows[nX];
+ IMemento childMem = memento
+ .createChild(IWorkbenchConstants.TAG_WINDOW);
+ result.merge(window.saveState(childMem));
+ }
+ result.add(getEditorHistory().saveState(
+ memento.createChild(IWorkbenchConstants.TAG_MRU_LIST)));
+ return result;
+ }
+
+ /*
+ * Save the workbench UI in a persistence file.
+ */
+ private boolean saveMementoToFile(XMLMemento memento) {
+ // Save it to a file.
+ // XXX: nobody currently checks the return value of this method.
+ File stateFile = getWorkbenchStateFile();
+ if (stateFile == null) {
+ return false;
+ }
+ try {
+ FileOutputStream stream = new FileOutputStream(stateFile);
+ OutputStreamWriter writer = new OutputStreamWriter(stream, "utf-8"); //$NON-NLS-1$
+ memento.save(writer);
+ writer.close();
+ } catch (IOException e) {
+ stateFile.delete();
+ MessageDialog.openError((Shell) null,
+ WorkbenchMessages.SavingProblem,
+ WorkbenchMessages.ProblemSavingState);
+ return false;
+ }
+
+ // Success !
+ return true;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public IWorkbenchPage showPerspective(String perspectiveId,
+ IWorkbenchWindow window) throws WorkbenchException {
+ Assert.isNotNull(perspectiveId);
+
+ // If the specified window has the requested perspective open, then the
+ // window
+ // is given focus and the perspective is shown. The page's input is
+ // ignored.
+ WorkbenchWindow win = (WorkbenchWindow) window;
+ if (win != null) {
+ WorkbenchPage page = win.getActiveWorkbenchPage();
+ if (page != null) {
+ IPerspectiveDescriptor perspectives[] = page
+ .getOpenPerspectives();
+ for (int i = 0; i < perspectives.length; i++) {
+ IPerspectiveDescriptor persp = perspectives[i];
+ if (perspectiveId.equals(persp.getId())) {
+ win.makeVisible();
+ page.setPerspective(persp);
+ return page;
+ }
+ }
+ }
+ }
+
+ // If another window that has the workspace root as input and the
+ // requested
+ // perpective open and active, then the window is given focus.
+ IAdaptable input = getDefaultPageInput();
+ IWorkbenchWindow[] windows = getWorkbenchWindows();
+ for (int i = 0; i < windows.length; i++) {
+ win = (WorkbenchWindow) windows[i];
+ if (window != win) {
+ WorkbenchPage page = win.getActiveWorkbenchPage();
+ if (page != null) {
+ boolean inputSame = false;
+ if (input == null) {
+ inputSame = (page.getInput() == null);
+ } else {
+ inputSame = input.equals(page.getInput());
+ }
+ if (inputSame) {
+ Perspective persp = page.getActivePerspective();
+ if (persp != null) {
+ IPerspectiveDescriptor desc = persp.getDesc();
+ if (desc != null) {
+ if (perspectiveId.equals(desc.getId())) {
+ Shell shell = win.getShell();
+ shell.open();
+ if (shell.getMinimized()) {
+ shell.setMinimized(false);
+ }
+ return page;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Otherwise the requested perspective is opened and shown in the
+ // specified
+ // window or in a new window depending on the current user preference
+ // for opening
+ // perspectives, and that window is given focus.
+ win = (WorkbenchWindow) window;
+ if (win != null) {
+ IPreferenceStore store = WorkbenchPlugin.getDefault()
+ .getPreferenceStore();
+ int mode = store.getInt(IPreferenceConstants.OPEN_PERSP_MODE);
+ IWorkbenchPage page = win.getActiveWorkbenchPage();
+ IPerspectiveDescriptor persp = null;
+ if (page != null) {
+ persp = page.getPerspective();
+ }
+
+ // Only open a new window if user preference is set and the window
+ // has an active perspective.
+ if (IPreferenceConstants.OPM_NEW_WINDOW == mode && persp != null) {
+ IWorkbenchWindow newWindow = openWorkbenchWindow(perspectiveId,
+ input);
+ return newWindow.getActivePage();
+ }
+
+ IPerspectiveDescriptor desc = getPerspectiveRegistry()
+ .findPerspectiveWithId(perspectiveId);
+ if (desc == null) {
+ throw new WorkbenchException(
+ NLS.bind(
+ WorkbenchMessages.WorkbenchPage_ErrorCreatingPerspective,
+ perspectiveId));
+ }
+ win.getShell().open();
+ if (page == null) {
+ page = win.openPage(perspectiveId, input);
+ } else {
+ page.setPerspective(desc);
+ }
+ return page;
+ }
+
+ // Just throw an exception....
+ throw new WorkbenchException(
+ NLS.bind(WorkbenchMessages.Workbench_showPerspectiveError,
+ perspectiveId));
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public IWorkbenchPage showPerspective(String perspectiveId,
+ IWorkbenchWindow window, IAdaptable input)
+ throws WorkbenchException {
+ Assert.isNotNull(perspectiveId);
+
+ // If the specified window has the requested perspective open and the
+ // same requested
+ // input, then the window is given focus and the perspective is shown.
+ boolean inputSameAsWindow = false;
+ WorkbenchWindow win = (WorkbenchWindow) window;
+ if (win != null) {
+ WorkbenchPage page = win.getActiveWorkbenchPage();
+ if (page != null) {
+ boolean inputSame = false;
+ if (input == null) {
+ inputSame = (page.getInput() == null);
+ } else {
+ inputSame = input.equals(page.getInput());
+ }
+ if (inputSame) {
+ inputSameAsWindow = true;
+ IPerspectiveDescriptor perspectives[] = page
+ .getOpenPerspectives();
+ for (int i = 0; i < perspectives.length; i++) {
+ IPerspectiveDescriptor persp = perspectives[i];
+ if (perspectiveId.equals(persp.getId())) {
+ win.makeVisible();
+ page.setPerspective(persp);
+ return page;
+ }
+ }
+ }
+ }
+ }
+
+ // If another window has the requested input and the requested
+ // perpective open and active, then that window is given focus.
+ IWorkbenchWindow[] windows = getWorkbenchWindows();
+ for (int i = 0; i < windows.length; i++) {
+ win = (WorkbenchWindow) windows[i];
+ if (window != win) {
+ WorkbenchPage page = win.getActiveWorkbenchPage();
+ if (page != null) {
+ boolean inputSame = false;
+ if (input == null) {
+ inputSame = (page.getInput() == null);
+ } else {
+ inputSame = input.equals(page.getInput());
+ }
+ if (inputSame) {
+ Perspective persp = page.getActivePerspective();
+ if (persp != null) {
+ IPerspectiveDescriptor desc = persp.getDesc();
+ if (desc != null) {
+ if (perspectiveId.equals(desc.getId())) {
+ win.getShell().open();
+ return page;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // If the specified window has the same requested input but not the
+ // requested
+ // perspective, then the window is given focus and the perspective is
+ // opened and shown
+ // on condition that the user preference is not to open perspectives in
+ // a new window.
+ win = (WorkbenchWindow) window;
+ if (inputSameAsWindow && win != null) {
+ IPreferenceStore store = WorkbenchPlugin.getDefault()
+ .getPreferenceStore();
+ int mode = store.getInt(IPreferenceConstants.OPEN_PERSP_MODE);
+
+ if (IPreferenceConstants.OPM_NEW_WINDOW != mode) {
+ IWorkbenchPage page = win.getActiveWorkbenchPage();
+ IPerspectiveDescriptor desc = getPerspectiveRegistry()
+ .findPerspectiveWithId(perspectiveId);
+ if (desc == null) {
+ throw new WorkbenchException(
+ NLS.bind(
+ WorkbenchMessages.WorkbenchPage_ErrorCreatingPerspective,
+ perspectiveId));
+ }
+ win.getShell().open();
+ if (page == null) {
+ page = win.openPage(perspectiveId, input);
+ } else {
+ page.setPerspective(desc);
+ }
+ return page;
+ }
+ }
+
+ // If the specified window has no active perspective, then open the
+ // requested perspective and show the specified window.
+ if (win != null) {
+ IWorkbenchPage page = win.getActiveWorkbenchPage();
+ IPerspectiveDescriptor persp = null;
+ if (page != null) {
+ persp = page.getPerspective();
+ }
+ if (persp == null) {
+ IPerspectiveDescriptor desc = getPerspectiveRegistry()
+ .findPerspectiveWithId(perspectiveId);
+ if (desc == null) {
+ throw new WorkbenchException(
+ NLS.bind(
+ WorkbenchMessages.WorkbenchPage_ErrorCreatingPerspective,
+ perspectiveId));
+ }
+ win.getShell().open();
+ if (page == null) {
+ page = win.openPage(perspectiveId, input);
+ } else {
+ page.setPerspective(desc);
+ }
+ return page;
+ }
+ }
+
+ // Otherwise the requested perspective is opened and shown in a new
+ // window, and the
+ // window is given focus.
+ IWorkbenchWindow newWindow = openWorkbenchWindow(perspectiveId, input);
+ return newWindow.getActivePage();
+ }
+
+ /*
+ * Shuts down the application.
+ */
+ private void shutdown() {
+ // shutdown application-specific portions first
+ try {
+ advisor.postShutdown();
+ } catch (Exception ex) {
+ StatusManager.getManager().handle(
+ StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH,
+ "Exceptions during shutdown", ex)); //$NON-NLS-1$
+ }
+
+ // notify regular workbench clients of shutdown, and clear the list when
+ // done
+ firePostShutdown();
+ workbenchListeners.clear();
+
+ cancelEarlyStartup();
+
+ // for dynamic UI
+ Platform.getExtensionRegistry().removeRegistryChangeListener(
+ extensionEventHandler);
+ Platform.getExtensionRegistry().removeRegistryChangeListener(
+ startupRegistryListener);
+
+ ((GrabFocus) Tweaklets.get(GrabFocus.KEY)).dispose();
+
+ // Bring down all of the services.
+ serviceLocator.dispose();
+
+ workbenchActivitySupport.dispose();
+ WorkbenchHelpSystem.disposeIfNecessary();
+
+ // shutdown the rest of the workbench
+ WorkbenchColors.shutdown();
+ activityHelper.shutdown();
+ uninitializeImages();
+ if (WorkbenchPlugin.getDefault() != null) {
+ WorkbenchPlugin.getDefault().reset();
+ }
+ WorkbenchThemeManager.getInstance().dispose();
+ PropertyPageContributorManager.getManager().dispose();
+ ObjectActionContributorManager.getManager().dispose();
+ if (tracker != null) {
+ tracker.close();
+ }
+ }
+
+ /**
+ * Cancels the early startup job, if it's still running.
+ */
+ private void cancelEarlyStartup() {
+ Job.getJobManager().cancel(EARLY_STARTUP_FAMILY);
+ // We do not currently wait for any plug-in currently being started to
+ // complete
+ // (e.g. by doing a join on EARLY_STARTUP_FAMILY), since they may do a
+ // syncExec,
+ // which would hang. See bug 94537 for rationale.
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public IDecoratorManager getDecoratorManager() {
+ return WorkbenchPlugin.getDefault().getDecoratorManager();
+ }
+
+ /*
+ * Returns the workbench window which was last known being the active one,
+ * or <code> null </code> .
+ */
+ private WorkbenchWindow getActivatedWindow() {
+ if (activatedWindow != null) {
+ Shell shell = activatedWindow.getShell();
+ if (shell != null && !shell.isDisposed()) {
+ return activatedWindow;
+ }
+ }
+
+ return null;
+ }
+
+ /*
+ * Sets the workbench window which was last known being the active one, or
+ * <code> null </code> .
+ */
+ /* package */
+ void setActivatedWindow(WorkbenchWindow window) {
+ activatedWindow = window;
+ }
+
+ /**
+ * Returns the unique object that applications use to configure the
+ * workbench.
+ * <p>
+ * IMPORTANT This method is declared package-private to prevent regular
+ * plug-ins from downcasting IWorkbench to Workbench and getting hold of the
+ * workbench configurer that would allow them to tamper with the workbench.
+ * The workbench configurer is available only to the application.
+ * </p>
+ */
+ /* package */
+ WorkbenchConfigurer getWorkbenchConfigurer() {
+ if (workbenchConfigurer == null) {
+ workbenchConfigurer = new WorkbenchConfigurer();
+ }
+ return workbenchConfigurer;
+ }
+
+ /**
+ * Returns the workbench advisor that created this workbench.
+ * <p>
+ * IMPORTANT This method is declared package-private to prevent regular
+ * plug-ins from downcasting IWorkbench to Workbench and getting hold of the
+ * workbench advisor that would allow them to tamper with the workbench. The
+ * workbench advisor is internal to the application.
+ * </p>
+ */
+ /* package */
+ WorkbenchAdvisor getAdvisor() {
+ return advisor;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbench.
+ */
+ public Display getDisplay() {
+ return display;
+ }
+
+ /**
+ * Returns the default perspective id, which may be <code>null</code>.
+ *
+ * @return the default perspective id, or <code>null</code>
+ */
+ public String getDefaultPerspectiveId() {
+ return getAdvisor().getInitialWindowPerspectiveId();
+ }
+
+ /**
+ * Returns the default workbench window page input.
+ *
+ * @return the default window page input or <code>null</code> if none
+ */
+ public IAdaptable getDefaultPageInput() {
+ return getAdvisor().getDefaultPageInput();
+ }
+
+ /**
+ * Returns the id of the preference page that should be presented most
+ * prominently.
+ *
+ * @return the id of the preference page, or <code>null</code> if none
+ */
+ public String getMainPreferencePageId() {
+ String id = getAdvisor().getMainPreferencePageId();
+ return id;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbench
+ *
+ * @since 3.0
+ */
+ public IElementFactory getElementFactory(String factoryId) {
+ Assert.isNotNull(factoryId);
+ return WorkbenchPlugin.getDefault().getElementFactory(factoryId);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbench#getProgressService()
+ */
+ public IProgressService getProgressService() {
+ return (IProgressService) e4Context.get(IProgressService.class
+ .getName());
+ }
+
+ private WorkbenchActivitySupport workbenchActivitySupport;
+
+ private WorkbenchCommandSupport workbenchCommandSupport;
+
+ private WorkbenchContextSupport workbenchContextSupport;
+
+ /**
+ * The single instance of the binding manager used by the workbench. This is
+ * initialized in <code>Workbench.init(Display)</code> and then never
+ * changed. This value will only be <code>null</code> if the initialization
+ * call has not yet completed.
+ *
+ * @since 3.1
+ */
+ private BindingManager bindingManager;
+
+ /**
+ * The single instance of the command manager used by the workbench. This is
+ * initialized in <code>Workbench.init(Display)</code> and then never
+ * changed. This value will only be <code>null</code> if the initialization
+ * call has not yet completed.
+ *
+ * @since 3.1
+ */
+ private CommandManager commandManager;
+
+ /**
+ * The single instance of the context manager used by the workbench. This is
+ * initialized in <code>Workbench.init(Display)</code> and then never
+ * changed. This value will only be <code>null</code> if the initialization
+ * call has not yet completed.
+ *
+ * @since 3.1
+ */
+ private ContextManager contextManager;
+
+ public IWorkbenchActivitySupport getActivitySupport() {
+ return (IWorkbenchActivitySupport) e4Context
+ .get(IWorkbenchActivitySupport.class.getName());
+ }
+
+ public IWorkbenchCommandSupport getCommandSupport() {
+ return (IWorkbenchCommandSupport) e4Context
+ .get(IWorkbenchCommandSupport.class.getName());
+ }
+
+ public IWorkbenchContextSupport getContextSupport() {
+ return (IWorkbenchContextSupport) e4Context
+ .get(IWorkbenchContextSupport.class.getName());
+ }
+
+ /**
+ * This method should not be called outside the framework.
+ *
+ * @return The context manager.
+ */
+ public ContextManager getContextManager() {
+ return (ContextManager) e4Context.get(ContextManager.class.getName());
+ }
+
+ private final IWindowListener windowListener = new IWindowListener() {
+
+ public void windowActivated(IWorkbenchWindow window) {
+ updateActiveWorkbenchWindowMenuManager(true);
+ }
+
+ public void windowClosed(IWorkbenchWindow window) {
+ updateActiveWorkbenchWindowMenuManager(true);
+ }
+
+ public void windowDeactivated(IWorkbenchWindow window) {
+ updateActiveWorkbenchWindowMenuManager(true);
+ }
+
+ public void windowOpened(IWorkbenchWindow window) {
+ updateActiveWorkbenchWindowMenuManager(true);
+ }
+ };
+
+ private final IBindingManagerListener bindingManagerListener = new IBindingManagerListener() {
+
+ public void bindingManagerChanged(
+ BindingManagerEvent bindingManagerEvent) {
+ if (bindingManagerEvent.isActiveBindingsChanged()) {
+ updateActiveWorkbenchWindowMenuManager(true);
+ }
+ }
+ };
+
+ /**
+ * The source provider that tracks the activation of action sets within the
+ * workbench. This source provider is <code>null</code> until
+ * {@link #initializeDefaultServices()} is called.
+ */
+ private ActionSetSourceProvider actionSetSourceProvider;
+
+ private WorkbenchWindow activeWorkbenchWindow = null;
+
+ private void updateActiveWorkbenchWindowMenuManager(boolean textOnly) {
+ if (activeWorkbenchWindow != null) {
+ activeWorkbenchWindow
+ .removeActionSetsListener(actionSetSourceProvider);
+ activeWorkbenchWindow = null;
+ }
+ boolean actionSetsUpdated = false;
+
+ final IWorkbenchWindow workbenchWindow = getActiveWorkbenchWindow();
+
+ if (workbenchWindow instanceof WorkbenchWindow) {
+ activeWorkbenchWindow = (WorkbenchWindow) workbenchWindow;
+ if (activeWorkbenchWindow.isClosing()) {
+ return;
+ }
+
+ // Update the action sets.
+ final Shell windowShell = activeWorkbenchWindow.getShell();
+ final Shell activeShell = getDisplay().getActiveShell();
+ final IContextService service = (IContextService) getService(IContextService.class);
+ if (Util.equals(windowShell, activeShell)
+ || service.getShellType(activeShell) == IContextService.TYPE_WINDOW) {
+ activeWorkbenchWindow
+ .addActionSetsListener(actionSetSourceProvider);
+ final WorkbenchPage page = activeWorkbenchWindow
+ .getActiveWorkbenchPage();
+ final IActionSetDescriptor[] newActionSets;
+ if (page != null) {
+ newActionSets = page.getActionSets();
+ final ActionSetsEvent event = new ActionSetsEvent(
+ newActionSets);
+ actionSetSourceProvider.actionSetsChanged(event);
+ actionSetsUpdated = true;
+ }
+ }
+
+ final MenuManager menuManager = activeWorkbenchWindow
+ .getMenuManager();
+
+ if (textOnly) {
+ menuManager.update(IAction.TEXT);
+ } else {
+ menuManager.update(true);
+ }
+ }
+
+ if (!actionSetsUpdated) {
+ final ActionSetsEvent event = new ActionSetsEvent(null);
+ actionSetSourceProvider.actionSetsChanged(event);
+ }
+ }
+
+ private ActivityPersistanceHelper activityHelper;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbench#getIntroManager()
+ */
+ public IIntroManager getIntroManager() {
+ return getWorkbenchIntroManager();
+ }
+
+ /**
+ * @return the workbench intro manager
+ * @since 3.0
+ */
+ /* package */WorkbenchIntroManager getWorkbenchIntroManager() {
+ return (WorkbenchIntroManager) e4Context
+ .get(WorkbenchIntroManager.class.getName());
+ }
+
+ private WorkbenchIntroManager introManager;
+
+ /**
+ * @return the intro extension for this workbench.
+ *
+ * @since 3.0
+ */
+ public IntroDescriptor getIntroDescriptor() {
+ if (introDescriptor == null) {
+ IIntroRegistry introRegistry = (IIntroRegistry) e4Context
+ .get(IIntroRegistry.class.getName());
+ if (introRegistry != null && introRegistry.getIntroCount() > 0) {
+ // TODO Avoid referencing platform (bug 272502)
+ IProduct product = Platform.getProduct();
+ if (product != null) {
+ introDescriptor = (IntroDescriptor) introRegistry
+ .getIntroForProduct(product.getId());
+ }
+ }
+ }
+ return introDescriptor;
+ }
+
+ /**
+ * This method exists as a test hook. This method should
+ * <strong>NEVER</strong> be called by clients.
+ *
+ * @param descriptor
+ * The intro descriptor to use.
+ * @since 3.0
+ */
+ public void setIntroDescriptor(IntroDescriptor descriptor) {
+ if (getIntroManager().getIntro() != null) {
+ getIntroManager().closeIntro(getIntroManager().getIntro());
+ }
+ introDescriptor = descriptor;
+ }
+
+ /**
+ * The descriptor for the intro extension that is valid for this workspace,
+ * <code>null</code> if none.
+ */
+ private IntroDescriptor introDescriptor;
+
+ private IExtensionTracker tracker;
+
+ private IRegistryChangeListener startupRegistryListener = new IRegistryChangeListener() {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.core.runtime.IRegistryChangeListener#registryChanged(
+ * org.eclipse.core.runtime.IRegistryChangeEvent)
+ */
+ public void registryChanged(IRegistryChangeEvent event) {
+ final IExtensionDelta[] deltas = event.getExtensionDeltas(
+ PlatformUI.PLUGIN_ID,
+ IWorkbenchRegistryConstants.PL_STARTUP);
+ if (deltas.length == 0) {
+ return;
+ }
+ final String disabledPlugins = PrefUtil
+ .getInternalPreferenceStore()
+ .getString(
+ IPreferenceConstants.PLUGINS_NOT_ACTIVATED_ON_STARTUP);
+
+ for (int i = 0; i < deltas.length; i++) {
+ IExtension extension = deltas[i].getExtension();
+ if (deltas[i].getKind() == IExtensionDelta.REMOVED) {
+ continue;
+ }
+
+ // if the plugin is not in the set of disabled plugins,
+ // then
+ // execute the code to start it
+ if (disabledPlugins.indexOf(extension.getNamespace()) == -1) {
+ SafeRunner.run(new EarlyStartupRunnable(extension));
+ }
+ }
+
+ }
+ };
+
+ private String factoryID;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbench#getThemeManager()
+ */
+ public IThemeManager getThemeManager() {
+ return (IThemeManager) e4Context.get(IThemeManager.class.getName());
+ }
+
+ /**
+ * Returns <code>true</code> if the workbench is running, <code>false</code>
+ * if it has been terminated.
+ *
+ * @return <code>true</code> if the workbench is running, <code>false</code>
+ * if it has been terminated.
+ */
+ public boolean isRunning() {
+ return runEventLoop;
+ }
+
+ /**
+ * Return the presentation ID specified by the preference or the default ID
+ * if undefined.
+ *
+ * @return the presentation ID
+ * @see IWorkbenchPreferenceConstants#PRESENTATION_FACTORY_ID
+ */
+ public String getPresentationId() {
+ if (factoryID != null) {
+ return factoryID;
+ }
+
+ factoryID = PrefUtil.getAPIPreferenceStore().getString(
+ IWorkbenchPreferenceConstants.PRESENTATION_FACTORY_ID);
+
+ // Workaround for bug 58975 - New preference mechanism does not properly
+ // initialize defaults
+ // Ensure that the UI plugin has started too.
+ if (factoryID == null || factoryID.equals("")) { //$NON-NLS-1$
+ factoryID = IWorkbenchConstants.DEFAULT_PRESENTATION_ID;
+ }
+ return factoryID;
+ }
+
+ /**
+ * <p>
+ * Indicates the start of a large update within the workbench. This is used
+ * to disable CPU-intensive, change-sensitive services that were temporarily
+ * disabled in the midst of large changes. This method should always be
+ * called in tandem with <code>largeUpdateEnd</code>, and the event loop
+ * should not be allowed to spin before that method is called.
+ * </p>
+ * <p>
+ * Important: always use with <code>largeUpdateEnd</code>!
+ * </p>
+ */
+ public final void largeUpdateStart() {
+ if (largeUpdates++ == 0) {
+ // TODO Consider whether these lines still need to be here.
+ // workbenchCommandSupport.setProcessing(false);
+ // workbenchContextSupport.setProcessing(false);
+
+ final IWorkbenchWindow[] windows = getWorkbenchWindows();
+ for (int i = 0; i < windows.length; i++) {
+ IWorkbenchWindow window = windows[i];
+ if (window instanceof WorkbenchWindow) {
+ ((WorkbenchWindow) window).largeUpdateStart();
+ }
+ }
+ }
+ }
+
+ /**
+ * <p>
+ * Indicates the end of a large update within the workbench. This is used to
+ * re-enable services that were temporarily disabled in the midst of large
+ * changes. This method should always be called in tandem with
+ * <code>largeUpdateStart</code>, and the event loop should not be allowed
+ * to spin before this method is called.
+ * </p>
+ * <p>
+ * Important: always protect this call by using <code>finally</code>!
+ * </p>
+ */
+ public final void largeUpdateEnd() {
+ if (--largeUpdates == 0) {
+ // TODO Consider whether these lines still need to be here.
+ // workbenchCommandSupport.setProcessing(true);
+ // workbenchContextSupport.setProcessing(true);
+
+ // Perform window-specific blocking.
+ final IWorkbenchWindow[] windows = getWorkbenchWindows();
+ for (int i = 0; i < windows.length; i++) {
+ IWorkbenchWindow window = windows[i];
+ if (window instanceof WorkbenchWindow) {
+ ((WorkbenchWindow) window).largeUpdateEnd();
+ }
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbench#getExtensionTracker()
+ */
+ public IExtensionTracker getExtensionTracker() {
+ return (IExtensionTracker) e4Context.get(IExtensionTracker.class
+ .getName());
+ }
+
+ /**
+ * Adds the listener that handles startup plugins
+ *
+ * @since 3.1
+ */
+ private void addStartupRegistryListener() {
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ registry.addRegistryChangeListener(startupRegistryListener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbench#getHelpSystem()
+ */
+ public IWorkbenchHelpSystem getHelpSystem() {
+ return (IWorkbenchHelpSystem) e4Context.get(IWorkbenchHelpSystem.class
+ .getName());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbench#getHelpSystem()
+ */
+ public IWorkbenchBrowserSupport getBrowserSupport() {
+ return (IWorkbenchBrowserSupport) e4Context
+ .get(IWorkbenchBrowserSupport.class.getName());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbench#getViewRegistry()
+ */
+ public IViewRegistry getViewRegistry() {
+ return WorkbenchPlugin.getDefault().getViewRegistry();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbench#getNewWizardRegistry()
+ */
+ public IWizardRegistry getNewWizardRegistry() {
+ return WorkbenchPlugin.getDefault().getNewWizardRegistry();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbench#getImportWizardRegistry()
+ */
+ public IWizardRegistry getImportWizardRegistry() {
+ return WorkbenchPlugin.getDefault().getImportWizardRegistry();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbench#getExportWizardRegistry()
+ */
+ public IWizardRegistry getExportWizardRegistry() {
+ return WorkbenchPlugin.getDefault().getExportWizardRegistry();
+ }
+
+ public final Object getAdapter(final Class key) {
+ return serviceLocator.getService(key);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.services.IServiceLocator#getService(java.lang.Object)
+ */
+ public final Object getService(final Class key) {
+ return serviceLocator.getService(key);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.services.IServiceLocator#hasService(java.lang.Object)
+ */
+ public final boolean hasService(final Class key) {
+ return serviceLocator.hasService(key);
+ }
+
+ /**
+ * Registers a service with this locator. If there is an existing service
+ * matching the same <code>api</code> and it implements {@link IDisposable},
+ * it will be disposed.
+ *
+ * @param api
+ * This is the interface that the service implements. Must not be
+ * <code>null</code>.
+ * @param service
+ * The service to register. This must be some implementation of
+ * <code>api</code>. This value must not be <code>null</code>.
+ */
+ public final void registerService(final Class api, final Object service) {
+ serviceLocator.registerService(api, service);
+ }
+
+ /**
+ * The source provider that tracks which context menus (i.e., menus with
+ * target identifiers) are now showing. This value is <code>null</code>
+ * until {@link #initializeDefaultServices()} is called.
+ */
+ private MenuSourceProvider menuSourceProvider;
+
+ private IEclipseContext e4Context;
+
+ private org.eclipse.e4.workbench.ui.internal.Workbench e4Workbench;
+
+ /**
+ * Adds the ids of a menu that is now showing to the menu source provider.
+ * This is used for legacy action-based handlers which need to become active
+ * only for the duration of a menu being visible.
+ *
+ * @param menuIds
+ * The identifiers of the menu that is now showing; must not be
+ * <code>null</code>.
+ * @param localSelection
+ * @param localEditorInput
+ */
+ public final void addShowingMenus(final Set menuIds,
+ final ISelection localSelection, final ISelection localEditorInput) {
+ menuSourceProvider.addShowingMenus(menuIds, localSelection,
+ localEditorInput);
+ e4Context.set(ISources.ACTIVE_MENU_NAME, menuIds);
+ e4Context.set(ISources.ACTIVE_MENU_SELECTION_NAME, localSelection);
+ e4Context.set(ISources.ACTIVE_MENU_EDITOR_INPUT_NAME, localEditorInput);
+ org.eclipse.e4.workbench.ui.internal.Activator.trace(
+ org.eclipse.e4.workbench.ui.internal.Policy.DEBUG_MENUS,
+ "Adding menus " + menuIds + ", selection: " + localSelection, //$NON-NLS-1$ //$NON-NLS-2$
+ null);
+ }
+
+ /**
+ * Removes the ids of a menu that is now hidden from the menu source
+ * provider. This is used for legacy action-based handlers which need to
+ * become active only for the duration of a menu being visible.
+ *
+ * @param menuIds
+ * The identifiers of the menu that is now hidden; must not be
+ * <code>null</code>.
+ * @param localSelection
+ * @param localEditorInput
+ */
+ public final void removeShowingMenus(final Set menuIds,
+ final ISelection localSelection, final ISelection localEditorInput) {
+ menuSourceProvider.removeShowingMenus(menuIds, localSelection,
+ localEditorInput);
+ e4Context.set(ISources.ACTIVE_MENU_NAME, null);
+ e4Context.set(ISources.ACTIVE_MENU_SELECTION_NAME, null);
+ e4Context.set(ISources.ACTIVE_MENU_EDITOR_INPUT_NAME, null);
+ org.eclipse.e4.workbench.ui.internal.Activator.trace(
+ org.eclipse.e4.workbench.ui.internal.Policy.DEBUG_MENUS,
+ "Clearing menus " + menuIds, null); //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.IWorkbench#saveAll(org.eclipse.jface.window.IShellProvider
+ * , org.eclipse.jface.operation.IRunnableContext,
+ * org.eclipse.ui.ISaveableFilter, boolean)
+ */
+ public boolean saveAll(IShellProvider shellProvider,
+ IRunnableContext runnableContext, ISaveableFilter filter,
+ boolean confirm) {
+ SaveablesList saveablesList = (SaveablesList) PlatformUI.getWorkbench()
+ .getService(ISaveablesLifecycleListener.class);
+ Saveable[] saveables = saveablesList.getOpenModels();
+ List toSave = getFilteredSaveables(filter, saveables);
+ if (toSave.isEmpty())
+ return true;
+
+ if (!confirm) {
+ return !saveablesList.saveModels(toSave, shellProvider,
+ runnableContext);
+ }
+
+ // We must negate the result since false is cancel saveAll
+ return !saveablesList.promptForSaving(toSave, shellProvider,
+ runnableContext, true, false);
+ }
+
+ /*
+ * Apply the given filter to the list of saveables
+ */
+ private List getFilteredSaveables(ISaveableFilter filter,
+ Saveable[] saveables) {
+ List toSave = new ArrayList();
+ if (filter == null) {
+ for (int i = 0; i < saveables.length; i++) {
+ Saveable saveable = saveables[i];
+ if (saveable.isDirty())
+ toSave.add(saveable);
+ }
+ } else {
+ SaveablesList saveablesList = (SaveablesList) getService(ISaveablesLifecycleListener.class);
+ for (int i = 0; i < saveables.length; i++) {
+ Saveable saveable = saveables[i];
+ if (saveable.isDirty()) {
+ IWorkbenchPart[] parts = saveablesList
+ .getPartsForSaveable(saveable);
+ if (matchesFilter(filter, saveable, parts))
+ toSave.add(saveable);
+ }
+ }
+ }
+ return toSave;
+ }
+
+ /*
+ * Test whether the given filter matches the saveable
+ */
+ private boolean matchesFilter(ISaveableFilter filter, Saveable saveable,
+ IWorkbenchPart[] parts) {
+ return filter == null || filter.select(saveable, parts);
+ }
+
+ public ServiceLocator getServiceLocator() {
+ return serviceLocator;
+ }
+
+ // TBD this seems like an API that should be in the model
+ public void addCommand(String id, String name) {
+ MApplication app = (MApplication) e4Context.get(MApplication.class
+ .getName());
+ MCommand newCommand = MApplicationFactory.eINSTANCE.createCommand();
+ newCommand.setId(id);
+ newCommand.setCommandName(name);
+ app.getCommands().add(newCommand);
+
+ ECommandService cs = (ECommandService) e4Context
+ .get(ECommandService.class.getName());
+ Command command = cs.getCommand(id);
+ if (!command.isDefined()) {
+ Category category = cs
+ .getCategory(IWorkbenchRegistryConstants.PL_ACTION_SETS);
+ if (!category.isDefined())
+ category.define("Action Sets", null); //$NON-NLS-1$
+ command.define(newCommand.getCommandName(), null, category);
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPage.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPage.java
new file mode 100644
index 0000000..1c049ec
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPage.java
@@ -0,0 +1,3562 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ui.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
+import org.eclipse.e4.compatibility.LegacyEditor;
+import org.eclipse.e4.compatibility.LegacyView;
+import org.eclipse.e4.core.services.IDisposable;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.extensions.ModelEditorReference;
+import org.eclipse.e4.extensions.ModelReference;
+import org.eclipse.e4.ui.model.application.MApplicationFactory;
+import org.eclipse.e4.ui.model.application.MContribution;
+import org.eclipse.e4.ui.model.application.MESCElement;
+import org.eclipse.e4.ui.model.application.MEditor;
+import org.eclipse.e4.ui.model.application.MEditorSashContainer;
+import org.eclipse.e4.ui.model.application.MElementContainer;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MPerspective;
+import org.eclipse.e4.ui.model.application.MPerspectiveStack;
+import org.eclipse.e4.ui.model.application.MUIElement;
+import org.eclipse.e4.ui.model.application.MWindow;
+import org.eclipse.e4.ui.workbench.swt.internal.AbstractPartRenderer;
+import org.eclipse.e4.workbench.ui.api.ModeledPageLayout;
+import org.eclipse.e4.workbench.ui.internal.IValueFunction;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.internal.provisional.action.ICoolBarManager2;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.program.Program;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.INavigationHistory;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IPartListener2;
+import org.eclipse.ui.IPathEditorInput;
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.IReusableEditor;
+import org.eclipse.ui.ISaveablePart;
+import org.eclipse.ui.ISaveablesLifecycleListener;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.ISelectionService;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.IWorkbenchPreferenceConstants;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.MultiPartInitException;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.contexts.IContextService;
+import org.eclipse.ui.internal.dialogs.CustomizePerspectiveDialog;
+import org.eclipse.ui.internal.misc.UIListenerLogging;
+import org.eclipse.ui.internal.misc.UIStats;
+import org.eclipse.ui.internal.registry.ActionSetRegistry;
+import org.eclipse.ui.internal.registry.EditorDescriptor;
+import org.eclipse.ui.internal.registry.IActionSetDescriptor;
+import org.eclipse.ui.internal.registry.PerspectiveDescriptor;
+import org.eclipse.ui.internal.registry.UIExtensionTracker;
+import org.eclipse.ui.internal.tweaklets.GrabFocus;
+import org.eclipse.ui.internal.tweaklets.TabBehaviour;
+import org.eclipse.ui.internal.tweaklets.Tweaklets;
+import org.eclipse.ui.internal.tweaklets.WorkbenchImplementation;
+import org.eclipse.ui.internal.util.PrefUtil;
+import org.eclipse.ui.internal.util.Util;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+import org.eclipse.ui.part.AbstractMultiEditor;
+import org.eclipse.ui.part.EditorPart;
+import org.eclipse.ui.presentations.IStackPresentationSite;
+
+/**
+ * A collection of views and editors in a workbench.
+ */
+public class WorkbenchPage extends CompatibleWorkbenchPage implements
+ IWorkbenchPage {
+
+ private static final String ATT_AGGREGATE_WORKING_SET_ID = "aggregateWorkingSetId"; //$NON-NLS-1$
+
+ private static final IEditorReference[] noEditorRefs = new IEditorReference[0];
+
+ protected WorkbenchWindow window;
+
+ private IAdaptable input;
+
+ private IWorkingSet workingSet;
+
+ private AggregateWorkingSet aggregateWorkingSet;
+
+ private Composite composite;
+
+ private EditorManager editorMgr;
+
+ private ArrayList removedEditors = new ArrayList();
+
+ private ListenerList propertyChangeListeners = new ListenerList();
+
+ private WorkbenchPagePartList partList = null;
+
+ private IActionBars actionBars;
+
+ private ActionSetManager actionSets;
+
+ private ViewFactory viewFactory;
+
+ private PerspectiveList perspList = new PerspectiveList();
+
+ private PerspectiveDescriptor deferredActivePersp;
+
+ private NavigationHistory navigationHistory = null;
+
+ private IStickyViewManager stickyViewMan = StickyViewManager
+ .getInstance(this);
+
+ /**
+ * If we're in the process of activating a part, this points to the new
+ * part. Otherwise, this is null.
+ */
+ private IWorkbenchPartReference partBeingActivated = null;
+
+ /**
+ * If a part is being opened, don't allow a forceFocus() to request its
+ * activation as well.
+ *
+ * @since 3.4
+ */
+ private boolean partBeingOpened = false;
+
+ /**
+ * Contains a list of perspectives that may be dirty due to plugin
+ * installation and removal.
+ */
+ private Set dirtyPerspectives = new HashSet();
+
+ private IPropertyChangeListener workingSetPropertyChangeListener = new IPropertyChangeListener() {
+ /*
+ * Remove the working set from the page if the working set is deleted.
+ */
+ public void propertyChange(PropertyChangeEvent event) {
+ String property = event.getProperty();
+ if (IWorkingSetManager.CHANGE_WORKING_SET_REMOVE.equals(property)) {
+ if (event.getOldValue().equals(workingSet)) {
+ setWorkingSet(null);
+ }
+
+ // room for optimization here
+ List newList = new ArrayList(Arrays.asList(workingSets));
+ if (newList.remove(event.getOldValue())) {
+ setWorkingSets((IWorkingSet[]) newList
+ .toArray(new IWorkingSet[newList.size()]));
+ }
+ }
+ }
+ };
+
+ private IExtensionTracker tracker;
+
+ private IWorkingSet[] workingSets = new IWorkingSet[0];
+ private String aggregateWorkingSetId;
+
+ private MWindow e4Window;
+
+ private IEclipseContext e4Context;
+
+ private ISelectionService selectionService;
+
+ /**
+ * Constructs a new page with a given perspective and input.
+ *
+ * @param w
+ * the parent window
+ * @param layoutID
+ * must not be <code>null</code>
+ * @param input
+ * the page input
+ * @throws WorkbenchException
+ * on null layout id
+ */
+ public WorkbenchPage(WorkbenchWindow w, String layoutID, IAdaptable input)
+ throws WorkbenchException {
+ super();
+ if (layoutID == null) {
+ throw new WorkbenchException(
+ WorkbenchMessages.WorkbenchPage_UndefinedPerspective);
+ }
+ init(w, layoutID, input, true);
+ }
+
+ /**
+ * Constructs a page. <code>restoreState(IMemento)</code> should be called
+ * to restore this page from data stored in a persistance file.
+ *
+ * @param w
+ * the parent window
+ * @param input
+ * the page input
+ * @throws WorkbenchException
+ */
+ public WorkbenchPage(WorkbenchWindow w, IAdaptable input)
+ throws WorkbenchException {
+ super();
+ init(w, null, input, false);
+ }
+
+ /**
+ * Activates a part. The part will be brought to the front and given focus.
+ *
+ * @param part
+ * the part to activate
+ */
+ public void activate(IWorkbenchPart part) {
+ // Sanity check.
+ if (part == null || !certifyPart(part) || window.isClosing()) {
+ return;
+ }
+
+ // Activate the part and set its focus
+ IWorkbenchPartReference ref = getReference(part);
+ if (ref instanceof ModelReference) {
+ ModelReference modelRef = (ModelReference) ref;
+ MPart modelElement = modelRef.getModel();
+ if (modelElement != null) {
+ AbstractPartRenderer renderer = (AbstractPartRenderer) modelElement
+ .getFactory();
+ if (renderer != null)
+ renderer.activate(modelElement);
+
+ }
+ }
+
+ }
+
+ /**
+ * Add a fast view.
+ */
+ public void addFastView(IViewReference ref) {
+ }
+
+ /**
+ * Add a fast view.
+ */
+ public void makeFastView(IViewReference ref) {
+ }
+
+ /**
+ * Adds an IPartListener to the part service.
+ */
+ public void addPartListener(IPartListener l) {
+ partList.getPartService().addPartListener(l);
+ }
+
+ /**
+ * Adds an IPartListener to the part service.
+ */
+ public void addPartListener(IPartListener2 l) {
+ partList.getPartService().addPartListener(l);
+ }
+
+ /**
+ * Implements IWorkbenchPage
+ *
+ * @see org.eclipse.ui.IWorkbenchPage#addPropertyChangeListener(IPropertyChangeListener)
+ * @since 2.0
+ * @deprecated individual views should store a working set if needed and
+ * register a property change listener directly with the working
+ * set manager to receive notification when the view working set
+ * is removed.
+ */
+ public void addPropertyChangeListener(IPropertyChangeListener listener) {
+ propertyChangeListeners.add(listener);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on ISelectionListener.
+ */
+ public void addSelectionListener(ISelectionListener listener) {
+ selectionService.addSelectionListener(listener);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on ISelectionListener.
+ */
+ public void addSelectionListener(String partId, ISelectionListener listener) {
+ selectionService.addSelectionListener(partId, listener);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on ISelectionListener.
+ */
+ public void addPostSelectionListener(ISelectionListener listener) {
+ selectionService.addPostSelectionListener(listener);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on ISelectionListener.
+ */
+ public void addPostSelectionListener(String partId,
+ ISelectionListener listener) {
+ selectionService.addPostSelectionListener(partId, listener);
+ }
+
+ /**
+ * Moves a part forward in the Z order of a perspective so it is visible. If
+ * the part is in the same stack as the active part, the new part is
+ * activated.
+ *
+ * @param part
+ * the part to bring to move forward
+ */
+ public void bringToTop(IWorkbenchPart part) {
+ // Sanity check.
+ Perspective persp = getActivePerspective();
+ if (persp == null || !certifyPart(part)) {
+ return;
+ }
+
+ if (!((GrabFocus) Tweaklets.get(GrabFocus.KEY)).grabFocusAllowed(part)) {
+ return;
+ }
+
+ // TBD we have no shared parts so far. Processing below should be
+ // updated once shared parts are implemented
+ if (part instanceof EditorPart) {
+ MEditorSashContainer ea = (MEditorSashContainer) findPartInCurrentPerspective(ModeledPageLayout
+ .internalGetEditorArea());
+ String editorID = ((EditorPart) part).getEditorSite().getId();
+ IEditorInput editorInput = ((EditorPart) part).getEditorInput();
+ MEditor editorPart = findEditor(ea, editorID, editorInput);
+ if (editorPart != null) {
+ editorPart.setVisible(true);
+ ea.setActiveChild((MESCElement) editorPart);
+ } else {
+ try {
+ openEditor(editorInput, editorID, true, MATCH_NONE);
+ } catch (PartInitException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ } else {
+ // TBD implement functionality for views
+ }
+ }
+
+ /**
+ * Shows a view.
+ *
+ * Assumes that a busy cursor is active.
+ */
+ protected IViewPart busyShowView(String viewID, String secondaryID, int mode)
+ throws PartInitException {
+ Perspective persp = getActivePerspective();
+ if (persp == null) {
+ return null;
+ }
+
+ // If this view is already visible just return.
+ IViewReference ref = persp.findView(viewID, secondaryID);
+ IViewPart view = null;
+ if (ref != null) {
+ view = ref.getView(true);
+ }
+ if (view != null) {
+ busyShowView(view, mode);
+ return view;
+ }
+
+ // Show the view.
+ view = persp.showView(viewID, secondaryID);
+ if (view != null) {
+
+ window.firePerspectiveChanged(this, getPerspective(), null,
+ CHANGE_VIEW_SHOW);
+ window.firePerspectiveChanged(this, getPerspective(),
+ CHANGE_VIEW_SHOW);
+ }
+ return view;
+ }
+
+ /*
+ * Performs showing of the view in the given mode.
+ */
+ private void busyShowView(IViewPart part, int mode) {
+ if (!((GrabFocus) Tweaklets.get(GrabFocus.KEY)).grabFocusAllowed(part)) {
+ return;
+ }
+ }
+
+ /**
+ * Returns whether a part exists in the current page.
+ */
+ private boolean certifyPart(IWorkbenchPart part) {
+ // Workaround for bug 22325
+ if (part != null && !(part.getSite() instanceof PartSite)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Closes the perspective.
+ */
+ public boolean close() {
+ final boolean[] ret = new boolean[1];
+ BusyIndicator.showWhile(null, new Runnable() {
+ public void run() {
+ ret[0] = window.closePage(WorkbenchPage.this, true);
+ }
+ });
+ return ret[0];
+ }
+
+ /**
+ * See IWorkbenchPage
+ */
+ public boolean closeAllSavedEditors() {
+ // get the Saved editors
+ IEditorReference editors[] = getEditorReferences();
+ IEditorReference savedEditors[] = new IEditorReference[editors.length];
+ int j = 0;
+ for (int i = 0; i < editors.length; i++) {
+ IEditorReference editor = editors[i];
+ if (!editor.isDirty()) {
+ savedEditors[j++] = editor;
+ }
+ }
+ // there are no unsaved editors
+ if (j == 0) {
+ return true;
+ }
+ IEditorReference[] newSaved = new IEditorReference[j];
+ System.arraycopy(savedEditors, 0, newSaved, 0, j);
+ return closeEditors(newSaved, false);
+ }
+
+ /**
+ * See IWorkbenchPage
+ */
+ public boolean closeAllEditors(boolean save) {
+ return closeEditors(getEditorReferences(), save);
+ }
+
+ /**
+ * See IWorkbenchPage
+ */
+ public boolean closeEditors(IEditorReference[] refArray, boolean save) {
+ if (refArray.length == 0) {
+ return true;
+ }
+
+ // Check if we're being asked to close any parts that are already closed
+ // or cannot
+ // be closed at this time
+ ArrayList toClose = new ArrayList();
+ for (int i = 0; i < refArray.length; i++) {
+ IEditorReference reference = refArray[i];
+
+ // If we're in the middle of creating this part, this is a
+ // programming error. Abort the entire
+ // close operation. This usually occurs if someone tries to open a
+ // dialog in a method that
+ // isn't allowed to do so, and a *syncExec tries to close the part.
+ // If this shows up in a log
+ // file with a dialog's event loop on the stack, then the code that
+ // opened the dialog is usually
+ // at fault.
+ if (reference == partBeingActivated) {
+ WorkbenchPlugin
+ .log(new RuntimeException(
+ "WARNING: Blocked recursive attempt to close part " //$NON-NLS-1$
+ + partBeingActivated.getId()
+ + " while still in the middle of activating it")); //$NON-NLS-1$
+ return false;
+ }
+
+ if (reference instanceof WorkbenchPartReference) {
+ WorkbenchPartReference ref = (WorkbenchPartReference) reference;
+
+ // If we're being asked to close a part that is disposed (ie:
+ // already closed),
+ // skip it and proceed with closing the remaining parts.
+ if (ref.isDisposed()) {
+ continue;
+ }
+ }
+
+ toClose.add(reference);
+ }
+
+ IEditorReference[] editorRefs = (IEditorReference[]) toClose
+ .toArray(new IEditorReference[toClose.size()]);
+
+ // if active navigation position belongs to an editor being closed,
+ // update it
+ // (The navigation position for an editor N was updated as an editor N +
+ // 1
+ // was activated. As a result, all but the last editor have up-to-date
+ // navigation positions.)
+ for (int i = 0; i < editorRefs.length; i++) {
+ IEditorReference ref = editorRefs[i];
+ if (ref == null)
+ continue;
+ IEditorPart oldPart = ref.getEditor(false);
+ if (oldPart == null)
+ continue;
+ if (navigationHistory.updateActive(oldPart))
+ break; // updated - skip the rest
+ }
+
+ // notify the model manager before the close
+ List partsToClose = new ArrayList();
+ for (int i = 0; i < editorRefs.length; i++) {
+ IEditorPart refPart = editorRefs[i].getEditor(false);
+ if (refPart != null) {
+ partsToClose.add(refPart);
+ }
+ }
+ SaveablesList modelManager = null;
+ Object postCloseInfo = null;
+ if (partsToClose.size() > 0) {
+ modelManager = (SaveablesList) getWorkbenchWindow().getService(
+ ISaveablesLifecycleListener.class);
+ // this may prompt for saving and return null if the user canceled:
+ postCloseInfo = modelManager.preCloseParts(partsToClose, save,
+ getWorkbenchWindow());
+ if (postCloseInfo == null) {
+ return false;
+ }
+ }
+
+ // Fire pre-removal changes
+ for (int i = 0; i < editorRefs.length; i++) {
+ IEditorReference ref = editorRefs[i];
+
+ // Notify interested listeners before the close
+ window.firePerspectiveChanged(this, getPerspective(), ref,
+ CHANGE_EDITOR_CLOSE);
+
+ }
+
+ if (modelManager != null) {
+ modelManager.postClose(postCloseInfo);
+ }
+
+ // Close all editors.
+ for (int i = 0; i < editorRefs.length; i++) {
+ IEditorReference ref = editorRefs[i];
+
+ // Remove editor from the presentation
+
+ partRemoved(ref);
+ // now that it has disappeared from the model, dispose its context
+ MPart mEditorPart = ((ModelEditorReference) ref).getModel();
+ ((IDisposable) mEditorPart.getContext()).dispose();
+ mEditorPart.setContext(null);
+ }
+
+ // Notify interested listeners after the close
+ window.firePerspectiveChanged(this, getPerspective(),
+ CHANGE_EDITOR_CLOSE);
+
+ // Return true on success.
+ return true;
+ }
+
+ /**
+ * See IWorkbenchPage#closeEditor
+ */
+ public boolean closeEditor(IEditorReference editorRef, boolean save) {
+ return closeEditors(new IEditorReference[] { editorRef }, save);
+ }
+
+ /**
+ * See IWorkbenchPage#closeEditor
+ */
+ public boolean closeEditor(IEditorPart editor, boolean save) {
+ IWorkbenchPartReference ref = getReference(editor);
+ if (ref instanceof IEditorReference) {
+ return closeEditors(
+ new IEditorReference[] { (IEditorReference) ref }, save);
+ }
+ return false;
+ }
+
+ /**
+ * @see IWorkbenchPage#closePerspective(IPerspectiveDescriptor, boolean,
+ * boolean)
+ */
+ public void closePerspective(IPerspectiveDescriptor desc,
+ boolean saveParts, boolean closePage) {
+ Perspective persp = findPerspective(desc);
+ if (persp != null) {
+ perspList.openedList.remove(persp);
+ perspList.usedList.remove(persp);
+
+ // If we close the last perspective there is no active one...
+ if (perspList.openedList.isEmpty())
+ perspList.setActive(null);
+ }
+ }
+
+ /**
+ * Closes the specified perspective in this page. If this is not the last
+ * perspective in the page, and it is active, then the perspective specified
+ * by <code>descToActivate</code> will be activated. If the last perspective
+ * in this page is closed, then all editors are closed. Views that are not
+ * shown in other perspectives are closed as well. If <code>saveParts</code>
+ * is <code>true</code>, the user will be prompted to save any unsaved
+ * changes for parts that are being closed. The page itself is closed if
+ * <code>closePage</code> is <code>true</code>.
+ *
+ * @param desc
+ * the descriptor of the perspective to be closed
+ * @param descToActivate
+ * the descriptor of the perspective to activate
+ * @param saveParts
+ * whether the page's parts should be saved if closed
+ * @param closePage
+ * whether the page itself should be closed if last perspective
+ * @since 3.4
+ */
+ public void closePerspective(IPerspectiveDescriptor desc,
+ IPerspectiveDescriptor descToActivate, boolean saveParts,
+ boolean closePage) {
+ Perspective persp = findPerspective(desc);
+ if (persp != null) {
+ perspList.openedList.remove(persp);
+ perspList.usedList.remove(persp);
+
+ // If we close the last perspective there is no active one...
+ if (perspList.openedList.isEmpty())
+ perspList.setActive(null);
+ }
+ }
+
+ /**
+ * Closes the specified perspective. If last perspective, then entire page
+ * is closed.
+ *
+ * @param persp
+ * the perspective to be closed
+ * @param saveParts
+ * whether the parts that are being closed should be saved
+ * (editors if last perspective, views if not shown in other
+ * parspectives)
+ */
+ /* package */
+ void closePerspective(Perspective persp, boolean saveParts,
+ boolean closePage) {
+ closePerspective(persp, null, saveParts, closePage);
+ }
+
+ /**
+ * Closes the specified perspective. If last perspective, then entire page
+ * is closed.
+ *
+ * @param persp
+ * the perspective to be closed
+ * @param perspToActivate
+ * the perspective to activate
+ * @param saveParts
+ * whether the parts that are being closed should be saved
+ * (editors if last perspective, views if not shown in other
+ * parspectives)
+ */
+ /* package */
+ void closePerspective(Perspective persp, Perspective perspToActivate,
+ boolean saveParts, boolean closePage) {
+
+ }
+
+ /**
+ * Forces all perspectives on the page to zoom out.
+ */
+ public void unzoomAllPerspectives() {
+ }
+
+ /**
+ * @see IWorkbenchPage#closeAllPerspectives(boolean, boolean)
+ */
+ public void closeAllPerspectives(boolean saveEditors, boolean closePage) {
+
+ if (perspList.isEmpty()) {
+ return;
+ }
+
+ // Always unzoom
+ if (isZoomed()) {
+ zoomOut();
+ }
+
+ if (saveEditors) {
+ if (!saveAllEditors(true)) {
+ return;
+ }
+ }
+ // Close all editors
+ if (!closeAllEditors(false)) {
+ return;
+ }
+
+ // Deactivate the active perspective and part
+ setPerspective((Perspective) null);
+
+ // Close each perspective in turn
+ PerspectiveList oldList = perspList;
+ perspList = new PerspectiveList();
+ Iterator itr = oldList.iterator();
+ while (itr.hasNext()) {
+ closePerspective((Perspective) itr.next(), false, false);
+ }
+ if (closePage) {
+ close();
+ }
+ }
+
+ /**
+ * Creates a new view set. Return null on failure.
+ *
+ * @param desc
+ * the perspective descriptor
+ * @param notify
+ * whether to fire a perspective opened event
+ */
+ private Perspective createPerspective(PerspectiveDescriptor desc,
+ boolean notify) {
+ String label = desc.getId(); // debugging only
+ try {
+ UIStats.start(UIStats.CREATE_PERSPECTIVE, label);
+ Perspective persp = ((WorkbenchImplementation) Tweaklets
+ .get(WorkbenchImplementation.KEY)).createPerspective(desc,
+ this);
+ perspList.add(persp);
+ if (notify) {
+ window.firePerspectiveOpened(this, desc);
+ }
+ // if the perspective is fresh and uncustomzied then it is not dirty
+ // no reset will be prompted for
+ if (!desc.hasCustomDefinition()) {
+ dirtyPerspectives.remove(desc.getId());
+ }
+ return persp;
+ } catch (WorkbenchException e) {
+ if (!((Workbench) window.getWorkbench()).isStarting()) {
+ MessageDialog
+ .openError(
+ window.getShell(),
+ WorkbenchMessages.Error,
+ NLS
+ .bind(
+ WorkbenchMessages.Workbench_showPerspectiveError,
+ desc.getId()));
+ }
+ return null;
+ } finally {
+ UIStats.end(UIStats.CREATE_PERSPECTIVE, desc.getId(), label);
+ }
+ }
+
+ /**
+ * This is called by child objects after a part has been added to the page.
+ * The page will in turn notify its listeners.
+ */
+ /* package */void partAdded(WorkbenchPartReference ref) {
+ partList.addPart(ref);
+ }
+
+ /**
+ * This is called by child objects after a part has been added to the page.
+ * The part will be queued for disposal after all listeners have been
+ * notified
+ */
+ /* package */void partRemoved(IWorkbenchPartReference ref) {
+ disposePart(ref);
+ }
+
+ private void disposePart(IWorkbenchPartReference ref) {
+ if (ref instanceof WorkbenchPartReference) {
+ partList.removePart((WorkbenchPartReference) ref);
+ ((WorkbenchPartReference) ref).dispose();
+ } else if (ref instanceof ModelReference) {
+ MPart modelPart = ((ModelReference) ref).getModel();
+ partList.firePartClosed(ref);
+ modelPart.setVisible(false);
+ }
+ }
+
+ /**
+ * Detaches a view from the WorkbenchWindow.
+ */
+ public void detachView(IViewReference ref) {
+
+ }
+
+ /**
+ * Removes a detachedwindow.
+ */
+ public void attachView(IViewReference ref) {
+ }
+
+ /**
+ * Cleanup.
+ */
+ public void dispose() {
+
+ // Always unzoom
+ if (isZoomed()) {
+ zoomOut();
+ }
+
+ }
+
+ /**
+ * @return NavigationHistory
+ */
+ public INavigationHistory getNavigationHistory() {
+ return (INavigationHistory) e4Context.get(INavigationHistory.class
+ .getName());
+ }
+
+ /**
+ * Edits the action sets.
+ */
+ public boolean editActionSets() {
+ Perspective persp = getActivePerspective();
+ if (persp == null) {
+ return false;
+ }
+
+ // Create list dialog.
+ CustomizePerspectiveDialog dlg = window
+ .createCustomizePerspectiveDialog(persp);
+
+ // Open.
+ boolean ret = (dlg.open() == Window.OK);
+ if (ret) {
+ window.updateActionSets();
+ window.firePerspectiveChanged(this, getPerspective(), CHANGE_RESET);
+ window.firePerspectiveChanged(this, getPerspective(),
+ CHANGE_RESET_COMPLETE);
+ }
+ return ret;
+ }
+
+ /**
+ * Returns the first view manager with given ID.
+ */
+ public Perspective findPerspective(IPerspectiveDescriptor desc) {
+ Iterator itr = perspList.iterator();
+ while (itr.hasNext()) {
+ Perspective mgr = (Perspective) itr.next();
+ if (desc.getId().equals(mgr.getDesc().getId())) {
+ return mgr;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * See IWorkbenchPage@findView.
+ */
+ public IViewPart findView(String id) {
+ IViewReference ref = findViewReference(id);
+ if (ref == null) {
+ return null;
+ }
+ return ref.getView(true);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPage
+ */
+ public IViewReference findViewReference(String viewId) {
+ return findViewReference(viewId, null);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPage
+ */
+ public IViewReference findViewReference(String viewId, String secondaryId) {
+ MPart modelPart = ModeledPageLayout.findPart(e4Window, viewId);
+ if (modelPart instanceof MPart) {
+ Object obj = ((MPart) modelPart).getObject();
+ if (!(obj instanceof LegacyView))
+ return null;
+
+ LegacyView lv = (LegacyView) obj;
+ return (IViewReference) getReference(lv.getViewPart());
+ }
+ return null;
+ }
+
+ /**
+ * Notify property change listeners about a property change.
+ *
+ * @param changeId
+ * the change id
+ * @param oldValue
+ * old property value
+ * @param newValue
+ * new property value
+ */
+ private void firePropertyChange(String changeId, Object oldValue,
+ Object newValue) {
+
+ UIListenerLogging.logPagePropertyChanged(this, changeId, oldValue,
+ newValue);
+
+ Object[] listeners = propertyChangeListeners.getListeners();
+ PropertyChangeEvent event = new PropertyChangeEvent(this, changeId,
+ oldValue, newValue);
+
+ for (int i = 0; i < listeners.length; i++) {
+ ((IPropertyChangeListener) listeners[i]).propertyChange(event);
+ }
+ }
+
+ /*
+ * Returns the action bars.
+ */
+ public IActionBars getActionBars() {
+ if (actionBars == null) {
+ actionBars = new WWinActionBars(window);
+ }
+ return actionBars;
+ }
+
+ /**
+ * Returns an array of the visible action sets.
+ */
+ public IActionSetDescriptor[] getActionSets() {
+
+ Collection visibleItems = actionSets.getVisibleItems();
+ return (IActionSetDescriptor[]) visibleItems
+ .toArray(new IActionSetDescriptor[visibleItems.size()]);
+ }
+
+ /**
+ * @see IWorkbenchPage
+ */
+ public IEditorPart getActiveEditor() {
+ return partList.getActiveEditor();
+ }
+
+ /**
+ * Returns the reference for the active editor, or <code>null</code> if
+ * there is no active editor.
+ *
+ * @return the active editor reference or <code>null</code>
+ */
+ public IEditorReference getActiveEditorReference() {
+ return partList.getActiveEditorReference();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IPartService
+ */
+ public IWorkbenchPart getActivePart() {
+ return partList.getActivePart();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IPartService
+ */
+ public IWorkbenchPartReference getActivePartReference() {
+ return partList.getActivePartReference();
+ }
+
+ /**
+ * Returns the active perspective for the page, <code>null</code> if none.
+ */
+ public Perspective getActivePerspective() {
+ return perspList.getActive();
+ }
+
+ /**
+ * Returns the client composite.
+ */
+ public Composite getClientComposite() {
+ return composite;
+ }
+
+ /**
+ * Answer the perspective presentation.
+ */
+ public PerspectiveHelper getPerspectivePresentation() {
+ if (getActivePerspective() != null) {
+ return getActivePerspective().getPresentation();
+ }
+ return null;
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public IEditorPart[] getEditors() {
+ final IEditorReference refs[] = getEditorReferences();
+ final ArrayList result = new ArrayList(refs.length);
+ Display d = getWorkbenchWindow().getShell().getDisplay();
+ // Must be backward compatible.
+ d.syncExec(new Runnable() {
+ public void run() {
+ for (int i = 0; i < refs.length; i++) {
+ IWorkbenchPart part = refs[i].getPart(true);
+ if (part != null) {
+ result.add(part);
+ }
+ }
+ }
+ });
+ final IEditorPart editors[] = new IEditorPart[result.size()];
+ return (IEditorPart[]) result.toArray(editors);
+ }
+
+ public IEditorPart[] getDirtyEditors() {
+ return new IEditorPart[0];
+ }
+
+ public ISaveablePart[] getDirtyParts() {
+ List result = new ArrayList(3);
+ IWorkbenchPartReference[] allParts = getAllParts();
+ for (int i = 0; i < allParts.length; i++) {
+ IWorkbenchPartReference reference = allParts[i];
+
+ IWorkbenchPart part = reference.getPart(false);
+ if (part != null && part instanceof ISaveablePart) {
+ ISaveablePart saveable = (ISaveablePart) part;
+ if (saveable.isDirty()) {
+ result.add(saveable);
+ }
+ }
+ }
+
+ return (ISaveablePart[]) result
+ .toArray(new ISaveablePart[result.size()]);
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public IEditorPart findEditor(IEditorInput input) {
+ IEditorReference[] editorReferences = findEditors(input, null,
+ IWorkbenchPage.MATCH_INPUT);
+ if (editorReferences.length == 0) {
+ return null;
+ }
+ return editorReferences[0].getEditor(true);
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public IEditorReference[] findEditors(IEditorInput input, String editorId,
+ int matchFlags) {
+ IEditorReference[] refs = getEditorReferences();
+ ArrayList<IEditorReference> matches = null;
+ for (IEditorReference ref : refs) {
+ if ((matchFlags & IWorkbenchPage.MATCH_ID) != 0) {
+ String testID = ref.getId();
+ if ((editorId != null) && !(editorId.equals(testID)))
+ continue;
+ if (editorId == null && testID != null)
+ continue;
+ }
+ if ((matchFlags & IWorkbenchPage.MATCH_INPUT) != 0) {
+ IEditorInput testInput;
+ try {
+ testInput = ref.getEditorInput();
+ } catch (PartInitException e) {
+ continue;
+ }
+ if ((input != null) && !(input.equals(testInput)))
+ continue;
+ if (input == null && testInput != null)
+ continue;
+ }
+ if (matches == null)
+ matches = new ArrayList<IEditorReference>(3);
+ matches.add(ref);
+ }
+ if (matches == null)
+ return noEditorRefs;
+ IEditorReference[] result = new IEditorReference[matches.size()];
+ matches.toArray(result);
+ return result;
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public IEditorReference[] getEditorReferences() {
+ ArrayList<IEditorReference> result = new ArrayList<IEditorReference>();
+ getContainedEditorRefs(result, e4Window);
+ IEditorReference[] typedResult = new IEditorReference[result.size()];
+ result.toArray(typedResult);
+ return typedResult;
+ }
+
+ public void getContainedEditorRefs(ArrayList<IEditorReference> result,
+ MElementContainer<?> container) {
+ for (MUIElement child : container.getChildren()) {
+ if (child instanceof MEditor) {
+ // @issue here we are expected to sort views from editors.
+ // However, there is no such distinction for E4 elements.
+ // The code below is only good for legacy views/editors.
+ Object object = ((MContribution) child).getObject();
+ if (object instanceof EditorPart)
+ result.add(new ModelEditorReference((MPart) child, this));
+ }
+ if (child instanceof MElementContainer<?>)
+ getContainedEditorRefs(result,
+ (MElementContainer<MUIElement>) child);
+ }
+ }
+
+ /**
+ * Returns the docked views.
+ */
+ public IViewReference[] getFastViews() {
+ Perspective persp = getActivePerspective();
+ if (persp != null) {
+ return persp.getFastViews();
+ } else {
+ return new IViewReference[0];
+ }
+ }
+
+ /**
+ * @see IWorkbenchPage
+ */
+ public IAdaptable getInput() {
+ return input;
+ }
+
+ /**
+ * Returns the page label. This is a combination of the page input and
+ * active perspective.
+ */
+ public String getLabel() {
+ String label = WorkbenchMessages.WorkbenchPage_UnknownLabel;
+ IWorkbenchAdapter adapter = (IWorkbenchAdapter) Util.getAdapter(input,
+ IWorkbenchAdapter.class);
+ if (adapter != null) {
+ label = adapter.getLabel(input);
+ }
+ Perspective persp = getActivePerspective();
+ if (persp != null) {
+ label = NLS.bind(WorkbenchMessages.WorkbenchPage_PerspectiveFormat,
+ label, persp.getDesc().getLabel());
+ } else if (deferredActivePersp != null) {
+ label = NLS.bind(WorkbenchMessages.WorkbenchPage_PerspectiveFormat,
+ label, deferredActivePersp.getLabel());
+ }
+ return label;
+ }
+
+ /**
+ * Returns the perspective.
+ */
+ public IPerspectiveDescriptor getPerspective() {
+ if (deferredActivePersp != null) {
+ return deferredActivePersp;
+ }
+ Perspective persp = getActivePerspective();
+ if (persp != null) {
+ return persp.getDesc();
+ } else {
+ return null;
+ }
+ }
+
+ /*
+ * (non-Javadoc) Method declared on ISelectionService
+ */
+ public ISelection getSelection() {
+ return selectionService.getSelection();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on ISelectionService
+ */
+ public ISelection getSelection(String partId) {
+ return selectionService.getSelection(partId);
+ }
+
+ /**
+ * Returns the ids of the parts to list in the Show In... prompter. This is
+ * a List of Strings.
+ */
+ public ArrayList getShowInPartIds() {
+ Perspective persp = getActivePerspective();
+ if (persp != null) {
+ return persp.getShowInPartIds();
+ } else {
+ return new ArrayList();
+ }
+ }
+
+ /**
+ * The user successfully performed a Show In... action on the specified
+ * part. Update the list of Show In items accordingly.
+ */
+ public void performedShowIn(String partId) {
+ Perspective persp = getActivePerspective();
+ if (persp != null) {
+ persp.performedShowIn(partId);
+ }
+ }
+
+ /**
+ * Sorts the given collection of show in target part ids in MRU order.
+ */
+ public void sortShowInPartIds(ArrayList partIds) {
+ final Perspective persp = getActivePerspective();
+ if (persp != null) {
+ Collections.sort(partIds, new Comparator() {
+ public int compare(Object a, Object b) {
+ long ta = persp.getShowInTime((String) a);
+ long tb = persp.getShowInTime((String) b);
+ return (ta == tb) ? 0 : ((ta > tb) ? -1 : 1);
+ }
+ });
+ }
+ }
+
+ /*
+ * Returns the view factory.
+ */
+ public ViewFactory getViewFactory() {
+ if (viewFactory == null) {
+ viewFactory = new ViewFactory(this, WorkbenchPlugin.getDefault()
+ .getViewRegistry());
+ }
+ return viewFactory;
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public IViewReference[] getViewReferences() {
+ Perspective persp = getActivePerspective();
+ if (persp != null) {
+ return persp.getViewReferences();
+ } else {
+ return new IViewReference[0];
+ }
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public IViewPart[] getViews() {
+ return getViews(null, true);
+ }
+
+ /**
+ * Returns all view parts in the specified perspective
+ *
+ * @param persp
+ * the perspective
+ * @return an array of view parts
+ * @since 3.1
+ */
+ /* package */IViewPart[] getViews(Perspective persp, boolean restore) {
+ if (persp == null) {
+ persp = getActivePerspective();
+ }
+
+ if (persp != null) {
+ IViewReference refs[] = persp.getViewReferences();
+ ArrayList parts = new ArrayList(refs.length);
+ for (int i = 0; i < refs.length; i++) {
+ IWorkbenchPart part = refs[i].getPart(restore);
+ if (part != null) {
+ parts.add(part);
+ }
+ }
+ IViewPart[] result = new IViewPart[parts.size()];
+ return (IViewPart[]) parts.toArray(result);
+ }
+ return new IViewPart[0];
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public IWorkbenchWindow getWorkbenchWindow() {
+ return window;
+ }
+
+ /**
+ * Implements IWorkbenchPage
+ *
+ * @see org.eclipse.ui.IWorkbenchPage#getWorkingSet()
+ * @since 2.0
+ * @deprecated individual views should store a working set if needed
+ */
+ public IWorkingSet getWorkingSet() {
+ return workingSet;
+ }
+
+ /**
+ * @see IWorkbenchPage
+ */
+ public void hideActionSet(String actionSetID) {
+ Perspective persp = getActivePerspective();
+ if (persp != null) {
+ persp.removeActionSet(actionSetID);
+ window.updateActionSets();
+ window.firePerspectiveChanged(this, getPerspective(),
+ CHANGE_ACTION_SET_HIDE);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.IWorkbenchPage#hideView(org.eclipse.ui.IViewReference)
+ */
+ public void hideView(IViewReference ref) {
+
+ // Sanity check.
+ if (ref == null) {
+ return;
+ }
+
+ Perspective persp = getActivePerspective();
+ if (persp == null) {
+ return;
+ }
+
+ IViewPart view = ref.getView(false);
+ if (view != null) {
+
+ if (!certifyPart(view)) {
+ return;
+ }
+
+ // Confirm.
+ if (view instanceof ISaveablePart) {
+ ISaveablePart saveable = (ISaveablePart) view;
+ if (saveable.isSaveOnCloseNeeded()) {
+ IWorkbenchWindow window = view.getSite()
+ .getWorkbenchWindow();
+ boolean success = EditorManager.saveAll(Collections
+ .singletonList(view), true, true, false, window);
+ if (!success) {
+ // the user cancelled.
+ return;
+ }
+ }
+ }
+ }
+
+ // Notify interested listeners before the hide
+ window.firePerspectiveChanged(this, persp.getDesc(), ref,
+ CHANGE_VIEW_HIDE);
+
+ // Hide the part.
+ persp.hideView(ref);
+
+ // Notify interested listeners after the hide
+ window.firePerspectiveChanged(this, getPerspective(), CHANGE_VIEW_HIDE);
+ }
+
+ /* package */void refreshActiveView() {
+
+ }
+
+ /**
+ * See IPerspective
+ */
+ public void hideView(IViewPart view) {
+ hideView((IViewReference) getReference(view));
+ }
+
+ /**
+ * Initialize the page.
+ *
+ * @param w
+ * the parent window
+ * @param layoutID
+ * may be <code>null</code> if restoring from file
+ * @param input
+ * the page input
+ * @param openExtras
+ * whether to process the perspective extras preference
+ */
+ private void init(WorkbenchWindow w, String layoutID, IAdaptable input,
+ boolean openExtras) throws WorkbenchException {
+ // Save args.
+ this.window = w;
+ this.input = input;
+ actionSets = new ActionSetManager(w);
+
+ e4Window = w.getModelWindow();
+ e4Context = e4Window.getContext();
+ e4Context.set(IWorkbenchPage.class.getName(), this);
+ e4Context.set(WorkbenchPage.class.getName(), this);
+ selectionService = (ISelectionService) e4Context
+ .get(ISelectionService.class.getName());
+ partList = new WorkbenchPagePartList(selectionService);
+
+ navigationHistory = new NavigationHistory(this);
+ e4Context.set(INavigationHistory.class.getName(), navigationHistory);
+
+ ((Notifier) e4Window).eAdapters().add(
+ new PartsEventTransformer(e4Context, partList));
+
+ // Create presentation.
+ // Get perspective descriptor.
+ if (layoutID != null) {
+ PerspectiveDescriptor desc = (PerspectiveDescriptor) WorkbenchPlugin
+ .getDefault().getPerspectiveRegistry()
+ .findPerspectiveWithId(layoutID);
+ if (desc == null) {
+ throw new WorkbenchException(
+ NLS
+ .bind(
+ WorkbenchMessages.WorkbenchPage_ErrorCreatingPerspective,
+ layoutID));
+ }
+ Perspective persp = findPerspective(desc);
+ if (persp == null) {
+ persp = createPerspective(desc, true);
+ }
+ perspList.setActive(persp);
+ window.firePerspectiveActivated(this, desc);
+ }
+
+ // read model extensions
+ ModelExtensionProcessor extProcessor = new ModelExtensionProcessor(
+ e4Window);
+ extProcessor.addModelExtensions();
+ partEvents();
+ }
+
+ private void partEvents() {
+ partList.getPartService().addPartListener(new IPartListener() {
+
+ public void partOpened(IWorkbenchPart part) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void partDeactivated(IWorkbenchPart part) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void partClosed(IWorkbenchPart part) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void partBroughtToTop(IWorkbenchPart part) {
+ calculateActionSets(part);
+ }
+
+ public void partActivated(IWorkbenchPart part) {
+ calculateActionSets(part);
+ }
+ });
+ }
+
+ private ArrayList oldActionSets = new ArrayList();
+
+ void calculateActionSets(IWorkbenchPart part) {
+ ArrayList newActionSets = new ArrayList();
+ if (part != null) {
+ IActionSetDescriptor[] partActionSets = WorkbenchPlugin
+ .getDefault().getActionSetRegistry().getActionSetsFor(
+ part.getSite().getId());
+ for (int i = 0; i < partActionSets.length; i++) {
+ newActionSets.add(partActionSets[i]);
+ }
+ }
+ IEditorPart editor = partList.getActiveEditor();
+ if (editor != null && editor != part) {
+ IActionSetDescriptor[] editorActionSets = WorkbenchPlugin
+ .getDefault().getActionSetRegistry().getActionSetsFor(
+ editor.getSite().getId());
+ for (int i = 0; i < editorActionSets.length; i++) {
+ newActionSets.add(editorActionSets[i]);
+ }
+ }
+ if (oldActionSets.equals(newActionSets)) {
+ return;
+ }
+ IContextService service = (IContextService) window
+ .getService(IContextService.class);
+ try {
+ service.deferUpdates(true);
+
+ // show the new
+ for (int i = 0; i < newActionSets.size(); i++) {
+ actionSets.showAction((IActionSetDescriptor) newActionSets
+ .get(i));
+ }
+
+ // hide the old
+ for (int i = 0; i < oldActionSets.size(); i++) {
+ actionSets.hideAction((IActionSetDescriptor) oldActionSets
+ .get(i));
+ }
+
+ oldActionSets = newActionSets;
+
+ } finally {
+ service.deferUpdates(false);
+ }
+ Perspective persp = getActivePerspective();
+ if (persp == null) {
+ return;
+ }
+
+ window.updateActionSets(); // this calls updateActionBars
+ window.firePerspectiveChanged(WorkbenchPage.this, getPerspective(),
+ CHANGE_ACTION_SET_SHOW);
+ }
+
+ /**
+ * Opens the perspectives specified in the PERSPECTIVE_BAR_EXTRAS preference
+ * (see bug 84226).
+ */
+ public void openPerspectiveExtras() {
+ String extras = PrefUtil.getAPIPreferenceStore().getString(
+ IWorkbenchPreferenceConstants.PERSPECTIVE_BAR_EXTRAS);
+ StringTokenizer tok = new StringTokenizer(extras, ", "); //$NON-NLS-1$
+ ArrayList descs = new ArrayList();
+ while (tok.hasMoreTokens()) {
+ String id = tok.nextToken();
+ IPerspectiveDescriptor desc = WorkbenchPlugin.getDefault()
+ .getPerspectiveRegistry().findPerspectiveWithId(id);
+ if (desc != null) {
+ descs.add(desc);
+ }
+ }
+ // HACK: The perspective switcher currently adds the button for a new
+ // perspective to the beginning of the list.
+ // So, we process the extra perspectives in reverse order here to have
+ // their buttons appear in the order declared.
+ for (int i = descs.size(); --i >= 0;) {
+ PerspectiveDescriptor desc = (PerspectiveDescriptor) descs.get(i);
+ if (findPerspective(desc) == null) {
+ createPerspective(desc, true);
+ }
+ }
+ }
+
+ /**
+ * Finds and returns a part in the current perspective with the
+ * corresponding id.
+ *
+ * @param partId
+ * the id of the part, must not be <code>null</code>
+ * @return a part in the current perspective with the specified id
+ */
+ private MPart findPartInCurrentPerspective(String partId) {
+ Assert.isNotNull(partId);
+ // retrieve the perspective stack from our window
+ MPerspectiveStack perspStack = (MPerspectiveStack) ModeledPageLayout
+ .findPart(e4Window, "PerspectiveStack"); //$NON-NLS-1$
+ // get the active/current one
+ MPerspective curPersp = (MPerspective) perspStack.getActiveChild();
+ // try to find a child part
+ return ModeledPageLayout.findPart(curPersp, partId);
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public boolean isPartVisible(IWorkbenchPart part) {
+ if (part == null) {
+ return false;
+ }
+
+ MPart modelPart = findPartInCurrentPerspective(part.getSite().getId());
+ // couldn't find the part, return false
+ if (modelPart == null) {
+ return false;
+ }
+
+ MElementContainer<MUIElement> parent = modelPart.getParent();
+ // no parent, probably not visible
+ if (parent == null) {
+ return false;
+ }
+ // return whether the parent's active child is us
+ return parent.getActiveChild() == modelPart;
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public boolean isEditorAreaVisible() {
+ Perspective persp = getActivePerspective();
+ if (persp == null) {
+ return false;
+ }
+ return persp.isEditorAreaVisible();
+ }
+
+ /**
+ * Returns whether the view is fast.
+ */
+ public boolean isFastView(IViewReference ref) {
+ Perspective persp = getActivePerspective();
+ if (persp != null) {
+ return persp.isFastView(ref);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Return whether the view is closeable or not.
+ *
+ * @param ref
+ * the view reference to check. Must not be <code>null</code>.
+ * @return true if the part is closeable.
+ * @since 3.1.1
+ */
+ public boolean isCloseable(IViewReference ref) {
+ Perspective persp = getActivePerspective();
+ if (persp != null) {
+ return persp.isCloseable(ref);
+ }
+ return false;
+ }
+
+ /**
+ * Return whether the view is moveable or not.
+ *
+ * @param ref
+ * the view reference to check. Must not be <code>null</code>.
+ * @return true if the part is moveable.
+ * @since 3.1.1
+ */
+ public boolean isMoveable(IViewReference ref) {
+ Perspective persp = getActivePerspective();
+ if (persp != null) {
+ return persp.isMoveable(ref);
+ }
+ return false;
+ }
+
+ /**
+ * Returns whether the layout of the active perspective is fixed.
+ */
+ public boolean isFixedLayout() {
+ Perspective persp = getActivePerspective();
+ if (persp != null) {
+ return persp.isFixedLayout();
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Return the active fast view or null if there are no fast views or if
+ * there are all minimized.
+ */
+ public IViewReference getActiveFastView() {
+ Perspective persp = getActivePerspective();
+ if (persp != null) {
+ return persp.getActiveFastView();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Return true if the perspective has a dirty editor.
+ */
+ protected boolean isSaveNeeded() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPage#isPageZoomed()
+ */
+ public boolean isPageZoomed() {
+ return false;
+ }
+
+ /**
+ * Returns whether the page is zoomed.
+ *
+ * @return <code>true</code> if the page is zoomed.
+ *
+ * <strong>NOTE:</strong> As of 3.3 this method should always return
+ * 'false' when using the new min/max behavior. It is only used for
+ * legacy 'zoom' handling.
+ *
+ */
+ public boolean isZoomed() {
+ return false;
+ }
+
+ /**
+ * This method is called when the page is activated.
+ */
+ protected void onActivate() {
+ composite.setVisible(true);
+ Perspective persp = getActivePerspective();
+
+ if (persp != null) {
+ persp.onActivate();
+ }
+ }
+
+ /**
+ * This method is called when the page is deactivated.
+ */
+ protected void onDeactivate() {
+ if (getActivePerspective() != null) {
+ getActivePerspective().onDeactivate();
+ }
+ composite.setVisible(false);
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public void reuseEditor(IReusableEditor editor, IEditorInput input) {
+
+ // Rather than calling editor.setInput on the editor directly, we do it
+ // through the part reference.
+ // This case lets us detect badly behaved editors that are not firing a
+ // PROP_INPUT event in response
+ // to the input change... but if all editors obeyed their API contract,
+ // the "else" branch would be
+ // sufficient.
+ IWorkbenchPartReference ref = getReference(editor);
+ if (ref instanceof EditorReference) {
+ EditorReference editorRef = (EditorReference) ref;
+
+ editorRef.setInput(input);
+ } else {
+ editor.setInput(input);
+ }
+ navigationHistory.markEditor(editor);
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public IEditorPart openEditor(IEditorInput input, String editorID)
+ throws PartInitException {
+ return openEditor(input, editorID, true, MATCH_INPUT);
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public IEditorPart openEditor(IEditorInput input, String editorID,
+ boolean activate) throws PartInitException {
+ return openEditor(input, editorID, activate, MATCH_INPUT);
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public IEditorPart openEditor(final IEditorInput input,
+ final String editorID, final boolean activate, final int matchFlags)
+ throws PartInitException {
+ return openEditor(input, editorID, activate, matchFlags, null);
+ }
+
+ /**
+ * This is not public API but for use internally. editorState can be
+ * <code>null</code>.
+ */
+ public IEditorPart openEditor(final IEditorInput input,
+ final String editorID, final boolean activate,
+ final int matchFlags, final IMemento editorState)
+ throws PartInitException {
+ if (input == null || editorID == null) {
+ throw new IllegalArgumentException();
+ }
+
+ // Special handling for external editors (they have no tabs...)
+ if ("org.eclipse.ui.systemExternalEditor".equals(editorID) //$NON-NLS-1$
+ || "org.eclipse.ui.browser.editorSupport".equals(editorID)) { //$NON-NLS-1$
+ if (input instanceof IPathEditorInput) {
+ IPathEditorInput fileInput = (IPathEditorInput) input;
+ String fullPath = fileInput.getPath().toOSString();
+ Program.launch(fullPath);
+ return null;
+ }
+ }
+
+ // retrieve the editor area
+ MEditorSashContainer ea = (MEditorSashContainer) findPartInCurrentPerspective(ModeledPageLayout
+ .internalGetEditorArea());
+
+ // TBD need to add processing for other flags: MATCH_INPUT, MATCH_ID
+ if (matchFlags != IWorkbenchPage.MATCH_NONE) {
+ // Find a matching editor
+ MEditor existingEditor = findEditor(ea, editorID, input);
+ if (existingEditor != null && activate) {
+ // Set the initial focus
+ LegacyEditor le = (LegacyEditor) existingEditor.getObject();
+ Object impl = le.getEditorWBPart();
+ if (impl instanceof IWorkbenchPart) {
+ activate((IWorkbenchPart) impl);
+ } else {
+ ea.setActiveChild(existingEditor);
+ }
+
+ // return the existing editor
+ return (IEditorPart) impl;
+ }
+ }
+
+ // No patching editor found, create one
+ MEditor editorPart = MApplicationFactory.eINSTANCE.createEditor();
+ editorPart.setURI(LegacyEditor.LEGACY_VIEW_URI);
+ editorPart.setId(editorID);
+ editorPart.setName(input.getName());
+ // editor part icon will be set in LegacyViewFactory
+ editorPart.setVisible(false);
+ ea.getChildren().add(editorPart);
+ editorPart.getContext().set(IEditorInput.class.getName(), input);
+ editorPart.setVisible(true);
+
+ // Manage the 'close' button
+ final IEclipseContext editorContext = editorPart.getContext();
+ final MEditor theEditor = editorPart;
+ IValueFunction closeFunc = new IValueFunction() {
+ public Object getValue() {
+ Object impl = ((MPart) theEditor).getObject();
+ if (impl instanceof EditorPart) {
+ EditorPart edPart = (EditorPart) impl;
+ boolean closed = closeEditor(edPart, true);
+ return closed;
+ }
+ return new Boolean(true);
+ }
+ };
+ editorContext.set("canCloseFunc", closeFunc); //$NON-NLS-1$
+
+ LegacyEditor le = (LegacyEditor) editorPart.getObject();
+ Object impl = le.getEditorWBPart();
+ if (impl instanceof IWorkbenchPart) { // TBD this is always the case?
+ IWorkbenchPart workbenchPart = (IWorkbenchPart) impl;
+ if (activate)
+ activate(workbenchPart);
+ else
+ bringToTop(workbenchPart);
+ }
+
+ return le.getEditorWBPart();
+ }
+
+ /**
+ * @param ea
+ * @param editorID
+ * @param input2
+ * @return
+ */
+ private MEditor findEditor(MEditorSashContainer ea, String editorID,
+ IEditorInput input) {
+ MUIElement ed = ModeledPageLayout.findElementById(ea, editorID);
+ if (ed instanceof MEditor) {
+ MEditor editor = (MEditor) ed;
+ IEditorInput e = (IEditorInput) editor.getContext().get(
+ IEditorInput.class.getName());
+ if (input.equals(e)) {
+ return editor;
+ }
+ }
+ return null;
+ }
+
+ /*
+ * Added to fix Bug 178235 [EditorMgmt] DBCS 3.3 - Cannot open file with
+ * external program. Opens a new editor using the given input and
+ * descriptor. (Normally, editors are opened using an editor ID and an
+ * input.)
+ */
+ public IEditorPart openEditorFromDescriptor(final IEditorInput input,
+ final IEditorDescriptor editorDescriptor, final boolean activate,
+ final IMemento editorState) throws PartInitException {
+ if (input == null || !(editorDescriptor instanceof EditorDescriptor)) {
+ throw new IllegalArgumentException();
+ }
+
+ final IEditorPart result[] = new IEditorPart[1];
+ final PartInitException ex[] = new PartInitException[1];
+ BusyIndicator.showWhile(window.getWorkbench().getDisplay(),
+ new Runnable() {
+ public void run() {
+ try {
+ result[0] = busyOpenEditorFromDescriptor(input,
+ (EditorDescriptor) editorDescriptor,
+ activate, editorState);
+ } catch (PartInitException e) {
+ ex[0] = e;
+ }
+ }
+ });
+ if (ex[0] != null) {
+ throw ex[0];
+ }
+ return result[0];
+ }
+
+ /*
+ * Added to fix Bug 178235 [EditorMgmt] DBCS 3.3 - Cannot open file with
+ * external program. See openEditorFromDescriptor().
+ */
+ private IEditorPart busyOpenEditorFromDescriptor(IEditorInput input,
+ EditorDescriptor editorDescriptor, boolean activate,
+ IMemento editorState) throws PartInitException {
+
+ final Workbench workbench = (Workbench) getWorkbenchWindow()
+ .getWorkbench();
+ workbench.largeUpdateStart();
+
+ try {
+ return busyOpenEditorFromDescriptorBatched(input, editorDescriptor,
+ activate, editorState);
+
+ } finally {
+ workbench.largeUpdateEnd();
+ }
+ }
+
+ /**
+ * Do not call this method. Use <code>busyOpenEditor</code>.
+ *
+ * @see IWorkbenchPage#openEditor(IEditorInput, String, boolean)
+ */
+ protected IEditorPart busyOpenEditorBatched(IEditorInput input,
+ String editorID, boolean activate, int matchFlags,
+ IMemento editorState) throws PartInitException {
+
+ IEditorPart editor = null;
+ // Otherwise, create a new one. This may cause the new editor to
+ // become the visible (i.e top) editor.
+ IEditorReference ref = null;
+ try {
+ partBeingOpened = true;
+ ref = null; // open the editor, somehow
+ if (ref != null) {
+ editor = ref.getEditor(true);
+ }
+ } finally {
+ partBeingOpened = false;
+ }
+
+ if (editor != null) {
+ setEditorAreaVisible(true);
+ if (activate) {
+ if (editor instanceof AbstractMultiEditor) {
+ activate(((AbstractMultiEditor) editor).getActiveEditor());
+ } else {
+ activate(editor);
+ }
+ } else {
+ bringToTop(editor);
+ }
+ window.firePerspectiveChanged(this, getPerspective(), ref,
+ CHANGE_EDITOR_OPEN);
+ window.firePerspectiveChanged(this, getPerspective(),
+ CHANGE_EDITOR_OPEN);
+ }
+
+ return editor;
+ }
+
+ /*
+ * Added to fix Bug 178235 [EditorMgmt] DBCS 3.3 - Cannot open file with
+ * external program. See openEditorFromDescriptor().
+ */
+ private IEditorPart busyOpenEditorFromDescriptorBatched(IEditorInput input,
+ EditorDescriptor editorDescriptor, boolean activate,
+ IMemento editorState) throws PartInitException {
+
+ IEditorPart editor = null;
+ // Create a new one. This may cause the new editor to
+ // become the visible (i.e top) editor.
+ IEditorReference ref = null;
+ ref = null; // open the editor somehow
+ if (ref != null) {
+ editor = ref.getEditor(true);
+ }
+
+ if (editor != null) {
+ setEditorAreaVisible(true);
+ if (activate) {
+ if (editor instanceof AbstractMultiEditor) {
+ activate(((AbstractMultiEditor) editor).getActiveEditor());
+ } else {
+ activate(editor);
+ }
+ } else {
+ bringToTop(editor);
+ }
+ window.firePerspectiveChanged(this, getPerspective(), ref,
+ CHANGE_EDITOR_OPEN);
+ window.firePerspectiveChanged(this, getPerspective(),
+ CHANGE_EDITOR_OPEN);
+ }
+
+ return editor;
+ }
+
+ public void openEmptyTab() {
+
+ }
+
+ protected void showEditor(boolean activate, IEditorPart editor) {
+ setEditorAreaVisible(true);
+ if (activate) {
+ zoomOutIfNecessary(editor);
+ activate(editor);
+ } else {
+ bringToTop(editor);
+ }
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public boolean isEditorPinned(IEditorPart editor) {
+ // TBD we need to add "pinned" attribute somewhere in the E4 model. The
+ // code
+ // below is just to work around a cast class exception
+ IWorkbenchPartReference ref = getReference(editor);
+ if (ref == null)
+ return false;
+ if (ref instanceof WorkbenchPartReference)
+ return ((WorkbenchPartReference) ref).isPinned();
+ return false;
+ }
+
+ /**
+ * Returns whether changes to a part will affect zoom. There are a few
+ * conditions for this .. - we are zoomed. - the part is contained in the
+ * main window. - the part is not the zoom part - the part is not a fast
+ * view - the part and the zoom part are not in the same editor workbook
+ */
+ private boolean partChangeAffectsZoom(IWorkbenchPartReference ref) {
+ PartPane pane = ((WorkbenchPartReference) ref).getPane();
+ if (pane instanceof MultiEditorInnerPane) {
+ pane = ((MultiEditorInnerPane) pane).getParentPane();
+ }
+ return getActivePerspective().getPresentation().partChangeAffectsZoom(
+ pane);
+ }
+
+ /**
+ * Removes a fast view.
+ */
+ public void removeFastView(IViewReference ref) {
+ Perspective persp = getActivePerspective();
+ if (persp == null) {
+ return;
+ }
+
+ // Do real work.
+ persp.removeFastView(ref);
+
+ // Notify listeners.
+ window.firePerspectiveChanged(this, getPerspective(), ref,
+ CHANGE_FAST_VIEW_REMOVE);
+ window.firePerspectiveChanged(this, getPerspective(),
+ CHANGE_FAST_VIEW_REMOVE);
+ }
+
+ /**
+ * Removes an IPartListener from the part service.
+ */
+ public void removePartListener(IPartListener l) {
+ partList.getPartService().removePartListener(l);
+ }
+
+ /**
+ * Removes an IPartListener from the part service.
+ */
+ public void removePartListener(IPartListener2 l) {
+ partList.getPartService().removePartListener(l);
+ }
+
+ /**
+ * Implements IWorkbenchPage
+ *
+ * @see org.eclipse.ui.IWorkbenchPage#removePropertyChangeListener(IPropertyChangeListener)
+ * @since 2.0
+ * @deprecated individual views should store a working set if needed and
+ * register a property change listener directly with the working
+ * set manager to receive notification when the view working set
+ * is removed.
+ */
+ public void removePropertyChangeListener(IPropertyChangeListener listener) {
+ propertyChangeListeners.remove(listener);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on ISelectionListener.
+ */
+ public void removeSelectionListener(ISelectionListener listener) {
+ selectionService.removeSelectionListener(listener);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on ISelectionListener.
+ */
+ public void removeSelectionListener(String partId,
+ ISelectionListener listener) {
+ selectionService.removeSelectionListener(partId, listener);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on ISelectionListener.
+ */
+ public void removePostSelectionListener(ISelectionListener listener) {
+ selectionService.removePostSelectionListener(listener);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on ISelectionListener.
+ */
+ public void removePostSelectionListener(String partId,
+ ISelectionListener listener) {
+ selectionService.removePostSelectionListener(partId, listener);
+ }
+
+ /**
+ * This method is called when a part is activated by clicking within it. In
+ * response, the part, the pane, and all of its actions will be activated.
+ * <p>
+ * In the current design this method is invoked by the part pane when the
+ * pane, the part, or any children gain focus.
+ * </p>
+ * <p>
+ * If creating the part causes a forceFocus() well ignore this activation
+ * request.
+ * </p>
+ */
+ public void requestActivation(IWorkbenchPart part) {
+ // Sanity check.
+ if (!certifyPart(part) || partBeingOpened) {
+ return;
+ }
+
+ if (part instanceof AbstractMultiEditor) {
+ part = ((AbstractMultiEditor) part).getActiveEditor();
+ }
+
+ // Real work.
+ }
+
+ /**
+ * Resets the layout for the perspective. The active part in the old layout
+ * is activated in the new layout for consistent user context.
+ */
+ public void resetPerspective() {
+
+ }
+
+ /**
+ * Restore this page from the memento and ensure that the active perspective
+ * is equals the active descriptor otherwise create a new perspective for
+ * that descriptor. If activeDescriptor is null active the old perspective.
+ */
+ public IStatus restoreState(IMemento memento,
+ final IPerspectiveDescriptor activeDescriptor) {
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * See IWorkbenchPage
+ */
+ public boolean saveAllEditors(boolean confirm) {
+ return saveAllEditors(confirm, false);
+ }
+
+ /**
+ * @param confirm
+ * @param addNonPartSources
+ * true if saveables from non-part sources should be saved too
+ * @return false if the user cancelled
+ *
+ */
+ public boolean saveAllEditors(boolean confirm, boolean addNonPartSources) {
+ // TBD the code below is oversimplified. See 3.x version for all things
+ // that have to be done:
+ // return getEditorManager().saveAll(confirm, false, addNonPartSources);
+
+ ISaveablePart[] dirtyParts = getDirtyParts();
+ for (ISaveablePart part : dirtyParts) {
+ part.doSave(new NullProgressMonitor());
+ }
+
+ return true;
+ }
+
+ /*
+ * Saves the workbench part.
+ */
+ protected boolean savePart(ISaveablePart saveable, IWorkbenchPart part,
+ boolean confirm) {
+ saveable.doSave(new NullProgressMonitor());
+ return true;
+ }
+
+ /**
+ * Saves an editors in the workbench. If <code>confirm</code> is
+ * <code>true</code> the user is prompted to confirm the command.
+ *
+ * @param confirm
+ * if user confirmation should be sought
+ * @return <code>true</code> if the command succeeded, or <code>false</code>
+ * if the user cancels the command
+ */
+ public boolean saveEditor(IEditorPart editor, boolean confirm) {
+ return savePart(editor, editor, confirm);
+ }
+
+ /**
+ * Saves the current perspective.
+ */
+ public void savePerspective() {
+ Perspective persp = getActivePerspective();
+ if (persp == null) {
+ return;
+ }
+
+ // Always unzoom.
+ if (isZoomed()) {
+ zoomOut();
+ }
+
+ persp.saveDesc();
+ }
+
+ /**
+ * Saves the perspective.
+ */
+ public void savePerspectiveAs(IPerspectiveDescriptor newDesc) {
+ Perspective persp = getActivePerspective();
+ if (persp == null) {
+ return;
+ }
+ IPerspectiveDescriptor oldDesc = persp.getDesc();
+
+ // Always unzoom.
+ if (isZoomed()) {
+ zoomOut();
+ }
+
+ persp.saveDescAs(newDesc);
+ window.firePerspectiveSavedAs(this, oldDesc, newDesc);
+ }
+
+ /**
+ * Save the state of the page.
+ */
+ public IStatus saveState(IMemento memento) {
+ // We must unzoom to get correct layout.
+ if (isZoomed()) {
+ zoomOut();
+ }
+
+ // Close any open Fast View
+ hideFastView();
+
+ MultiStatus result = new MultiStatus(
+ PlatformUI.PLUGIN_ID,
+ IStatus.OK,
+ NLS
+ .bind(
+ WorkbenchMessages.WorkbenchPage_unableToSavePerspective,
+ getLabel()), null);
+
+ // Save editor manager.
+ IMemento childMem = memento
+ .createChild(IWorkbenchConstants.TAG_EDITORS);
+ result.merge(editorMgr.saveState(childMem));
+
+ childMem = memento.createChild(IWorkbenchConstants.TAG_VIEWS);
+ result.merge(getViewFactory().saveState(childMem));
+
+ // Create persp block.
+ childMem = memento.createChild(IWorkbenchConstants.TAG_PERSPECTIVES);
+ if (getPerspective() != null) {
+ childMem.putString(IWorkbenchConstants.TAG_ACTIVE_PERSPECTIVE,
+ getPerspective().getId());
+ }
+ if (getActivePart() != null) {
+ if (getActivePart() instanceof IViewPart) {
+ IViewReference ref = (IViewReference) getReference(getActivePart());
+ if (ref != null) {
+ childMem.putString(IWorkbenchConstants.TAG_ACTIVE_PART,
+ ViewFactory.getKey(ref));
+ }
+ } else {
+ childMem.putString(IWorkbenchConstants.TAG_ACTIVE_PART,
+ getActivePart().getSite().getId());
+ }
+ }
+
+ // Save each perspective in opened order
+ Iterator itr = perspList.iterator();
+ while (itr.hasNext()) {
+ Perspective persp = (Perspective) itr.next();
+ IMemento gChildMem = childMem
+ .createChild(IWorkbenchConstants.TAG_PERSPECTIVE);
+ result.merge(persp.saveState(gChildMem));
+ }
+ // Save working set if set
+ if (workingSet != null) {
+ memento.putString(IWorkbenchConstants.TAG_WORKING_SET, workingSet
+ .getName());
+ }
+
+ IMemento workingSetMem = memento
+ .createChild(IWorkbenchConstants.TAG_WORKING_SETS);
+ for (int i = 0; i < workingSets.length; i++) {
+ workingSetMem.createChild(IWorkbenchConstants.TAG_WORKING_SET,
+ workingSets[i].getName());
+ }
+
+ if (aggregateWorkingSetId != null) {
+ memento.putString(ATT_AGGREGATE_WORKING_SET_ID,
+ aggregateWorkingSetId);
+ }
+
+ navigationHistory.saveState(memento
+ .createChild(IWorkbenchConstants.TAG_NAVIGATION_HISTORY));
+
+ // save the sticky activation state
+ stickyViewMan.save(memento);
+
+ return result;
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public void setEditorAreaVisible(boolean showEditorArea) {
+ Perspective persp = getActivePerspective();
+ if (persp == null) {
+ return;
+ }
+ if (showEditorArea == persp.isEditorAreaVisible()) {
+ return;
+ }
+ // If parts change always update zoom.
+ if (isZoomed()) {
+ zoomOut();
+ }
+ // Update editor area visibility.
+ if (showEditorArea) {
+ persp.showEditorArea();
+ window.firePerspectiveChanged(this, getPerspective(),
+ CHANGE_EDITOR_AREA_SHOW);
+ } else {
+ persp.hideEditorArea();
+ window.firePerspectiveChanged(this, getPerspective(),
+ CHANGE_EDITOR_AREA_HIDE);
+ }
+ }
+
+ /**
+ * Sets the layout of the page. Assumes the new perspective is not null.
+ * Keeps the active part if possible. Updates the window menubar and toolbar
+ * if necessary.
+ */
+ private void setPerspective(Perspective newPersp) {
+ // Don't do anything if already active layout
+ Perspective oldPersp = getActivePerspective();
+ if (oldPersp == newPersp) {
+ return;
+ }
+
+ window.largeUpdateStart();
+ try {
+ if (oldPersp != null) {
+ // fire the pre-deactivate
+ window.firePerspectivePreDeactivate(this, oldPersp.getDesc());
+ }
+
+ if (newPersp != null) {
+ IStatus status = newPersp.restoreState();
+ if (status.getSeverity() != IStatus.OK) {
+ String title = WorkbenchMessages.WorkbenchPage_problemRestoringTitle;
+ String msg = WorkbenchMessages.WorkbenchPage_errorReadingState;
+ ErrorDialog.openError(getWorkbenchWindow().getShell(),
+ title, msg, status);
+ }
+ }
+
+ // Deactivate the old layout
+ if (oldPersp != null) {
+ oldPersp.onDeactivate();
+
+ // Notify listeners of deactivation
+ window.firePerspectiveDeactivated(this, oldPersp.getDesc());
+ }
+
+ // Activate the new layout
+ perspList.setActive(newPersp);
+ if (newPersp != null) {
+ newPersp.onActivate();
+
+ // Notify listeners of activation
+ window.firePerspectiveActivated(this, newPersp.getDesc());
+ }
+
+ // Update the window
+ window.updateActionSets();
+
+ // Update sticky views
+ stickyViewMan.update(oldPersp, newPersp);
+
+ } finally {
+ window.largeUpdateEnd();
+ if (newPersp == null) {
+ return;
+ }
+ IPerspectiveDescriptor desc = newPersp.getDesc();
+ if (desc == null) {
+ return;
+ }
+ if (dirtyPerspectives.remove(desc.getId())) {
+ suggestReset();
+ }
+ }
+ }
+
+ void perspectiveActionSetChanged(Perspective perspective,
+ IActionSetDescriptor descriptor, int changeType) {
+ if (perspective == getActivePerspective()) {
+ actionSets.change(descriptor, changeType);
+ }
+ }
+
+ /**
+ * Sets the perspective.
+ *
+ * @param desc
+ * identifies the new perspective.
+ */
+ public void setPerspective(final IPerspectiveDescriptor desc) {
+ try {
+ Perspective oldPersp = getActivePerspective();
+ if ((oldPersp != null)
+ && oldPersp.getDesc().getId() == desc.getId())
+ return;
+
+ Perspective newPersp = findPerspective(desc);
+ if (newPersp == null) {
+ newPersp = new Perspective((PerspectiveDescriptor) desc, this);
+ perspList.add(newPersp);
+ }
+ // TBD firePerspectivePreDeactivate
+ if (oldPersp != null) {
+ // TBD: exceptions due to null presentations
+ // oldPersp.onDeactivate();
+ // TBD firePerspectiveDeactivated
+ }
+ // Activate the new layout
+ perspList.setActive(newPersp);
+ // also need to let E4 know
+ MPerspective e4perspective = findPerspectiveE4(e4Window, desc
+ .getId());
+ if (e4perspective != null
+ && e4perspective.getParent().getActiveChild() != e4perspective)
+ e4perspective.getParent().setActiveChild(e4perspective);
+
+ if (newPersp != null) {
+ // TBD exceptions due to null presentations
+ // newPersp.onActivate();
+ // TBD firePerspectiveActivated(this, newPersp.getDesc());
+ }
+ } catch (WorkbenchException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Allow access to the part service for this page ... used internally to
+ * propogate certain types of events to the page part listeners.
+ *
+ * @return the part service for this page.
+ */
+ public PartService getPartService() {
+ return (PartService) partList.getPartService();
+ }
+
+ /**
+ * Restore the toolbar layout for the active perspective.
+ */
+ protected void resetToolBarLayout() {
+ ICoolBarManager2 mgr = (ICoolBarManager2) window.getCoolBarManager2();
+ mgr.resetItemOrder();
+ }
+
+ /**
+ * Sets the active working set for the workbench page. Notifies property
+ * change listener about the change.
+ *
+ * @param newWorkingSet
+ * the active working set for the page. May be null.
+ * @since 2.0
+ * @deprecated individual views should store a working set if needed
+ */
+ public void setWorkingSet(IWorkingSet newWorkingSet) {
+ IWorkingSet oldWorkingSet = workingSet;
+
+ workingSet = newWorkingSet;
+ if (oldWorkingSet != newWorkingSet) {
+ firePropertyChange(CHANGE_WORKING_SET_REPLACE, oldWorkingSet,
+ newWorkingSet);
+ }
+ if (newWorkingSet != null) {
+ WorkbenchPlugin
+ .getDefault()
+ .getWorkingSetManager()
+ .addPropertyChangeListener(workingSetPropertyChangeListener);
+ } else {
+ WorkbenchPlugin.getDefault().getWorkingSetManager()
+ .removePropertyChangeListener(
+ workingSetPropertyChangeListener);
+ }
+ }
+
+ /**
+ * @see IWorkbenchPage
+ */
+ public void showActionSet(String actionSetID) {
+ Perspective persp = getActivePerspective();
+ if (persp != null) {
+ ActionSetRegistry reg = WorkbenchPlugin.getDefault()
+ .getActionSetRegistry();
+
+ IActionSetDescriptor desc = reg.findActionSet(actionSetID);
+ if (desc != null) {
+ persp.addActionSet(desc);
+ window.updateActionSets();
+ window.firePerspectiveChanged(this, getPerspective(),
+ CHANGE_ACTION_SET_SHOW);
+ }
+ }
+ }
+
+ /**
+ * See IWorkbenchPage.
+ */
+ public IViewPart showView(String viewID) throws PartInitException {
+ return showView(viewID, null, VIEW_ACTIVATE);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPage#showView(java.lang.String,
+ * java.lang.String, int)
+ */
+ public IViewPart showView(final String viewID, final String secondaryID,
+ final int mode) throws PartInitException {
+
+ if (secondaryID != null) {
+ if (secondaryID.length() == 0
+ || secondaryID.indexOf(ViewFactory.ID_SEP) != -1) {
+ throw new IllegalArgumentException(
+ WorkbenchMessages.WorkbenchPage_IllegalSecondaryId);
+ }
+ }
+ if (!certifyMode(mode)) {
+ throw new IllegalArgumentException(
+ WorkbenchMessages.WorkbenchPage_IllegalViewMode);
+ }
+
+ // Run op in busy cursor.
+ final Object[] result = new Object[1];
+ BusyIndicator.showWhile(null, new Runnable() {
+ public void run() {
+ try {
+ result[0] = busyShowView(viewID, secondaryID, mode);
+ } catch (PartInitException e) {
+ result[0] = e;
+ }
+ }
+ });
+ if (result[0] instanceof IViewPart) {
+ return (IViewPart) result[0];
+ } else if (result[0] instanceof PartInitException) {
+ throw (PartInitException) result[0];
+ } else {
+ throw new PartInitException(
+ WorkbenchMessages.WorkbenchPage_AbnormalWorkbenchCondition);
+ }
+ }
+
+ /**
+ * @param mode
+ * the mode to test
+ * @return whether the mode is recognized
+ * @since 3.0
+ */
+ private boolean certifyMode(int mode) {
+ switch (mode) {
+ case VIEW_ACTIVATE:
+ case VIEW_VISIBLE:
+ case VIEW_CREATE:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Hides the active fast view. Has no effect if there is no fast view
+ * active.
+ */
+ public void hideFastView() {
+ Perspective persp = getActivePerspective();
+ if (persp != null) {
+ IViewReference ref = persp.getActiveFastView();
+ if (ref != null) {
+ toggleFastView(ref);
+ }
+ }
+ }
+
+ /**
+ * Toggles the visibility of a fast view. If the view is active it is
+ * deactivated. Otherwise, it is activated.
+ */
+ public void toggleFastView(IViewReference ref) {
+
+ }
+
+ /**
+ * Sets the state of the given part.
+ *
+ * @param ref
+ * part whose state should be modified (not null)
+ * @param newState
+ * one of the IStackPresentationSite.STATE_* constants
+ */
+ public void setState(IWorkbenchPartReference ref, int newState) {
+ Perspective persp = getActivePerspective();
+ if (persp == null) {
+ return;
+ }
+
+ PartPane pane = ((WorkbenchPartReference) ref).getPane();
+
+ // If target part is detached fire the zoom event. Note this doesn't
+ // actually cause any changes in size and is required to support
+ // intro state changes. We may want to introduce the notion of a zoomed
+ // (fullscreen) detached view at a later time.
+ if (!pane.isDocked()) {
+ pane.setZoomed(newState == IStackPresentationSite.STATE_MAXIMIZED);
+ return;
+ }
+
+ if (ref instanceof IViewReference
+ && persp.isFastView((IViewReference) ref)) {
+ persp.setFastViewState(newState);
+ return;
+ }
+
+ if (Perspective.useNewMinMax(persp)) {
+ // set the container's state to the new one
+ PartStack parent = ((PartStack) pane.getContainer());
+ parent.setState(newState);
+ return;
+ }
+
+ boolean wasZoomed = isZoomed();
+ boolean isZoomed = newState == IStackPresentationSite.STATE_MAXIMIZED;
+
+ // Update zoom status.
+ if (wasZoomed && !isZoomed) {
+ zoomOut();
+ } else if (!wasZoomed && isZoomed) {
+ persp.getPresentation().zoomIn(ref);
+ activate(ref.getPart(true));
+ }
+
+ PartStack parent = ((PartStack) pane.getContainer());
+
+ if (parent != null) {
+ parent
+ .setMinimized(newState == IStackPresentationSite.STATE_MINIMIZED);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.ui.IWorkbenchPage#setPartState(org.eclipse.ui.
+ * IWorkbenchPartReference, int)
+ */
+ public void setPartState(IWorkbenchPartReference ref, int state) {
+ setState(ref, state);
+ }
+
+ /**
+ * Returns the maximized/minimized/restored state of the given part
+ * reference
+ *
+ * @param ref
+ * part to query (not null)
+ * @return one of the IStackPresentationSite.STATE_* constants
+ */
+ int getState(IWorkbenchPartReference ref) {
+ Perspective persp = getActivePerspective();
+ if (persp == null) {
+ return IStackPresentationSite.STATE_RESTORED;
+ }
+
+ // TBD concept not yet implemented in E4
+ if (!(ref instanceof WorkbenchPartReference))
+ return IStackPresentationSite.STATE_RESTORED;
+
+ PartPane pane = ((WorkbenchPartReference) ref).getPane();
+
+ if (ref instanceof IViewReference
+ && persp.isFastView((IViewReference) ref)) {
+ return persp.getFastViewState();
+ }
+
+ PartStack parent = ((PartStack) pane.getContainer());
+
+ if (parent != null) {
+ return parent.getState();
+ }
+
+ return IStackPresentationSite.STATE_RESTORED;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.ui.IWorkbenchPage#getPartState(org.eclipse.ui.
+ * IWorkbenchPartReference)
+ */
+ public int getPartState(IWorkbenchPartReference ref) {
+ return getState(ref);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.ui.IWorkbenchPage#toggleZoom(org.eclipse.ui.
+ * IWorkbenchPartReference)
+ */
+ public void toggleZoom(IWorkbenchPartReference ref) {
+ int oldState = getState(ref);
+ boolean shouldZoom = oldState != IStackPresentationSite.STATE_MAXIMIZED;
+ int newState = shouldZoom ? IStackPresentationSite.STATE_MAXIMIZED
+ : IStackPresentationSite.STATE_RESTORED;
+
+ setState(ref, newState);
+ }
+
+ /**
+ * updateActionBars method comment.
+ */
+ public void updateActionBars() {
+ window.updateActionBars();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPage#zoomOut()
+ */
+ public void zoomOut() {
+ Perspective persp = getActivePerspective();
+ if (persp != null) {
+ persp.getPresentation().zoomOut();
+ }
+ }
+
+ /**
+ * Zooms out a zoomed in part if it is necessary to do so for the user to
+ * view the IWorkbenchPart that is the argument. Otherwise, does nothing.
+ *
+ * @param part
+ * the part to be made viewable
+ */
+ private void zoomOutIfNecessary(IWorkbenchPart part) {
+ if (isZoomed()
+ && partChangeAffectsZoom(((PartSite) part.getSite())
+ .getPartReference())) {
+ zoomOut();
+ }
+ }
+
+ /**
+ *
+ */
+ public int getEditorReuseThreshold() {
+ return ((TabBehaviour) Tweaklets.get(TabBehaviour.KEY))
+ .getEditorReuseThreshold();
+ }
+
+ /**
+ *
+ */
+ public void setEditorReuseThreshold(int openEditors) {
+ }
+
+ /*
+ * Returns the editors in activation order (oldest first).
+ */
+ public IEditorReference[] getSortedEditors() {
+ return getEditorReferences();
+ }
+
+ /**
+ * @see IWorkbenchPage#getOpenPerspectives()
+ */
+ public IPerspectiveDescriptor[] getOpenPerspectives() {
+ Perspective opened[] = perspList.getOpenedPerspectives();
+ IPerspectiveDescriptor[] result = new IPerspectiveDescriptor[opened.length];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = opened[i].getDesc();
+ }
+ return result;
+ }
+
+ /**
+ * Return all open Perspective objects.
+ *
+ * @return all open Perspective objects
+ * @since 3.1
+ */
+ /* package */Perspective[] getOpenInternalPerspectives() {
+ return perspList.getOpenedPerspectives();
+ }
+
+ /**
+ * Checks perspectives in the order they were activiated for the specfied
+ * part. The first sorted perspective that contains the specified part is
+ * returned.
+ *
+ * @param part
+ * specified part to search for
+ * @return the first sorted perspespective containing the part
+ * @since 3.1
+ */
+ /* package */Perspective getFirstPerspectiveWithView(IViewPart part) {
+ Perspective[] perspectives = perspList.getSortedPerspectives();
+ for (int i = perspectives.length - 1; i >= 0; i--) {
+ if (perspectives[i].containsView(part)) {
+ return perspectives[i];
+ }
+ }
+ // we should never get here
+ return null;
+ }
+
+ /**
+ * Returns the perspectives in activation order (oldest first).
+ */
+ public IPerspectiveDescriptor[] getSortedPerspectives() {
+ Perspective sortedArray[] = perspList.getSortedPerspectives();
+ IPerspectiveDescriptor[] result = new IPerspectiveDescriptor[sortedArray.length];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = sortedArray[i].getDesc();
+ }
+ return result;
+ }
+
+ /*
+ * Returns the parts in activation order (oldest first).
+ */
+ public IWorkbenchPartReference[] getSortedParts() {
+ return new IWorkbenchPartReference[0];
+ }
+
+ /**
+ * Returns the reference to the given part, or <code>null</code> if it has
+ * no reference (i.e. it is not a top-level part in this workbench page).
+ *
+ * @param part
+ * the part
+ * @return the part's reference or <code>null</code> if the given part does
+ * not belong to this workbench page
+ */
+ public IWorkbenchPartReference getReference(IWorkbenchPart part) {
+ if (part == null) {
+ return null;
+ }
+ IWorkbenchPartSite site = part.getSite();
+ if (!(site instanceof PartSite)) {
+ return null;
+ }
+ PartSite partSite = ((PartSite) site);
+ PartPane pane = partSite.getPane();
+ if (pane instanceof MultiEditorInnerPane) {
+ MultiEditorInnerPane innerPane = (MultiEditorInnerPane) pane;
+ return innerPane.getParentPane().getPartReference();
+ }
+ return partSite.getPartReference();
+ }
+
+ /**
+ * Helper class to keep track of all opened perspective. Both the opened and
+ * used order is kept.
+ */
+ private class PerspectiveList {
+ /**
+ * List of perspectives in the order they were opened;
+ */
+ private List openedList;
+
+ /**
+ * List of perspectives in the order they were used. Last element is the
+ * most recently used, and first element is the least recently used.
+ */
+ private List usedList;
+
+ /**
+ * The perspective explicitly set as being the active one
+ */
+ private Perspective active;
+
+ /**
+ * Creates an empty instance of the perspective list
+ */
+ public PerspectiveList() {
+ openedList = new ArrayList();
+ usedList = new ArrayList();
+ }
+
+ /**
+ * Return all perspectives in the order they were activated.
+ *
+ * @return an array of perspectives sorted by activation order, least
+ * recently activated perspective last.
+ */
+ public Perspective[] getSortedPerspectives() {
+ Perspective[] result = new Perspective[usedList.size()];
+ return (Perspective[]) usedList.toArray(result);
+ }
+
+ /**
+ * Adds a perspective to the list. No check is done for a duplicate when
+ * adding.
+ *
+ * @param perspective
+ * the perspective to add
+ * @return boolean <code>true</code> if the perspective was added
+ */
+ public boolean add(Perspective perspective) {
+ openedList.add(perspective);
+ usedList.add(0, perspective);
+ // It will be moved to top only when activated.
+ return true;
+ }
+
+ /**
+ * Returns an iterator on the perspective list in the order they were
+ * opened.
+ */
+ public Iterator iterator() {
+ return openedList.iterator();
+ }
+
+ /**
+ * Returns an array with all opened perspectives
+ */
+ public Perspective[] getOpenedPerspectives() {
+ Perspective[] result = new Perspective[openedList.size()];
+ return (Perspective[]) openedList.toArray(result);
+ }
+
+ /**
+ * Returns whether the list contains any perspectives
+ */
+ public boolean isEmpty() {
+ return openedList.isEmpty();
+ }
+
+ /**
+ * Returns the most recently used perspective in the list.
+ */
+ public Perspective getActive() {
+ return active;
+ }
+
+ /**
+ * Marks the specified perspective as the most recently used one in the
+ * list.
+ */
+ public void setActive(Perspective perspective) {
+ if (perspective == active) {
+ return;
+ }
+
+ updateActionSets(active, perspective);
+ active = perspective;
+
+ if (perspective != null) {
+ usedList.remove(perspective);
+ usedList.add(perspective);
+ }
+ }
+
+ private void updateActionSets(Perspective oldPersp, Perspective newPersp) {
+ // Update action sets
+
+ IContextService service = (IContextService) window
+ .getService(IContextService.class);
+ try {
+ service.deferUpdates(true);
+ if (newPersp != null) {
+ IActionSetDescriptor[] newAlwaysOn = newPersp
+ .getAlwaysOnActionSets();
+ for (int i = 0; i < newAlwaysOn.length; i++) {
+ IActionSetDescriptor descriptor = newAlwaysOn[i];
+
+ actionSets.showAction(descriptor);
+ }
+
+ IActionSetDescriptor[] newAlwaysOff = newPersp
+ .getAlwaysOffActionSets();
+ for (int i = 0; i < newAlwaysOff.length; i++) {
+ IActionSetDescriptor descriptor = newAlwaysOff[i];
+
+ actionSets.maskAction(descriptor);
+ }
+ }
+
+ if (oldPersp != null) {
+ IActionSetDescriptor[] newAlwaysOn = oldPersp
+ .getAlwaysOnActionSets();
+ for (int i = 0; i < newAlwaysOn.length; i++) {
+ IActionSetDescriptor descriptor = newAlwaysOn[i];
+
+ actionSets.hideAction(descriptor);
+ }
+
+ IActionSetDescriptor[] newAlwaysOff = oldPersp
+ .getAlwaysOffActionSets();
+ for (int i = 0; i < newAlwaysOff.length; i++) {
+ IActionSetDescriptor descriptor = newAlwaysOff[i];
+
+ actionSets.unmaskAction(descriptor);
+ }
+ }
+ } finally {
+ service.deferUpdates(false);
+ }
+ }
+ }
+
+ // for dynamic UI
+ protected void addPerspective(Perspective persp) {
+ perspList.add(persp);
+ window.firePerspectiveOpened(this, persp.getDesc());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPage#getViewStack(org.eclipse.ui.IViewPart)
+ */
+ public IViewPart[] getViewStack(IViewPart part) {
+ // check to make sure this part is in the current perspective
+ MPart modelPart = findPartInCurrentPerspective(part.getSite().getId());
+ if (modelPart == null) {
+ // if not, return null
+ return null;
+ }
+
+ List<IViewPart> stack = new ArrayList<IViewPart>();
+ // retrieve the parent stack
+ MElementContainer<MUIElement> viewStack = modelPart.getParent();
+ // get the contents of the stack
+ for (MUIElement child : viewStack.getChildren()) {
+ if (child instanceof MContribution) {
+ Object object = ((MContribution) child).getObject();
+ // queue it up if it's a view
+ if (object instanceof IViewPart) {
+ stack.add((IViewPart) object);
+ }
+ }
+ }
+ return stack.toArray(new IViewPart[stack.size()]);
+ }
+
+ /**
+ * Allow for programmatically resizing a part.
+ * <p>
+ * <em>EXPERIMENTAL</em>
+ * </p>
+ * <p>
+ * Known limitations:
+ * <ul>
+ * <li>currently applies only to views</li>
+ * <li>has no effect when view is zoomed</li>
+ * </ul>
+ */
+ public void resizeView(IViewPart part, int width, int height) {
+ SashInfo sashInfo = new SashInfo();
+ PartPane pane = ((PartSite) part.getSite()).getPane();
+ ILayoutContainer container = pane.getContainer();
+ LayoutTree tree = getPerspectivePresentation().getLayout().root
+ .find(((ViewStack) container));
+
+ // retrieve our layout sashes from the layout tree
+ findSashParts(tree, pane.findSashes(), sashInfo);
+
+ // first set the width
+ float deltaWidth = width - pane.getBounds().width;
+ if (sashInfo.right != null) {
+ Rectangle rightBounds = sashInfo.rightNode.getBounds();
+ // set the new ratio
+ sashInfo.right
+ .setRatio(((deltaWidth + sashInfo.right.getBounds().x) - rightBounds.x)
+ / rightBounds.width);
+ // complete the resize
+ sashInfo.rightNode.setBounds(rightBounds);
+ } else if (sashInfo.left != null) {
+ Rectangle leftBounds = sashInfo.leftNode.getBounds();
+ // set the ratio
+ sashInfo.left
+ .setRatio(((sashInfo.left.getBounds().x - deltaWidth) - leftBounds.x)
+ / leftBounds.width);
+ // complete the resize
+ sashInfo.leftNode.setBounds(sashInfo.leftNode.getBounds());
+ }
+
+ // next set the height
+ float deltaHeight = height - pane.getBounds().height;
+ if (sashInfo.bottom != null) {
+ Rectangle bottomBounds = sashInfo.bottomNode.getBounds();
+ // set the new ratio
+ sashInfo.bottom.setRatio(((deltaHeight + sashInfo.bottom
+ .getBounds().y) - bottomBounds.y)
+ / bottomBounds.height);
+ // complete the resize
+ sashInfo.bottomNode.setBounds(bottomBounds);
+ } else if (sashInfo.top != null) {
+ Rectangle topBounds = sashInfo.topNode.getBounds();
+ // set the ratio
+ sashInfo.top
+ .setRatio(((sashInfo.top.getBounds().y - deltaHeight) - topBounds.y)
+ / topBounds.height);
+ // complete the resize
+ sashInfo.topNode.setBounds(topBounds);
+ }
+
+ }
+
+ // provides sash information for the given pane
+ private class SashInfo {
+ private LayoutPartSash right;
+
+ private LayoutPartSash left;
+
+ private LayoutPartSash top;
+
+ private LayoutPartSash bottom;
+
+ private LayoutTreeNode rightNode;
+
+ private LayoutTreeNode leftNode;
+
+ private LayoutTreeNode topNode;
+
+ private LayoutTreeNode bottomNode;
+ }
+
+ private void findSashParts(LayoutTree tree, PartPane.Sashes sashes,
+ SashInfo info) {
+ LayoutTree parent = tree.getParent();
+ if (parent == null) {
+ return;
+ }
+
+ if (parent.part instanceof LayoutPartSash) {
+ // get the layout part sash from this tree node
+ LayoutPartSash sash = (LayoutPartSash) parent.part;
+ // make sure it has a sash control
+ Control control = sash.getControl();
+ if (control != null) {
+ // check for a vertical sash
+ if (sash.isVertical()) {
+ if (sashes.left == control) {
+ info.left = sash;
+ info.leftNode = parent.findSash(sash);
+ } else if (sashes.right == control) {
+ info.right = sash;
+ info.rightNode = parent.findSash(sash);
+ }
+ }
+ // check for a horizontal sash
+ else {
+ if (sashes.top == control) {
+ info.top = sash;
+ info.topNode = parent.findSash(sash);
+ } else if (sashes.bottom == control) {
+ info.bottom = sash;
+ info.bottomNode = parent.findSash(sash);
+ }
+ }
+ }
+ }
+ // recursive call to continue up the tree
+ findSashParts(parent, sashes, info);
+ }
+
+ /**
+ * Returns all parts that are owned by this page
+ *
+ * @return all open parts, including non-participating editors.
+ */
+ IWorkbenchPartReference[] getAllParts() {
+ ArrayList<IWorkbenchPartReference> result = new ArrayList<IWorkbenchPartReference>();
+ getContainedPartRefs(result, e4Window);
+ IWorkbenchPartReference[] typedResult = new IWorkbenchPartReference[result
+ .size()];
+ result.toArray(typedResult);
+ return typedResult;
+ }
+
+ // TBD this code repeats multiple times in variations (get editors, get
+ // views, get parts). When typically callers filter them some more (isDirty,
+ // isVisble, etc.).
+ // This needs to be a generic utility
+ private void getContainedPartRefs(
+ ArrayList<IWorkbenchPartReference> result,
+ MElementContainer<?> container) {
+ for (MUIElement child : container.getChildren()) {
+ if (child instanceof MPart) {
+ MPart contributedChild = (MPart) child;
+ if (contributedChild.isVisible()) {
+ Object object = contributedChild.getObject();
+ if (object instanceof IWorkbenchPart)
+ result.add(new ModelReference(contributedChild, this));
+ }
+ }
+ if (child instanceof MElementContainer<?>)
+ getContainedPartRefs(result, (MElementContainer<?>) child);
+ }
+ }
+
+ /**
+ * Returns all open parts that are owned by this page (that is, all parts
+ * for which a part opened event would have been sent -- these would be
+ * activated parts whose controls have already been created.
+ */
+ IWorkbenchPartReference[] getOpenParts() {
+ IWorkbenchPartReference[] refs = getAllParts();
+ List result = new ArrayList();
+
+ for (int i = 0; i < refs.length; i++) {
+ IWorkbenchPartReference reference = refs[i];
+
+ IWorkbenchPart part = reference.getPart(false);
+ if (part != null) {
+ result.add(reference);
+ }
+ }
+
+ return (IWorkbenchPartReference[]) result
+ .toArray(new IWorkbenchPartReference[result.size()]);
+ }
+
+ /**
+ * Sanity-checks the objects in this page. Throws an Assertation exception
+ * if an object's internal state is invalid. ONLY INTENDED FOR USE IN THE UI
+ * TEST SUITES.
+ */
+ public void testInvariants() {
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPage#getExtensionTracker()
+ */
+ public IExtensionTracker getExtensionTracker() {
+ if (tracker == null) {
+ tracker = new UIExtensionTracker(getWorkbenchWindow()
+ .getWorkbench().getDisplay());
+ }
+ return tracker;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPage#getNewWizardShortcuts()
+ */
+ public String[] getNewWizardShortcuts() {
+ Perspective persp = getActivePerspective();
+ if (persp == null) {
+ return new String[0];
+ }
+ return persp.getNewWizardShortcuts();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPage#getPerspectiveShortcuts()
+ */
+ public String[] getPerspectiveShortcuts() {
+ Perspective persp = getActivePerspective();
+ if (persp == null) {
+ return new String[0];
+ }
+ return persp.getPerspectiveShortcuts();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPage#getShowViewShortcuts()
+ */
+ public String[] getShowViewShortcuts() {
+ Perspective persp = getActivePerspective();
+ if (persp == null) {
+ return new String[0];
+ }
+ return persp.getShowViewShortcuts();
+ }
+
+ /**
+ * @since 3.1
+ */
+ private void suggestReset() {
+ final IWorkbench workbench = getWorkbenchWindow().getWorkbench();
+ workbench.getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ Shell parentShell = null;
+
+ IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
+ if (window == null) {
+ if (workbench.getWorkbenchWindowCount() == 0) {
+ return;
+ }
+ window = workbench.getWorkbenchWindows()[0];
+ }
+
+ parentShell = window.getShell();
+
+ if (MessageDialog.openQuestion(parentShell,
+ WorkbenchMessages.Dynamic_resetPerspectiveTitle,
+ WorkbenchMessages.Dynamic_resetPerspectiveMessage)) {
+ IWorkbenchPage page = window.getActivePage();
+ if (page == null) {
+ return;
+ }
+ page.resetPerspective();
+ }
+ }
+ });
+
+ }
+
+ public boolean isPartVisible(IWorkbenchPartReference reference) {
+ IWorkbenchPart part = reference.getPart(false);
+ // Can't be visible if it isn't created yet
+ if (part == null) {
+ return false;
+ }
+
+ return isPartVisible(part);
+ }
+
+ public IWorkingSet[] getWorkingSets() {
+ return workingSets;
+ }
+
+ public void setWorkingSets(IWorkingSet[] newWorkingSets) {
+ if (newWorkingSets != null) {
+ WorkbenchPlugin
+ .getDefault()
+ .getWorkingSetManager()
+ .addPropertyChangeListener(workingSetPropertyChangeListener);
+ } else {
+ WorkbenchPlugin.getDefault().getWorkingSetManager()
+ .removePropertyChangeListener(
+ workingSetPropertyChangeListener);
+ }
+
+ if (newWorkingSets == null) {
+ newWorkingSets = new IWorkingSet[0];
+ }
+
+ IWorkingSet[] oldWorkingSets = workingSets;
+
+ // filter out any duplicates if necessary
+ if (newWorkingSets.length > 1) {
+ Set setOfSets = new HashSet();
+ for (int i = 0; i < newWorkingSets.length; i++) {
+ if (newWorkingSets[i] == null) {
+ throw new IllegalArgumentException();
+ }
+ setOfSets.add(newWorkingSets[i]);
+ }
+ newWorkingSets = (IWorkingSet[]) setOfSets
+ .toArray(new IWorkingSet[setOfSets.size()]);
+ }
+
+ workingSets = newWorkingSets;
+ if (!Arrays.equals(oldWorkingSets, newWorkingSets)) {
+ firePropertyChange(CHANGE_WORKING_SETS_REPLACE, oldWorkingSets,
+ newWorkingSets);
+ if (aggregateWorkingSet != null) {
+ aggregateWorkingSet.setComponents(workingSets);
+ }
+ }
+ }
+
+ public IWorkingSet getAggregateWorkingSet() {
+ if (aggregateWorkingSet == null) {
+ IWorkingSetManager workingSetManager = PlatformUI.getWorkbench()
+ .getWorkingSetManager();
+ aggregateWorkingSet = (AggregateWorkingSet) workingSetManager
+ .getWorkingSet(getAggregateWorkingSetId());
+ if (aggregateWorkingSet == null) {
+ aggregateWorkingSet = (AggregateWorkingSet) workingSetManager
+ .createAggregateWorkingSet(
+ getAggregateWorkingSetId(),
+ WorkbenchMessages.WorkbenchPage_workingSet_default_label,
+ getWorkingSets());
+ workingSetManager.addWorkingSet(aggregateWorkingSet);
+ }
+ }
+ return aggregateWorkingSet;
+ }
+
+ private String getAggregateWorkingSetId() {
+ if (aggregateWorkingSetId == null) {
+ aggregateWorkingSetId = "Aggregate for window " + System.currentTimeMillis(); //$NON-NLS-1$
+ }
+ return aggregateWorkingSetId;
+ }
+
+ public void showEditor(IEditorReference ref) {
+ }
+
+ public void hideEditor(IEditorReference ref) {
+ // partList.removePart((WorkbenchPartReference)ref);
+ }
+
+ public IEditorReference[] openEditors(final IEditorInput[] inputs,
+ final String[] editorIDs, final int matchFlags)
+ throws MultiPartInitException {
+ if (inputs == null)
+ throw new IllegalArgumentException();
+ if (editorIDs == null)
+ throw new IllegalArgumentException();
+ if (inputs.length != editorIDs.length)
+ throw new IllegalArgumentException();
+
+ ArrayList refs = new ArrayList();
+
+ for (int i = 0; i < inputs.length; i++) {
+ IEditorPart ed = null;
+ try {
+ // brute force approach
+ ed = openEditor(inputs[i], editorIDs[i], true, matchFlags);
+ } catch (PartInitException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ if (ed != null) {
+ refs.add(((PartSite) ed.getSite()).getPartReference());
+ }
+ }
+
+ return (IEditorReference[]) refs.toArray(new IEditorReference[refs
+ .size()]);
+ }
+
+ public void resetHiddenEditors() {
+ IEditorReference[] refs = (IEditorReference[]) removedEditors
+ .toArray(new IEditorReference[removedEditors.size()]);
+ for (int i = 0; i < refs.length; i++) {
+ showEditor(refs[i]);
+ }
+ }
+
+ public MWindow getModelWindow() {
+ return e4Window;
+ }
+
+ // TBD this code repeats multiple times in variations (get editors, get
+ // views, get parts). When typically callers filter them some more (isDirty,
+ // isVisble, etc.).
+ // This needs to be a generic utility
+ private MPerspective findPerspectiveE4(MWindow e4Window, String id) {
+ MUIElement pe = ModeledPageLayout.findElementById(e4Window, id);
+ if (pe instanceof MPerspective)
+ return (MPerspective) pe;
+ return null;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPagePartList.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPagePartList.java
new file mode 100644
index 0000000..12b25b8
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPagePartList.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2008 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.ui.internal;
+
+import org.eclipse.jface.dialogs.PageChangedEvent;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.ISelectionService;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.internal.misc.UIListenerLogging;
+
+public class WorkbenchPagePartList extends PartList {
+
+ private PartService partService = new PartService(
+ UIListenerLogging.PAGE_PARTLISTENER_EVENTS,
+ UIListenerLogging.PAGE_PARTLISTENER2_EVENTS);
+
+ public WorkbenchPagePartList(ISelectionService selectionService) {
+ }
+
+ public IPartService getPartService() {
+ return partService;
+ }
+
+ protected void firePartOpened(IWorkbenchPartReference part) {
+ partService.firePartOpened(part);
+ }
+
+ protected void firePartClosed(IWorkbenchPartReference part) {
+ partService.firePartClosed(part);
+ }
+
+ protected void firePartAdded(IWorkbenchPartReference part) {
+ // TODO: There is no listener for workbench page additions yet
+ }
+
+ protected void firePartRemoved(IWorkbenchPartReference part) {
+ // TODO: There is no listener for workbench page removals yet
+ }
+
+ protected void fireActiveEditorChanged(IWorkbenchPartReference ref) {
+ if (ref != null) {
+ firePartBroughtToTop(ref);
+ }
+ }
+
+ protected void fireActivePartChanged(IWorkbenchPartReference oldRef,
+ IWorkbenchPartReference newRef) {
+ partService.setActivePart(newRef);
+
+ }
+
+ protected void firePartHidden(IWorkbenchPartReference ref) {
+ partService.firePartHidden(ref);
+ }
+
+ protected void firePartVisible(IWorkbenchPartReference ref) {
+ partService.firePartVisible(ref);
+ }
+
+ protected void firePartInputChanged(IWorkbenchPartReference ref) {
+ partService.firePartInputChanged(ref);
+ }
+
+ public void firePartBroughtToTop(IWorkbenchPartReference ref) {
+ partService.firePartBroughtToTop(ref);
+ }
+
+ protected void firePageChanged(PageChangedEvent event) {
+ partService.firePageChanged(event);
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPlugin.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPlugin.java
new file mode 100644
index 0000000..83fee54
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchPlugin.java
@@ -0,0 +1,1471 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.ui.internal;
+
+import com.ibm.icu.text.MessageFormat;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Locale;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.ContextFunction;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceManager;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IDecoratorManager;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IElementFactory;
+import org.eclipse.ui.IPerspectiveRegistry;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
+import org.eclipse.ui.internal.decorators.DecoratorManager;
+import org.eclipse.ui.internal.dialogs.WorkbenchPreferenceManager;
+import org.eclipse.ui.internal.intro.IIntroRegistry;
+import org.eclipse.ui.internal.intro.IntroRegistry;
+import org.eclipse.ui.internal.misc.StatusUtil;
+import org.eclipse.ui.internal.operations.WorkbenchOperationSupport;
+import org.eclipse.ui.internal.progress.ProgressManager;
+import org.eclipse.ui.internal.registry.ActionSetRegistry;
+import org.eclipse.ui.internal.registry.EditorRegistry;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.internal.registry.PerspectiveRegistry;
+import org.eclipse.ui.internal.registry.PreferencePageRegistryReader;
+import org.eclipse.ui.internal.registry.ViewRegistry;
+import org.eclipse.ui.internal.registry.WorkingSetRegistry;
+import org.eclipse.ui.internal.themes.IThemeRegistry;
+import org.eclipse.ui.internal.themes.ThemeRegistry;
+import org.eclipse.ui.internal.themes.ThemeRegistryReader;
+import org.eclipse.ui.internal.util.BundleUtility;
+import org.eclipse.ui.internal.wizards.ExportWizardRegistry;
+import org.eclipse.ui.internal.wizards.ImportWizardRegistry;
+import org.eclipse.ui.internal.wizards.NewWizardRegistry;
+import org.eclipse.ui.operations.IWorkbenchOperationSupport;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.ui.presentations.AbstractPresentationFactory;
+import org.eclipse.ui.views.IViewRegistry;
+import org.eclipse.ui.wizards.IWizardRegistry;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.SynchronousBundleListener;
+
+/**
+ * This class represents the TOP of the workbench UI world A plugin class is
+ * effectively an org.eclipse.e4.ui.model.application wrapper for a plugin & its classes. This class
+ * should be thought of as the workbench UI's org.eclipse.e4.ui.model.application class.
+ *
+ * This class is responsible for tracking various registries font, preference,
+ * graphics, dialog store.
+ *
+ * This class is explicitly referenced by the workbench plugin's "plugin.xml"
+ * and places it into the UI start extension point of the main overall
+ * org.eclipse.e4.ui.model.application harness
+ *
+ * When is this class started? When the Application calls
+ * createExecutableExtension to create an executable instance of our workbench
+ * class.
+ */
+public class WorkbenchPlugin extends AbstractUIPlugin {
+
+ /**
+ * Splash shell constant.
+ */
+ private static final String DATA_SPLASH_SHELL = "org.eclipse.ui.workbench.splashShell"; //$NON-NLS-1$
+
+ /**
+ * The OSGi splash property.
+ *
+ * @since 3.4
+ */
+ private static final String PROP_SPLASH_HANDLE = "org.eclipse.equinox.launcher.splash.handle"; //$NON-NLS-1$
+
+ private static final String LEFT_TO_RIGHT = "ltr"; //$NON-NLS-1$
+ private static final String RIGHT_TO_LEFT = "rtl";//$NON-NLS-1$
+ private static final String ORIENTATION_COMMAND_LINE = "-dir";//$NON-NLS-1$
+ private static final String ORIENTATION_PROPERTY = "eclipse.orientation";//$NON-NLS-1$
+ private static final String NL_USER_PROPERTY = "osgi.nl.user"; //$NON-NLS-1$
+
+ // Default instance of the receiver
+ private static WorkbenchPlugin inst;
+
+ // Manager that maps resources to descriptors of editors to use
+ private EditorRegistry editorRegistry;
+
+ // Manager for the DecoratorManager
+ private DecoratorManager decoratorManager;
+
+ // Theme registry
+ private ThemeRegistry themeRegistry;
+
+ // Manager for working sets (IWorkingSet)
+ private WorkingSetManager workingSetManager;
+
+ // Working set registry, stores working set dialogs
+ private WorkingSetRegistry workingSetRegistry;
+
+ // The context within which this plugin was started.
+ private BundleContext bundleContext;
+
+ // The set of currently starting bundles
+ private Collection startingBundles = new HashSet();
+
+ /**
+ * Global workbench ui plugin flag. Only workbench implementation is allowed
+ * to use this flag All other plugins, examples, or test cases must *not*
+ * use this flag.
+ */
+ public static boolean DEBUG = false;
+
+ /**
+ * The workbench plugin ID.
+ *
+ * @issue we should just drop this constant and use PlatformUI.PLUGIN_ID
+ * instead
+ */
+ public static String PI_WORKBENCH = PlatformUI.PLUGIN_ID;
+
+ /**
+ * The character used to separate preference page category ids
+ */
+ public static char PREFERENCE_PAGE_CATEGORY_SEPARATOR = '/';
+
+ // Other data.
+ private WorkbenchPreferenceManager preferenceManager;
+
+ private ViewRegistry viewRegistry;
+
+ private PerspectiveRegistry perspRegistry;
+
+ private ActionSetRegistry actionSetRegistry;
+
+ private SharedImages sharedImages;
+
+ /**
+ * Information describing the product (formerly called "primary plugin");
+ * lazily initialized.
+ *
+ * @since 3.0
+ */
+ private ProductInfo productInfo = null;
+
+ private IntroRegistry introRegistry;
+
+ private WorkbenchOperationSupport operationSupport;
+ private BundleListener bundleListener;
+
+ private IEclipseContext e4Context;
+
+ /**
+ * Create an instance of the WorkbenchPlugin. The workbench plugin is
+ * effectively the "org.eclipse.e4.ui.model.application" for the workbench UI. The entire UI
+ * operates as a good plugin citizen.
+ */
+ public WorkbenchPlugin() {
+ super();
+ inst = this;
+ }
+
+ /**
+ * Unload all members. This can be used to run a second instance of a
+ * workbench.
+ *
+ * @since 3.0
+ */
+ void reset() {
+ editorRegistry = null;
+
+ if (decoratorManager != null) {
+ decoratorManager.dispose();
+ decoratorManager = null;
+ }
+
+ ProgressManager.shutdownProgressManager();
+
+ themeRegistry = null;
+ if (workingSetManager != null) {
+ workingSetManager.dispose();
+ workingSetManager = null;
+ }
+ workingSetRegistry = null;
+
+ preferenceManager = null;
+ if (viewRegistry != null) {
+ viewRegistry.dispose();
+ viewRegistry = null;
+ }
+ if (perspRegistry != null) {
+ perspRegistry.dispose();
+ perspRegistry = null;
+ }
+ actionSetRegistry = null;
+ sharedImages = null;
+
+ productInfo = null;
+ introRegistry = null;
+
+ if (operationSupport != null) {
+ operationSupport.dispose();
+ operationSupport = null;
+ }
+
+ DEBUG = false;
+
+ }
+
+ /**
+ * Creates an extension. If the extension plugin has not been loaded a busy
+ * cursor will be activated during the duration of the load.
+ *
+ * @param element
+ * the config element defining the extension
+ * @param classAttribute
+ * the name of the attribute carrying the class
+ * @return the extension object
+ * @throws CoreException
+ * if the extension cannot be created
+ */
+ public static Object createExtension(final IConfigurationElement element,
+ final String classAttribute) throws CoreException {
+ try {
+ // If plugin has been loaded create extension.
+ // Otherwise, show busy cursor then create extension.
+ if (BundleUtility.isActivated(element.getDeclaringExtension()
+ .getNamespace())) {
+ return element.createExecutableExtension(classAttribute);
+ }
+ final Object[] ret = new Object[1];
+ final CoreException[] exc = new CoreException[1];
+ BusyIndicator.showWhile(null, new Runnable() {
+ public void run() {
+ try {
+ ret[0] = element
+ .createExecutableExtension(classAttribute);
+ } catch (CoreException e) {
+ exc[0] = e;
+ }
+ }
+ });
+ if (exc[0] != null) {
+ throw exc[0];
+ }
+ return ret[0];
+
+ } catch (CoreException core) {
+ throw core;
+ } catch (Exception e) {
+ throw new CoreException(new Status(IStatus.ERROR, PI_WORKBENCH,
+ IStatus.ERROR, WorkbenchMessages.WorkbenchPlugin_extension,
+ e));
+ }
+ }
+
+ /**
+ * Answers whether the provided element either has an attribute with the
+ * given name or a child element with the given name with an attribute
+ * called class.
+ *
+ * @param element
+ * the element to test
+ * @param extensionName
+ * the name of the extension to test for
+ * @return whether or not the extension is declared
+ * @since 3.3
+ */
+ public static boolean hasExecutableExtension(IConfigurationElement element,
+ String extensionName) {
+
+ if (element.getAttribute(extensionName) != null)
+ return true;
+ String elementText = element.getValue();
+ if (elementText != null && !elementText.equals("")) //$NON-NLS-1$
+ return true;
+ IConfigurationElement[] children = element.getChildren(extensionName);
+ if (children.length == 1) {
+ if (children[0].getAttribute(IWorkbenchRegistryConstants.ATT_CLASS) != null)
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Checks to see if the provided element has the syntax for an executable
+ * extension with a given name that resides in a bundle that is already
+ * active. Determining the bundle happens in one of two ways:<br/>
+ * <ul>
+ * <li>The element has an attribute with the specified name or element text
+ * in the form <code>bundle.id/class.name[:optional attributes]</code></li>
+ * <li>The element has a child element with the specified name that has a
+ * <code>plugin</code> attribute</li>
+ * </ul>
+ *
+ * @param element
+ * the element to test
+ * @param extensionName
+ * the name of the extension to test for
+ * @return whether or not the bundle expressed by the above criteria is
+ * active. If the bundle cannot be determined then the state of the
+ * bundle that declared the element is returned.
+ * @since 3.3
+ */
+ public static boolean isBundleLoadedForExecutableExtension(
+ IConfigurationElement element, String extensionName) {
+ Bundle bundle = getBundleForExecutableExtension(element, extensionName);
+
+ if (bundle == null)
+ return true;
+ return bundle.getState() == Bundle.ACTIVE;
+ }
+
+ /**
+ * Returns the bundle that contains the class referenced by an executable
+ * extension. Determining the bundle happens in one of two ways:<br/>
+ * <ul>
+ * <li>The element has an attribute with the specified name or element text
+ * in the form <code>bundle.id/class.name[:optional attributes]</code></li>
+ * <li>The element has a child element with the specified name that has a
+ * <code>plugin</code> attribute</li>
+ * </ul>
+ *
+ * @param element
+ * the element to test
+ * @param extensionName
+ * the name of the extension to test for
+ * @return the bundle referenced by the extension. If that bundle cannot be
+ * determined the bundle that declared the element is returned. Note
+ * that this may be <code>null</code>.
+ * @since 3.3
+ */
+ public static Bundle getBundleForExecutableExtension(
+ IConfigurationElement element, String extensionName) {
+ // this code is derived heavily from
+ // ConfigurationElement.createExecutableExtension.
+ String prop = null;
+ String executable;
+ String contributorName = null;
+ int i;
+
+ if (extensionName != null)
+ prop = element.getAttribute(extensionName);
+ else {
+ // property not specified, try as element value
+ prop = element.getValue();
+ if (prop != null) {
+ prop = prop.trim();
+ if (prop.equals("")) //$NON-NLS-1$
+ prop = null;
+ }
+ }
+
+ if (prop == null) {
+ // property not defined, try as a child element
+ IConfigurationElement[] exec = element.getChildren(extensionName);
+ if (exec.length != 0)
+ contributorName = exec[0].getAttribute("plugin"); //$NON-NLS-1$
+ } else {
+ // simple property or element value, parse it into its components
+ i = prop.indexOf(':');
+ if (i != -1)
+ executable = prop.substring(0, i).trim();
+ else
+ executable = prop;
+
+ i = executable.indexOf('/');
+ if (i != -1)
+ contributorName = executable.substring(0, i).trim();
+
+ }
+
+ if (contributorName == null)
+ contributorName = element.getContributor().getName();
+
+ return Platform.getBundle(contributorName);
+ }
+
+ /**
+ * Returns the image registry for this plugin.
+ *
+ * Where are the images? The images (typically gifs) are found in the same
+ * plugins directory.
+ *
+ * @see ImageRegistry
+ *
+ * Note: The workbench uses the standard JFace ImageRegistry to track
+ * its images. In addition the class WorkbenchGraphicResources provides
+ * convenience access to the graphics resources and fast field access
+ * for some of the commonly used graphical images.
+ */
+ protected ImageRegistry createImageRegistry() {
+ return WorkbenchImages.getImageRegistry();
+ }
+
+ /**
+ * Returns the action set registry for the workbench.
+ *
+ * @return the workbench action set registry
+ */
+ public ActionSetRegistry getActionSetRegistry() {
+ return (ActionSetRegistry) e4Context.get(ActionSetRegistry.class
+ .getName());
+ }
+
+ /**
+ * Return the default instance of the receiver. This represents the runtime
+ * plugin.
+ *
+ * @return WorkbenchPlugin
+ * @see AbstractUIPlugin for the typical implementation pattern for plugin
+ * classes.
+ */
+ public static WorkbenchPlugin getDefault() {
+ return inst;
+ }
+
+ /**
+ * Answer the manager that maps resource types to a the description of the
+ * editor to use
+ *
+ * @return IEditorRegistry the editor registry used by this plug-in.
+ */
+
+ public IEditorRegistry getEditorRegistry() {
+ return (IEditorRegistry) e4Context.get(IEditorRegistry.class.getName());
+ }
+
+ /**
+ * Answer the element factory for an id, or <code>null</code. if not found.
+ *
+ * @param targetID
+ * @return IElementFactory
+ */
+ public IElementFactory getElementFactory(String targetID) {
+
+ // Get the extension point registry.
+ IExtensionPoint extensionPoint;
+ extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(
+ PI_WORKBENCH, IWorkbenchRegistryConstants.PL_ELEMENT_FACTORY);
+
+ if (extensionPoint == null) {
+ WorkbenchPlugin
+ .log("Unable to find element factory. Extension point: " + IWorkbenchRegistryConstants.PL_ELEMENT_FACTORY + " not found"); //$NON-NLS-2$ //$NON-NLS-1$
+ return null;
+ }
+
+ // Loop through the config elements.
+ IConfigurationElement targetElement = null;
+ IConfigurationElement[] configElements = extensionPoint
+ .getConfigurationElements();
+ for (int j = 0; j < configElements.length; j++) {
+ String strID = configElements[j].getAttribute("id"); //$NON-NLS-1$
+ if (targetID.equals(strID)) {
+ targetElement = configElements[j];
+ break;
+ }
+ }
+ if (targetElement == null) {
+ // log it since we cannot safely display a dialog.
+ WorkbenchPlugin.log("Unable to find element factory: " + targetID); //$NON-NLS-1$
+ return null;
+ }
+
+ // Create the extension.
+ IElementFactory factory = null;
+ try {
+ factory = (IElementFactory) createExtension(targetElement, "class"); //$NON-NLS-1$
+ } catch (CoreException e) {
+ // log it since we cannot safely display a dialog.
+ WorkbenchPlugin.log(
+ "Unable to create element factory.", e.getStatus()); //$NON-NLS-1$
+ factory = null;
+ }
+ return factory;
+ }
+
+ /**
+ * Returns the presentation factory with the given id, or <code>null</code>
+ * if not found.
+ *
+ * @param targetID
+ * The id of the presentation factory to use.
+ * @return AbstractPresentationFactory or <code>null</code> if not factory
+ * matches that id.
+ */
+ public AbstractPresentationFactory getPresentationFactory(String targetID) {
+ Object o = createExtension(
+ IWorkbenchRegistryConstants.PL_PRESENTATION_FACTORIES,
+ "factory", targetID); //$NON-NLS-1$
+ if (o instanceof AbstractPresentationFactory) {
+ return (AbstractPresentationFactory) o;
+ }
+ WorkbenchPlugin
+ .log("Error creating presentation factory: " + targetID + " -- class is not an AbstractPresentationFactory"); //$NON-NLS-1$ //$NON-NLS-2$
+ return null;
+ }
+
+ /**
+ * Looks up the configuration element with the given id on the given
+ * extension point and instantiates the class specified by the class
+ * attributes.
+ *
+ * @param extensionPointId
+ * the extension point id (simple id)
+ * @param elementName
+ * the name of the configuration element, or <code>null</code> to
+ * match any element
+ * @param targetID
+ * the target id
+ * @return the instantiated extension object, or <code>null</code> if not
+ * found
+ */
+ private Object createExtension(String extensionPointId, String elementName,
+ String targetID) {
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry()
+ .getExtensionPoint(PI_WORKBENCH, extensionPointId);
+ if (extensionPoint == null) {
+ WorkbenchPlugin
+ .log("Unable to find extension. Extension point: " + extensionPointId + " not found"); //$NON-NLS-1$ //$NON-NLS-2$
+ return null;
+ }
+
+ // Loop through the config elements.
+ IConfigurationElement targetElement = null;
+ IConfigurationElement[] elements = extensionPoint
+ .getConfigurationElements();
+ for (int j = 0; j < elements.length; j++) {
+ IConfigurationElement element = elements[j];
+ if (elementName == null || elementName.equals(element.getName())) {
+ String strID = element.getAttribute("id"); //$NON-NLS-1$
+ if (targetID.equals(strID)) {
+ targetElement = element;
+ break;
+ }
+ }
+ }
+ if (targetElement == null) {
+ // log it since we cannot safely display a dialog.
+ WorkbenchPlugin.log("Unable to find extension: " + targetID //$NON-NLS-1$
+ + " in extension point: " + extensionPointId); //$NON-NLS-1$
+ return null;
+ }
+
+ // Create the extension.
+ try {
+ return createExtension(targetElement, "class"); //$NON-NLS-1$
+ } catch (CoreException e) {
+ // log it since we cannot safely display a dialog.
+ WorkbenchPlugin.log("Unable to create extension: " + targetID //$NON-NLS-1$
+ + " in extension point: " + extensionPointId //$NON-NLS-1$
+ + ", status: ", e.getStatus()); //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ /**
+ * Return the perspective registry.
+ *
+ * @return IPerspectiveRegistry. The registry for the receiver.
+ */
+ public IPerspectiveRegistry getPerspectiveRegistry() {
+ if (perspRegistry == null) {
+ perspRegistry = new PerspectiveRegistry();
+ // the load methods can touch on WorkbenchImages if
+ // an image is
+ // missing so we need to wrap the call in
+ // a startup block for the case where a custom
+ // descriptor exists on
+ // startup that does not have an image
+ // associated with it. See bug 196352.
+ StartupThreading.runWithoutExceptions(new StartupRunnable() {
+ public void runWithException() throws Throwable {
+ perspRegistry.load();
+ }
+ });
+
+ }
+ return perspRegistry;
+ }
+
+ /**
+ * Returns the working set manager
+ *
+ * @return the working set manager
+ * @since 2.0
+ */
+ public IWorkingSetManager getWorkingSetManager() {
+ return (IWorkingSetManager) e4Context.get(IWorkingSetManager.class
+ .getName());
+ }
+
+ /**
+ * Returns the working set registry
+ *
+ * @return the working set registry
+ * @since 2.0
+ */
+ public WorkingSetRegistry getWorkingSetRegistry() {
+ return (WorkingSetRegistry) e4Context.get(WorkingSetRegistry.class
+ .getName());
+ }
+
+ /**
+ * Returns the introduction registry.
+ *
+ * @return the introduction registry.
+ * @since 3.0
+ */
+ public IIntroRegistry getIntroRegistry() {
+ return (IIntroRegistry) e4Context.get(IIntroRegistry.class.getName());
+ }
+
+ /**
+ * Returns the operation support.
+ *
+ * @return the workbench operation support.
+ * @since 3.1
+ */
+ public IWorkbenchOperationSupport getOperationSupport() {
+ return (IWorkbenchOperationSupport) e4Context
+ .get(IWorkbenchOperationSupport.class.getName());
+ }
+
+ /**
+ * Get the preference manager.
+ *
+ * @return PreferenceManager the preference manager for the receiver.
+ */
+ public PreferenceManager getPreferenceManager() {
+ return (PreferenceManager) e4Context.get(PreferenceManager.class
+ .getName());
+ }
+
+ /**
+ * Returns the shared images for the workbench.
+ *
+ * @return the shared image manager
+ */
+ public ISharedImages getSharedImages() {
+ return (ISharedImages) e4Context.get(ISharedImages.class.getName());
+ }
+
+ /**
+ * Returns the theme registry for the workbench.
+ *
+ * @return the theme registry
+ */
+ public IThemeRegistry getThemeRegistry() {
+ return (IThemeRegistry) e4Context.get(IThemeRegistry.class.getName());
+ }
+
+ /**
+ * Answer the view registry.
+ *
+ * @return IViewRegistry the view registry for the receiver.
+ */
+ public IViewRegistry getViewRegistry() {
+ return (IViewRegistry) e4Context.get(IViewRegistry.class.getName());
+ }
+
+ /**
+ * Answer the workbench.
+ *
+ * @deprecated Use <code>PlatformUI.getWorkbench()</code> instead.
+ */
+ public IWorkbench getWorkbench() {
+ return PlatformUI.getWorkbench();
+ }
+
+ /**
+ * Set default preference values. This method must be called whenever the
+ * preference store is initially loaded because the default values are not
+ * stored in the preference store.
+ */
+ protected void initializeDefaultPreferences(IPreferenceStore store) {
+ // Do nothing. This should not be called.
+ // Prefs are initialized in WorkbenchPreferenceInitializer.
+ }
+
+ /**
+ * Logs the given message to the platform log.
+ *
+ * If you have an exception in hand, call log(String, Throwable) instead.
+ *
+ * If you have a status object in hand call log(String, IStatus) instead.
+ *
+ * This convenience method is for internal use by the Workbench only and
+ * must not be called outside the Workbench.
+ *
+ * @param message
+ * A high level UI message describing when the problem happened.
+ */
+ public static void log(String message) {
+ getDefault().getLog().log(
+ StatusUtil.newStatus(IStatus.ERROR, message, null));
+ }
+
+ /**
+ * Log the throwable.
+ *
+ * @param t
+ */
+ public static void log(Throwable t) {
+ getDefault().getLog().log(getStatus(t));
+ }
+
+ /**
+ * Return the status from throwable
+ *
+ * @param t
+ * throwable
+ * @return IStatus
+ */
+ public static IStatus getStatus(Throwable t) {
+ String message = StatusUtil.getLocalizedMessage(t);
+
+ return newError(message, t);
+ }
+
+ /**
+ * Create a new error from the message and the throwable.
+ *
+ * @param message
+ * @param t
+ * @return IStatus
+ */
+ public static IStatus newError(String message, Throwable t) {
+ String pluginId = "org.eclipse.ui.workbench"; //$NON-NLS-1$
+ int errorCode = IStatus.OK;
+
+ // If this was a CoreException, keep the original plugin ID and error
+ // code
+ if (t instanceof CoreException) {
+ CoreException ce = (CoreException) t;
+ pluginId = ce.getStatus().getPlugin();
+ errorCode = ce.getStatus().getCode();
+ }
+
+ return new Status(IStatus.ERROR, pluginId, errorCode, message,
+ StatusUtil.getCause(t));
+ }
+
+ /**
+ * Logs the given message and throwable to the platform log.
+ *
+ * If you have a status object in hand call log(String, IStatus) instead.
+ *
+ * This convenience method is for internal use by the Workbench only and
+ * must not be called outside the Workbench.
+ *
+ * @param message
+ * A high level UI message describing when the problem happened.
+ * @param t
+ * The throwable from where the problem actually occurred.
+ */
+ public static void log(String message, Throwable t) {
+ IStatus status = StatusUtil.newStatus(IStatus.ERROR, message, t);
+ log(message, status);
+ }
+
+ /**
+ * Logs the given throwable to the platform log, indicating the class and
+ * method from where it is being logged (this is not necessarily where it
+ * occurred).
+ *
+ * This convenience method is for internal use by the Workbench only and
+ * must not be called outside the Workbench.
+ *
+ * @param clazz
+ * The calling class.
+ * @param methodName
+ * The calling method name.
+ * @param t
+ * The throwable from where the problem actually occurred.
+ */
+ public static void log(Class clazz, String methodName, Throwable t) {
+ String msg = MessageFormat.format("Exception in {0}.{1}: {2}", //$NON-NLS-1$
+ new Object[] { clazz.getName(), methodName, t });
+ log(msg, t);
+ }
+
+ /**
+ * Logs the given message and status to the platform log.
+ *
+ * This convenience method is for internal use by the Workbench only and
+ * must not be called outside the Workbench.
+ *
+ * @param message
+ * A high level UI message describing when the problem happened.
+ * May be <code>null</code>.
+ * @param status
+ * The status describing the problem. Must not be null.
+ */
+ public static void log(String message, IStatus status) {
+
+ // 1FTUHE0: ITPCORE:ALL - API - Status & logging - loss of semantic info
+
+ if (message != null) {
+ getDefault().getLog().log(
+ StatusUtil.newStatus(IStatus.ERROR, message, null));
+ }
+
+ getDefault().getLog().log(status);
+ }
+
+ /**
+ * Log the status to the default log.
+ *
+ * @param status
+ */
+ public static void log(IStatus status) {
+ getDefault().getLog().log(status);
+ }
+
+ /**
+ * Get the decorator manager for the receiver
+ *
+ * @return DecoratorManager the decorator manager for the receiver.
+ */
+ public DecoratorManager getDecoratorManager() {
+ return (DecoratorManager) e4Context.get(IDecoratorManager.class
+ .getName());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext
+ * )
+ */
+ public void start(BundleContext context) throws Exception {
+ context.addBundleListener(getBundleListener());
+ super.start(context);
+ bundleContext = context;
+
+ JFaceUtil.initializeJFace();
+
+ Window.setDefaultOrientation(getDefaultOrientation());
+
+ // The UI plugin needs to be initialized so that it can install the
+ // callback in PrefUtil,
+ // which needs to be done as early as possible, before the workbench
+ // accesses any API preferences.
+ Bundle uiBundle = Platform.getBundle(PlatformUI.PLUGIN_ID);
+ try {
+ // Attempt to load the activator of the ui bundle. This will force
+ // lazy start
+ // of the ui bundle. Using the bundle activator class here because
+ // it is a
+ // class that needs to be loaded anyway so it should not cause extra
+ // classes
+ // to be loaded.s
+ if (uiBundle != null)
+ uiBundle.start(Bundle.START_TRANSIENT);
+ } catch (BundleException e) {
+ WorkbenchPlugin.log("Unable to load UI activator", e); //$NON-NLS-1$
+ }
+ /*
+ * DO NOT RUN ANY OTHER CODE AFTER THIS LINE. If you do, then you are
+ * likely to cause a deadlock in class loader code. Please see Bug 86450
+ * for more information.
+ */
+
+ }
+
+ /**
+ * Get the default orientation from the command line arguments. If there are
+ * no arguments imply the orientation.
+ *
+ * @return int
+ * @see SWT#NONE
+ * @see SWT#RIGHT_TO_LEFT
+ * @see SWT#LEFT_TO_RIGHT
+ */
+ private int getDefaultOrientation() {
+
+ String[] commandLineArgs = Platform.getCommandLineArgs();
+
+ int orientation = getCommandLineOrientation(commandLineArgs);
+
+ if (orientation != SWT.NONE) {
+ return orientation;
+ }
+
+ orientation = getSystemPropertyOrientation();
+
+ if (orientation != SWT.NONE) {
+ return orientation;
+ }
+
+ return checkCommandLineLocale(); // Use the default value if there is
+ // nothing specified
+ }
+
+ /**
+ * Check to see if the command line parameter for -nl has been set. If so
+ * imply the orientation from this specified Locale. If it is a
+ * bidirectional Locale return SWT#RIGHT_TO_LEFT. If it has not been set or
+ * has been set to a unidirectional Locale then return SWT#NONE.
+ *
+ * Locale is determined differently by different JDKs and may not be
+ * consistent with the users expectations.
+ *
+ *
+ * @return int
+ * @see SWT#NONE
+ * @see SWT#RIGHT_TO_LEFT
+ */
+ private int checkCommandLineLocale() {
+
+ // Check if the user property is set. If not do not
+ // rely on the vm.
+ if (System.getProperty(NL_USER_PROPERTY) == null) {
+ return SWT.NONE;
+ }
+
+ Locale locale = Locale.getDefault();
+ String lang = locale.getLanguage();
+
+ if ("iw".equals(lang) || "he".equals(lang) || "ar".equals(lang) || //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ "fa".equals(lang) || "ur".equals(lang)) { //$NON-NLS-1$ //$NON-NLS-2$
+ return SWT.RIGHT_TO_LEFT;
+ }
+
+ return SWT.NONE;
+ }
+
+ /**
+ * Check to see if the orientation was set in the system properties. If
+ * there is no orientation specified return SWT#NONE.
+ *
+ * @return int
+ * @see SWT#NONE
+ * @see SWT#RIGHT_TO_LEFT
+ * @see SWT#LEFT_TO_RIGHT
+ */
+ private int getSystemPropertyOrientation() {
+ String orientation = System.getProperty(ORIENTATION_PROPERTY);
+ if (RIGHT_TO_LEFT.equals(orientation)) {
+ return SWT.RIGHT_TO_LEFT;
+ }
+ if (LEFT_TO_RIGHT.equals(orientation)) {
+ return SWT.LEFT_TO_RIGHT;
+ }
+ return SWT.NONE;
+ }
+
+ /**
+ * Find the orientation in the commandLineArgs. If there is no orientation
+ * specified return SWT#NONE.
+ *
+ * @param commandLineArgs
+ * @return int
+ * @see SWT#NONE
+ * @see SWT#RIGHT_TO_LEFT
+ * @see SWT#LEFT_TO_RIGHT
+ */
+ private int getCommandLineOrientation(String[] commandLineArgs) {
+ // Do not process the last one as it will never have a parameter
+ for (int i = 0; i < commandLineArgs.length - 1; i++) {
+ if (commandLineArgs[i].equalsIgnoreCase(ORIENTATION_COMMAND_LINE)) {
+ String orientation = commandLineArgs[i + 1];
+ if (orientation.equals(RIGHT_TO_LEFT)) {
+ System.setProperty(ORIENTATION_PROPERTY, RIGHT_TO_LEFT);
+ return SWT.RIGHT_TO_LEFT;
+ }
+ if (orientation.equals(LEFT_TO_RIGHT)) {
+ System.setProperty(ORIENTATION_PROPERTY, LEFT_TO_RIGHT);
+ return SWT.LEFT_TO_RIGHT;
+ }
+ }
+ }
+
+ return SWT.NONE;
+ }
+
+ /**
+ * Return an array of all bundles contained in this workbench.
+ *
+ * @return an array of bundles in the workbench or an empty array if none
+ * @since 3.0
+ */
+ public Bundle[] getBundles() {
+ return bundleContext == null ? new Bundle[0] : bundleContext
+ .getBundles();
+ }
+
+ /**
+ * Returns the bundle context associated with the workbench plug-in.
+ *
+ * @return the bundle context
+ * @since 3.1
+ */
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
+
+ /**
+ * Returns the org.eclipse.e4.ui.model.application name.
+ * <p>
+ * Note this is never shown to the user. It is used to initialize the SWT
+ * Display. On Motif, for example, this can be used to set the name used for
+ * resource lookup.
+ * </p>
+ *
+ * @return the org.eclipse.e4.ui.model.application name, or <code>null</code>
+ * @see org.eclipse.swt.widgets.Display#setAppName
+ * @since 3.0
+ */
+ public String getAppName() {
+ return getProductInfo().getAppName();
+ }
+
+ /**
+ * Returns the name of the product.
+ *
+ * @return the product name, or <code>null</code> if none
+ * @since 3.0
+ */
+ public String getProductName() {
+ return getProductInfo().getProductName();
+ }
+
+ /**
+ * Returns the image descriptors for the window image to use for this
+ * product.
+ *
+ * @return an array of the image descriptors for the window image, or
+ * <code>null</code> if none
+ * @since 3.0
+ */
+ public ImageDescriptor[] getWindowImages() {
+ return getProductInfo().getWindowImages();
+ }
+
+ /**
+ * Returns an instance that describes this plugin's product (formerly
+ * "primary plugin").
+ *
+ * @return ProductInfo the product info for the receiver
+ */
+ private ProductInfo getProductInfo() {
+ if (productInfo == null) {
+ productInfo = new ProductInfo(Platform.getProduct());
+ }
+ return productInfo;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+ * )
+ */
+ public void stop(BundleContext context) throws Exception {
+ if (bundleListener != null) {
+ context.removeBundleListener(bundleListener);
+ bundleListener = null;
+ }
+ // TODO normally super.stop(*) would be the last statement in this
+ // method
+ super.stop(context);
+ }
+
+ /**
+ * Return the new wizard registry.
+ *
+ * @return the new wizard registry
+ * @since 3.1
+ */
+ public IWizardRegistry getNewWizardRegistry() {
+ return (IWizardRegistry) e4Context.get(NewWizardRegistry.class
+ .getName());
+ }
+
+ /**
+ * Return the import wizard registry.
+ *
+ * @return the import wizard registry
+ * @since 3.1
+ */
+ public IWizardRegistry getImportWizardRegistry() {
+ return (IWizardRegistry) e4Context.get(ImportWizardRegistry.class
+ .getName());
+ }
+
+ /**
+ * Return the export wizard registry.
+ *
+ * @return the export wizard registry
+ * @since 3.1
+ */
+ public IWizardRegistry getExportWizardRegistry() {
+ return (IWizardRegistry) e4Context.get(ExportWizardRegistry.class
+ .getName());
+ }
+
+ /**
+ * FOR INTERNAL WORKBENCH USE ONLY.
+ *
+ * Returns the path to a location in the file system that can be used to
+ * persist/restore state between workbench invocations. If the location did
+ * not exist prior to this call it will be created. Returns
+ * <code>null</code> if no such location is available.
+ *
+ * @return path to a location in the file system where this plug-in can
+ * persist data between sessions, or <code>null</code> if no such
+ * location is available.
+ * @since 3.1
+ */
+ public IPath getDataLocation() {
+ try {
+ return getStateLocation();
+ } catch (IllegalStateException e) {
+ // This occurs if -data=@none is explicitly specified, so ignore
+ // this silently.
+ // Is this OK? See bug 85071.
+ return null;
+ }
+ }
+
+ /* package */void addBundleListener(BundleListener bundleListener) {
+ bundleContext.addBundleListener(bundleListener);
+ }
+
+ /* package */void removeBundleListener(BundleListener bundleListener) {
+ bundleContext.removeBundleListener(bundleListener);
+ }
+
+ /* package */int getBundleCount() {
+ return bundleContext.getBundles().length;
+ }
+
+ /* package */OutputStream getSplashStream() {
+ // assumes the output stream is available as a service
+ // see EclipseStarter.publishSplashScreen
+ ServiceReference[] ref;
+ try {
+ ref = bundleContext.getServiceReferences(OutputStream.class
+ .getName(), null);
+ } catch (InvalidSyntaxException e) {
+ return null;
+ }
+ if (ref == null) {
+ return null;
+ }
+ for (int i = 0; i < ref.length; i++) {
+ String name = (String) ref[i].getProperty("name"); //$NON-NLS-1$
+ if (name != null && name.equals("splashstream")) { //$NON-NLS-1$
+ Object result = bundleContext.getService(ref[i]);
+ bundleContext.ungetService(ref[i]);
+ return (OutputStream) result;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return
+ */
+ private BundleListener getBundleListener() {
+ if (bundleListener == null) {
+ bundleListener = new SynchronousBundleListener() {
+ public void bundleChanged(BundleEvent event) {
+ WorkbenchPlugin.this.bundleChanged(event);
+ }
+ };
+ }
+ return bundleListener;
+ }
+
+ private void bundleChanged(BundleEvent event) {
+ // a bundle in the STARTING state generates 2 events, LAZY_ACTIVATION
+ // when it enters STARTING and STARTING when it exists STARTING :-)
+ synchronized (startingBundles) {
+ switch (event.getType()) {
+ case BundleEvent.STARTING:
+ startingBundles.add(event.getBundle());
+ break;
+ case BundleEvent.STARTED:
+ case BundleEvent.STOPPED:
+ startingBundles.remove(event.getBundle());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ public boolean isStarting(Bundle bundle) {
+ synchronized (startingBundles) {
+ return startingBundles.contains(bundle);
+ }
+ }
+
+ /**
+ * Return whether or not the OSGi framework has specified the handle of a
+ * splash shell.
+ *
+ * @return whether or not the OSGi framework has specified the handle of a
+ * splash shell
+ * @since 3.4
+ */
+ public static boolean isSplashHandleSpecified() {
+ return System.getProperty(PROP_SPLASH_HANDLE) != null;
+ }
+
+ /**
+ * Get the splash shell for this workbench instance, if any. This will find
+ * the splash created by the launcher (native) code and wrap it in a SWT
+ * shell. This may have the side effect of setting data on the provided
+ * {@link Display}.
+ *
+ * @param display
+ * the display to parent the shell on
+ *
+ * @return the splash shell or <code>null</code>
+ * @throws InvocationTargetException
+ * @throws IllegalAccessException
+ * @throws IllegalArgumentException
+ * @throws NumberFormatException
+ * @see Display#setData(String, Object)
+ * @since 3.4
+ */
+ public static Shell getSplashShell(Display display)
+ throws NumberFormatException, IllegalArgumentException,
+ IllegalAccessException, InvocationTargetException {
+ Shell splashShell = (Shell) display.getData(DATA_SPLASH_SHELL);
+ if (splashShell != null)
+ return splashShell;
+
+ String splashHandle = System.getProperty(PROP_SPLASH_HANDLE);
+ if (splashHandle == null) {
+ return null;
+ }
+
+ // look for the 32 bit internal_new shell method
+ try {
+ Method method = Shell.class.getMethod(
+ "internal_new", new Class[] { Display.class, int.class }); //$NON-NLS-1$
+ // we're on a 32 bit platform so invoke it with splash
+ // handle as an int
+ splashShell = (Shell) method.invoke(null, new Object[] { display,
+ new Integer(splashHandle) });
+ } catch (NoSuchMethodException e) {
+ // look for the 64 bit internal_new shell method
+ try {
+ Method method = Shell.class
+ .getMethod(
+ "internal_new", new Class[] { Display.class, long.class }); //$NON-NLS-1$
+
+ // we're on a 64 bit platform so invoke it with a long
+ splashShell = (Shell) method.invoke(null, new Object[] {
+ display, new Long(splashHandle) });
+ } catch (NoSuchMethodException e2) {
+ // cant find either method - don't do anything.
+ }
+ }
+
+ display.setData(DATA_SPLASH_SHELL, splashShell);
+ return splashShell;
+ }
+
+ /**
+ * Removes any splash shell data set on the provided display and disposes
+ * the shell if necessary.
+ *
+ * @param display
+ * the display to parent the shell on
+ * @since 3.4
+ */
+ public static void unsetSplashShell(Display display) {
+ Shell splashShell = (Shell) display.getData(DATA_SPLASH_SHELL);
+ if (splashShell != null) {
+ if (!splashShell.isDisposed())
+ splashShell.dispose();
+ display.setData(DATA_SPLASH_SHELL, null);
+ }
+
+ }
+
+ public void initializeContext(IEclipseContext context) {
+ e4Context = context;
+ context.set(ActionSetRegistry.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ if (actionSetRegistry == null) {
+ actionSetRegistry = new ActionSetRegistry();
+ }
+ return actionSetRegistry;
+ }
+ });
+ context.set(IDecoratorManager.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ if (decoratorManager == null) {
+ decoratorManager = new DecoratorManager();
+ }
+ return decoratorManager;
+ }
+ });
+ context.set(IEditorRegistry.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ if (editorRegistry == null) {
+ editorRegistry = new EditorRegistry();
+ }
+ return editorRegistry;
+ }
+ });
+ context.set(ExportWizardRegistry.class.getName(),
+ new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context,
+ Object[] arguments) {
+ return ExportWizardRegistry.getInstance();
+ }
+ });
+ context.set(ImportWizardRegistry.class.getName(),
+ new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context,
+ Object[] arguments) {
+ return ImportWizardRegistry.getInstance();
+ }
+ });
+ context.set(IIntroRegistry.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ if (introRegistry == null) {
+ introRegistry = new IntroRegistry();
+ }
+ return introRegistry;
+ }
+ });
+ context.set(NewWizardRegistry.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ return NewWizardRegistry.getInstance();
+ }
+ });
+ context.set(IWorkbenchOperationSupport.class.getName(),
+ new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context,
+ Object[] arguments) {
+ if (operationSupport == null) {
+ operationSupport = new WorkbenchOperationSupport();
+ }
+ return operationSupport;
+ }
+ });
+ context.set(IPerspectiveRegistry.class.getName(),
+ new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context,
+ Object[] arguments) {
+ return getPerspectiveRegistry();
+ }
+ });
+ context.set(PreferenceManager.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ if (preferenceManager == null) {
+ preferenceManager = new WorkbenchPreferenceManager(
+ PREFERENCE_PAGE_CATEGORY_SEPARATOR);
+
+ // Get the pages from the registry
+ PreferencePageRegistryReader registryReader = new PreferencePageRegistryReader(
+ getWorkbench());
+ registryReader.loadFromRegistry(Platform
+ .getExtensionRegistry());
+ preferenceManager.addPages(registryReader
+ .getTopLevelNodes());
+
+ }
+ return preferenceManager;
+ }
+ });
+ context.set(ISharedImages.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ if (sharedImages == null) {
+ sharedImages = new SharedImages();
+ }
+ return sharedImages;
+ }
+ });
+
+ context.set(IThemeRegistry.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ if (themeRegistry == null) {
+ themeRegistry = new ThemeRegistry();
+ ThemeRegistryReader reader = new ThemeRegistryReader();
+ reader.readThemes(Platform.getExtensionRegistry(),
+ themeRegistry);
+ }
+ return themeRegistry;
+ }
+ });
+ context.set(IViewRegistry.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ if (viewRegistry == null) {
+ viewRegistry = new ViewRegistry();
+ }
+ return viewRegistry;
+ }
+ });
+ context.set(IWorkingSetManager.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ if (workingSetManager == null) {
+ workingSetManager = new WorkingSetManager(bundleContext);
+ workingSetManager.restoreState();
+ }
+ return workingSetManager;
+ }
+ });
+ context.set(WorkingSetRegistry.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ if (workingSetRegistry == null) {
+ workingSetRegistry = new WorkingSetRegistry();
+ workingSetRegistry.load();
+ }
+ return workingSetRegistry;
+ }
+ });
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchWindow.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchWindow.java
new file mode 100644
index 0000000..b20df89
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/WorkbenchWindow.java
@@ -0,0 +1,2510 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ui.internal;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IProduct;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.ContextFunction;
+import org.eclipse.e4.extensions.ExtensionUtils;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.MApplicationFactory;
+import org.eclipse.e4.ui.model.application.MMenu;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MWindow;
+import org.eclipse.e4.ui.services.EContextService;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.e4.workbench.ui.api.LegacySelectionService;
+import org.eclipse.e4.workbench.ui.internal.Activator;
+import org.eclipse.e4.workbench.ui.internal.Policy;
+import org.eclipse.e4.workbench.ui.menus.ActionSet;
+import org.eclipse.e4.workbench.ui.menus.MenuHelper;
+import org.eclipse.jface.action.ContributionManager;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.ICoolBarManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.StatusLineManager;
+import org.eclipse.jface.commands.ActionHandler;
+import org.eclipse.jface.internal.provisional.action.ICoolBarManager2;
+import org.eclipse.jface.internal.provisional.action.IToolBarManager2;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.TextProcessor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.custom.CBanner;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.CoolBar;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.ActiveShellExpression;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPageListener;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.IPersistable;
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.ISelectionService;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.LegacyHandlerService;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.application.ActionBarAdvisor;
+import org.eclipse.ui.application.WorkbenchAdvisor;
+import org.eclipse.ui.application.WorkbenchWindowAdvisor;
+import org.eclipse.ui.branding.IProductConstants;
+import org.eclipse.ui.commands.ICommandService;
+import org.eclipse.ui.contexts.IContextService;
+import org.eclipse.ui.contexts.IWorkbenchContextSupport;
+import org.eclipse.ui.handlers.IHandlerActivation;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.internal.StartupThreading.StartupRunnable;
+import org.eclipse.ui.internal.actions.CommandAction;
+import org.eclipse.ui.internal.dialogs.CustomizePerspectiveDialog;
+import org.eclipse.ui.internal.dnd.DragUtil;
+import org.eclipse.ui.internal.dnd.SwtUtil;
+import org.eclipse.ui.internal.expressions.WorkbenchWindowExpression;
+import org.eclipse.ui.internal.handlers.ActionCommandMappingService;
+import org.eclipse.ui.internal.handlers.ActionDelegateHandlerProxy;
+import org.eclipse.ui.internal.handlers.IActionCommandMappingService;
+import org.eclipse.ui.internal.layout.ITrimManager;
+import org.eclipse.ui.internal.layout.IWindowTrim;
+import org.eclipse.ui.internal.layout.TrimLayout;
+import org.eclipse.ui.internal.menus.IActionSetsListener;
+import org.eclipse.ui.internal.menus.LegacyActionPersistence;
+import org.eclipse.ui.internal.menus.TrimBarManager2;
+import org.eclipse.ui.internal.menus.TrimContributionManager;
+import org.eclipse.ui.internal.misc.UIListenerLogging;
+import org.eclipse.ui.internal.misc.UIStats;
+import org.eclipse.ui.internal.presentations.DefaultActionBarPresentationFactory;
+import org.eclipse.ui.internal.progress.ProgressRegion;
+import org.eclipse.ui.internal.provisional.application.IActionBarConfigurer2;
+import org.eclipse.ui.internal.provisional.presentations.IActionBarPresentationFactory;
+import org.eclipse.ui.internal.registry.ActionSetRegistry;
+import org.eclipse.ui.internal.registry.IActionSetDescriptor;
+import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
+import org.eclipse.ui.internal.registry.UIExtensionTracker;
+import org.eclipse.ui.internal.services.IServiceLocatorCreator;
+import org.eclipse.ui.internal.services.IWorkbenchLocationService;
+import org.eclipse.ui.internal.services.ServiceLocator;
+import org.eclipse.ui.internal.services.WorkbenchLocationService;
+import org.eclipse.ui.internal.tweaklets.Tweaklets;
+import org.eclipse.ui.internal.tweaklets.WorkbenchImplementation;
+import org.eclipse.ui.menus.IMenuService;
+import org.eclipse.ui.presentations.AbstractPresentationFactory;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.services.IServiceScopes;
+
+/**
+ * A window within the workbench.
+ */
+public class WorkbenchWindow extends ApplicationWindow implements
+ IWorkbenchWindow {
+
+ private WorkbenchWindowAdvisor windowAdvisor;
+
+ private ActionBarAdvisor actionBarAdvisor;
+
+ private int number;
+
+ private PageList pageList = new PageList();
+
+ private PageListenerList pageListeners = new PageListenerList();
+
+ private PerspectiveListenerList perspectiveListeners = new PerspectiveListenerList();
+
+ private WWinPartService partService = new WWinPartService(this);
+
+ private WWinActionBars actionBars;
+
+ private boolean closing = false;
+
+ private boolean shellActivated = false;
+
+ private FastViewBar fastViewBar;
+
+ private PerspectiveSwitcher perspectiveSwitcher = null;
+
+ private TrimLayout defaultLayout;
+
+ ProgressRegion progressRegion = null;
+
+ // Legacy (3.2) contribution handling
+ private TrimBarManager2 trimMgr2 = null;
+
+ // 3.3 Trim Contribution handling
+ private TrimContributionManager trimContributionMgr = null;
+
+ /**
+ * The map of services maintained by the workbench window. These services
+ * are initialized during workbench window during the
+ * {@link #configureShell(Shell)}.
+ */
+ private final ServiceLocator serviceLocator;
+
+ private CBanner topBar;
+
+ // Previous shell size. Used to prevent the CBanner from triggering
+ // redundant layouts
+ // private Point lastShellSize = new Point(0, 0);
+
+ /**
+ * The composite under which workbench pages create their controls.
+ *
+ * @since 3.0
+ */
+ private Composite pageComposite;
+
+ /**
+ * Bit flags indication which submenus (New, Show Views, ...) this window
+ * contains. Initially none.
+ *
+ * @since 3.0
+ */
+ private int submenus = 0x00;
+
+ /**
+ * Object for configuring this workbench window. Lazily initialized to an
+ * instance unique to this window.
+ *
+ * @since 3.0
+ */
+ private WorkbenchWindowConfigurer windowConfigurer = null;
+
+ /**
+ * List of generic property listeners.
+ *
+ * @since 3.3
+ */
+ private ListenerList genericPropertyListeners = new ListenerList();
+
+ static final String TEXT_DELIMITERS = TextProcessor.getDefaultDelimiters()
+ + "-"; //$NON-NLS-1$
+
+ // constants for shortcut bar group ids
+ static final String GRP_PAGES = "pages"; //$NON-NLS-1$
+
+ static final String GRP_PERSPECTIVES = "perspectives"; //$NON-NLS-1$
+
+ static final String GRP_FAST_VIEWS = "fastViews"; //$NON-NLS-1$
+
+ // static fields for inner classes.
+ static final int VGAP = 0;
+
+ static final int CLIENT_INSET = 3;
+
+ static final int BAR_SIZE = 23;
+
+ /**
+ * Coolbar visibility change property.
+ *
+ * @since 3.3
+ */
+ public static final String PROP_COOLBAR_VISIBLE = "coolbarVisible"; //$NON-NLS-1$
+
+ /**
+ * Perspective bar visibility change property.
+ *
+ * @since 3.3
+ */
+ public static final String PROP_PERSPECTIVEBAR_VISIBLE = "perspectiveBarVisible"; //$NON-NLS-1$
+
+ /**
+ * The status line visibility change property. for internal use only.
+ *
+ * @since 3.4
+ */
+ public static final String PROP_STATUS_LINE_VISIBLE = "statusLineVisible"; //$NON-NLS-1$
+
+ /**
+ * Constant (bit mask) indicating which the Show View submenu is probably
+ * present somewhere in this window.
+ *
+ * @see #addSubmenu
+ * @since 3.0
+ */
+ public static final int SHOW_VIEW_SUBMENU = 0x01;
+
+ /**
+ * Constant (bit mask) indicating which the Open Perspective submenu is
+ * probably present somewhere in this window.
+ *
+ * @see #addSubmenu
+ * @since 3.0
+ */
+ public static final int OPEN_PERSPECTIVE_SUBMENU = 0x02;
+
+ /**
+ * Constant (bit mask) indicating which the New Wizard submenu is probably
+ * present somewhere in this window.
+ *
+ * @see #addSubmenu
+ * @since 3.0
+ */
+ public static final int NEW_WIZARD_SUBMENU = 0x04;
+
+ /**
+ * Remembers that this window contains the given submenu.
+ *
+ * @param type
+ * the type of submenu, one of: {@link #NEW_WIZARD_SUBMENU
+ * NEW_WIZARD_SUBMENU}, {@link #OPEN_PERSPECTIVE_SUBMENU
+ * OPEN_PERSPECTIVE_SUBMENU}, {@link #SHOW_VIEW_SUBMENU
+ * SHOW_VIEW_SUBMENU}
+ * @see #containsSubmenu
+ * @since 3.0
+ */
+ public void addSubmenu(int type) {
+ submenus |= type;
+ }
+
+ /**
+ * Checks to see if this window contains the given type of submenu.
+ *
+ * @param type
+ * the type of submenu, one of: {@link #NEW_WIZARD_SUBMENU
+ * NEW_WIZARD_SUBMENU}, {@link #OPEN_PERSPECTIVE_SUBMENU
+ * OPEN_PERSPECTIVE_SUBMENU}, {@link #SHOW_VIEW_SUBMENU
+ * SHOW_VIEW_SUBMENU}
+ * @return <code>true</code> if window contains submenu, <code>false</code>
+ * otherwise
+ * @see #addSubmenu
+ * @since 3.0
+ */
+ public boolean containsSubmenu(int type) {
+ return ((submenus & type) != 0);
+ }
+
+ /**
+ * Constant indicating that all the actions bars should be filled.
+ *
+ * @since 3.0
+ */
+ private static final int FILL_ALL_ACTION_BARS = ActionBarAdvisor.FILL_MENU_BAR
+ | ActionBarAdvisor.FILL_COOL_BAR
+ | ActionBarAdvisor.FILL_STATUS_LINE;
+
+ /**
+ * Creates and initializes a new workbench window.
+ *
+ * @param number
+ * the number for the window
+ */
+ public WorkbenchWindow(int number) {
+ super(null);
+ this.number = number;
+
+ // Make sure there is a workbench. This call will throw
+ // an exception if workbench not created yet.
+ final Workbench workbench = (Workbench) PlatformUI.getWorkbench();
+ createE4Model(workbench);
+ e4Context = e4Window.getContext();
+
+ IServiceLocatorCreator slc = (IServiceLocatorCreator) workbench
+ .getService(IServiceLocatorCreator.class);
+ this.serviceLocator = (ServiceLocator) slc.createServiceLocator(
+ workbench, null, new IDisposable() {
+ public void dispose() {
+ final Shell shell = getShell();
+ if (shell != null && !shell.isDisposed()) {
+ close();
+ }
+ }
+ });
+ serviceLocator.setContext(e4Context);
+
+ initializeDefaultServices();
+
+ // Add contribution managers that are exposed to other plugins.
+ addMenuBar();
+ addCoolBar(SWT.NONE); // style is unused
+ addStatusLine();
+
+ fireWindowOpening();
+
+ // set the shell style
+ setShellStyle(getWindowConfigurer().getShellStyle());
+
+ // Fill the action bars
+ fillActionBars(FILL_ALL_ACTION_BARS);
+ MenuHelper.loadMainMenu(e4Window.getContext(), e4Window.getMainMenu(),
+ getMenuBarManager());
+ e4ActionSets = MenuHelper.processActionSets(e4Window.getContext(),
+ e4Window.getMainMenu());
+ }
+
+ /**
+ * @param workbench
+ */
+ private void createE4Model(Workbench workbench) {
+ e4Window = MApplicationFactory.eINSTANCE.createWindow();
+ MApplication app = (MApplication) workbench
+ .getService(MApplication.class);
+ app.getChildren().add(e4Window);
+ e4Window.setWidth(1024);
+ e4Window.setHeight(768);
+ e4Window.setName("MyWindow"); //$NON-NLS-1$
+ initializeWindowImages(e4Window);
+ final MMenu mainMenu = MApplicationFactory.eINSTANCE.createMenu();
+ mainMenu.setId(MenuHelper.MAIN_MENU_ID);
+ e4Window.setMainMenu(mainMenu);
+ }
+
+ /**
+ * Set the images corresponding to the workbench window
+ */
+ private void initializeWindowImages(MWindow window) {
+ IProduct product = Platform.getProduct();
+ String images = product == null ? null : product
+ .getProperty(IProductConstants.WINDOW_IMAGES);
+ if (images == null) {
+ // backwards compatibility
+ images = product == null ? null : product
+ .getProperty(IProductConstants.WINDOW_IMAGE);
+ }
+ if (images == null)
+ return;
+ // for now just take the first image - the model currently only accepts
+ // one image
+ if (images.indexOf(',') > 0)
+ images = images.substring(0, images.indexOf(','));
+ URL iconURL = FileLocator.find(product.getDefiningBundle(), new Path(
+ images), null);
+ if (iconURL != null)
+ e4Window.setIconURI(iconURL.toExternalForm());
+ }
+
+ /**
+ * Return the style bits for the shortcut bar.
+ *
+ * @return int
+ */
+ protected int perspectiveBarStyle() {
+ return SWT.FLAT | SWT.WRAP | SWT.RIGHT | SWT.HORIZONTAL;
+ }
+
+ private TrimDropTarget trimDropTarget;
+
+ private boolean coolBarVisible = true;
+
+ private boolean perspectiveBarVisible = true;
+
+ private boolean fastViewBarVisible = true;
+
+ private boolean statusLineVisible = true;
+
+ private IWindowTrim statusLineTrim = null;
+
+ /**
+ * The handlers for global actions that were last submitted to the workbench
+ * command support. This is a map of command identifiers to
+ * <code>ActionHandler</code>. This map is never <code>null</code>, and is
+ * never empty as long as at least one global action has been registered.
+ */
+ private Map globalActionHandlersByCommandId = new HashMap();
+
+ /**
+ * The list of handler submissions submitted to the workbench command
+ * support. This list may be empty, but it is never <code>null</code>.
+ */
+ private List handlerActivations = new ArrayList();
+
+ /**
+ * The number of large updates that are currently going on. If this is
+ * number is greater than zero, then UI updateActionBars is a no-op.
+ *
+ * @since 3.1
+ */
+ private int largeUpdates = 0;
+
+ private IExtensionTracker tracker;
+
+ void registerGlobalAction(IAction globalAction) {
+ String commandId = globalAction.getActionDefinitionId();
+
+ if (commandId != null) {
+ final Object value = globalActionHandlersByCommandId.get(commandId);
+ if (value instanceof ActionHandler) {
+ // This handler is about to get clobbered, so dispose it.
+ final ActionHandler handler = (ActionHandler) value;
+ handler.dispose();
+ }
+
+ if (globalAction instanceof CommandAction) {
+ final String actionId = globalAction.getId();
+ if (actionId != null) {
+ final IActionCommandMappingService mappingService = (IActionCommandMappingService) serviceLocator
+ .getService(IActionCommandMappingService.class);
+ mappingService.map(actionId, commandId);
+ }
+ } else {
+ globalActionHandlersByCommandId.put(commandId,
+ new ActionHandler(globalAction));
+ }
+ }
+
+ submitGlobalActions();
+ }
+
+ /**
+ * <p>
+ * Submits the action handlers for action set actions and global actions.
+ * Global actions are given priority, so that if a global action and an
+ * action set action both handle the same command, the global action is
+ * given priority.
+ * </p>
+ * <p>
+ * These submissions are submitted as <code>Priority.LEGACY</code>, which
+ * means that they are the lowest priority. This means that if a higher
+ * priority submission handles the same command under the same conditions,
+ * that that submission will become the handler.
+ * </p>
+ */
+ void submitGlobalActions() {
+ final IHandlerService handlerService = (IHandlerService) serviceLocator
+ .getService(IHandlerService.class);
+
+ /*
+ * Mash the action sets and global actions together, with global actions
+ * taking priority.
+ */
+ Map handlersByCommandId = new HashMap();
+ handlersByCommandId.putAll(globalActionHandlersByCommandId);
+
+ List newHandlers = new ArrayList(handlersByCommandId.size());
+
+ Iterator existingIter = handlerActivations.iterator();
+ while (existingIter.hasNext()) {
+ IHandlerActivation next = (IHandlerActivation) existingIter.next();
+
+ String cmdId = next.getCommandId();
+
+ Object handler = handlersByCommandId.get(cmdId);
+ if (handler == next.getHandler()) {
+ handlersByCommandId.remove(cmdId);
+ newHandlers.add(next);
+ } else {
+ handlerService.deactivateHandler(next);
+ }
+ }
+
+ final Shell shell = getShell();
+ if (shell != null) {
+ final Expression expression = new ActiveShellExpression(shell);
+ for (Iterator iterator = handlersByCommandId.entrySet().iterator(); iterator
+ .hasNext();) {
+ Map.Entry entry = (Map.Entry) iterator.next();
+ String commandId = (String) entry.getKey();
+ IHandler handler = (IHandler) entry.getValue();
+ newHandlers.add(handlerService.activateHandler(commandId,
+ handler, expression));
+ }
+ }
+
+ handlerActivations = newHandlers;
+ }
+
+ /**
+ * Add a generic property listener.
+ *
+ * @param listener
+ * the listener to add
+ * @since 3.3
+ */
+ public void addPropertyChangeListener(IPropertyChangeListener listener) {
+ genericPropertyListeners.add(listener);
+ }
+
+ /**
+ * Removes a generic property listener.
+ *
+ * @param listener
+ * the listener to remove
+ * @since 3.3
+ */
+ public void removePropertyChangeListener(IPropertyChangeListener listener) {
+ genericPropertyListeners.remove(listener);
+ }
+
+ /*
+ * Adds an listener to the part service.
+ */
+ public void addPageListener(IPageListener l) {
+ pageListeners.addPageListener(l);
+ }
+
+ /**
+ * @see org.eclipse.ui.IPageService
+ */
+ public void addPerspectiveListener(org.eclipse.ui.IPerspectiveListener l) {
+ perspectiveListeners.addPerspectiveListener(l);
+ }
+
+ /**
+ * Configures this window to have a perspecive bar. Does nothing if it
+ * already has one.
+ */
+ protected void addPerspectiveBar(int style) {
+ Assert.isTrue(perspectiveSwitcher == null);
+ perspectiveSwitcher = new PerspectiveSwitcher(this, topBar, style);
+ }
+
+ /**
+ * Close the window.
+ *
+ * Assumes that busy cursor is active.
+ */
+ private boolean busyClose() {
+ // Whether the window was actually closed or not
+ boolean windowClosed = false;
+
+ // Setup internal flags to indicate window is in
+ // progress of closing and no update should be done.
+ closing = true;
+
+ try {
+ // Only do the check if it is OK to close if we are not closing
+ // via the workbench as the workbench will check this itself.
+ Workbench workbench = getWorkbenchImpl();
+ int count = workbench.getWorkbenchWindowCount();
+ // also check for starting - if the first window dies on startup
+ // then we'll need to open a default window.
+ if (!workbench.isStarting()
+ && !workbench.isClosing()
+ && count <= 1
+ && workbench.getWorkbenchConfigurer()
+ .getExitOnLastWindowClose()) {
+ windowClosed = workbench.close();
+ } else {
+ if (okToClose()) {
+ windowClosed = hardClose();
+ }
+ }
+ } finally {
+ if (!windowClosed) {
+ // Reset the internal flags if window was not closed.
+ closing = false;
+ }
+ }
+
+ if (windowClosed && tracker != null) {
+ tracker.close();
+ }
+
+ return windowClosed;
+ }
+
+ /**
+ * Opens a new page. Assumes that busy cursor is active.
+ * <p>
+ * <b>Note:</b> Since release 2.0, a window is limited to contain at most
+ * one page. If a page exist in the window when this method is used, then
+ * another window is created for the new page. Callers are strongly
+ * recommended to use the <code>IWorkbench.openPerspective</code> APIs to
+ * programmatically show a perspective.
+ * </p>
+ */
+ protected IWorkbenchPage busyOpenPage(String perspID, IAdaptable input)
+ throws WorkbenchException {
+ IWorkbenchPage newPage = null;
+
+ if (pageList.isEmpty()) {
+ newPage = ((WorkbenchImplementation) Tweaklets
+ .get(WorkbenchImplementation.KEY)).createWorkbenchPage(
+ this, perspID, input);
+ pageList.add(newPage);
+ firePageOpened(newPage);
+ setActivePage(newPage);
+ } else {
+ IWorkbenchWindow window = getWorkbench().openWorkbenchWindow(
+ perspID, input);
+ newPage = window.getActivePage();
+ }
+
+ return newPage;
+ }
+
+ /**
+ * @see Window
+ */
+ public int open() {
+ fireWindowCreated();
+ // getWindowAdvisor().openIntro();
+ // int result = super.open();
+ org.eclipse.e4.workbench.ui.internal.Workbench e4Workbench = (org.eclipse.e4.workbench.ui.internal.Workbench) e4Window
+ .getContext().get(
+ org.eclipse.e4.workbench.ui.internal.Workbench.class
+ .getName());
+ e4Workbench.createGUI(e4Window);
+
+ // It's time for a layout ... to insure that if TrimLayout
+ // is in play, it updates all of the trim it's responsible
+ // for. We have to do this before updating in order to get
+ // the PerspectiveBar management correct...see defect 137334
+ if (getShell().getChildren()[0] instanceof Composite) {
+ try {
+ Field field = Window.class.getDeclaredField("contents"); //$NON-NLS-1$
+ field.setAccessible(true);
+ field.set(this, getShell().getChildren()[0]);
+ } catch (SecurityException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (NoSuchFieldException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IllegalArgumentException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ e4Context.set(ISources.ACTIVE_WORKBENCH_WINDOW_SHELL_NAME, getShell());
+ // createStatusLine(getShell());
+ getShell().layout();
+ getShell().addShellListener(getShellListener());
+ getShell().setData(this);
+ String title = getWindowConfigurer().basicGetTitle();
+ if (title != null) {
+ getShell().setText(TextProcessor.process(title, TEXT_DELIMITERS));
+ }
+
+ submitGlobalActions();
+
+ fireWindowOpened();
+ if (perspectiveSwitcher != null) {
+ perspectiveSwitcher.updatePerspectiveBar();
+ perspectiveSwitcher.updateBarParent();
+ }
+
+ return OK;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.window.Window#getShell()
+ */
+ @Override
+ public Shell getShell() {
+ return (Shell) e4Window.getWidget();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on Window.
+ */
+ protected boolean canHandleShellCloseEvent() {
+ if (!super.canHandleShellCloseEvent()) {
+ return false;
+ }
+ // let the advisor or other interested parties
+ // veto the user's explicit request to close the window
+ return fireWindowShellClosing();
+ }
+
+ /**
+ * @see IWorkbenchWindow
+ */
+ public boolean close() {
+ final boolean[] ret = new boolean[1];
+ BusyIndicator.showWhile(null, new Runnable() {
+ public void run() {
+ ret[0] = busyClose();
+ }
+ });
+ return ret[0];
+ }
+
+ protected boolean isClosing() {
+ return closing || getWorkbenchImpl().isClosing();
+ }
+
+ /**
+ * Return whether or not the coolbar layout is locked.
+ */
+ protected boolean isCoolBarLocked() {
+ ICoolBarManager cbm = getCoolBarManager2();
+ return cbm != null && cbm.getLockLayout();
+ }
+
+ /**
+ * Close all of the pages.
+ */
+ private void closeAllPages() {
+ // Deactivate active page.
+ setActivePage(null);
+
+ // Clone and deref all so that calls to getPages() returns
+ // empty list (if call by pageClosed event handlers)
+ PageList oldList = pageList;
+ pageList = new PageList();
+
+ // Close all.
+ Iterator itr = oldList.iterator();
+ while (itr.hasNext()) {
+ WorkbenchPage page = (WorkbenchPage) itr.next();
+ firePageClosed(page);
+ page.dispose();
+ }
+ }
+
+ /**
+ * Save and close all of the pages.
+ */
+ public void closeAllPages(boolean save) {
+ if (save) {
+ boolean ret = saveAllPages(true);
+ if (!ret) {
+ return;
+ }
+ }
+ closeAllPages();
+ }
+
+ /**
+ * closePerspective method comment.
+ */
+ protected boolean closePage(IWorkbenchPage in, boolean save) {
+
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets
+ * .Shell)
+ */
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ }
+
+ /* package */ShellPool getDetachedWindowPool() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.window.ApplicationWindow#createTrimWidgets(org.eclipse
+ * .swt.widgets.Shell)
+ */
+ protected void createTrimWidgets(Shell shell) {
+ // do nothing -- trim widgets are created in createDefaultContents
+ }
+
+ /**
+ * Creates and remembers the client composite, under which workbench pages
+ * create their controls.
+ *
+ * @since 3.0
+ */
+ protected Composite createPageComposite(Composite parent) {
+ pageComposite = new Composite(parent, SWT.NONE);
+ // use a StackLayout instead of a FillLayout (see bug 81460 [Workbench]
+ // (regression) Close all perspectives, open Java perspective, layout
+ // wrong)
+ pageComposite.setLayout(new StackLayout());
+ return pageComposite;
+ }
+
+ /**
+ * Creates the contents of the workbench window, including trim controls and
+ * the client composite. This MUST create the client composite via a call to
+ * <code>createClientComposite</code>.
+ *
+ * @since 3.0
+ */
+ protected Control createContents(Composite parent) {
+ return pageComposite;
+ }
+
+ /**
+ * If the perspective bar is drawn on the top right corner of the window,
+ * then this method changes its appearance from curved to square. This
+ * should have its own preference, but for now it piggy-backs on the
+ * SHOW_TRADITIONAL_STYLE_TABS preference.
+ *
+ * @param square
+ * true for a square banner and false otherwise
+ */
+ public void setBannerCurve(boolean square) {
+ }
+
+ /**
+ * Creates the default contents and layout of the shell.
+ *
+ * @param shell
+ * the shell
+ */
+ protected void createDefaultContents(final Shell shell) {
+ defaultLayout = new TrimLayout();
+ shell.setLayout(defaultLayout);
+
+ // System.err.println(defaultLayout.displayTrim());
+ }
+
+ /**
+ * <p>
+ * Returns a new menu manager for this workbench window. This menu manager
+ * will just be a proxy to the new command-based menu service.
+ * </p>
+ * <p>
+ * Subclasses may override this method to customize the menu manager.
+ * </p>
+ *
+ * @return a menu manager for this workbench window; never <code>null</code>
+ * .
+ */
+ protected MenuManager createMenuManager() {
+ MenuManager manager = super.createMenuManager();
+ return manager;
+ }
+
+ /**
+ * Set the perspective bar location
+ *
+ * @param location
+ * the location to place the bar
+ */
+ public void setPerspectiveBarLocation(String location) {
+ }
+
+ /**
+ * Notifies interested parties (namely the advisor) that the window is about
+ * to be opened.
+ *
+ * @since 3.1
+ */
+ private void fireWindowOpening() {
+ // let the org.eclipse.e4.ui.model.application do further configuration
+ getWindowAdvisor().preWindowOpen();
+ }
+
+ /**
+ * Notifies interested parties (namely the advisor) that the window has been
+ * restored from a previously saved state.
+ *
+ * @throws WorkbenchException
+ * passed through from the advisor
+ * @since 3.1
+ */
+ void fireWindowRestored() throws WorkbenchException {
+ StartupThreading.runWithWorkbenchExceptions(new StartupRunnable() {
+ public void runWithException() throws Throwable {
+ getWindowAdvisor().postWindowRestore();
+ }
+ });
+ }
+
+ /**
+ * Notifies interested parties (namely the advisor) that the window has been
+ * created.
+ *
+ * @since 3.1
+ */
+ private void fireWindowCreated() {
+ getWindowAdvisor().postWindowCreate();
+ }
+
+ /**
+ * Notifies interested parties (namely the advisor and the window listeners)
+ * that the window has been opened.
+ *
+ * @since 3.1
+ */
+ private void fireWindowOpened() {
+ getWorkbenchImpl().fireWindowOpened(this);
+ getWindowAdvisor().postWindowOpen();
+ }
+
+ /**
+ * Notifies interested parties (namely the advisor) that the window's shell
+ * is closing. Allows the close to be vetoed.
+ *
+ * @return <code>true</code> if the close should proceed, <code>false</code>
+ * if it should be canceled
+ * @since 3.1
+ */
+ private boolean fireWindowShellClosing() {
+ return getWindowAdvisor().preWindowShellClose();
+ }
+
+ /**
+ * Notifies interested parties (namely the advisor and the window listeners)
+ * that the window has been closed.
+ *
+ * @since 3.1
+ */
+ private void fireWindowClosed() {
+ // let the org.eclipse.e4.ui.model.application do further
+ // deconfiguration
+ getWindowAdvisor().postWindowClose();
+ getWorkbenchImpl().fireWindowClosed(this);
+ }
+
+ /**
+ * Fires page activated
+ */
+ void firePageActivated(IWorkbenchPage page) {
+ String label = null; // debugging only
+ if (UIStats.isDebugging(UIStats.NOTIFY_PAGE_LISTENERS)) {
+ label = "activated " + page.getLabel(); //$NON-NLS-1$
+ }
+ try {
+ UIStats.start(UIStats.NOTIFY_PAGE_LISTENERS, label);
+ UIListenerLogging.logPageEvent(this, page,
+ UIListenerLogging.WPE_PAGE_ACTIVATED);
+ pageListeners.firePageActivated(page);
+ partService.pageActivated(page);
+ } finally {
+ UIStats.end(UIStats.NOTIFY_PAGE_LISTENERS, page.getLabel(), label);
+ }
+ }
+
+ /**
+ * Fires page closed
+ */
+ private void firePageClosed(IWorkbenchPage page) {
+ String label = null; // debugging only
+ if (UIStats.isDebugging(UIStats.NOTIFY_PAGE_LISTENERS)) {
+ label = "closed " + page.getLabel(); //$NON-NLS-1$
+ }
+ try {
+ UIStats.start(UIStats.NOTIFY_PAGE_LISTENERS, label);
+ UIListenerLogging.logPageEvent(this, page,
+ UIListenerLogging.WPE_PAGE_CLOSED);
+ pageListeners.firePageClosed(page);
+ partService.pageClosed(page);
+ } finally {
+ UIStats.end(UIStats.NOTIFY_PAGE_LISTENERS, page.getLabel(), label);
+ }
+
+ }
+
+ /**
+ * Fires page opened
+ */
+ private void firePageOpened(IWorkbenchPage page) {
+ String label = null; // debugging only
+ if (UIStats.isDebugging(UIStats.NOTIFY_PAGE_LISTENERS)) {
+ label = "opened " + page.getLabel(); //$NON-NLS-1$
+ }
+ try {
+ UIStats.start(UIStats.NOTIFY_PAGE_LISTENERS, label);
+ UIListenerLogging.logPageEvent(this, page,
+ UIListenerLogging.WPE_PAGE_OPENED);
+ pageListeners.firePageOpened(page);
+ partService.pageOpened(page);
+ } finally {
+ UIStats.end(UIStats.NOTIFY_PAGE_LISTENERS, page.getLabel(), label);
+ }
+ }
+
+ /**
+ * Fires perspective activated
+ */
+ void firePerspectiveActivated(IWorkbenchPage page,
+ IPerspectiveDescriptor perspective) {
+ UIListenerLogging.logPerspectiveEvent(this, page, perspective,
+ UIListenerLogging.PLE_PERSP_ACTIVATED);
+ perspectiveListeners.firePerspectiveActivated(page, perspective);
+ }
+
+ /**
+ * Fires perspective deactivated.
+ *
+ * @since 3.2
+ */
+ void firePerspectivePreDeactivate(IWorkbenchPage page,
+ IPerspectiveDescriptor perspective) {
+ UIListenerLogging.logPerspectiveEvent(this, page, perspective,
+ UIListenerLogging.PLE_PERSP_PRE_DEACTIVATE);
+ perspectiveListeners.firePerspectivePreDeactivate(page, perspective);
+ }
+
+ /**
+ * Fires perspective deactivated.
+ *
+ * @since 3.1
+ */
+ void firePerspectiveDeactivated(IWorkbenchPage page,
+ IPerspectiveDescriptor perspective) {
+ UIListenerLogging.logPerspectiveEvent(this, page, perspective,
+ UIListenerLogging.PLE_PERSP_DEACTIVATED);
+ perspectiveListeners.firePerspectiveDeactivated(page, perspective);
+ }
+
+ /**
+ * Fires perspective changed
+ */
+ public void firePerspectiveChanged(IWorkbenchPage page,
+ IPerspectiveDescriptor perspective, String changeId) {
+ // Some callers call this even when there is no active perspective.
+ // Just ignore this case.
+ if (perspective != null) {
+ UIListenerLogging.logPerspectiveChangedEvent(this, page,
+ perspective, null, changeId);
+ perspectiveListeners.firePerspectiveChanged(page, perspective,
+ changeId);
+ }
+ }
+
+ /**
+ * Fires perspective changed for an affected part
+ */
+ public void firePerspectiveChanged(IWorkbenchPage page,
+ IPerspectiveDescriptor perspective,
+ IWorkbenchPartReference partRef, String changeId) {
+ // Some callers call this even when there is no active perspective.
+ // Just ignore this case.
+ if (perspective != null) {
+ UIListenerLogging.logPerspectiveChangedEvent(this, page,
+ perspective, partRef, changeId);
+ perspectiveListeners.firePerspectiveChanged(page, perspective,
+ partRef, changeId);
+ }
+ }
+
+ /**
+ * Fires perspective closed
+ */
+ void firePerspectiveClosed(IWorkbenchPage page,
+ IPerspectiveDescriptor perspective) {
+ UIListenerLogging.logPerspectiveEvent(this, page, perspective,
+ UIListenerLogging.PLE_PERSP_CLOSED);
+ perspectiveListeners.firePerspectiveClosed(page, perspective);
+ }
+
+ /**
+ * Fires perspective opened
+ */
+ void firePerspectiveOpened(IWorkbenchPage page,
+ IPerspectiveDescriptor perspective) {
+ UIListenerLogging.logPerspectiveEvent(this, page, perspective,
+ UIListenerLogging.PLE_PERSP_OPENED);
+ perspectiveListeners.firePerspectiveOpened(page, perspective);
+ }
+
+ /**
+ * Fires perspective saved as.
+ *
+ * @since 3.1
+ */
+ void firePerspectiveSavedAs(IWorkbenchPage page,
+ IPerspectiveDescriptor oldPerspective,
+ IPerspectiveDescriptor newPerspective) {
+ UIListenerLogging.logPerspectiveSavedAs(this, page, oldPerspective,
+ newPerspective);
+ perspectiveListeners.firePerspectiveSavedAs(page, oldPerspective,
+ newPerspective);
+ }
+
+ /**
+ * Returns the action bars for this window.
+ */
+ public WWinActionBars getActionBars() {
+ if (actionBars == null) {
+ actionBars = new WWinActionBars(this);
+ }
+ return actionBars;
+ }
+
+ /**
+ * Returns the active page.
+ *
+ * @return the active page
+ */
+ public IWorkbenchPage getActivePage() {
+ return pageList.getActive();
+ }
+
+ /**
+ * Returns the active workbench page.
+ *
+ * @return the active workbench page
+ */
+ /* package */
+ WorkbenchPage getActiveWorkbenchPage() {
+ return pageList.getActive();
+ }
+
+ /**
+ * Returns the page composite, under which the window's pages create their
+ * controls.
+ */
+ protected Composite getPageComposite() {
+ return pageComposite;
+ }
+
+ /**
+ * Answer the menu manager for this window.
+ */
+ public MenuManager getMenuManager() {
+ return getMenuBarManager();
+ }
+
+ /**
+ * Returns the number. This corresponds to a page number in a window or a
+ * window number in the workbench.
+ */
+ public int getNumber() {
+ return number;
+ }
+
+ /**
+ * Returns an array of the pages in the workbench window.
+ *
+ * @return an array of pages
+ */
+ public IWorkbenchPage[] getPages() {
+ return pageList.getPages();
+ }
+
+ /**
+ * @see IWorkbenchWindow
+ */
+ public IPartService getPartService() {
+ return partService;
+ }
+
+ /**
+ * Returns the layout for the shell.
+ *
+ * @return the layout for the shell
+ */
+ protected Layout getLayout() {
+ return null;
+ }
+
+ /**
+ * @see IWorkbenchWindow
+ */
+ public ISelectionService getSelectionService() {
+ return (ISelectionService) e4Window.getContext().get(
+ ISelectionService.class.getName());
+ }
+
+ /**
+ * Returns <code>true</code> when the window's shell is activated,
+ * <code>false</code> when it's shell is deactivated
+ *
+ * @return boolean <code>true</code> when shell activated,
+ * <code>false</code> when shell deactivated
+ */
+ public boolean getShellActivated() {
+ return shellActivated;
+ }
+
+ /**
+ * Returns the status line manager for this window (if it has one).
+ *
+ * @return the status line manager, or <code>null</code> if this window does
+ * not have a status line
+ * @see ApplicationWindow#addStatusLine
+ */
+ public StatusLineManager getStatusLineManager() {
+ return super.getStatusLineManager();
+ }
+
+ private IWindowTrim getStatusLineTrim() {
+ if (statusLineTrim == null) {
+ statusLineTrim = new WindowTrimProxy(
+ getStatusLineManager().getControl(),
+ "org.eclipse.jface.action.StatusLineManager", //$NON-NLS-1$
+ WorkbenchMessages.TrimCommon_StatusLine_TrimName, SWT.NONE,
+ true);
+ }
+ return statusLineTrim;
+ }
+
+ /**
+ * @see IWorkbenchWindow
+ */
+ public IWorkbench getWorkbench() {
+ return PlatformUI.getWorkbench();
+ }
+
+ /*
+ * The implementation of this method is copied from the 3.x
+ * WorkbenchWindow's implementation. This is for rendering the group labels
+ * within the 'Customize Perspective' dialog, amongst other places.
+ */
+ public String getToolbarLabel(String actionSetId) {
+ ActionSetRegistry registry = WorkbenchPlugin.getDefault()
+ .getActionSetRegistry();
+ IActionSetDescriptor actionSet = registry.findActionSet(actionSetId);
+ if (actionSet != null) {
+ return actionSet.getLabel();
+ }
+
+ if (IWorkbenchActionConstants.TOOLBAR_FILE
+ .equalsIgnoreCase(actionSetId)) {
+ return WorkbenchMessages.WorkbenchWindow_FileToolbar;
+ }
+
+ if (IWorkbenchActionConstants.TOOLBAR_NAVIGATE
+ .equalsIgnoreCase(actionSetId)) {
+ return WorkbenchMessages.WorkbenchWindow_NavigateToolbar;
+ }
+
+ return null;
+ }
+
+ /**
+ * Unconditionally close this window. Assumes the proper flags have been set
+ * correctly (e.i. closing and updateDisabled)
+ */
+ private boolean hardClose() {
+ boolean result;
+ try {
+ // Remove the handler submissions. Bug 64024.
+ final IWorkbench workbench = getWorkbench();
+ final IHandlerService handlerService = (IHandlerService) workbench
+ .getService(IHandlerService.class);
+ handlerService.deactivateHandlers(handlerActivations);
+ final Iterator activationItr = handlerActivations.iterator();
+ while (activationItr.hasNext()) {
+ final IHandlerActivation activation = (IHandlerActivation) activationItr
+ .next();
+ activation.getHandler().dispose();
+ }
+ handlerActivations.clear();
+ globalActionHandlersByCommandId.clear();
+
+ // Remove the enabled submissions. Bug 64024.
+ final IContextService contextService = (IContextService) workbench
+ .getService(IContextService.class);
+ contextService.unregisterShell(getShell());
+
+ closeAllPages();
+
+ fireWindowClosed();
+
+ // time to wipe our our populate
+ IMenuService menuService = (IMenuService) workbench
+ .getService(IMenuService.class);
+ menuService
+ .releaseContributions(((ContributionManager) getActionBars()
+ .getMenuManager()));
+ ICoolBarManager coolbar = getActionBars().getCoolBarManager();
+ if (coolbar != null) {
+ menuService
+ .releaseContributions(((ContributionManager) coolbar));
+ }
+
+ getActionBarAdvisor().dispose();
+ getWindowAdvisor().dispose();
+
+ // Null out the progress region. Bug 64024.
+ progressRegion = null;
+
+ // Remove drop targets
+ DragUtil.removeDragTarget(null, trimDropTarget);
+ DragUtil.removeDragTarget(getShell(), trimDropTarget);
+ trimDropTarget = null;
+
+ if (trimMgr2 != null) {
+ trimMgr2.dispose();
+ trimMgr2 = null;
+ }
+
+ if (trimContributionMgr != null) {
+ trimContributionMgr.dispose();
+ trimContributionMgr = null;
+ }
+ } finally {
+ result = super.close();
+
+ if (result) {
+ // explicitly dispose the shell here, our superclasses does not
+ // handle this scenario because they don't have a reference to
+ // the real shell, see bug 279731
+ Shell shell = getShell();
+ if (shell != null && !shell.isDisposed()) {
+ shell.dispose();
+ }
+ }
+
+ // Clear the action sets, fix for bug 27416.
+ // getActionPresentation().clearActionSets();
+ try {
+ // Bring down all of the services ... after the window goes away
+ serviceLocator.dispose();
+ } catch (Exception ex) {
+ WorkbenchPlugin.log(ex);
+ }
+ menuRestrictions.clear();
+ }
+ return result;
+ }
+
+ /**
+ * @see IWorkbenchWindow
+ */
+ public boolean isApplicationMenu(String menuID) {
+ // delegate this question to the action bar advisor
+ return getActionBarAdvisor().isApplicationMenu(menuID);
+ }
+
+ /**
+ * Return whether or not the given id matches the id of the coolitems that
+ * the org.eclipse.e4.ui.model.application creates.
+ */
+ /* package */
+ boolean isWorkbenchCoolItemId(String id) {
+ return windowConfigurer.containsCoolItem(id);
+ }
+
+ /**
+ * Locks/unlocks the CoolBar for the workbench.
+ *
+ * @param lock
+ * whether the CoolBar should be locked or unlocked
+ */
+ /* package */
+ void lockCoolBar(boolean lock) {
+ getCoolBarManager2().setLockLayout(lock);
+ }
+
+ /**
+ * Makes the window visible and frontmost.
+ */
+ void makeVisible() {
+ Shell shell = getShell();
+ if (shell != null && !shell.isDisposed()) {
+ // see bug 96700 and bug 4414 for a discussion on the use of open()
+ // here
+ shell.open();
+ }
+ }
+
+ /**
+ * Called when this window is about to be closed.
+ *
+ * Subclasses may overide to add code that returns <code>false</code> to
+ * prevent closing under certain conditions.
+ */
+ public boolean okToClose() {
+ // Save all of the editors.
+ if (!getWorkbenchImpl().isClosing()) {
+ if (!saveAllPages(true)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Opens a new page.
+ * <p>
+ * <b>Note:</b> Since release 2.0, a window is limited to contain at most
+ * one page. If a page exist in the window when this method is used, then
+ * another window is created for the new page. Callers are strongly
+ * recommended to use the <code>IWorkbench.openPerspective</code> APIs to
+ * programmatically show a perspective.
+ * </p>
+ */
+ public IWorkbenchPage openPage(final String perspId, final IAdaptable input)
+ throws WorkbenchException {
+ Assert.isNotNull(perspId);
+
+ // Run op in busy cursor.
+ final Object[] result = new Object[1];
+ BusyIndicator.showWhile(null, new Runnable() {
+ public void run() {
+ try {
+ result[0] = busyOpenPage(perspId, input);
+ } catch (WorkbenchException e) {
+ result[0] = e;
+ }
+ }
+ });
+
+ if (result[0] instanceof IWorkbenchPage) {
+ return (IWorkbenchPage) result[0];
+ } else if (result[0] instanceof WorkbenchException) {
+ throw (WorkbenchException) result[0];
+ } else {
+ throw new WorkbenchException(
+ WorkbenchMessages.WorkbenchWindow_exceptionMessage);
+ }
+ }
+
+ /**
+ * Opens a new page.
+ * <p>
+ * <b>Note:</b> Since release 2.0, a window is limited to contain at most
+ * one page. If a page exist in the window when this method is used, then
+ * another window is created for the new page. Callers are strongly
+ * recommended to use the <code>IWorkbench.openPerspective</code> APIs to
+ * programmatically show a perspective.
+ * </p>
+ */
+ public IWorkbenchPage openPage(IAdaptable input) throws WorkbenchException {
+ String perspId = getWorkbenchImpl().getPerspectiveRegistry()
+ .getDefaultPerspective();
+ return openPage(perspId, input);
+ }
+
+ /*
+ * Removes an listener from the part service.
+ */
+ public void removePageListener(IPageListener l) {
+ pageListeners.removePageListener(l);
+ }
+
+ /**
+ * @see org.eclipse.ui.IPageService
+ */
+ public void removePerspectiveListener(org.eclipse.ui.IPerspectiveListener l) {
+ perspectiveListeners.removePerspectiveListener(l);
+ }
+
+ public IStatus restoreState(IMemento memento,
+ IPerspectiveDescriptor activeDescriptor) {
+
+ return Status.OK_STATUS;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IRunnableContext.
+ */
+ public void run(boolean fork, boolean cancelable,
+ IRunnableWithProgress runnable) throws InvocationTargetException,
+ InterruptedException {
+ IWorkbenchContextSupport contextSupport = getWorkbench()
+ .getContextSupport();
+ final boolean keyFilterEnabled = contextSupport.isKeyFilterEnabled();
+
+ Control fastViewBarControl = getFastViewBar() == null ? null
+ : getFastViewBar().getControl();
+ boolean fastViewBarWasEnabled = fastViewBarControl == null ? false
+ : fastViewBarControl.getEnabled();
+
+ Control perspectiveBarControl = getPerspectiveBar() == null ? null
+ : getPerspectiveBar().getControl();
+ boolean perspectiveBarWasEnabled = perspectiveBarControl == null ? false
+ : perspectiveBarControl.getEnabled();
+
+ // Cache for any diabled trim controls
+ List disabledControls = null;
+
+ try {
+ if (fastViewBarControl != null && !fastViewBarControl.isDisposed()) {
+ fastViewBarControl.setEnabled(false);
+ }
+
+ if (perspectiveBarControl != null
+ && !perspectiveBarControl.isDisposed()) {
+ perspectiveBarControl.setEnabled(false);
+ }
+
+ if (keyFilterEnabled) {
+ contextSupport.setKeyFilterEnabled(false);
+ }
+
+ // Disable all trim -except- the StatusLine
+ if (defaultLayout != null)
+ disabledControls = defaultLayout
+ .disableTrim(getStatusLineTrim());
+
+ super.run(fork, cancelable, runnable);
+ } finally {
+ if (fastViewBarControl != null && !fastViewBarControl.isDisposed()) {
+ fastViewBarControl.setEnabled(fastViewBarWasEnabled);
+ }
+
+ if (perspectiveBarControl != null
+ && !perspectiveBarControl.isDisposed()) {
+ perspectiveBarControl.setEnabled(perspectiveBarWasEnabled);
+ }
+
+ if (keyFilterEnabled) {
+ contextSupport.setKeyFilterEnabled(true);
+ }
+
+ // Re-enable any disabled trim
+ if (defaultLayout != null && disabledControls != null)
+ defaultLayout.enableTrim(disabledControls);
+ }
+ }
+
+ /**
+ * Save all of the pages. Returns true if the operation succeeded.
+ */
+ private boolean saveAllPages(boolean bConfirm) {
+ boolean bRet = true;
+ Iterator itr = pageList.iterator();
+ while (bRet && itr.hasNext()) {
+ WorkbenchPage page = (WorkbenchPage) itr.next();
+ bRet = page.saveAllEditors(bConfirm);
+ }
+ return bRet;
+ }
+
+ /**
+ * @see IPersistable
+ */
+ public IStatus saveState(IMemento memento) {
+
+ MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
+ WorkbenchMessages.WorkbenchWindow_problemsSavingWindow, null);
+
+ return result;
+ }
+
+ /**
+ * Sets the active page within the window.
+ *
+ * @param in
+ * identifies the new active page, or <code>null</code> for no
+ * active page
+ */
+ public void setActivePage(final IWorkbenchPage in) {
+ if (getActiveWorkbenchPage() == in) {
+ return;
+ }
+ pageList.setActive(in);
+ updateActionSets();
+ if (isClosing()) {
+ return;
+ }
+ firePageActivated(in);
+ }
+
+ /**
+ * Returns whether or not children exist for the Window's toolbar control.
+ * Overridden for coolbar support.
+ * <p>
+ *
+ * @return boolean true if children exist, false otherwise
+ */
+ protected boolean toolBarChildrenExist() {
+ CoolBar coolBarControl = (CoolBar) getCoolBarControl();
+ return coolBarControl.getItemCount() > 0;
+ }
+
+ private Set menuRestrictions = new HashSet();
+
+ public Set getMenuRestrictions() {
+ return menuRestrictions;
+ }
+
+ void liftRestrictions() {
+
+ }
+
+ void imposeRestrictions() {
+
+ }
+
+ /**
+ * update the action bars.
+ */
+ public void updateActionBars() {
+
+ }
+
+ /**
+ * <p>
+ * Indicates the start of a large update within this window. This is used to
+ * disable CPU-intensive, change-sensitive services that were temporarily
+ * disabled in the midst of large changes. This method should always be
+ * called in tandem with <code>largeUpdateEnd</code>, and the event loop
+ * should not be allowed to spin before that method is called.
+ * </p>
+ * <p>
+ * Important: always use with <code>largeUpdateEnd</code>!
+ * </p>
+ *
+ * @since 3.1
+ */
+ public final void largeUpdateStart() {
+ largeUpdates++;
+ }
+
+ /**
+ * <p>
+ * Indicates the end of a large update within this window. This is used to
+ * re-enable services that were temporarily disabled in the midst of large
+ * changes. This method should always be called in tandem with
+ * <code>largeUpdateStart</code>, and the event loop should not be allowed
+ * to spin before this method is called.
+ * </p>
+ * <p>
+ * Important: always protect this call by using <code>finally</code>!
+ * </p>
+ *
+ * @since 3.1
+ */
+ public final void largeUpdateEnd() {
+ if (--largeUpdates == 0) {
+ updateActionBars();
+ }
+ }
+
+ /**
+ * Update the visible action sets. This method is typically called from a
+ * page when the user changes the visible action sets within the
+ * prespective.
+ */
+ public void updateActionSets() {
+ WorkbenchPage page = pageList.getActive();
+ if (page == null) {
+ return;
+ }
+ final IActionSetDescriptor[] actionSets = page.getActionSets();
+ e4Context.set(ISources.ACTIVE_ACTION_SETS_NAME, actionSets);
+ final HashSet<String> set = new HashSet<String>();
+ for (int i = 0; i < actionSets.length; i++) {
+ set.add(actionSets[i].getId());
+ }
+ for (int i = 0; i < e4ActionSets.length; i++) {
+ if (set.contains(e4ActionSets[i].getId())) {
+ e4ActionSets[i].setVisible(true);
+ } else {
+ e4ActionSets[i].setVisible(false);
+ }
+ }
+ Shell shell = getShell();
+ if (shell != null) {
+ Menu bar = shell.getMenuBar();
+ if (bar != null) {
+ final MenuManager manager = (MenuManager) bar.getData();
+ if (manager != null) {
+ manager.update(true);
+ }
+ }
+ }
+ }
+
+ private ListenerList actionSetListeners = null;
+
+ private ListenerList backgroundSaveListeners = new ListenerList(
+ ListenerList.IDENTITY);
+
+ private MWindow e4Window;
+
+ private IEclipseContext e4Context;
+
+ private ActionSet[] e4ActionSets;
+
+ final void addActionSetsListener(final IActionSetsListener listener) {
+ if (actionSetListeners == null) {
+ actionSetListeners = new ListenerList();
+ }
+
+ actionSetListeners.add(listener);
+ }
+
+ final void removeActionSetsListener(final IActionSetsListener listener) {
+ if (actionSetListeners != null) {
+ actionSetListeners.remove(listener);
+ if (actionSetListeners.isEmpty()) {
+ actionSetListeners = null;
+ }
+ }
+ }
+
+ /**
+ * Create the progress indicator for the receiver.
+ *
+ * @param shell
+ * the parent shell
+ */
+ void createProgressIndicator(Shell shell) {
+ if (getWindowConfigurer().getShowProgressIndicator()) {
+ progressRegion = new ProgressRegion();
+ progressRegion.createContents(shell, this);
+ }
+
+ }
+
+ class PageList {
+ // List of pages in the order they were created;
+ private List pagesInCreationOrder;
+
+ // List of pages where the top is the last activated.
+ private List pageInActivationOrder;
+
+ // The page explicitly activated
+ private Object active;
+
+ public PageList() {
+ pagesInCreationOrder = new ArrayList(4);
+ pageInActivationOrder = new ArrayList(4);
+ }
+
+ public boolean add(Object object) {
+ pagesInCreationOrder.add(object);
+ pageInActivationOrder.add(0, object);
+ // It will be moved to top only when activated.
+ return true;
+ }
+
+ public Iterator iterator() {
+ return pagesInCreationOrder.iterator();
+ }
+
+ public boolean contains(Object object) {
+ return pagesInCreationOrder.contains(object);
+ }
+
+ public boolean remove(Object object) {
+ if (active == object) {
+ active = null;
+ }
+ pageInActivationOrder.remove(object);
+ return pagesInCreationOrder.remove(object);
+ }
+
+ public boolean isEmpty() {
+ return pagesInCreationOrder.isEmpty();
+ }
+
+ public IWorkbenchPage[] getPages() {
+ int nSize = pagesInCreationOrder.size();
+ IWorkbenchPage[] retArray = new IWorkbenchPage[nSize];
+ pagesInCreationOrder.toArray(retArray);
+ return retArray;
+ }
+
+ public void setActive(Object page) {
+ if (active == page) {
+ return;
+ }
+
+ active = page;
+
+ if (page != null) {
+ pageInActivationOrder.remove(page);
+ pageInActivationOrder.add(page);
+ }
+ }
+
+ public WorkbenchPage getActive() {
+ return (WorkbenchPage) active;
+ }
+
+ public WorkbenchPage getNextActive() {
+ if (active == null) {
+ if (pageInActivationOrder.isEmpty()) {
+ return null;
+ }
+
+ return (WorkbenchPage) pageInActivationOrder
+ .get(pageInActivationOrder.size() - 1);
+ }
+
+ if (pageInActivationOrder.size() < 2) {
+ return null;
+ }
+
+ return (WorkbenchPage) pageInActivationOrder
+ .get(pageInActivationOrder.size() - 2);
+ }
+ }
+
+ /**
+ * Returns the unique object that applications use to configure this window.
+ * <p>
+ * IMPORTANT This method is declared package-private to prevent regular
+ * plug-ins from downcasting IWorkbenchWindow to WorkbenchWindow and getting
+ * hold of the workbench window configurer that would allow them to tamper
+ * with the workbench window. The workbench window configurer is available
+ * only to the org.eclipse.e4.ui.model.application.
+ * </p>
+ */
+ /* package - DO NOT CHANGE */
+ WorkbenchWindowConfigurer getWindowConfigurer() {
+ if (windowConfigurer == null) {
+ // lazy initialize
+ windowConfigurer = new WorkbenchWindowConfigurer(this);
+ }
+ return windowConfigurer;
+ }
+
+ /**
+ * Returns the workbench advisor. Assumes the workbench has been created
+ * already.
+ * <p>
+ * IMPORTANT This method is declared private to prevent regular plug-ins
+ * from downcasting IWorkbenchWindow to WorkbenchWindow and getting hold of
+ * the workbench advisor that would allow them to tamper with the workbench.
+ * The workbench advisor is internal to the
+ * org.eclipse.e4.ui.model.application.
+ * </p>
+ */
+ private/* private - DO NOT CHANGE */
+ WorkbenchAdvisor getAdvisor() {
+ return getWorkbenchImpl().getAdvisor();
+ }
+
+ /**
+ * Returns the window advisor, creating a new one for this window if needed.
+ * <p>
+ * IMPORTANT This method is declared package private to prevent regular
+ * plug-ins from downcasting IWorkbenchWindow to WorkbenchWindow and getting
+ * hold of the window advisor that would allow them to tamper with the
+ * window. The window advisor is internal to the
+ * org.eclipse.e4.ui.model.application.
+ * </p>
+ */
+ /* package private - DO NOT CHANGE */
+ WorkbenchWindowAdvisor getWindowAdvisor() {
+ if (windowAdvisor == null) {
+ windowAdvisor = getAdvisor().createWorkbenchWindowAdvisor(
+ getWindowConfigurer());
+ Assert.isNotNull(windowAdvisor);
+ }
+ return windowAdvisor;
+ }
+
+ /**
+ * Returns the action bar advisor, creating a new one for this window if
+ * needed.
+ * <p>
+ * IMPORTANT This method is declared private to prevent regular plug-ins
+ * from downcasting IWorkbenchWindow to WorkbenchWindow and getting hold of
+ * the action bar advisor that would allow them to tamper with the window's
+ * action bars. The action bar advisor is internal to the
+ * org.eclipse.e4.ui.model.application.
+ * </p>
+ */
+ private/* private - DO NOT CHANGE */
+ ActionBarAdvisor getActionBarAdvisor() {
+ if (actionBarAdvisor == null) {
+ actionBarAdvisor = getWindowAdvisor().createActionBarAdvisor(
+ getWindowConfigurer().getActionBarConfigurer());
+ Assert.isNotNull(actionBarAdvisor);
+ }
+ return actionBarAdvisor;
+ }
+
+ /*
+ * Returns the IWorkbench implementation.
+ */
+ private Workbench getWorkbenchImpl() {
+ return Workbench.getInstance();
+ }
+
+ /**
+ * Fills the window's real action bars.
+ *
+ * @param flags
+ * indicate which bars to fill
+ */
+ public void fillActionBars(int flags) {
+ Workbench workbench = getWorkbenchImpl();
+ workbench.largeUpdateStart();
+ try {
+ getActionBarAdvisor().fillActionBars(flags);
+ //
+ // 3.3 start
+ // final IMenuService menuService = (IMenuService) serviceLocator
+ // .getService(IMenuService.class);
+ // menuService.populateContributionManager(
+ // (ContributionManager) getActionBars().getMenuManager(),
+ // MenuUtil.MAIN_MENU);
+ // ICoolBarManager coolbar = getActionBars().getCoolBarManager();
+ // if (coolbar != null) {
+ // menuService.populateContributionManager(
+ // (ContributionManager) coolbar, MenuUtil.MAIN_TOOLBAR);
+ // }
+ // 3.3 end
+ } finally {
+ workbench.largeUpdateEnd();
+ }
+ }
+
+ /**
+ * Fills the window's proxy action bars.
+ *
+ * @param proxyBars
+ * the proxy configurer
+ * @param flags
+ * indicate which bars to fill
+ */
+ public void fillActionBars(IActionBarConfigurer2 proxyBars, int flags) {
+ Assert.isNotNull(proxyBars);
+ WorkbenchWindowConfigurer.WindowActionBarConfigurer wab = (WorkbenchWindowConfigurer.WindowActionBarConfigurer) getWindowConfigurer()
+ .getActionBarConfigurer();
+ wab.setProxy(proxyBars);
+ try {
+ getActionBarAdvisor().fillActionBars(
+ flags | ActionBarAdvisor.FILL_PROXY);
+ } finally {
+ wab.setProxy(null);
+ }
+ }
+
+ /**
+ * The <code>WorkbenchWindow</code> implementation of this method has the
+ * same logic as <code>Window</code>'s implementation, but without the
+ * resize check. We don't want to skip setting the bounds if the shell has
+ * been resized since a free resize event occurs on Windows when the menubar
+ * is set in configureShell.
+ */
+ protected void initializeBounds() {
+ Point size = getInitialSize();
+ Point location = getInitialLocation(size);
+ getShell().setBounds(
+ getConstrainedShellBounds(new Rectangle(location.x, location.y,
+ size.x, size.y)));
+ }
+
+ /*
+ * Unlike dialogs, the position of the workbench window is set by the user
+ * and persisted across sessions. If the user wants to put the window
+ * offscreen or spanning multiple monitors, let them (bug 74762)
+ */
+ protected void constrainShellSize() {
+ // As long as the shell is visible on some monitor, don't change it.
+ Rectangle bounds = getShell().getBounds();
+ if (!SwtUtil.intersectsAnyMonitor(Display.getCurrent(), bounds)) {
+ super.constrainShellSize();
+ }
+ }
+
+ /*
+ * Unlike dialogs, the position of the workbench window is set by the user
+ * and persisted across sessions. If the user wants to put the window
+ * offscreen or spanning multiple monitors, let them (bug 74762)
+ */
+ protected Point getInitialLocation(Point size) {
+ Shell shell = getShell();
+ if (shell != null) {
+ return shell.getLocation();
+ }
+
+ return super.getInitialLocation(size);
+ }
+
+ /**
+ * The <code>WorkbenchWindow</code> implementation of this method delegates
+ * to the window configurer.
+ *
+ * @since 3.0
+ */
+ protected Point getInitialSize() {
+ return getWindowConfigurer().getInitialSize();
+ }
+
+ /**
+ * @param visible
+ * whether the cool bar should be shown. This is only applicable
+ * if the window configurer also wishes either the cool bar to be
+ * visible.
+ * @since 3.0
+ */
+ public void setCoolBarVisible(boolean visible) {
+ }
+
+ /**
+ * @return whether the cool bar should be shown. This is only applicable if
+ * the window configurer also wishes either the cool bar to be
+ * visible.
+ * @since 3.0
+ */
+ public boolean getCoolBarVisible() {
+ return coolBarVisible;
+ }
+
+ /**
+ * @param visible
+ * whether the perspective bar should be shown. This is only
+ * applicable if the window configurer also wishes either the
+ * perspective bar to be visible.
+ * @since 3.0
+ */
+ public void setPerspectiveBarVisible(boolean visible) {
+ }
+
+ /**
+ * @return whether the perspective bar should be shown. This is only
+ * applicable if the window configurer also wishes either the
+ * perspective bar to be visible.
+ * @since 3.0
+ */
+ public boolean getPerspectiveBarVisible() {
+ return perspectiveBarVisible;
+ }
+
+ /**
+ * Tell the workbench window a visible state for the fastview bar. This is
+ * only applicable if the window configurer also wishes the fast view bar to
+ * be visible.
+ *
+ * @param visible
+ * <code>true</code> or <code>false</code>
+ * @since 3.2
+ */
+ public void setFastViewBarVisible(boolean visible) {
+ }
+
+ /**
+ * The workbench window take on the fastview bar. This is only applicable if
+ * the window configurer also wishes the fast view bar to be visible.
+ *
+ * @return <code>true</code> if the workbench window thinks the fastview bar
+ * should be visible.
+ * @since 3.2
+ */
+ public boolean getFastViewBarVisible() {
+ return fastViewBarVisible;
+ }
+
+ /**
+ * @param visible
+ * whether the perspective bar should be shown. This is only
+ * applicable if the window configurer also wishes either the
+ * perspective bar to be visible.
+ * @since 3.0
+ */
+ public void setStatusLineVisible(boolean visible) {
+ }
+
+ /**
+ * @return whether the perspective bar should be shown. This is only
+ * applicable if the window configurer also wishes either the
+ * perspective bar to be visible.
+ * @since 3.0
+ */
+ public boolean getStatusLineVisible() {
+ return statusLineVisible;
+ }
+
+ public boolean getShowFastViewBars() {
+ return getWindowConfigurer().getShowFastViewBars();
+ }
+
+ /**
+ * Set the layout data for the contents of the window.
+ */
+ void setLayoutDataForContents() {
+
+ }
+
+ /**
+ * Returns the fast view bar.
+ */
+ public FastViewBar getFastViewBar() {
+ return fastViewBar;
+ }
+
+ /**
+ * Returns the perspective bar.
+ *
+ * @return Returns the perspective bar, or <code>null</code> if it has not
+ * been initialized.
+ */
+ public PerspectiveBarManager getPerspectiveBar() {
+ return perspectiveSwitcher == null ? null : perspectiveSwitcher
+ .getPerspectiveBar();
+ }
+
+ /**
+ * Returns the action presentation for dynamic UI
+ *
+ * @return action presentation
+ */
+ public ActionPresentation getActionPresentation() {
+ return null;
+ }
+
+ /**
+ * Return the action bar presentation used for creating toolbars. This is
+ * for internal use only, used for consistency with the window.
+ *
+ * @return the presentation used.
+ */
+ public IActionBarPresentationFactory getActionBarPresentationFactory() {
+ // allow replacement of the actionbar presentation
+ IActionBarPresentationFactory actionBarPresentation;
+ AbstractPresentationFactory presentationFactory = getWindowConfigurer()
+ .getPresentationFactory();
+ if (presentationFactory instanceof IActionBarPresentationFactory) {
+ actionBarPresentation = ((IActionBarPresentationFactory) presentationFactory);
+ } else {
+ actionBarPresentation = new DefaultActionBarPresentationFactory();
+ }
+
+ return actionBarPresentation;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.window.ApplicationWindow#showTopSeperator()
+ */
+ protected boolean showTopSeperator() {
+ return false;
+ }
+
+ /**
+ * Returns a new cool bar manager for the window.
+ * <p>
+ * Subclasses may override this method to customize the cool bar manager.
+ * </p>
+ *
+ * @return a cool bar manager
+ * @since 3.2
+ */
+ protected ICoolBarManager createCoolBarManager2(int style) {
+ final ICoolBarManager2 coolBarManager = getActionBarPresentationFactory()
+ .createCoolBarManager();
+ return coolBarManager;
+ }
+
+ /**
+ * Returns a new tool bar manager for the window.
+ * <p>
+ * Subclasses may override this method to customize the tool bar manager.
+ * </p>
+ *
+ * @return a tool bar manager
+ * @since 3.2
+ */
+ protected IToolBarManager createToolBarManager2(int style) {
+ final IToolBarManager2 toolBarManager = getActionBarPresentationFactory()
+ .createToolBarManager();
+ return toolBarManager;
+ }
+
+ /**
+ * Delegate to the presentation factory.
+ *
+ * @see org.eclipse.jface.window.ApplicationWindow#createStatusLineManager
+ * @since 3.0
+ */
+ protected StatusLineManager createStatusLineManager() {
+ // @issue ApplicationWindow and WorkbenchWindow should allow full
+ // IStatusLineManager
+ return new StatusLineManager() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.action.StatusLineManager#getProgressMonitor()
+ */
+ @Override
+ public IProgressMonitor getProgressMonitor() {
+ return new NullProgressMonitor();
+ }
+ };
+ }
+
+ /**
+ * Delegate to the presentation factory.
+ *
+ * @see org.eclipse.jface.window.ApplicationWindow#createStatusLine
+ * @since 3.0
+ */
+ protected void createStatusLine(Shell shell) {
+ getWindowConfigurer().getPresentationFactory().createStatusLineControl(
+ getStatusLineManager(), shell);
+ }
+
+ /**
+ * Updates the fast view bar, if present. TODO: The fast view bar should
+ * update itself as necessary. All calls to this should be cleaned up.
+ *
+ * @since 3.0
+ */
+ public void updateFastViewBar() {
+ }
+
+ /**
+ * @return Returns the progressRegion.
+ */
+ public ProgressRegion getProgressRegion() {
+ return progressRegion;
+ }
+
+ /**
+ * Adds the given control to the specified side of this window's trim.
+ *
+ * @param trim
+ * the bar's IWindowTrim
+ * @param side
+ * one of <code>SWT.LEFT</code>,<code>SWT.BOTTOM</code>, or
+ * <code>SWT.RIGHT</code> (only LEFT has been tested)
+ * @since 3.0
+ */
+ public void addToTrim(IWindowTrim trim, int side) {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchWindow#getExtensionTracker()
+ */
+ public IExtensionTracker getExtensionTracker() {
+ return (IExtensionTracker) e4Window.getContext().get(
+ IExtensionTracker.class.getName());
+ }
+
+ /**
+ * Creates the perspective customization dialog.
+ *
+ * @param persp
+ * perspective to customize
+ *
+ * @return a new perspective customization dialog
+ * @since 3.1
+ */
+ public CustomizePerspectiveDialog createCustomizePerspectiveDialog(
+ Perspective persp) {
+ return new CustomizePerspectiveDialog(getWindowConfigurer(), persp);
+ }
+
+ /**
+ * Returns the default page input for workbench pages opened in this window.
+ *
+ * @return the default page input or <code>null</code> if none
+ * @since 3.1
+ */
+ IAdaptable getDefaultPageInput() {
+ return getWorkbenchImpl().getDefaultPageInput();
+ }
+
+ /**
+ * Add a listener for perspective reordering.
+ *
+ * @param listener
+ */
+ public void addPerspectiveReorderListener(IReorderListener listener) {
+ if (perspectiveSwitcher != null) {
+ perspectiveSwitcher.addReorderListener(listener);
+ }
+ }
+
+ /**
+ * Show the heap status
+ *
+ * @param selection
+ */
+ public void showHeapStatus(boolean selection) {
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchWindow#getTrimManager()
+ */
+ public ITrimManager getTrimManager() {
+ return defaultLayout;
+ }
+
+ /**
+ * Initializes all of the default command-based services for the workbench
+ * window.
+ */
+ private final void initializeDefaultServices() {
+ e4Context.declareModifiable(IServiceConstants.SELECTION);
+
+ e4Context.set(IExtensionTracker.class.getName(), new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ if (tracker == null) {
+ tracker = new UIExtensionTracker(getWorkbench()
+ .getDisplay());
+ }
+ return tracker;
+ }
+ });
+ e4Context.set(IPartService.class.getName(), getPartService());
+ e4Context.set(ISelectionService.class.getName(),
+ new LegacySelectionService(e4Context));
+ // END: e4 services
+ serviceLocator.registerService(IWorkbenchLocationService.class,
+ new WorkbenchLocationService(IServiceScopes.WINDOW_SCOPE,
+ getWorkbench(), this, null, null, null, 1));
+ // added back for legacy reasons
+ serviceLocator.registerService(IWorkbenchWindow.class, this);
+ serviceLocator.registerService(getClass(), this);
+
+ final ActionCommandMappingService mappingService = new ActionCommandMappingService();
+ serviceLocator.registerService(IActionCommandMappingService.class,
+ mappingService);
+
+ final LegacyActionPersistence actionPersistence = new LegacyActionPersistence(
+ this);
+ serviceLocator.registerService(LegacyActionPersistence.class,
+ actionPersistence);
+ actionPersistence.read();
+
+ // BEGIN: e4 registration
+ EContextService cs = (EContextService) e4Context
+ .get(EContextService.class.getName());
+ cs.activateContext("org.eclipse.ui.contexts.window"); //$NON-NLS-1$
+ cs.getActiveContextIds();
+ e4Context.set(ISources.ACTIVE_WORKBENCH_WINDOW_NAME, this);
+ e4Context.set(ISources.ACTIVE_PART_NAME, new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ Object o = context.get(IServiceConstants.ACTIVE_PART);
+ if (o instanceof MPart) {
+ Object impl = ((MPart) o).getObject();
+ if (impl instanceof IWorkbenchPart) {
+ return impl;
+ }
+ }
+ return null;
+ }
+ });
+ e4Context.set(ISources.ACTIVE_SITE_NAME, new ContextFunction() {
+ @Override
+ public Object compute(IEclipseContext context, Object[] arguments) {
+ Object o = context.get(IServiceConstants.ACTIVE_PART);
+ if (o instanceof MPart) {
+ Object impl = ((MPart) o).getObject();
+ if (impl instanceof IWorkbenchPart) {
+ return ((IWorkbenchPart) impl).getSite();
+ }
+ }
+ return null;
+ }
+ });
+ // local handler service for local handlers
+ IHandlerService handlerService = new LegacyHandlerService(e4Context);
+ serviceLocator.registerService(IHandlerService.class, handlerService);
+ readActionSets();
+ }
+
+ private void readActionSets() {
+ WorkbenchWindowExpression windowExpression = new WorkbenchWindowExpression(
+ this);
+ ICommandService cs = (ICommandService) e4Context
+ .get(ICommandService.class.getName());
+ IConfigurationElement[] actionSetElements = ExtensionUtils
+ .getExtensions(IWorkbenchRegistryConstants.PL_ACTION_SETS);
+ for (IConfigurationElement ase : actionSetElements) {
+ IConfigurationElement[] elements = ase
+ .getChildren(IWorkbenchRegistryConstants.TAG_ACTION);
+ for (IConfigurationElement configElement : elements) {
+ String id = MenuHelper.getId(configElement);
+ String cmdId = MenuHelper.getActionSetCommandId(configElement);
+ if (id == null || id.length() == 0
+ || MenuHelper.getRetarget(configElement)) {
+ continue;
+ }
+ Command cmd = cs.getCommand(cmdId);
+ if (!cmd.isDefined()) {
+ Activator.trace(Policy.DEBUG_CMDS, "Still no command for " //$NON-NLS-1$
+ + cmdId, null);
+ continue;
+ }
+ LegacyHandlerService.registerLegacyHandler(e4Context, id,
+ cmdId, new ActionDelegateHandlerProxy(configElement,
+ IWorkbenchRegistryConstants.ATT_CLASS, id,
+ new ParameterizedCommand(cmd, null), this,
+ null, null, null), windowExpression);
+ }
+ }
+ }
+
+ public final Object getService(final Class key) {
+ return serviceLocator.getService(key);
+ }
+
+ public final boolean hasService(final Class key) {
+ return serviceLocator.hasService(key);
+ }
+
+ /**
+ * Toggle the visibility of the coolbar/perspective bar. This method
+ * respects the window configurer and will only toggle visibility if the
+ * item in question was originally declared visible by the window advisor.
+ *
+ * @since 3.3
+ */
+ public void toggleToolbarVisibility() {
+ boolean coolbarVisible = getCoolBarVisible();
+ boolean perspectivebarVisible = getPerspectiveBarVisible();
+ // only toggle the visibility of the components that
+ // were on initially
+ if (getWindowConfigurer().getShowCoolBar()) {
+ setCoolBarVisible(!coolbarVisible);
+ }
+ if (getWindowConfigurer().getShowPerspectiveBar()) {
+ setPerspectiveBarVisible(!perspectivebarVisible);
+ }
+ getShell().layout();
+ }
+
+ /* package */void addBackgroundSaveListener(IBackgroundSaveListener listener) {
+ backgroundSaveListeners.add(listener);
+ }
+
+ /* package */void fireBackgroundSaveStarted() {
+ Object[] listeners = backgroundSaveListeners.getListeners();
+ for (int i = 0; i < listeners.length; i++) {
+ IBackgroundSaveListener listener = (IBackgroundSaveListener) listeners[i];
+ listener.handleBackgroundSaveStarted();
+ }
+ }
+
+ /* package */void removeBackgroundSaveListener(
+ IBackgroundSaveListener listener) {
+ backgroundSaveListeners.remove(listener);
+ }
+
+ public MWindow getModelWindow() {
+ return e4Window;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/progress/WorkbenchSiteProgressService.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/progress/WorkbenchSiteProgressService.java
new file mode 100644
index 0000000..10c6764
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/progress/WorkbenchSiteProgressService.java
@@ -0,0 +1,463 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 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 - Initial API and implementation
+ * Remy Chi Jian Suen (Versant Corporation) - bug 255005
+ *******************************************************************************/
+package org.eclipse.ui.internal.progress;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.IJobChangeListener;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.PartSite;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.part.WorkbenchPart;
+import org.eclipse.ui.progress.IProgressService;
+import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
+import org.eclipse.ui.progress.WorkbenchJob;
+
+/**
+ * The WorkbenchSiteProgressService is the concrete implementation of the
+ * WorkbenchSiteProgressService used by the workbench components.
+ */
+public class WorkbenchSiteProgressService implements
+ IWorkbenchSiteProgressService, IJobBusyListener {
+ PartSite site;
+
+ private Collection busyJobs = Collections.synchronizedSet(new HashSet());
+
+ private Object busyLock = new Object();
+
+ IPropertyChangeListener[] changeListeners = new IPropertyChangeListener[0];
+
+ private Cursor waitCursor;
+
+ private int waitCursorJobCount;
+
+ private Object waitCursorLock = new Object();
+
+ private SiteUpdateJob updateJob;
+
+ /**
+ * Flag that keeps state from calls to {@link #showBusy(boolean)}
+ */
+ private int busyCount = 0;
+
+ public class SiteUpdateJob extends WorkbenchJob {
+ private boolean busy;
+
+ Object lock = new Object();
+
+ /**
+ * Set whether we are updating with the wait or busy cursor.
+ *
+ * @param cursorState
+ */
+ void setBusy(boolean cursorState) {
+ synchronized (lock) {
+ busy = cursorState;
+ }
+ }
+
+ private SiteUpdateJob() {
+ super(ProgressMessages.WorkbenchSiteProgressService_CursorJob);
+ }
+
+ /**
+ * Get the wait cursor. Initialize it if required.
+ *
+ * @param display
+ * the display to create the cursor on.
+ * @return the created cursor
+ */
+ private Cursor getWaitCursor(Display display) {
+ if (waitCursor == null) {
+ waitCursor = new Cursor(display, SWT.CURSOR_APPSTARTING);
+ }
+ return waitCursor;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime
+ * .IProgressMonitor)
+ */
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ Control control = site.getPane().getControl();
+ if (control == null || control.isDisposed()) {
+ return Status.CANCEL_STATUS;
+ }
+ synchronized (lock) {
+ // Update cursors if we are doing that
+ Cursor cursor = null;
+ if (waitCursorJobCount != 0) {
+ // at least one job which is running has requested for wait
+ // cursor
+ cursor = getWaitCursor(control.getDisplay());
+ }
+ control.setCursor(cursor);
+ site.getPane().setBusy(busy);
+ IWorkbenchPart part = site.getPart();
+ if (part instanceof WorkbenchPart) {
+ ((WorkbenchPart) part).showBusy(busy);
+ }
+ }
+ return Status.OK_STATUS;
+ }
+
+ void clearCursors() {
+ if (waitCursor != null) {
+ waitCursor.dispose();
+ waitCursor = null;
+ }
+ }
+
+ }
+
+ /**
+ * Create a new instance of the receiver with a site of partSite
+ *
+ * @param partSite
+ * PartSite.
+ */
+ public WorkbenchSiteProgressService(final PartSite partSite) {
+ site = partSite;
+ updateJob = new SiteUpdateJob();
+ updateJob.setSystem(true);
+ }
+
+ /**
+ * Dispose the resources allocated by the receiver.
+ *
+ */
+ public void dispose() {
+ if (updateJob != null) {
+ updateJob.cancel();
+ }
+
+ ProgressManager.getInstance().removeListener(this);
+
+ if (waitCursor == null) {
+ return;
+ }
+ waitCursor.dispose();
+ waitCursor = null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.progress.IProgressService#busyCursorWhile(org.eclipse.
+ * jface.operation.IRunnableWithProgress)
+ */
+ public void busyCursorWhile(IRunnableWithProgress runnable)
+ throws InvocationTargetException, InterruptedException {
+ getWorkbenchProgressService().busyCursorWhile(runnable);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.progress.IWorkbenchSiteProgressService#schedule(org.eclipse
+ * .core.runtime.jobs.Job, long, boolean)
+ */
+ public void schedule(Job job, long delay, boolean useHalfBusyCursor) {
+ job.addJobChangeListener(getJobChangeListener(useHalfBusyCursor));
+ job.schedule(delay);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.progress.IWorkbenchSiteProgressService#schedule(org.eclipse
+ * .core.runtime.jobs.Job, int)
+ */
+ public void schedule(Job job, long delay) {
+ schedule(job, delay, false);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.progress.IWorkbenchSiteProgressService#schedule(org.eclipse
+ * .core.runtime.jobs.Job)
+ */
+ public void schedule(Job job) {
+ schedule(job, 0L, false);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.progress.IWorkbenchSiteProgressService#showBusyForFamily
+ * (java.lang.Object)
+ */
+ public void showBusyForFamily(Object family) {
+ ProgressManager.getInstance().addListenerToFamily(family, this);
+ }
+
+ /**
+ * Get the job change listener for this site.
+ *
+ * @param job
+ * @param useHalfBusyCursor
+ * @return IJobChangeListener
+ */
+ public IJobChangeListener getJobChangeListener(
+ final boolean useHalfBusyCursor) {
+ return new JobChangeAdapter() {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.core.runtime.jobs.JobChangeAdapter#aboutToRun(org
+ * .eclipse.core.runtime.jobs.IJobChangeEvent)
+ */
+ public void aboutToRun(IJobChangeEvent event) {
+ if (useHalfBusyCursor) {
+ synchronized (waitCursorLock) {
+ waitCursorJobCount++;
+ }
+ }
+ incrementBusy(event.getJob());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.core.runtime.jobs.JobChangeAdapter#done(org.eclipse
+ * .core.runtime.jobs.IJobChangeEvent)
+ */
+ public void done(IJobChangeEvent event) {
+ if (useHalfBusyCursor) {
+ synchronized (waitCursorLock) {
+ waitCursorJobCount--;
+ }
+ }
+
+ Job job = event.getJob();
+ decrementBusy(job);
+ job.removeJobChangeListener(this);
+ }
+ };
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.internal.progress.IJobBusyListener#decrementBusy(org.eclipse
+ * .core.runtime.jobs.Job)
+ */
+ public void decrementBusy(Job job) {
+ synchronized (busyLock) {
+ if (!busyJobs.contains(job)) {
+ return;
+ }
+ busyJobs.remove(job);
+ }
+ try {
+ decrementBusy();
+ } catch (Exception ex) {
+ // protecting against assertion failures
+ WorkbenchPlugin.log(ex);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.internal.progress.IJobBusyListener#incrementBusy(org.eclipse
+ * .core.runtime.jobs.Job)
+ */
+ public void incrementBusy(Job job) {
+ synchronized (busyLock) {
+ if (busyJobs.contains(job)) {
+ return;
+ }
+ busyJobs.add(job);
+ }
+ incrementBusy();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.progress.IWorkbenchSiteProgressService#warnOfContentChange
+ * ()
+ */
+ public void warnOfContentChange() {
+ // site.getPane().showHighlight();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.progress.IProgressService#showInDialog(org.eclipse.swt
+ * .widgets.Shell, org.eclipse.core.runtime.jobs.Job)
+ */
+ public void showInDialog(Shell shell, Job job) {
+ getWorkbenchProgressService().showInDialog(shell, job);
+ }
+
+ /**
+ * Get the progress service for the workbnech,
+ *
+ * @return IProgressService
+ */
+ private IProgressService getWorkbenchProgressService() {
+ return site.getWorkbenchWindow().getWorkbench().getProgressService();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.operation.IRunnableContext#run(boolean, boolean,
+ * org.eclipse.jface.operation.IRunnableWithProgress)
+ */
+ public void run(boolean fork, boolean cancelable,
+ IRunnableWithProgress runnable) throws InvocationTargetException,
+ InterruptedException {
+ getWorkbenchProgressService().run(fork, cancelable, runnable);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.progress.IProgressService#runInUI(org.eclipse.jface.operation
+ * .IRunnableContext, org.eclipse.jface.operation.IRunnableWithProgress,
+ * org.eclipse.core.runtime.jobs.ISchedulingRule)
+ */
+ public void runInUI(IRunnableContext context,
+ IRunnableWithProgress runnable, ISchedulingRule rule)
+ throws InvocationTargetException, InterruptedException {
+ getWorkbenchProgressService().runInUI(context, runnable, rule);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.progress.IProgressService#getLongOperationTime()
+ */
+ public int getLongOperationTime() {
+ return getWorkbenchProgressService().getLongOperationTime();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.progress.IProgressService#registerIconForFamily(org.eclipse
+ * .jface.resource.ImageDescriptor, java.lang.Object)
+ */
+ public void registerIconForFamily(ImageDescriptor icon, Object family) {
+ getWorkbenchProgressService().registerIconForFamily(icon, family);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.progress.IProgressService#getIconFor(org.eclipse.core.
+ * runtime.jobs.Job)
+ */
+ public Image getIconFor(Job job) {
+ return getWorkbenchProgressService().getIconFor(job);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.progress.IWorkbenchSiteProgressService#showBusy(boolean)
+ */
+ public void incrementBusy() {
+ synchronized (busyLock) {
+ this.busyCount++;
+ if (busyCount != 1) {
+ return;
+ }
+ updateJob.setBusy(true);
+ }
+ if (PlatformUI.isWorkbenchRunning()) {
+ // updateJob.schedule(100);
+ } else {
+ updateJob.cancel();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.progress.IWorkbenchSiteProgressService#showBusy(boolean)
+ */
+ public void decrementBusy() {
+ synchronized (busyLock) {
+ Assert
+ .isTrue(
+ busyCount > 0,
+ "Ignoring unexpected call to IWorkbenchSiteProgressService.decrementBusy(). This might be due to an earlier call to this method."); //$NON-NLS-1$
+ this.busyCount--;
+ if (busyCount != 0) {
+ return;
+ }
+ updateJob.setBusy(false);
+ }
+ if (PlatformUI.isWorkbenchRunning()) {
+ // updateJob.schedule(100);
+ } else {
+ updateJob.cancel();
+ }
+ }
+
+ /**
+ * This method is made public only for the tests. Clients should not be
+ * using this method
+ *
+ * @return the updateJob that updates the site
+ */
+ public SiteUpdateJob getUpdateJob() {
+ return updateJob;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/registry/EditorDescriptor.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/registry/EditorDescriptor.java
new file mode 100644
index 0000000..7c94906
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/registry/EditorDescriptor.java
@@ -0,0 +1,682 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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
+ * James Blackburn - Bug 256316 getImageDescriptor() is not thread safe
+ *******************************************************************************/
+package org.eclipse.ui.internal.registry;
+
+import java.io.File;
+import java.io.Serializable;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.program.Program;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorMatchingStrategy;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPluginContribution;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.internal.IWorkbenchConstants;
+import org.eclipse.ui.internal.WorkbenchImages;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.internal.misc.ProgramImageDescriptor;
+import org.eclipse.ui.internal.tweaklets.InterceptContributions;
+import org.eclipse.ui.internal.tweaklets.Tweaklets;
+import org.eclipse.ui.internal.util.Util;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * @see IEditorDescriptor
+ */
+public final class EditorDescriptor implements IEditorDescriptor, Serializable,
+ IPluginContribution {
+
+ /**
+ * Generated serial version UID for this class.
+ *
+ * @since 3.1
+ */
+ private static final long serialVersionUID = 3905241225668998961L;
+
+ // @issue the following constants need not be public; see bug 47600
+ /**
+ * Open internal constant. Value <code>0x01</code>.
+ */
+ public static final int OPEN_INTERNAL = 0x01;
+
+ /**
+ * Open in place constant. Value <code>0x02</code>.
+ */
+ public static final int OPEN_INPLACE = 0x02;
+
+ /**
+ * Open external constant. Value <code>0x04</code>.
+ */
+ public static final int OPEN_EXTERNAL = 0x04;
+
+ private String editorName;
+
+ private String imageFilename;
+
+ private transient ImageDescriptor imageDesc;
+ private transient Object imageDescLock = new Object();
+
+ private boolean testImage = true;
+
+ private String className;
+
+ private String launcherName;
+
+ private String fileName;
+
+ private String id = Util.ZERO_LENGTH_STRING;
+
+ private boolean matchingStrategyChecked = false;
+ private IEditorMatchingStrategy matchingStrategy;
+
+ private Program program;
+
+ // The id of the plugin which contributed this editor, null for external
+ // editors
+ private String pluginIdentifier;
+
+ private int openMode = 0;
+
+ private transient IConfigurationElement configurationElement;
+
+ /**
+ * Create a new instance of an editor descriptor. Limited to internal
+ * framework calls.
+ *
+ * @param element
+ * @param id2
+ */
+ public EditorDescriptor(String id2, IConfigurationElement element) {
+ setID(id2);
+ setConfigurationElement(element);
+ }
+
+ /**
+ * Create a new instance of an editor descriptor. Limited to internal
+ * framework calls.
+ */
+ /* package */EditorDescriptor() {
+ super();
+ }
+
+ /**
+ * Creates a descriptor for an external program.
+ *
+ * @param filename
+ * the external editor full path and filename
+ * @return the editor descriptor
+ */
+ public static EditorDescriptor createForProgram(String filename) {
+ if (filename == null) {
+ throw new IllegalArgumentException();
+ }
+ EditorDescriptor editor = new EditorDescriptor();
+
+ editor.setFileName(filename);
+ editor.setID(filename);
+ editor.setOpenMode(OPEN_EXTERNAL);
+
+ // Isolate the program name (no directory or extension)
+ int start = filename.lastIndexOf(File.separator);
+ String name;
+ if (start != -1) {
+ name = filename.substring(start + 1);
+ } else {
+ name = filename;
+ }
+ int end = name.lastIndexOf('.');
+ if (end != -1) {
+ name = name.substring(0, end);
+ }
+ editor.setName(name);
+
+ // get the program icon without storing it in the registry
+ ImageDescriptor imageDescriptor = new ProgramImageDescriptor(filename,
+ 0);
+ editor.setImageDescriptor(imageDescriptor);
+
+ return editor;
+ }
+
+ /**
+ * Return the program called programName. Return null if it is not found.
+ *
+ * @return org.eclipse.swt.program.Program
+ */
+ private static Program findProgram(String programName) {
+
+ Program[] programs = Program.getPrograms();
+ for (int i = 0; i < programs.length; i++) {
+ if (programs[i].getName().equals(programName)) {
+ return programs[i];
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Create the editor action bar contributor for editors of this type.
+ *
+ * @return the action bar contributor, or <code>null</code>
+ */
+ public IEditorActionBarContributor createActionBarContributor() {
+ // Handle case for predefined editor descriptors, like the
+ // one for IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID, which
+ // don't have a configuration element.
+ if (configurationElement == null) {
+ return null;
+ }
+
+ // Get the contributor class name.
+ String className = configurationElement
+ .getAttribute(IWorkbenchRegistryConstants.ATT_CONTRIBUTOR_CLASS);
+ if (className == null) {
+ return null;
+ }
+
+ // Create the contributor object.
+ IEditorActionBarContributor contributor = null;
+ try {
+ contributor = (IEditorActionBarContributor) WorkbenchPlugin
+ .createExtension(configurationElement,
+ IWorkbenchRegistryConstants.ATT_CONTRIBUTOR_CLASS);
+ } catch (CoreException e) {
+ WorkbenchPlugin.log("Unable to create editor contributor: " + //$NON-NLS-1$
+ id, e.getStatus());
+ }
+ return contributor;
+ }
+
+ /**
+ * Return the editor class name.
+ *
+ * @return the class name
+ */
+ public String getClassName() {
+ if (configurationElement == null) {
+ return className;
+ }
+ return RegistryReader.getClassValue(configurationElement,
+ IWorkbenchRegistryConstants.ATT_CLASS);
+ }
+
+ /**
+ * Return the configuration element used to define this editor, or
+ * <code>null</code>.
+ *
+ * @return the element or null
+ */
+ public IConfigurationElement getConfigurationElement() {
+ return configurationElement;
+ }
+
+ /**
+ * Create an editor part based on this descriptor.
+ *
+ * @return the editor part
+ * @throws CoreException
+ * thrown if there is an issue creating the editor
+ */
+ public IEditorPart createEditor() throws CoreException {
+ Object extension = WorkbenchPlugin.createExtension(
+ getConfigurationElement(),
+ IWorkbenchRegistryConstants.ATT_CLASS);
+ return ((InterceptContributions) Tweaklets
+ .get(InterceptContributions.KEY)).tweakEditor(extension);
+ }
+
+ /**
+ * Return the file name of the command to execute for this editor.
+ *
+ * @return the file name to execute
+ */
+ public String getFileName() {
+ if (program == null) {
+ if (configurationElement == null) {
+ return fileName;
+ }
+ return configurationElement
+ .getAttribute(IWorkbenchRegistryConstants.ATT_COMMAND);
+ }
+ return program.getName();
+ }
+
+ /**
+ * Return the id for this editor.
+ *
+ * @return the id
+ */
+ public String getId() {
+ if (program == null) {
+ if (configurationElement == null) {
+ return Util.safeString(id);
+ }
+ return Util.safeString(configurationElement
+ .getAttribute(IWorkbenchRegistryConstants.ATT_ID));
+
+ }
+ return Util.safeString(program.getName());
+ }
+
+ /**
+ * Return the image descriptor describing this editor.
+ *
+ * @return the image descriptor
+ */
+ public ImageDescriptor getImageDescriptor() {
+ ImageDescriptor tempDescriptor = null;
+
+ synchronized (imageDescLock) {
+ if (!testImage)
+ return imageDesc;
+
+ if (imageDesc == null) {
+ String imageFileName = getImageFilename();
+ String command = getFileName();
+ if (imageFileName != null && configurationElement != null)
+ tempDescriptor = AbstractUIPlugin
+ .imageDescriptorFromPlugin(configurationElement
+ .getNamespaceIdentifier(), imageFileName);
+ else if (command != null)
+ tempDescriptor = WorkbenchImages
+ .getImageDescriptorFromProgram(command, 0);
+ } else
+ tempDescriptor = imageDesc;
+
+ if (tempDescriptor == null) { // still null? return default image
+ imageDesc = WorkbenchImages
+ .getImageDescriptor(ISharedImages.IMG_OBJ_FILE);
+ testImage = false;
+ return imageDesc;
+ }
+ }
+
+ // Verifies that the image descriptor generates an image. If not, the
+ // descriptor is
+ // replaced with the default image.
+ // We must create the image without holding any locks, since there is a
+ // potential for deadlock
+ // on Linux due to SWT's implementation of Image. See bugs 265028 and
+ // 256316 for details.
+ Image img = tempDescriptor.createImage(false);
+ if (img == null) // @issue what should be the default image?
+ tempDescriptor = WorkbenchImages
+ .getImageDescriptor(ISharedImages.IMG_OBJ_FILE);
+ else
+ img.dispose();
+ // <----- End of must-not-lock part
+
+ // reenter synchronized block
+ synchronized (imageDescLock) {
+ // if another thread has set the image description, use it
+ if (!testImage)
+ return imageDesc;
+ // otherwise set the image description we calculated above
+ imageDesc = tempDescriptor;
+ testImage = false;
+ return imageDesc;
+ }
+ }
+
+ /**
+ * The Image to use to repesent this editor
+ */
+ /* package */void setImageDescriptor(ImageDescriptor desc) {
+ synchronized (imageDescLock) {
+ imageDesc = desc;
+ testImage = true;
+ }
+ }
+
+ /**
+ * The name of the image describing this editor.
+ *
+ * @return the image file name
+ */
+ public String getImageFilename() {
+ if (configurationElement == null) {
+ return imageFilename;
+ }
+ return configurationElement
+ .getAttribute(IWorkbenchRegistryConstants.ATT_ICON);
+ }
+
+ /**
+ * Return the user printable label for this editor.
+ *
+ * @return the label
+ */
+ public String getLabel() {
+ if (program == null) {
+ if (configurationElement == null) {
+ return editorName;
+ }
+ return configurationElement
+ .getAttribute(IWorkbenchRegistryConstants.ATT_NAME);
+ }
+ return program.getName();
+ }
+
+ /**
+ * Returns the class name of the launcher.
+ *
+ * @return the launcher class name
+ */
+ public String getLauncher() {
+ if (configurationElement == null) {
+ return launcherName;
+ }
+ return configurationElement
+ .getAttribute(IWorkbenchRegistryConstants.ATT_LAUNCHER);
+ }
+
+ /**
+ * Return the contributing plugin id.
+ *
+ * @return the contributing plugin id
+ */
+ public String getPluginID() {
+ if (configurationElement != null) {
+ return configurationElement.getNamespace();
+ }
+ return pluginIdentifier;
+ }
+
+ /**
+ * Get the program for the receiver if there is one.
+ *
+ * @return Program
+ */
+ public Program getProgram() {
+ return this.program;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IEditorDescriptor#isInternal
+ */
+ public boolean isInternal() {
+ return getOpenMode() == OPEN_INTERNAL;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IEditorDescriptor#isOpenInPlace
+ */
+ public boolean isOpenInPlace() {
+ return getOpenMode() == OPEN_INPLACE;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IEditorDescriptor#isOpenExternal
+ */
+ public boolean isOpenExternal() {
+ return getOpenMode() == OPEN_EXTERNAL;
+ }
+
+ /**
+ * Load the object properties from a memento.
+ *
+ * @return <code>true</code> if the values are valid, <code>false</code>
+ * otherwise
+ */
+ protected boolean loadValues(IMemento memento) {
+ editorName = memento.getString(IWorkbenchConstants.TAG_LABEL);
+ imageFilename = memento.getString(IWorkbenchConstants.TAG_IMAGE);
+ className = memento.getString(IWorkbenchConstants.TAG_CLASS);
+ launcherName = memento.getString(IWorkbenchConstants.TAG_LAUNCHER);
+ fileName = memento.getString(IWorkbenchConstants.TAG_FILE);
+ id = Util.safeString(memento.getString(IWorkbenchConstants.TAG_ID));
+ pluginIdentifier = memento.getString(IWorkbenchConstants.TAG_PLUGIN);
+
+ Integer openModeInt = memento
+ .getInteger(IWorkbenchConstants.TAG_OPEN_MODE);
+ if (openModeInt != null) {
+ openMode = openModeInt.intValue();
+ } else {
+ // legacy: handle the older attribute names, needed to allow reading
+ // of pre-3.0-RCP workspaces
+ boolean internal = new Boolean(memento
+ .getString(IWorkbenchConstants.TAG_INTERNAL))
+ .booleanValue();
+ boolean openInPlace = new Boolean(memento
+ .getString(IWorkbenchConstants.TAG_OPEN_IN_PLACE))
+ .booleanValue();
+ if (internal) {
+ openMode = OPEN_INTERNAL;
+ } else {
+ if (openInPlace) {
+ openMode = OPEN_INPLACE;
+ } else {
+ openMode = OPEN_EXTERNAL;
+ }
+ }
+ }
+ if (openMode != OPEN_EXTERNAL && openMode != OPEN_INTERNAL
+ && openMode != OPEN_INPLACE) {
+ WorkbenchPlugin
+ .log("Ignoring editor descriptor with invalid openMode: " + this); //$NON-NLS-1$
+ return false;
+ }
+
+ String programName = memento
+ .getString(IWorkbenchConstants.TAG_PROGRAM_NAME);
+ if (programName != null) {
+ this.program = findProgram(programName);
+ }
+ return true;
+ }
+
+ /**
+ * Save the object values in a IMemento
+ */
+ protected void saveValues(IMemento memento) {
+ memento.putString(IWorkbenchConstants.TAG_LABEL, getLabel());
+ memento.putString(IWorkbenchConstants.TAG_IMAGE, getImageFilename());
+ memento.putString(IWorkbenchConstants.TAG_CLASS, getClassName());
+ memento.putString(IWorkbenchConstants.TAG_LAUNCHER, getLauncher());
+ memento.putString(IWorkbenchConstants.TAG_FILE, getFileName());
+ memento.putString(IWorkbenchConstants.TAG_ID, getId());
+ memento.putString(IWorkbenchConstants.TAG_PLUGIN, getPluginId());
+
+ memento.putInteger(IWorkbenchConstants.TAG_OPEN_MODE, getOpenMode());
+ // legacy: handle the older attribute names, needed to allow reading of
+ // workspace by pre-3.0-RCP eclipses
+ memento.putString(IWorkbenchConstants.TAG_INTERNAL, String
+ .valueOf(isInternal()));
+ memento.putString(IWorkbenchConstants.TAG_OPEN_IN_PLACE, String
+ .valueOf(isOpenInPlace()));
+
+ if (this.program != null) {
+ memento.putString(IWorkbenchConstants.TAG_PROGRAM_NAME,
+ this.program.getName());
+ }
+ }
+
+ /**
+ * Return the open mode of this editor.
+ *
+ * @return the open mode of this editor
+ * @since 3.1
+ */
+ private int getOpenMode() {
+ if (configurationElement == null) { // if we've been serialized, return
+ // our serialized value
+ return openMode;
+ } else if (getLauncher() != null) {
+ // open using a launcer
+ return EditorDescriptor.OPEN_EXTERNAL;
+ } else if (getFileName() != null) {
+ // open using an external editor
+ return EditorDescriptor.OPEN_EXTERNAL;
+ } else if (getPluginId() != null) {
+ // open using an internal editor
+ return EditorDescriptor.OPEN_INTERNAL;
+ } else {
+ return 0; // default for system editor
+ }
+ }
+
+ /**
+ * Set the class name of an internal editor.
+ */
+ /* package */void setClassName(String newClassName) {
+ className = newClassName;
+ }
+
+ /**
+ * Set the configuration element which contributed this editor.
+ */
+ /* package */void setConfigurationElement(
+ IConfigurationElement newConfigurationElement) {
+ configurationElement = newConfigurationElement;
+ }
+
+ /**
+ * Set the filename of an external editor.
+ */
+ /* package */void setFileName(String aFileName) {
+ fileName = aFileName;
+ }
+
+ /**
+ * Set the id of the editor. For internal editors this is the id as provided
+ * in the extension point For external editors it is path and filename of
+ * the editor
+ */
+ /* package */void setID(String anID) {
+ Assert.isNotNull(anID);
+ id = anID;
+ }
+
+ /**
+ * The name of the image to use for this editor.
+ */
+ /* package */void setImageFilename(String aFileName) {
+ imageFilename = aFileName;
+ }
+
+ /**
+ * Sets the new launcher class name
+ *
+ * @param newLauncher
+ * the new launcher
+ */
+ /* package */void setLauncher(String newLauncher) {
+ launcherName = newLauncher;
+ }
+
+ /**
+ * The label to show for this editor.
+ */
+ /* package */void setName(String newName) {
+ editorName = newName;
+ }
+
+ /**
+ * Sets the open mode of this editor descriptor.
+ *
+ * @param mode
+ * the open mode
+ *
+ * @issue this method is public as a temporary fix for bug 47600
+ */
+ public void setOpenMode(int mode) {
+ openMode = mode;
+ }
+
+ /**
+ * The id of the plugin which contributed this editor, null for external
+ * editors.
+ */
+ /* package */void setPluginIdentifier(String anID) {
+ pluginIdentifier = anID;
+ }
+
+ /**
+ * Set the receivers program.
+ *
+ * @param newProgram
+ */
+ /* package */void setProgram(Program newProgram) {
+
+ this.program = newProgram;
+ if (editorName == null) {
+ setName(newProgram.getName());
+ }
+ }
+
+ /**
+ * For debugging purposes only.
+ */
+ public String toString() {
+ return "EditorDescriptor(id=" + getId() + ", label=" + getLabel() + ")"; //$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.activities.support.IPluginContribution#getLocalId()
+ */
+ public String getLocalId() {
+ return getId();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.activities.support.IPluginContribution#getPluginId()
+ */
+ public String getPluginId() {
+ return getPluginID();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IEditorDescriptor#getEditorManagementPolicy()
+ */
+ public IEditorMatchingStrategy getEditorMatchingStrategy() {
+ if (matchingStrategy == null && !matchingStrategyChecked) {
+ matchingStrategyChecked = true;
+ if (program == null && configurationElement != null) {
+ if (configurationElement
+ .getAttribute(IWorkbenchRegistryConstants.ATT_MATCHING_STRATEGY) != null) {
+ try {
+ matchingStrategy = (IEditorMatchingStrategy) WorkbenchPlugin
+ .createExtension(
+ configurationElement,
+ IWorkbenchRegistryConstants.ATT_MATCHING_STRATEGY);
+ } catch (CoreException e) {
+ WorkbenchPlugin
+ .log(
+ "Error creating editor management policy for editor id " + getId(), e); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ return matchingStrategy;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/services/ServiceLocator.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/services/ServiceLocator.java
new file mode 100644
index 0000000..9697efa
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/services/ServiceLocator.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 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.ui.internal.services;
+
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.ui.services.AbstractServiceFactory;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.services.IServiceLocator;
+
+/**
+ * @since 3.2
+ *
+ */
+public final class ServiceLocator implements IDisposable, INestable,
+ IServiceLocator {
+ boolean activated = false;
+
+ // private AbstractServiceFactory factory;
+
+ /**
+ * The parent for this service locator. If a service can't be found in this
+ * locator, then the parent is asked. This value may be <code>null</code> if
+ * there is no parent.
+ */
+ // private IServiceLocator parent;
+
+ private boolean disposed;
+
+ private final IDisposable owner;
+
+ private IEclipseContext e4Context;
+
+ /**
+ * Constructs a service locator with no parent.
+ */
+ public ServiceLocator() {
+ this(null, null, null);
+ }
+
+ /**
+ * Constructs a service locator with the given parent.
+ *
+ * @param parent
+ * The parent for this service locator; this value may be
+ * <code>null</code>.
+ * @param factory
+ * a local factory that can provide services at this level
+ * @param owner
+ */
+ public ServiceLocator(final IServiceLocator parent,
+ AbstractServiceFactory factory, IDisposable owner) {
+ // this.parent = parent;
+ // this.factory = factory;
+ this.owner = owner;
+ }
+
+ public final void activate() {
+ activated = true;
+ }
+
+ public final void deactivate() {
+ activated = false;
+ }
+
+ public final void dispose() {
+ // parent = null;
+ e4Context = null;
+ disposed = true;
+ }
+
+ public final Object getService(final Class key) {
+ if (disposed) {
+ return null;
+ }
+ return e4Context.get(key.getName());
+ }
+
+ public final boolean hasService(final Class key) {
+ if (disposed) {
+ return false;
+ }
+ return e4Context.containsKey(key.getName());
+ }
+
+ /**
+ * Registers a service with this locator. If there is an existing service
+ * matching the same <code>api</code> and it implements {@link IDisposable},
+ * it will be disposed.
+ *
+ * @param api
+ * This is the interface that the service implements. Must not be
+ * <code>null</code>.
+ * @param service
+ * The service to register. This must be some implementation of
+ * <code>api</code>. This value must not be <code>null</code>.
+ */
+ public final void registerService(final Class api, final Object service) {
+ if (api == null) {
+ throw new NullPointerException("The service key cannot be null"); //$NON-NLS-1$
+ }
+
+ if (!api.isInstance(service)) {
+ throw new IllegalArgumentException(
+ "The service does not implement the given interface"); //$NON-NLS-1$
+ }
+ e4Context.set(api.getName(), service);
+ }
+
+ /**
+ * @return
+ */
+ public boolean isDisposed() {
+ return disposed;
+ }
+
+ /**
+ * Some services that were contributed to this locator are no longer
+ * available (because the plug-in containing the AbstractServiceFactory is
+ * no longer available). Notify the owner of the locator about this.
+ */
+ public void unregisterServices(String[] serviceNames) {
+ if (owner != null) {
+ owner.dispose();
+ }
+ }
+
+ public void setContext(IEclipseContext context) {
+ e4Context = context;
+ }
+
+ public IEclipseContext getContext() {
+ return e4Context;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorPart.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorPart.java
new file mode 100644
index 0000000..cb95109
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorPart.java
@@ -0,0 +1,1311 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ui.part;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.util.Tracing;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.e4.core.services.context.EclipseContextFactory;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.workbench.ui.internal.UISchedulerStrategy;
+import org.eclipse.jface.dialogs.IPageChangeProvider;
+import org.eclipse.jface.dialogs.IPageChangedListener;
+import org.eclipse.jface.dialogs.PageChangedEvent;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IKeyBindingService;
+import org.eclipse.ui.INestableKeyBindingService;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.internal.EditorSite;
+import org.eclipse.ui.internal.PartSite;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.internal.misc.Policy;
+import org.eclipse.ui.internal.services.INestable;
+import org.eclipse.ui.internal.services.IServiceLocatorCreator;
+import org.eclipse.ui.internal.services.ServiceLocator;
+import org.eclipse.ui.internal.util.Util;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.services.IServiceLocator;
+
+/**
+ * A multi-page editor is an editor with multiple pages, each of which may
+ * contain an editor or an arbitrary SWT control.
+ * <p>
+ * Subclasses must implement the following methods:
+ * <ul>
+ * <li><code>createPages</code> - to create the required pages by calling one of
+ * the <code>addPage</code> methods</li>
+ * <li><code>IEditorPart.doSave</code> - to save contents of editor</li>
+ * <li><code>IEditorPart.doSaveAs</code> - to save contents of editor</li>
+ * <li><code>IEditorPart.isSaveAsAllowed</code> - to enable Save As</li>
+ * <li><code>IEditorPart.gotoMarker</code> - to scroll to a marker</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Multi-page editors have a single action bar contributor, which manages
+ * contributions for all the pages. The contributor must be a subclass of
+ * <code>MultiPageEditorActionBarContributor</code>. Note that since any nested
+ * editors are created directly in code by callers of
+ * <code>addPage(IEditorPart,IEditorInput)</code>, nested editors do not have
+ * their own contributors.
+ * </p>
+ * <p>
+ * As of 3.5 multi-page editors will post PageChangedEvents at the end of
+ * {@link #pageChange(int)}. Subclasses may override {@link #getSelectedPage()}
+ * to return a page appropriate to their multi-page editor. IPartListener2
+ * listeners registered with the IPartService can implement IPageChangedListener
+ * to be notified about all page change events within the workbench page or
+ * workbench window.
+ * </p>
+ *
+ * @see org.eclipse.ui.part.MultiPageEditorActionBarContributor
+ * @see org.eclipse.jface.dialogs.IPageChangeProvider
+ * @see org.eclipse.jface.dialogs.IPageChangedListener
+ * @see org.eclipse.ui.IPartService
+ */
+public abstract class MultiPageEditorPart extends EditorPart implements
+ IPageChangeProvider {
+
+ private static final String COMMAND_NEXT_SUB_TAB = "org.eclipse.ui.navigate.nextSubTab"; //$NON-NLS-1$
+ private static final String COMMAND_PREVIOUS_SUB_TAB = "org.eclipse.ui.navigate.previousSubTab"; //$NON-NLS-1$
+
+ /**
+ * Subclasses that override {@link #createPageContainer(Composite)} can use
+ * this constant to get a site for the container that can be active while
+ * the current page is deactivated.
+ *
+ * @since 3.4
+ * @see #activateSite()
+ * @see #deactivateSite(boolean, boolean)
+ * @see #getPageSite(int)
+ */
+ protected static final int PAGE_CONTAINER_SITE = 65535;
+
+ /**
+ * Private tracing output.
+ */
+ private static final String TRACING_COMPONENT = "MPE"; //$NON-NLS-1$
+
+ /**
+ * The active service locator. This value may be <code>null</code> if there
+ * is no selected page, or if the selected page is a control with no site.
+ */
+ private INestable activeServiceLocator;
+
+ /**
+ * The container widget.
+ */
+ private CTabFolder container;
+
+ /**
+ * List of nested editors. Element type: IEditorPart. Need to hang onto them
+ * here, in addition to using get/setData on the items, because dispose()
+ * needs to access them, but widgetry has already been disposed at that
+ * point.
+ */
+ private ArrayList nestedEditors = new ArrayList(3);
+
+ private List pageSites = new ArrayList(3);
+
+ private IServiceLocator pageContainerSite;
+
+ private ListenerList pageChangeListeners = new ListenerList(
+ ListenerList.IDENTITY);
+
+ /**
+ * Creates an empty multi-page editor with no pages.
+ */
+ protected MultiPageEditorPart() {
+ super();
+ }
+
+ /**
+ * Creates and adds a new page containing the given control to this
+ * multi-page editor. The control may be <code>null</code>, allowing it to
+ * be created and set later using <code>setControl</code>.
+ *
+ * @param control
+ * the control, or <code>null</code>
+ * @return the index of the new page
+ *
+ * @see MultiPageEditorPart#setControl(int, Control)
+ */
+ public int addPage(Control control) {
+ int index = getPageCount();
+ addPage(index, control);
+ return index;
+ }
+
+ /**
+ * Creates and adds a new page containing the given control to this
+ * multi-page editor. The page is added at the given index. The control may
+ * be <code>null</code>, allowing it to be created and set later using
+ * <code>setControl</code>.
+ *
+ * @param index
+ * the index at which to add the page (0-based)
+ * @param control
+ * the control, or <code>null</code>
+ *
+ * @see MultiPageEditorPart#setControl(int, Control)
+ */
+ public void addPage(int index, Control control) {
+ createItem(index, control);
+ }
+
+ /**
+ * Creates and adds a new page containing the given editor to this
+ * multi-page editor. This also hooks a property change listener on the
+ * nested editor.
+ *
+ * @param editor
+ * the nested editor
+ * @param input
+ * the input for the nested editor
+ * @return the index of the new page
+ * @exception PartInitException
+ * if a new page could not be created
+ *
+ * @see MultiPageEditorPart#handlePropertyChange(int) the handler for
+ * property change events from the nested editor
+ */
+ public int addPage(IEditorPart editor, IEditorInput input)
+ throws PartInitException {
+ int index = getPageCount();
+ addPage(index, editor, input);
+ return index;
+ }
+
+ /**
+ * Creates and adds a new page containing the given editor to this
+ * multi-page editor. The page is added at the given index. This also hooks
+ * a property change listener on the nested editor.
+ *
+ * @param index
+ * the index at which to add the page (0-based)
+ * @param editor
+ * the nested editor
+ * @param input
+ * the input for the nested editor
+ * @exception PartInitException
+ * if a new page could not be created
+ *
+ * @see MultiPageEditorPart#handlePropertyChange(int) the handler for
+ * property change events from the nested editor
+ */
+ public void addPage(int index, IEditorPart editor, IEditorInput input)
+ throws PartInitException {
+ IEditorSite site = createSite(editor);
+ // call init first so that if an exception is thrown, we have created no
+ // new widgets
+ editor.init(site, input);
+ Composite parent2 = new Composite(getContainer(),
+ getOrientation(editor));
+ parent2.setLayout(new FillLayout());
+ editor.createPartControl(parent2);
+ editor.addPropertyListener(new IPropertyListener() {
+ public void propertyChanged(Object source, int propertyId) {
+ MultiPageEditorPart.this.handlePropertyChange(propertyId);
+ }
+ });
+ // create item for page only after createPartControl has succeeded
+ Item item = createItem(index, parent2);
+ // remember the editor, as both data on the item, and in the list of
+ // editors (see field comment)
+ item.setData(editor);
+ nestedEditors.add(editor);
+ }
+
+ /**
+ * Get the orientation of the editor.
+ *
+ * @param editor
+ * @return int the orientation flag
+ * @see SWT#RIGHT_TO_LEFT
+ * @see SWT#LEFT_TO_RIGHT
+ * @see SWT#NONE
+ */
+ private int getOrientation(IEditorPart editor) {
+ if (editor instanceof IWorkbenchPartOrientation) {
+ return ((IWorkbenchPartOrientation) editor).getOrientation();
+ }
+ return getOrientation();
+ }
+
+ /**
+ * Creates an empty container. Creates a CTabFolder with no style bits set,
+ * and hooks a selection listener which calls <code>pageChange()</code>
+ * whenever the selected tab changes.
+ *
+ * @param parent
+ * The composite in which the container tab folder should be
+ * created; must not be <code>null</code>.
+ * @return a new container
+ */
+ private CTabFolder createContainer(Composite parent) {
+ // use SWT.FLAT style so that an extra 1 pixel border is not reserved
+ // inside the folder
+ parent.setLayout(new FillLayout());
+ final CTabFolder newContainer = new CTabFolder(parent, SWT.BOTTOM
+ | SWT.FLAT);
+ newContainer.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ int newPageIndex = newContainer.indexOf((CTabItem) e.item);
+ pageChange(newPageIndex);
+ }
+ });
+ newContainer.addTraverseListener(new TraverseListener() {
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=199499 :
+ // Switching tabs by Ctrl+PageUp/PageDown must not be caught on the
+ // inner tab set
+ public void keyTraversed(TraverseEvent e) {
+ switch (e.detail) {
+ case SWT.TRAVERSE_PAGE_NEXT:
+ case SWT.TRAVERSE_PAGE_PREVIOUS:
+ int detail = e.detail;
+ e.doit = true;
+ e.detail = SWT.TRAVERSE_NONE;
+ Control control = newContainer.getParent();
+ do {
+ if (control.traverse(detail))
+ return;
+ if (control.getListeners(SWT.Traverse).length != 0)
+ return;
+ if (control instanceof Shell)
+ return;
+ control = control.getParent();
+ } while (control != null);
+ }
+ }
+ });
+ return newContainer;
+ }
+
+ /**
+ * Creates a tab item at the given index and places the given control in the
+ * new item. The item is a CTabItem with no style bits set.
+ *
+ * @param index
+ * the index at which to add the control
+ * @param control
+ * is the control to be placed in an item
+ * @return a new item
+ */
+ private CTabItem createItem(int index, Control control) {
+ CTabItem item = new CTabItem(getTabFolder(), SWT.NONE, index);
+ item.setControl(control);
+ return item;
+ }
+
+ /**
+ * Creates the pages of this multi-page editor.
+ * <p>
+ * Subclasses must implement this method.
+ * </p>
+ */
+ protected abstract void createPages();
+
+ /**
+ * The <code>MultiPageEditor</code> implementation of this
+ * <code>IWorkbenchPart</code> method creates the control for the multi-page
+ * editor by calling <code>createContainer</code>, then
+ * <code>createPages</code>. Subclasses should implement
+ * <code>createPages</code> rather than overriding this method.
+ *
+ * @param parent
+ * The parent in which the editor should be created; must not be
+ * <code>null</code>.
+ */
+ public final void createPartControl(Composite parent) {
+ Composite pageContainer = createPageContainer(parent);
+ this.container = createContainer(pageContainer);
+ createPages();
+ // set the active page (page 0 by default), unless it has already been
+ // done
+ if (getActivePage() == -1) {
+ setActivePage(0);
+ IEditorPart part = getEditor(0);
+ if (part != null) {
+ final IServiceLocator serviceLocator = part.getEditorSite();
+ if (serviceLocator instanceof INestable) {
+ activeServiceLocator = (INestable) serviceLocator;
+ activeServiceLocator.activate();
+ }
+ }
+ }
+ initializePageSwitching();
+ initializeSubTabSwitching();
+ }
+
+ /**
+ * Initialize the MultiPageEditorPart to use the page switching command.
+ * Clients can override this method with an empty body if they wish to
+ * opt-out.
+ *
+ * @since 3.4
+ */
+ protected void initializePageSwitching() {
+ new PageSwitcher(this) {
+ public Object[] getPages() {
+ int pageCount = getPageCount();
+ Object[] result = new Object[pageCount];
+ for (int i = 0; i < pageCount; i++) {
+ result[i] = new Integer(i);
+ }
+ return result;
+ }
+
+ public String getName(Object page) {
+ return getPageText(((Integer) page).intValue());
+ }
+
+ public ImageDescriptor getImageDescriptor(Object page) {
+ Image image = getPageImage(((Integer) page).intValue());
+ if (image == null)
+ return null;
+
+ return ImageDescriptor.createFromImage(image);
+ }
+
+ public void activatePage(Object page) {
+ setActivePage(((Integer) page).intValue());
+ }
+
+ public int getCurrentPageIndex() {
+ return getActivePage();
+ }
+ };
+ }
+
+ /**
+ * Initialize the MultiPageEditorPart to use the sub-tab switching commands.
+ *
+ * @since 3.5
+ */
+ private void initializeSubTabSwitching() {
+ IHandlerService service = (IHandlerService) getSite().getService(
+ IHandlerService.class);
+ service.activateHandler(COMMAND_NEXT_SUB_TAB, new AbstractHandler() {
+ /**
+ * {@inheritDoc}
+ *
+ * @throws ExecutionException
+ * if an exception occurred during execution
+ */
+ public Object execute(ExecutionEvent event)
+ throws ExecutionException {
+ int n = getPageCount();
+ if (n == 0)
+ return null;
+
+ int i = getActivePage() + 1;
+ if (i >= n)
+ i = 0;
+ setActivePage(i);
+ return null;
+ }
+ });
+
+ service.activateHandler(COMMAND_PREVIOUS_SUB_TAB,
+ new AbstractHandler() {
+ /**
+ * {@inheritDoc}
+ *
+ * @throws ExecutionException
+ * if an exception occurred during execution
+ */
+ public Object execute(ExecutionEvent event)
+ throws ExecutionException {
+ int n = getPageCount();
+ if (n == 0)
+ return null;
+
+ int i = getActivePage() - 1;
+ if (i < 0)
+ i = n - 1;
+ setActivePage(i);
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Creates the parent control for the container returned by
+ * {@link #getContainer() }.
+ *
+ * <p>
+ * Subclasses may extend and must call super implementation first.
+ * </p>
+ *
+ * @param parent
+ * the parent for all of the editors contents.
+ * @return the parent for this editor's container. Must not be
+ * <code>null</code>.
+ *
+ * @since 3.2
+ */
+ protected Composite createPageContainer(Composite parent) {
+ return parent;
+ }
+
+ /**
+ * Creates the site for the given nested editor. The
+ * <code>MultiPageEditorPart</code> implementation of this method creates an
+ * instance of <code>MultiPageEditorSite</code>. Subclasses may reimplement
+ * to create more specialized sites.
+ *
+ * @param editor
+ * the nested editor
+ * @return the editor site
+ */
+ protected IEditorSite createSite(IEditorPart editor) {
+ return new MultiPageEditorSite(this, editor);
+ }
+
+ /**
+ * The <code>MultiPageEditorPart</code> implementation of this
+ * <code>IWorkbenchPart</code> method disposes all nested editors.
+ * Subclasses may extend.
+ */
+ public void dispose() {
+ pageChangeListeners.clear();
+ for (int i = 0; i < nestedEditors.size(); ++i) {
+ IEditorPart editor = (IEditorPart) nestedEditors.get(i);
+ disposePart(editor);
+ }
+ nestedEditors.clear();
+ if (pageContainerSite instanceof IDisposable) {
+ ((IDisposable) pageContainerSite).dispose();
+ pageContainerSite = null;
+ }
+ for (int i = 0; i < pageSites.size(); i++) {
+ IServiceLocator sl = (IServiceLocator) pageSites.get(i);
+ if (sl instanceof IDisposable) {
+ ((IDisposable) sl).dispose();
+ }
+ }
+ pageSites.clear();
+ super.dispose();
+ }
+
+ /**
+ * Returns the active nested editor if there is one.
+ * <p>
+ * Subclasses should not override this method
+ * </p>
+ *
+ * @nooverride
+ * @return the active nested editor, or <code>null</code> if none
+ */
+ protected IEditorPart getActiveEditor() {
+ int index = getActivePage();
+ if (index != -1) {
+ return getEditor(index);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the index of the currently active page, or -1 if there is no
+ * active page.
+ * <p>
+ * Subclasses should not override this method
+ * </p>
+ *
+ * @nooverride
+ *
+ * @return the index of the active page, or -1 if there is no active page
+ * @since 3.5
+ */
+ public int getActivePage() {
+ CTabFolder tabFolder = getTabFolder();
+ if (tabFolder != null && !tabFolder.isDisposed()) {
+ return tabFolder.getSelectionIndex();
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the composite control containing this multi-page editor's pages.
+ * This should be used as the parent when creating controls for the
+ * individual pages. That is, when calling <code>addPage(Control)</code>,
+ * the passed control should be a child of this container.
+ * <p>
+ * Warning: Clients should not assume that the container is any particular
+ * subclass of Composite. The actual class used may change in order to
+ * improve the look and feel of multi-page editors. Any code making
+ * assumptions on the particular subclass would thus be broken.
+ * </p>
+ * <p>
+ * Subclasses should not override this method
+ * </p>
+ *
+ * @return the composite, or <code>null</code> if
+ * <code>createPartControl</code> has not been called yet
+ */
+ protected Composite getContainer() {
+ return container;
+ }
+
+ /**
+ * Returns the control for the given page index, or <code>null</code> if no
+ * control has been set for the page. The page index must be valid.
+ * <p>
+ * Subclasses should not override this method
+ * </p>
+ *
+ * @param pageIndex
+ * the index of the page
+ * @return the control for the specified page, or <code>null</code> if none
+ * has been set
+ */
+ protected Control getControl(int pageIndex) {
+ return getItem(pageIndex).getControl();
+ }
+
+ /**
+ * Returns the editor for the given page index. The page index must be
+ * valid.
+ *
+ * @param pageIndex
+ * the index of the page
+ * @return the editor for the specified page, or <code>null</code> if the
+ * specified page was not created with
+ * <code>addPage(IEditorPart,IEditorInput)</code>
+ */
+ protected IEditorPart getEditor(int pageIndex) {
+ Item item = getItem(pageIndex);
+ if (item != null) {
+ Object data = item.getData();
+ if (data instanceof IEditorPart) {
+ return (IEditorPart) data;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the service locator for the given page index. This method can be
+ * used to create service locators for pages that are just controls. The
+ * page index must be valid.
+ * <p>
+ * This will return the editor site service locator for an editor, and
+ * create one for a page that is just a control.
+ * </p>
+ *
+ * @param pageIndex
+ * the index of the page
+ * @return the editor for the specified page, or <code>null</code> if the
+ * specified page was not created with
+ * <code>addPage(IEditorPart,IEditorInput)</code>
+ * @since 3.4
+ */
+ protected final IServiceLocator getPageSite(int pageIndex) {
+ if (pageIndex == PAGE_CONTAINER_SITE) {
+ return getPageContainerSite();
+ }
+
+ Item item = getItem(pageIndex);
+ if (item != null) {
+ Object data = item.getData();
+ if (data instanceof IEditorPart) {
+ return ((IEditorPart) data).getSite();
+ } else if (data instanceof IServiceLocator) {
+ return (IServiceLocator) data;
+ } else if (data == null) {
+ IServiceLocatorCreator slc = (IServiceLocatorCreator) getSite()
+ .getService(IServiceLocatorCreator.class);
+ IServiceLocator sl = slc.createServiceLocator(getSite(), null,
+ new IDisposable() {
+ public void dispose() {
+ final Control control = ((PartSite) getSite())
+ .getPane().getControl();
+ if (control != null && !control.isDisposed()) {
+ ((PartSite) getSite()).getPane().doHide();
+ }
+ }
+ });
+ IEclipseContext e4Context = EclipseContextFactory.create(
+ ((EditorSite) getSite()).getContext(),
+ UISchedulerStrategy.getInstance());
+ ((ServiceLocator) sl).setContext(e4Context);
+ item.setData(sl);
+ pageSites.add(sl);
+ return sl;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return A site that can be used with a header.
+ * @since 3.4
+ * @see #createPageContainer(Composite)
+ * @see #PAGE_CONTAINER_SITE
+ * @see #getPageSite(int)
+ */
+ private IServiceLocator getPageContainerSite() {
+ if (pageContainerSite == null) {
+ IServiceLocatorCreator slc = (IServiceLocatorCreator) getSite()
+ .getService(IServiceLocatorCreator.class);
+ pageContainerSite = slc.createServiceLocator(getSite(), null,
+ new IDisposable() {
+ public void dispose() {
+ final Control control = ((PartSite) getSite())
+ .getPane().getControl();
+ if (control != null && !control.isDisposed()) {
+ ((PartSite) getSite()).getPane().doHide();
+ }
+ }
+ });
+ IEclipseContext e4Context = EclipseContextFactory.create(
+ ((EditorSite) getSite()).getContext(), UISchedulerStrategy
+ .getInstance());
+ ((ServiceLocator) pageContainerSite).setContext(e4Context);
+ }
+ return pageContainerSite;
+ }
+
+ /**
+ * Returns the tab item for the given page index (page index is 0-based).
+ * The page index must be valid.
+ *
+ * @param pageIndex
+ * the index of the page
+ * @return the tab item for the given page index
+ */
+ private CTabItem getItem(int pageIndex) {
+ return getTabFolder().getItem(pageIndex);
+ }
+
+ /**
+ * Returns the number of pages in this multi-page editor.
+ *
+ * @return the number of pages
+ */
+ protected int getPageCount() {
+ CTabFolder folder = getTabFolder();
+ // May not have been created yet, or may have been disposed.
+ if (folder != null && !folder.isDisposed()) {
+ return folder.getItemCount();
+ }
+ return 0;
+ }
+
+ /**
+ * Returns the image for the page with the given index, or <code>null</code>
+ * if no image has been set for the page. The page index must be valid.
+ *
+ * @param pageIndex
+ * the index of the page
+ * @return the image, or <code>null</code> if none
+ */
+ protected Image getPageImage(int pageIndex) {
+ return getItem(pageIndex).getImage();
+ }
+
+ /**
+ * Returns the text label for the page with the given index. Returns the
+ * empty string if no text label has been set for the page. The page index
+ * must be valid.
+ *
+ * @param pageIndex
+ * the index of the page
+ * @return the text label for the page
+ */
+ protected String getPageText(int pageIndex) {
+ return getItem(pageIndex).getText();
+ }
+
+ /**
+ * Returns the tab folder containing this multi-page editor's pages.
+ *
+ * @return the tab folder, or <code>null</code> if
+ * <code>createPartControl</code> has not been called yet
+ */
+ private CTabFolder getTabFolder() {
+ return container;
+ }
+
+ /**
+ * Handles a property change notification from a nested editor. The default
+ * implementation simply forwards the change to listeners on this multi-page
+ * editor by calling <code>firePropertyChange</code> with the same property
+ * id. For example, if the dirty state of a nested editor changes (property
+ * id <code>IEditorPart.PROP_DIRTY</code>), this method handles it by firing
+ * a property change event for <code>IEditorPart.PROP_DIRTY</code> to
+ * property listeners on this multi-page editor.
+ * <p>
+ * Subclasses may extend or reimplement this method.
+ * </p>
+ *
+ * @param propertyId
+ * the id of the property that changed
+ */
+ protected void handlePropertyChange(int propertyId) {
+ firePropertyChange(propertyId);
+ }
+
+ /**
+ * The <code>MultiPageEditorPart</code> implementation of this
+ * <code>IEditorPart</code> method sets its site to the given site, its
+ * input to the given input, and the site's selection provider to a
+ * <code>MultiPageSelectionProvider</code>. Subclasses may extend this
+ * method.
+ *
+ * @param site
+ * The site for which this part is being created; must not be
+ * <code>null</code>.
+ * @param input
+ * The input on which this editor should be created; must not be
+ * <code>null</code>.
+ * @throws PartInitException
+ * If the initialization of the part fails -- currently never.
+ */
+ public void init(IEditorSite site, IEditorInput input)
+ throws PartInitException {
+ setSite(site);
+ setInput(input);
+ site.setSelectionProvider(new MultiPageSelectionProvider(this));
+ }
+
+ /**
+ * The <code>MultiPageEditorPart</code> implementation of this
+ * <code>IEditorPart</code> method returns whether the contents of any of
+ * this multi-page editor's nested editors have changed since the last save.
+ * Pages created with <code>addPage(Control)</code> are ignored.
+ * <p>
+ * Subclasses may extend or reimplement this method.
+ * </p>
+ *
+ * @return <code>true</code> if any of the nested editors are dirty;
+ * <code>false</code> otherwise.
+ */
+ public boolean isDirty() {
+ // use nestedEditors to avoid SWT requests; see bug 12996
+ for (Iterator i = nestedEditors.iterator(); i.hasNext();) {
+ IEditorPart editor = (IEditorPart) i.next();
+ if (editor.isDirty()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Notifies this multi-page editor that the page with the given id has been
+ * activated. This method is called when the user selects a different tab.
+ * <p>
+ * The <code>MultiPageEditorPart</code> implementation of this method sets
+ * focus to the new page, and notifies the action bar contributor (if there
+ * is one). This checks whether the action bar contributor is an instance of
+ * <code>MultiPageEditorActionBarContributor</code>, and, if so, calls
+ * <code>setActivePage</code> with the active nested editor. This also fires
+ * a selection change event if required.
+ * </p>
+ * <p>
+ * Subclasses may extend this method.
+ * </p>
+ *
+ * @param newPageIndex
+ * the index of the activated page
+ */
+ protected void pageChange(int newPageIndex) {
+ deactivateSite(false, false);
+
+ IPartService partService = (IPartService) getSite().getService(
+ IPartService.class);
+ if (partService.getActivePart() == this) {
+ setFocus();
+ }
+
+ IEditorPart activeEditor = getEditor(newPageIndex);
+
+ IEditorActionBarContributor contributor = getEditorSite()
+ .getActionBarContributor();
+ if (contributor != null
+ && contributor instanceof MultiPageEditorActionBarContributor) {
+ ((MultiPageEditorActionBarContributor) contributor)
+ .setActivePage(activeEditor);
+ }
+
+ if (activeEditor != null) {
+ ISelectionProvider selectionProvider = activeEditor.getSite()
+ .getSelectionProvider();
+ if (selectionProvider != null) {
+ ISelectionProvider outerProvider = getSite()
+ .getSelectionProvider();
+ if (outerProvider instanceof MultiPageSelectionProvider) {
+ SelectionChangedEvent event = new SelectionChangedEvent(
+ selectionProvider, selectionProvider.getSelection());
+
+ MultiPageSelectionProvider provider = (MultiPageSelectionProvider) outerProvider;
+ provider.fireSelectionChanged(event);
+ provider.firePostSelectionChanged(event);
+ } else {
+ if (Policy.DEBUG_MPE) {
+ Tracing.printTrace(TRACING_COMPONENT,
+ "MultiPageEditorPart " + getTitle() //$NON-NLS-1$
+ + " did not propogate selection for " //$NON-NLS-1$
+ + activeEditor.getTitle());
+ }
+ }
+ }
+ }
+
+ activateSite();
+ Object selectedPage = getSelectedPage();
+ if (selectedPage != null) {
+ firePageChanged(new PageChangedEvent(this, selectedPage));
+ }
+ }
+
+ /**
+ * This method can be used by implementors of
+ * {@link MultiPageEditorPart#createPageContainer(Composite)} to deactivate
+ * the active inner editor services while their header has focus. A
+ * deactivateSite() must have a matching call to activateSite() when
+ * appropriate.
+ * <p>
+ * An new inner editor will have its site activated on a
+ * {@link MultiPageEditorPart#pageChange(int)}.
+ * </p>
+ * <p>
+ * <b>Note:</b> This API is evolving in 3.4 and this might not be its final
+ * form.
+ * </p>
+ *
+ * @param immediate
+ * immediately deactivate the legacy keybinding service
+ * @param containerSiteActive
+ * Leave the page container site active.
+ * @since 3.4
+ * @see #activateSite()
+ * @see #createPageContainer(Composite)
+ * @see #getPageSite(int)
+ * @see #PAGE_CONTAINER_SITE
+ */
+ protected final void deactivateSite(boolean immediate,
+ boolean containerSiteActive) {
+ // Deactivate the nested services from the last active service locator.
+ if (activeServiceLocator != null) {
+ activeServiceLocator.deactivate();
+ activeServiceLocator = null;
+ }
+
+ final int pageIndex = getActivePage();
+ final IKeyBindingService service = getSite().getKeyBindingService();
+ if (pageIndex < 0 || pageIndex >= getPageCount() || immediate) {
+ // There is no selected page, so deactivate the active service.
+ if (service instanceof INestableKeyBindingService) {
+ final INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
+ nestableService.activateKeyBindingService(null);
+ } else {
+ WorkbenchPlugin
+ .log("MultiPageEditorPart.deactivateSite() Parent key binding service was not an instance of INestableKeyBindingService. It was an instance of " + service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ if (containerSiteActive) {
+ IServiceLocator containerSite = getPageContainerSite();
+ if (containerSite instanceof INestable) {
+ activeServiceLocator = (INestable) containerSite;
+ activeServiceLocator.activate();
+ }
+ }
+ }
+
+ /**
+ * This method can be used by implementors of
+ * {@link #createPageContainer(Composite)} to activate the active inner
+ * editor services when their header loses focus.
+ * <p>
+ * An new inner editor will have its site activated on a
+ * {@link #pageChange(int)}.
+ * </p>
+ * <p>
+ * <b>Note:</b> This API is evolving in 3.4 and this might not be its final
+ * form.
+ * </p>
+ *
+ * @since 3.4
+ * @see #deactivateSite(boolean,boolean)
+ * @see #createPageContainer(Composite)
+ * @see #getPageSite(int)
+ */
+ protected final void activateSite() {
+ if (activeServiceLocator != null) {
+ activeServiceLocator.deactivate();
+ activeServiceLocator = null;
+ }
+
+ final IKeyBindingService service = getSite().getKeyBindingService();
+ final int pageIndex = getActivePage();
+ final IEditorPart editor = getEditor(pageIndex);
+
+ if (editor != null) {
+ // active the service for this inner editor
+ if (service instanceof INestableKeyBindingService) {
+ final INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
+ nestableService.activateKeyBindingService(editor
+ .getEditorSite());
+
+ } else {
+ WorkbenchPlugin
+ .log("MultiPageEditorPart.activateSite() Parent key binding service was not an instance of INestableKeyBindingService. It was an instance of " + service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ // Activate the services for the new service locator.
+ final IServiceLocator serviceLocator = editor.getEditorSite();
+ if (serviceLocator instanceof INestable) {
+ activeServiceLocator = (INestable) serviceLocator;
+ activeServiceLocator.activate();
+ }
+
+ } else {
+ Item item = getItem(pageIndex);
+
+ // There is no selected editor, so deactivate the active service.
+ if (service instanceof INestableKeyBindingService) {
+ final INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
+ nestableService.activateKeyBindingService(null);
+ } else {
+ WorkbenchPlugin
+ .log("MultiPageEditorPart.activateSite() Parent key binding service was not an instance of INestableKeyBindingService. It was an instance of " + service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ if (item.getData() instanceof INestable) {
+ activeServiceLocator = (INestable) item.getData();
+ activeServiceLocator.activate();
+ }
+ }
+ }
+
+ /**
+ * Disposes the given part and its site.
+ *
+ * @param part
+ * The part to dispose; must not be <code>null</code>.
+ */
+ private void disposePart(final IWorkbenchPart part) {
+ SafeRunner.run(new ISafeRunnable() {
+ public void run() {
+ IWorkbenchPartSite partSite = part.getSite();
+ part.dispose();
+ if (partSite instanceof MultiPageEditorSite) {
+ ((MultiPageEditorSite) partSite).dispose();
+ }
+ }
+
+ public void handleException(Throwable e) {
+ // Exception has already being logged by Core. Do nothing.
+ }
+ });
+ }
+
+ /**
+ * Removes the page with the given index from this multi-page editor. The
+ * controls for the page are disposed of; if the page has an editor, it is
+ * disposed of too. The page index must be valid.
+ *
+ * @param pageIndex
+ * the index of the page
+ * @see MultiPageEditorPart#addPage(Control)
+ * @see MultiPageEditorPart#addPage(IEditorPart, IEditorInput)
+ */
+ public void removePage(int pageIndex) {
+ Assert.isTrue(pageIndex >= 0 && pageIndex < getPageCount());
+ // get editor (if any) before disposing item
+ IEditorPart editor = getEditor(pageIndex);
+
+ // get control for the item if it's not an editor
+ CTabItem item = getItem(pageIndex);
+ IServiceLocator pageLocator = null;
+ if (item.getData() instanceof IServiceLocator) {
+ pageLocator = (IServiceLocator) item.getData();
+ }
+ Control pageControl = item.getControl();
+
+ // dispose item before disposing editor, in case there's an exception
+ // in editor's dispose
+ item.dispose();
+
+ if (pageControl != null) {
+ pageControl.dispose();
+ }
+
+ // dispose editor (if any)
+ if (editor != null) {
+ nestedEditors.remove(editor);
+ disposePart(editor);
+ }
+ if (pageLocator != null) {
+ pageSites.remove(pageLocator);
+ if (pageLocator instanceof IDisposable) {
+ ((IDisposable) pageLocator).dispose();
+ }
+ }
+ }
+
+ /**
+ * Sets the currently active page.
+ *
+ * @param pageIndex
+ * the index of the page to be activated; the index must be valid
+ */
+ protected void setActivePage(int pageIndex) {
+ Assert.isTrue(pageIndex >= 0 && pageIndex < getPageCount());
+ getTabFolder().setSelection(pageIndex);
+ pageChange(pageIndex);
+ }
+
+ /**
+ * Sets the control for the given page index. The page index must be valid.
+ *
+ * @param pageIndex
+ * the index of the page
+ * @param control
+ * the control for the specified page, or <code>null</code> to
+ * clear the control
+ */
+ protected void setControl(int pageIndex, Control control) {
+ getItem(pageIndex).setControl(control);
+ }
+
+ /**
+ * The <code>MultiPageEditor</code> implementation of this
+ * <code>IWorkbenchPart</code> method sets focus on the active nested
+ * editor, if there is one.
+ * <p>
+ * Subclasses may extend or reimplement.
+ * </p>
+ */
+ public void setFocus() {
+ setFocus(getActivePage());
+ }
+
+ /**
+ * Sets focus to the control for the given page. If the page has an editor,
+ * this calls its <code>setFocus()</code> method. Otherwise, this calls
+ * <code>setFocus</code> on the control for the page.
+ *
+ * @param pageIndex
+ * the index of the page
+ */
+ private void setFocus(int pageIndex) {
+ if (pageIndex < 0 || pageIndex >= getPageCount()) {
+ // page index out of bounds, don't set focus.
+ return;
+ }
+ final IEditorPart editor = getEditor(pageIndex);
+ if (editor != null) {
+ editor.setFocus();
+
+ } else {
+ // Give the page's control focus.
+ final Control control = getControl(pageIndex);
+ if (control != null) {
+ control.setFocus();
+ }
+ }
+ }
+
+ /**
+ * Sets the image for the page with the given index, or <code>null</code> to
+ * clear the image for the page. The page index must be valid.
+ *
+ * @param pageIndex
+ * the index of the page
+ * @param image
+ * the image, or <code>null</code>
+ */
+ protected void setPageImage(int pageIndex, Image image) {
+ getItem(pageIndex).setImage(image);
+ }
+
+ /**
+ * Sets the text label for the page with the given index. The page index
+ * must be valid. The text label must not be null.
+ *
+ * @param pageIndex
+ * the index of the page
+ * @param text
+ * the text label
+ */
+ protected void setPageText(int pageIndex, String text) {
+ getItem(pageIndex).setText(text);
+ }
+
+ /**
+ * If there is an adapter registered against the subclass of
+ * MultiPageEditorPart return that. Otherwise, delegate to the internal
+ * editor.
+ *
+ * @see org.eclipse.ui.part.WorkbenchPart#getAdapter(java.lang.Class)
+ */
+ public Object getAdapter(Class adapter) {
+ Object result = super.getAdapter(adapter);
+ // restrict delegating to the UI thread for bug 144851
+ if (result == null && Display.getCurrent() != null) {
+ IEditorPart innerEditor = getActiveEditor();
+ // see bug 138823 - prevent some subclasses from causing
+ // an infinite loop
+ if (innerEditor != null && innerEditor != this) {
+ result = Util.getAdapter(innerEditor, adapter);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Find the editors contained in this multi-page editor whose editor input
+ * match the provided input.
+ *
+ * @param input
+ * the editor input
+ * @return the editors contained in this multi-page editor whose editor
+ * input match the provided input
+ * @since 3.3
+ */
+ public final IEditorPart[] findEditors(IEditorInput input) {
+ List result = new ArrayList();
+ int count = getPageCount();
+ for (int i = 0; i < count; i++) {
+ IEditorPart editor = getEditor(i);
+ if (editor != null && editor.getEditorInput() != null
+ && editor.getEditorInput().equals(input)) {
+ result.add(editor);
+ }
+ }
+ return (IEditorPart[]) result.toArray(new IEditorPart[result.size()]);
+ }
+
+ /**
+ * Set the active page of this multi-page editor to the page that contains
+ * the given editor part. This method has no effect of the given editor part
+ * is not contained in this multi-page editor.
+ *
+ * @param editorPart
+ * the editor part
+ * @since 3.3
+ */
+ public final void setActiveEditor(IEditorPart editorPart) {
+ int count = getPageCount();
+ for (int i = 0; i < count; i++) {
+ IEditorPart editor = getEditor(i);
+ if (editor == editorPart) {
+ setActivePage(i);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Returns the selected page for the current active page index, either the
+ * IEditorPart for editors or the Control for other pages.
+ * <p>
+ * <b>Note:</b> clients may override this method to return a page
+ * appropriate for their editors. Maybe be <code>null</code>.
+ * </p>
+ *
+ * @return The IEditorPart or Control representing the current active page,
+ * or <code>null</code> if there are no active pages.
+ * @since 3.5
+ * @see #getActivePage()
+ */
+ public Object getSelectedPage() {
+ int index = getActivePage();
+ if (index == -1) {
+ return null;
+ }
+ IEditorPart editor = getEditor(index);
+ if (editor != null) {
+ return editor;
+ }
+ return getControl(index);
+ }
+
+ /**
+ * Add the page change listener to be notified when the page changes. The
+ * newly selected page will be the Object returned from
+ * {@link #getSelectedPage()}. In the default case, this will be the active
+ * page Control, IEditorPart, or <code>null</code>.
+ * <p>
+ * This method has no effect if the listener has already been added.
+ * </p>
+ *
+ * @nooverride
+ *
+ * @since 3.5
+ */
+ public void addPageChangedListener(IPageChangedListener listener) {
+ pageChangeListeners.add(listener);
+ }
+
+ /**
+ * Remove the page change listener.
+ * <p>
+ * This method has no effect if the listener is not in the list.
+ * </p>
+ *
+ * @nooverride
+ *
+ * @since 3.5
+ */
+ public void removePageChangedListener(IPageChangedListener listener) {
+ pageChangeListeners.remove(listener);
+ }
+
+ private void firePageChanged(final PageChangedEvent event) {
+ Object[] listeners = pageChangeListeners.getListeners();
+ for (int i = 0; i < listeners.length; ++i) {
+ final IPageChangedListener l = (IPageChangedListener) listeners[i];
+ SafeRunnable.run(new SafeRunnable() {
+ public void run() {
+ l.pageChanged(event);
+ }
+ });
+ }
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorSite.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorSite.java
new file mode 100644
index 0000000..7f1776e
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorSite.java
@@ -0,0 +1,555 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.ui.part;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.e4.core.services.context.EclipseContextFactory;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.workbench.ui.internal.UISchedulerStrategy;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IKeyBindingService;
+import org.eclipse.ui.INestableKeyBindingService;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.internal.EditorSite;
+import org.eclipse.ui.internal.PartSite;
+import org.eclipse.ui.internal.PopupMenuExtender;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.internal.part.IMultiPageEditorSiteHolder;
+import org.eclipse.ui.internal.services.INestable;
+import org.eclipse.ui.internal.services.IServiceLocatorCreator;
+import org.eclipse.ui.internal.services.IWorkbenchLocationService;
+import org.eclipse.ui.internal.services.ServiceLocator;
+import org.eclipse.ui.internal.services.WorkbenchLocationService;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.services.IServiceLocator;
+import org.eclipse.ui.services.IServiceScopes;
+
+/**
+ * Site for a nested editor within a multi-page editor. Selection is handled by
+ * forwarding the event to the multi-page editor's selection listeners; most
+ * other methods are forwarded to the multi-page editor's site.
+ * <p>
+ * The base implementation of <code>MultiPageEditor.createSite</code> creates an
+ * instance of this class. This class may be instantiated or subclassed.
+ * </p>
+ */
+public class MultiPageEditorSite implements IEditorSite, INestable {
+
+ /**
+ * The nested editor.
+ */
+ private IEditorPart editor;
+
+ /**
+ * The list of popup menu extenders; <code>null</code> if none registered.
+ */
+ private ArrayList menuExtenders;
+
+ /**
+ * The multi-page editor.
+ */
+ private MultiPageEditorPart multiPageEditor;
+
+ /**
+ * The post selection changed listener.
+ */
+ private ISelectionChangedListener postSelectionChangedListener = null;
+
+ /**
+ * The selection change listener, initialized lazily; <code>null</code> if
+ * not yet created.
+ */
+ private ISelectionChangedListener selectionChangedListener = null;
+
+ /**
+ * The selection provider; <code>null</code> if none.
+ *
+ * @see MultiPageEditorSite#setSelectionProvider(ISelectionProvider)
+ */
+ private ISelectionProvider selectionProvider = null;
+
+ /**
+ * The cached copy of the key binding service specific to this multi-page
+ * editor site. This value is <code>null</code> if it is not yet
+ * initialized.
+ */
+ private IKeyBindingService service = null;
+
+ /**
+ * The local service locator for this multi-page editor site. This value is
+ * never <code>null</code>.
+ */
+ private final ServiceLocator serviceLocator;
+
+ /**
+ * Creates a site for the given editor nested within the given multi-page
+ * editor.
+ *
+ * @param multiPageEditor
+ * the multi-page editor
+ * @param editor
+ * the nested editor
+ */
+ public MultiPageEditorSite(MultiPageEditorPart multiPageEditor,
+ IEditorPart editor) {
+ Assert.isNotNull(multiPageEditor);
+ Assert.isNotNull(editor);
+ this.multiPageEditor = multiPageEditor;
+ this.editor = editor;
+
+ final IServiceLocator parentServiceLocator = multiPageEditor.getSite();
+ IServiceLocatorCreator slc = (IServiceLocatorCreator) parentServiceLocator
+ .getService(IServiceLocatorCreator.class);
+ this.serviceLocator = (ServiceLocator) slc.createServiceLocator(
+ multiPageEditor.getSite(), null, new IDisposable() {
+ public void dispose() {
+ final Control control = ((PartSite) getMultiPageEditor()
+ .getSite()).getPane().getControl();
+ if (control != null && !control.isDisposed()) {
+ ((PartSite) getMultiPageEditor().getSite())
+ .getPane().doHide();
+ }
+ }
+ });
+ IEclipseContext e4Context = EclipseContextFactory.create(
+ ((EditorSite) multiPageEditor.getSite()).getContext(),
+ UISchedulerStrategy.getInstance());
+ this.serviceLocator.setContext(e4Context);
+
+ initializeDefaultServices();
+ }
+
+ /**
+ * Initialize the slave services for this site.
+ */
+ private void initializeDefaultServices() {
+ serviceLocator.registerService(IWorkbenchLocationService.class,
+ new WorkbenchLocationService(IServiceScopes.MPESITE_SCOPE,
+ getWorkbenchWindow().getWorkbench(),
+ getWorkbenchWindow(), getMultiPageEditor().getSite(),
+ this, null, 3));
+ serviceLocator.registerService(IMultiPageEditorSiteHolder.class,
+ new IMultiPageEditorSiteHolder() {
+ public MultiPageEditorSite getSite() {
+ return MultiPageEditorSite.this;
+ }
+ });
+ }
+
+ /**
+ * Notifies the multi page editor service that the component within which it
+ * exists has become active.
+ *
+ * @since 3.2
+ */
+ public final void activate() {
+ serviceLocator.activate();
+ }
+
+ /**
+ * Notifies the multi page editor service that the component within which it
+ * exists has been deactived.
+ *
+ * @since 3.2
+ */
+ public final void deactivate() {
+ serviceLocator.deactivate();
+ }
+
+ /**
+ * Dispose the contributions.
+ */
+ public void dispose() {
+ if (menuExtenders != null) {
+ for (int i = 0; i < menuExtenders.size(); i++) {
+ ((PopupMenuExtender) menuExtenders.get(i)).dispose();
+ }
+ menuExtenders = null;
+ }
+
+ // Remove myself from the list of nested key binding services.
+ if (service != null) {
+ IKeyBindingService parentService = getEditor().getSite()
+ .getKeyBindingService();
+ if (parentService instanceof INestableKeyBindingService) {
+ INestableKeyBindingService nestableParent = (INestableKeyBindingService) parentService;
+ nestableParent.removeKeyBindingService(this);
+ }
+ service = null;
+ }
+
+ if (serviceLocator != null) {
+ serviceLocator.dispose();
+ }
+ }
+
+ /**
+ * The <code>MultiPageEditorSite</code> implementation of this
+ * <code>IEditorSite</code> method returns <code>null</code>, since nested
+ * editors do not have their own action bar contributor.
+ *
+ * @return <code>null</code>
+ */
+ public IEditorActionBarContributor getActionBarContributor() {
+ return null;
+ }
+
+ /**
+ * The <code>MultiPageEditorSite</code> implementation of this
+ * <code>IEditorSite</code> method forwards to the multi-page editor to
+ * return the action bars.
+ *
+ * @return The action bars from the parent multi-page editor.
+ */
+ public IActionBars getActionBars() {
+ return multiPageEditor.getEditorSite().getActionBars();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ public Object getAdapter(Class adapter) {
+ return null;
+ }
+
+ /**
+ * The <code>MultiPageEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+ * to return the decorator manager.
+ *
+ * @return The decorator from the workbench window.
+ * @deprecated use IWorkbench.getDecoratorManager()
+ */
+ public ILabelDecorator getDecoratorManager() {
+ return getWorkbenchWindow().getWorkbench().getDecoratorManager()
+ .getLabelDecorator();
+ }
+
+ /**
+ * Returns the nested editor.
+ *
+ * @return the nested editor
+ */
+ public IEditorPart getEditor() {
+ return editor;
+ }
+
+ /**
+ * The <code>MultiPageEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method returns an empty string since the
+ * nested editor is not created from the registry.
+ *
+ * @return An empty string.
+ */
+ public String getId() {
+ return ""; //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IEditorSite.
+ */
+ public IKeyBindingService getKeyBindingService() {
+ if (service == null) {
+ service = getMultiPageEditor().getEditorSite()
+ .getKeyBindingService();
+ if (service instanceof INestableKeyBindingService) {
+ INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
+ service = nestableService.getKeyBindingService(this);
+
+ } else {
+ /*
+ * This is an internal reference, and should not be copied by
+ * client code. If you are thinking of copying this, DON'T DO
+ * IT.
+ */
+ WorkbenchPlugin
+ .log("MultiPageEditorSite.getKeyBindingService() Parent key binding service was not an instance of INestableKeyBindingService. It was an instance of " + service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ return service;
+ }
+
+ /**
+ * Returns the multi-page editor.
+ *
+ * @return the multi-page editor
+ */
+ public MultiPageEditorPart getMultiPageEditor() {
+ return multiPageEditor;
+ }
+
+ /**
+ * The <code>MultiPageEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+ * to return the workbench page.
+ *
+ * @return The workbench page in which this editor site resides.
+ */
+ public IWorkbenchPage getPage() {
+ return getMultiPageEditor().getSite().getPage();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.IWorkbenchPartSite#getPart()
+ */
+ public IWorkbenchPart getPart() {
+ return editor;
+ }
+
+ /**
+ * The <code>MultiPageEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method returns an empty string since the
+ * nested editor is not created from the registry.
+ *
+ * @return An empty string.
+ */
+ public String getPluginId() {
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the post selection change listener which listens to the nested
+ * editor's selection changes.
+ *
+ * @return the post selection change listener.
+ */
+ private ISelectionChangedListener getPostSelectionChangedListener() {
+ if (postSelectionChangedListener == null) {
+ postSelectionChangedListener = new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ MultiPageEditorSite.this.handlePostSelectionChanged(event);
+ }
+ };
+ }
+ return postSelectionChangedListener;
+ }
+
+ /**
+ * The <code>MultiPageEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method returns an empty string since the
+ * nested editor is not created from the registry.
+ *
+ * @return An empty string.
+ */
+ public String getRegisteredName() {
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the selection changed listener which listens to the nested
+ * editor's selection changes, and calls <code>handleSelectionChanged</code>
+ * .
+ *
+ * @return the selection changed listener
+ */
+ private ISelectionChangedListener getSelectionChangedListener() {
+ if (selectionChangedListener == null) {
+ selectionChangedListener = new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ MultiPageEditorSite.this.handleSelectionChanged(event);
+ }
+ };
+ }
+ return selectionChangedListener;
+ }
+
+ /**
+ * The <code>MultiPageEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method returns the selection provider set
+ * by <code>setSelectionProvider</code>.
+ *
+ * @return The current selection provider.
+ */
+ public ISelectionProvider getSelectionProvider() {
+ return selectionProvider;
+ }
+
+ public final Object getService(final Class key) {
+ return serviceLocator.getService(key);
+ }
+
+ /**
+ * The <code>MultiPageEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+ * to return the shell.
+ *
+ * @return The shell in which this editor site resides.
+ */
+ public Shell getShell() {
+ return getMultiPageEditor().getSite().getShell();
+ }
+
+ /**
+ * The <code>MultiPageEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+ * to return the workbench window.
+ *
+ * @return The workbench window in which this editor site resides.
+ */
+ public IWorkbenchWindow getWorkbenchWindow() {
+ return getMultiPageEditor().getSite().getWorkbenchWindow();
+ }
+
+ /**
+ * Handles a post selection changed even from the nexted editor.
+ * <p>
+ * Subclasses may extend or reimplement this method
+ *
+ * @param event
+ * the event
+ *
+ * @since 3.2
+ */
+ protected void handlePostSelectionChanged(SelectionChangedEvent event) {
+ ISelectionProvider parentProvider = getMultiPageEditor().getSite()
+ .getSelectionProvider();
+ if (parentProvider instanceof MultiPageSelectionProvider) {
+ SelectionChangedEvent newEvent = new SelectionChangedEvent(
+ parentProvider, event.getSelection());
+ MultiPageSelectionProvider prov = (MultiPageSelectionProvider) parentProvider;
+ prov.firePostSelectionChanged(newEvent);
+ }
+ }
+
+ /**
+ * Handles a selection changed event from the nested editor. The default
+ * implementation gets the selection provider from the multi-page editor's
+ * site, and calls <code>fireSelectionChanged</code> on it (only if it is an
+ * instance of <code>MultiPageSelectionProvider</code>), passing a new event
+ * object.
+ * <p>
+ * Subclasses may extend or reimplement this method.
+ * </p>
+ *
+ * @param event
+ * the event
+ */
+ protected void handleSelectionChanged(SelectionChangedEvent event) {
+ ISelectionProvider parentProvider = getMultiPageEditor().getSite()
+ .getSelectionProvider();
+ if (parentProvider instanceof MultiPageSelectionProvider) {
+ SelectionChangedEvent newEvent = new SelectionChangedEvent(
+ parentProvider, event.getSelection());
+ MultiPageSelectionProvider prov = (MultiPageSelectionProvider) parentProvider;
+ prov.fireSelectionChanged(newEvent);
+ }
+ }
+
+ public final boolean hasService(final Class key) {
+ return serviceLocator.hasService(key);
+ }
+
+ /**
+ * The <code>MultiPageEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+ * for registration.
+ *
+ * @param menuManager
+ * The menu manager
+ * @param selProvider
+ * The selection provider.
+ */
+ public void registerContextMenu(MenuManager menuManager,
+ ISelectionProvider selProvider) {
+ getMultiPageEditor().getSite().registerContextMenu(menuManager,
+ selProvider);
+ }
+
+ public final void registerContextMenu(final MenuManager menuManager,
+ final ISelectionProvider selectionProvider,
+ final boolean includeEditorInput) {
+ registerContextMenu(getId(), menuManager, selectionProvider,
+ includeEditorInput);
+ }
+
+ /**
+ * The <code>MultiPageEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+ * for registration.
+ *
+ * @param menuID
+ * The identifier for the menu.
+ * @param menuMgr
+ * The menu manager
+ * @param selProvider
+ * The selection provider.
+ */
+ public void registerContextMenu(String menuID, MenuManager menuMgr,
+ ISelectionProvider selProvider) {
+ if (menuExtenders == null) {
+ menuExtenders = new ArrayList(1);
+ }
+ PartSite.registerContextMenu(menuID, menuMgr, selProvider, true,
+ editor, menuExtenders);
+ }
+
+ public final void registerContextMenu(final String menuId,
+ final MenuManager menuManager,
+ final ISelectionProvider selectionProvider,
+ final boolean includeEditorInput) {
+ if (menuExtenders == null) {
+ menuExtenders = new ArrayList(1);
+ }
+ PartSite.registerContextMenu(menuId, menuManager, selectionProvider,
+ includeEditorInput, editor, menuExtenders);
+ }
+
+ /**
+ * The <code>MultiPageEditorSite</code> implementation of this
+ * <code>IWorkbenchPartSite</code> method remembers the selection provider,
+ * and also hooks a listener on it, which calls
+ * <code>handleSelectionChanged</code> when a selection changed event
+ * occurs.
+ *
+ * @param provider
+ * The selection provider.
+ * @see MultiPageEditorSite#handleSelectionChanged(SelectionChangedEvent)
+ */
+ public void setSelectionProvider(ISelectionProvider provider) {
+ ISelectionProvider oldSelectionProvider = selectionProvider;
+ selectionProvider = provider;
+ if (oldSelectionProvider != null) {
+ oldSelectionProvider
+ .removeSelectionChangedListener(getSelectionChangedListener());
+ if (oldSelectionProvider instanceof IPostSelectionProvider) {
+ ((IPostSelectionProvider) oldSelectionProvider)
+ .removePostSelectionChangedListener(getPostSelectionChangedListener());
+ }
+ }
+ if (selectionProvider != null) {
+ selectionProvider
+ .addSelectionChangedListener(getSelectionChangedListener());
+ if (selectionProvider instanceof IPostSelectionProvider) {
+ ((IPostSelectionProvider) selectionProvider)
+ .addPostSelectionChangedListener(getPostSelectionChangedListener());
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/PageBookView.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/PageBookView.java
new file mode 100644
index 0000000..c16171a
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/PageBookView.java
@@ -0,0 +1,1105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ui.part;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import org.eclipse.core.commands.common.EventManager;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IPartListener2;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.SubActionBars;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.internal.util.Util;
+
+/**
+ * Abstract superclass of all multi-page workbench views.
+ * <p>
+ * Within the workbench there are many views which track the active part. If a
+ * part is activated these views display some properties for the active part. A
+ * simple example is the <code>Outline View</code>, which displays the outline
+ * for the active editor. To avoid loss of context when part activation changes,
+ * these views may implement a multi-page approach. A separate page is
+ * maintained within the view for each source view. If a part is activated the
+ * associated page for the part is brought to top. If a part is closed the
+ * associated page is disposed. <code>PageBookView</code> is a base
+ * implementation for multi page views.
+ * </p>
+ * <p>
+ * <code>PageBookView</code>s provide an <code>IPageSite</code> for each of
+ * their pages. This site is supplied during the page's initialization. The page
+ * may supply a selection provider for this site. <code>PageBookView</code>s
+ * deal with these selection providers in a similar way to a workbench page's
+ * <code>SelectionService</code>. When a page is made visible, if its site has a
+ * selection provider, then changes in the selection are listened for and the
+ * current selection is obtained and fired as a selection change event.
+ * Selection changes are no longer listened for when a page is made invisible.
+ * </p>
+ * <p>
+ * This class should be subclassed by clients wishing to define new multi-page
+ * views.
+ * </p>
+ * <p>
+ * When a <code>PageBookView</code> is created the following methods are
+ * invoked. Subclasses must implement these.
+ * <ul>
+ * <li><code>createDefaultPage</code> - called to create a default page for the
+ * view. This page is displayed when the active part in the workbench does not
+ * have a page.</li>
+ * <li><code>getBootstrapPart</code> - called to determine the active part in
+ * the workbench. A page will be created for this part</li>
+ * </ul>
+ * </p>
+ * <p>
+ * When a part is activated the base implementation does not know if a page
+ * should be created for the part. Therefore, it delegates creation to the
+ * subclass.
+ * <ul>
+ * <li><code>isImportant</code> - called when a workbench part is activated.
+ * Subclasses return whether a page should be created for the new part.</li>
+ * <li><code>doCreatePage</code> - called to create a page for a particular part
+ * in the workbench. This is only invoked when <code>isImportant</code> returns
+ * </code>true</code>.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * When a part is closed the base implementation will destroy the page
+ * associated with the particular part. The page was created by a subclass, so
+ * the subclass must also destroy it. Subclasses must implement these.
+ * <ul>
+ * <li><code>doDestroyPage</code> - called to destroy a page for a particular
+ * part in the workbench.</li>
+ * </ul>
+ * </p>
+ */
+public abstract class PageBookView extends ViewPart implements IPartListener {
+ /**
+ * The pagebook control, or <code>null</code> if not initialized.
+ */
+ private PageBook book;
+
+ /**
+ * The page record for the default page.
+ */
+ private PageRec defaultPageRec;
+
+ /**
+ * Map from parts to part records (key type: <code>IWorkbenchPart</code>;
+ * value type: <code>PartRec</code>).
+ */
+ private Map mapPartToRec = new HashMap();
+
+ /**
+ * Map from pages to view sites Note that view sites were not added to page
+ * recs to avoid breaking binary compatibility with previous builds
+ */
+ private Map mapPageToSite = new HashMap();
+
+ /**
+ * Map from pages to the number of pageRecs actively associated with a page.
+ */
+ private Map mapPageToNumRecs = new HashMap();
+
+ /**
+ * The page rec which provided the current page or <code>null</code>
+ */
+ private PageRec activeRec;
+
+ /**
+ * If the part is hidden (usually an editor) then store it so we can
+ * continue to track it when it becomes visible.
+ */
+ private IWorkbenchPart hiddenPart = null;
+
+ /**
+ * The action bar property listener.
+ */
+ private IPropertyChangeListener actionBarPropListener = new IPropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ if (event.getProperty().equals(SubActionBars.P_ACTION_HANDLERS)
+ && activeRec != null
+ && event.getSource() == activeRec.subActionBars) {
+ refreshGlobalActionHandlers();
+ }
+ }
+ };
+
+ /**
+ * Selection change listener to listen for page selection changes
+ */
+ private ISelectionChangedListener selectionChangedListener = new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ pageSelectionChanged(event);
+ }
+ };
+
+ /**
+ * Selection change listener to listen for page selection changes
+ */
+ private ISelectionChangedListener postSelectionListener = new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ postSelectionChanged(event);
+ }
+ };
+
+ /**
+ * Selection provider for this view's site
+ */
+ private SelectionProvider selectionProvider = new SelectionProvider();
+
+ /**
+ * A data structure used to store the information about a single page within
+ * a pagebook view.
+ */
+ protected static class PageRec {
+
+ /**
+ * The part.
+ */
+ public IWorkbenchPart part;
+
+ /**
+ * The page.
+ */
+ public IPage page;
+
+ /**
+ * The page's action bars
+ */
+ public SubActionBars subActionBars;
+
+ /**
+ * Creates a new page record initialized to the given part and page.
+ *
+ * @param part
+ * @param page
+ */
+ public PageRec(IWorkbenchPart part, IPage page) {
+ this.part = part;
+ this.page = page;
+ }
+
+ /**
+ * Disposes of this page record by <code>null</code>ing its fields.
+ */
+ public void dispose() {
+ part = null;
+ page = null;
+ }
+ }
+
+ private static class SelectionManager extends EventManager {
+ /**
+ *
+ * @param listener
+ * listen
+ */
+ public void addSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ addListenerObject(listener);
+ }
+
+ /**
+ *
+ * @param listener
+ * listen
+ */
+ public void removeSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ removeListenerObject(listener);
+ }
+
+ /**
+ *
+ * @param event
+ * the event
+ */
+ public void selectionChanged(final SelectionChangedEvent event) {
+ // pass on the notification to listeners
+ Object[] listeners = getListeners();
+ for (int i = 0; i < listeners.length; ++i) {
+ final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i];
+ Platform.run(new SafeRunnable() {
+ public void run() {
+ l.selectionChanged(event);
+ }
+ });
+ }
+ }
+
+ }
+
+ /**
+ * A selection provider/listener for this view. It is a selection provider
+ * for this view's site.
+ */
+ protected class SelectionProvider implements IPostSelectionProvider {
+
+ private SelectionManager fSelectionListener = new SelectionManager();
+
+ private SelectionManager fPostSelectionListeners = new SelectionManager();
+
+ /*
+ * (non-Javadoc) Method declared on ISelectionProvider.
+ */
+ public void addSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ fSelectionListener.addSelectionChangedListener(listener);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on ISelectionProvider.
+ */
+ public ISelection getSelection() {
+ // get the selection provider from the current page
+ IPage currentPage = getCurrentPage();
+ // during workbench startup we may be in a state when
+ // there is no current page
+ if (currentPage == null) {
+ return StructuredSelection.EMPTY;
+ }
+ IPageSite site = getPageSite(currentPage);
+ if (site == null) {
+ return StructuredSelection.EMPTY;
+ }
+ ISelectionProvider selProvider = site.getSelectionProvider();
+ if (selProvider != null) {
+ return selProvider.getSelection();
+ }
+ return StructuredSelection.EMPTY;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on ISelectionProvider.
+ */
+ public void removeSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ fSelectionListener.removeSelectionChangedListener(listener);
+ }
+
+ /**
+ * The selection has changed. Process the event, notifying selection
+ * listeners and post selection listeners.
+ *
+ * @param event
+ * the change
+ */
+ public void selectionChanged(final SelectionChangedEvent event) {
+ fSelectionListener.selectionChanged(event);
+ }
+
+ /**
+ * The selection has changed, so notify any post-selection listeners.
+ *
+ * @param event
+ * the change
+ */
+ public void postSelectionChanged(final SelectionChangedEvent event) {
+ fPostSelectionListeners.selectionChanged(event);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on ISelectionProvider.
+ */
+ public void setSelection(ISelection selection) {
+ // get the selection provider from the current page
+ IPage currentPage = getCurrentPage();
+ // during workbench startup we may be in a state when
+ // there is no current page
+ if (currentPage == null) {
+ return;
+ }
+ IPageSite site = getPageSite(currentPage);
+ if (site == null) {
+ return;
+ }
+ ISelectionProvider selProvider = site.getSelectionProvider();
+ // and set its selection
+ if (selProvider != null) {
+ selProvider.setSelection(selection);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.jface.viewers.IPostSelectionProvider#
+ * addPostSelectionChangedListener
+ * (org.eclipse.jface.viewers.ISelectionChangedListener)
+ */
+ public void addPostSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ fPostSelectionListeners.addSelectionChangedListener(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.jface.viewers.IPostSelectionProvider#
+ * removePostSelectionChangedListener
+ * (org.eclipse.jface.viewers.ISelectionChangedListener)
+ */
+ public void removePostSelectionChangedListener(
+ ISelectionChangedListener listener) {
+ fPostSelectionListeners.removeSelectionChangedListener(listener);
+ }
+ }
+
+ /**
+ * Creates a new pagebook view.
+ */
+ protected PageBookView() {
+ super();
+ }
+
+ /**
+ * Creates and returns the default page for this view.
+ * <p>
+ * Subclasses must implement this method.
+ * </p>
+ * <p>
+ * Subclasses must call initPage with the new page (if it is an
+ * <code>IPageBookViewPage</code>) before calling createControl on the page.
+ * </p>
+ *
+ * @param book
+ * the pagebook control
+ * @return the default page
+ */
+ protected abstract IPage createDefaultPage(PageBook book);
+
+ /**
+ * Creates a page for a given part. Adds it to the pagebook but does not
+ * show it.
+ *
+ * @param part
+ * The part we are making a page for.
+ * @return IWorkbenchPart
+ */
+ private PageRec createPage(IWorkbenchPart part) {
+ PageRec rec = doCreatePage(part);
+ if (rec != null) {
+ mapPartToRec.put(part, rec);
+ preparePage(rec);
+ }
+ return rec;
+ }
+
+ /**
+ * Prepares the page in the given page rec for use in this view.
+ *
+ * @param rec
+ */
+ private void preparePage(PageRec rec) {
+ IPageSite site = null;
+ Integer count;
+
+ if (!doesPageExist(rec.page)) {
+ if (rec.page instanceof IPageBookViewPage) {
+ site = ((IPageBookViewPage) rec.page).getSite();
+ }
+ if (site == null) {
+ // We will create a site for our use
+ site = new PageSite(getViewSite());
+ }
+ mapPageToSite.put(rec.page, site);
+
+ rec.subActionBars = (SubActionBars) site.getActionBars();
+ rec.subActionBars.addPropertyChangeListener(actionBarPropListener);
+ // for backward compability with IPage
+ rec.page.setActionBars(rec.subActionBars);
+
+ count = new Integer(0);
+ } else {
+ site = (IPageSite) mapPageToSite.get(rec.page);
+ rec.subActionBars = (SubActionBars) site.getActionBars();
+ count = ((Integer) mapPageToNumRecs.get(rec.page));
+ }
+
+ mapPageToNumRecs.put(rec.page, new Integer(count.intValue() + 1));
+ }
+
+ /**
+ * Initializes the given page with a page site.
+ * <p>
+ * Subclasses should call this method after the page is created but before
+ * creating its controls.
+ * </p>
+ * <p>
+ * Subclasses may override
+ * </p>
+ *
+ * @param page
+ * The page to initialize
+ */
+ protected void initPage(IPageBookViewPage page) {
+ try {
+ page.init(new PageSite(getViewSite()));
+ } catch (PartInitException e) {
+ WorkbenchPlugin.log(getClass(), "initPage", e); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * The <code>PageBookView</code> implementation of this
+ * <code>IWorkbenchPart</code> method creates a <code>PageBook</code>
+ * control with its default page showing. Subclasses may extend.
+ */
+ public void createPartControl(Composite parent) {
+
+ // Create the page book.
+ book = new PageBook(parent, SWT.NONE);
+
+ // Create the default page rec.
+ IPage defaultPage = createDefaultPage(book);
+ defaultPageRec = new PageRec(null, defaultPage);
+ preparePage(defaultPageRec);
+
+ // Show the default page
+ showPageRec(defaultPageRec);
+
+ // Listen to part activation events.
+ getSite().getPage().addPartListener(partListener);
+ showBootstrapPart();
+ }
+
+ /**
+ * The <code>PageBookView</code> implementation of this
+ * <code>IWorkbenchPart</code> method cleans up all the pages. Subclasses
+ * may extend.
+ */
+ public void dispose() {
+ // stop listening to part activation
+ getSite().getPage().removePartListener(partListener);
+
+ // Deref all of the pages.
+ activeRec = null;
+ if (defaultPageRec != null) {
+ // check for null since the default page may not have
+ // been created (ex. perspective never visible)
+ defaultPageRec.page.dispose();
+ defaultPageRec = null;
+ }
+ Map clone = (Map) ((HashMap) mapPartToRec).clone();
+ Iterator itr = clone.values().iterator();
+ while (itr.hasNext()) {
+ PageRec rec = (PageRec) itr.next();
+ removePage(rec);
+ }
+
+ // Run super.
+ super.dispose();
+ }
+
+ /**
+ * Creates a new page in the pagebook for a particular part. This page will
+ * be made visible whenever the part is active, and will be destroyed with a
+ * call to <code>doDestroyPage</code>.
+ * <p>
+ * Subclasses must implement this method.
+ * </p>
+ * <p>
+ * Subclasses must call initPage with the new page (if it is an
+ * <code>IPageBookViewPage</code>) before calling createControl on the page.
+ * </p>
+ *
+ * @param part
+ * the input part
+ * @return the record describing a new page for this view
+ * @see #doDestroyPage
+ */
+ protected abstract PageRec doCreatePage(IWorkbenchPart part);
+
+ /**
+ * Destroys a page in the pagebook for a particular part. This page was
+ * returned as a result from <code>doCreatePage</code>.
+ * <p>
+ * Subclasses must implement this method.
+ * </p>
+ *
+ * @param part
+ * the input part
+ * @param pageRecord
+ * a page record for the part
+ * @see #doCreatePage
+ */
+ protected abstract void doDestroyPage(IWorkbenchPart part,
+ PageRec pageRecord);
+
+ /**
+ * Returns true if the page has already been created.
+ *
+ * @param page
+ * the page to test
+ * @return true if this page has already been created.
+ */
+ protected boolean doesPageExist(IPage page) {
+ return mapPageToNumRecs.containsKey(page);
+ }
+
+ /**
+ * The <code>PageBookView</code> implementation of this
+ * <code>IAdaptable</code> method delegates to the current page, if it
+ * implements <code>IAdaptable</code>.
+ */
+ public Object getAdapter(Class key) {
+ // delegate to the current page, if supported
+ IPage page = getCurrentPage();
+ Object adapter = Util.getAdapter(page, key);
+ if (adapter != null) {
+ return adapter;
+ }
+ // if the page did not find the adapter, look for one provided by
+ // this view before delegating to super.
+ adapter = getViewAdapter(key);
+ if (adapter != null) {
+ return adapter;
+ }
+ // delegate to super
+ return super.getAdapter(key);
+ }
+
+ /**
+ * Returns an adapter of the specified type, as provided by this view (not
+ * the current page), or <code>null</code> if this view does not provide an
+ * adapter of the specified adapter.
+ * <p>
+ * The default implementation returns <code>null</code>. Subclasses may
+ * override.
+ * </p>
+ *
+ * @param adapter
+ * the adapter class to look up
+ * @return a object castable to the given class, or <code>null</code> if
+ * this object does not have an adapter for the given class
+ * @since 3.2
+ */
+ protected Object getViewAdapter(Class adapter) {
+ return null;
+ }
+
+ /**
+ * Returns the active, important workbench part for this view.
+ * <p>
+ * When the page book view is created it has no idea which part within the
+ * workbook should be used to generate the first page. Therefore, it
+ * delegates the choice to subclasses of <code>PageBookView</code>.
+ * </p>
+ * <p>
+ * Implementors of this method should return an active, important part in
+ * the workbench or <code>null</code> if none found.
+ * </p>
+ * <p>
+ * Subclasses must implement this method.
+ * </p>
+ *
+ * @return the active important part, or <code>null</code> if none
+ */
+ protected abstract IWorkbenchPart getBootstrapPart();
+
+ /**
+ * Returns the part which contributed the current page to this view.
+ *
+ * @return the part which contributed the current page or <code>null</code>
+ * if no part contributed the current page
+ */
+ protected IWorkbenchPart getCurrentContributingPart() {
+ if (activeRec == null) {
+ return null;
+ }
+ return activeRec.part;
+ }
+
+ /**
+ * Returns the currently visible page for this view or <code>null</code> if
+ * no page is currently visible.
+ *
+ * @return the currently visible page
+ */
+ public IPage getCurrentPage() {
+ if (activeRec == null) {
+ return null;
+ }
+ return activeRec.page;
+ }
+
+ /**
+ * Returns the view site for the given page of this view.
+ *
+ * @param page
+ * the page
+ * @return the corresponding site, or <code>null</code> if not found
+ */
+ protected PageSite getPageSite(IPage page) {
+ return (PageSite) mapPageToSite.get(page);
+ }
+
+ /**
+ * Returns the default page for this view.
+ *
+ * @return the default page
+ */
+ public IPage getDefaultPage() {
+ return defaultPageRec.page;
+ }
+
+ /**
+ * Returns the pagebook control for this view.
+ *
+ * @return the pagebook control, or <code>null</code> if not initialized
+ */
+ protected PageBook getPageBook() {
+ return book;
+ }
+
+ /**
+ * Returns the page record for the given part.
+ *
+ * @param part
+ * the part
+ * @return the corresponding page record, or <code>null</code> if not found
+ */
+ protected PageRec getPageRec(IWorkbenchPart part) {
+ return (PageRec) mapPartToRec.get(part);
+ }
+
+ /**
+ * Returns the page record for the given page of this view.
+ *
+ * @param page
+ * the page
+ * @return the corresponding page record, or <code>null</code> if not found
+ */
+ protected PageRec getPageRec(IPage page) {
+ Iterator itr = mapPartToRec.values().iterator();
+ while (itr.hasNext()) {
+ PageRec rec = (PageRec) itr.next();
+ if (rec.page == page) {
+ return rec;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns whether the given part should be added to this view.
+ * <p>
+ * Subclasses must implement this method.
+ * </p>
+ *
+ * @param part
+ * the input part
+ * @return <code>true</code> if the part is relevant, and <code>false</code>
+ * otherwise
+ */
+ protected abstract boolean isImportant(IWorkbenchPart part);
+
+ /*
+ * (non-Javadoc) Method declared on IViewPart.
+ */
+ public void init(IViewSite site) throws PartInitException {
+ site.setSelectionProvider(selectionProvider);
+ super.init(site);
+ }
+
+ /**
+ * The <code>PageBookView</code> implementation of this
+ * <code>IPartListener</code> method shows the page when the given part is
+ * activated. Subclasses may extend.
+ */
+ public void partActivated(IWorkbenchPart part) {
+ // Is this an important part? If not just return.
+ if (!isImportant(part)) {
+ return;
+ }
+ hiddenPart = null;
+
+ // Create a page for the part.
+ PageRec rec = getPageRec(part);
+ if (rec == null) {
+ rec = createPage(part);
+ }
+
+ // Show the page.
+ if (rec != null) {
+ showPageRec(rec);
+ } else {
+ showPageRec(defaultPageRec);
+ }
+ }
+
+ /**
+ * The <code>PageBookView</code> implementation of this
+ * <code>IPartListener</code> method does nothing. Subclasses may extend.
+ */
+ public void partBroughtToTop(IWorkbenchPart part) {
+ // Do nothing by default
+ }
+
+ /**
+ * The <code>PageBookView</code> implementation of this
+ * <code>IPartListener</code> method deal with the closing of the active
+ * part. Subclasses may extend.
+ */
+ public void partClosed(IWorkbenchPart part) {
+ // Update the active part.
+ if (activeRec != null && activeRec.part == part) {
+ showPageRec(defaultPageRec);
+ }
+
+ // Find and remove the part page.
+ PageRec rec = getPageRec(part);
+ if (rec != null) {
+ removePage(rec);
+ }
+ if (part == hiddenPart) {
+ hiddenPart = null;
+ }
+ }
+
+ /**
+ * The <code>PageBookView</code> implementation of this
+ * <code>IPartListener</code> method does nothing. Subclasses may extend.
+ */
+ public void partDeactivated(IWorkbenchPart part) {
+ // Do nothing.
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.IPartListener#partOpened(org.eclipse.ui.IWorkbenchPart)
+ */
+ public void partOpened(IWorkbenchPart part) {
+ // Do nothing by default.
+ }
+
+ /**
+ * Refreshes the global actions for the active page.
+ */
+ private void refreshGlobalActionHandlers() {
+ // Clear old actions.
+ IActionBars bars = getViewSite().getActionBars();
+ bars.clearGlobalActionHandlers();
+
+ // Set new actions.
+ Map newActionHandlers = activeRec.subActionBars
+ .getGlobalActionHandlers();
+ if (newActionHandlers != null) {
+ Set keys = newActionHandlers.entrySet();
+ Iterator iter = keys.iterator();
+ while (iter.hasNext()) {
+ Map.Entry entry = (Map.Entry) iter.next();
+ bars.setGlobalActionHandler((String) entry.getKey(),
+ (IAction) entry.getValue());
+ }
+ }
+ }
+
+ /**
+ * Removes a page record. If it is the last reference to the page dispose of
+ * it - otherwise just decrement the reference count.
+ *
+ * @param rec
+ */
+ private void removePage(PageRec rec) {
+ mapPartToRec.remove(rec.part);
+
+ int newCount = ((Integer) mapPageToNumRecs.get(rec.page)).intValue() - 1;
+
+ if (newCount == 0) {
+ Object site = mapPageToSite.remove(rec.page);
+ mapPageToNumRecs.remove(rec.page);
+
+ Control control = rec.page.getControl();
+ if (control != null && !control.isDisposed()) {
+ // Dispose the page's control so pages don't have to do this in
+ // their
+ // dispose method.
+ // The page's control is a child of this view's control so if
+ // this view
+ // is closed, the page's control will already be disposed.
+ control.dispose();
+ }
+
+ // free the page
+ doDestroyPage(rec.part, rec);
+
+ if (rec.subActionBars != null) {
+ rec.subActionBars.dispose();
+ }
+
+ if (site instanceof PageSite) {
+ ((PageSite) site).dispose();
+ }
+ } else {
+ mapPageToNumRecs.put(rec.page, new Integer(newCount));
+ }
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWorkbenchPart.
+ */
+ public void setFocus() {
+ // first set focus on the page book, in case the page
+ // doesn't properly handle setFocus
+ if (book != null) {
+ book.setFocus();
+ }
+ // then set focus on the page, if any
+ if (activeRec != null) {
+ activeRec.page.setFocus();
+ }
+ }
+
+ /**
+ * Handle page selection changes.
+ *
+ * @param event
+ */
+ private void pageSelectionChanged(SelectionChangedEvent event) {
+ // forward this change from a page to our site's selection provider
+ SelectionProvider provider = (SelectionProvider) getSite()
+ .getSelectionProvider();
+ if (provider != null) {
+ provider.selectionChanged(event);
+ }
+ }
+
+ /**
+ * Handle page selection changes.
+ *
+ * @param event
+ */
+ private void postSelectionChanged(SelectionChangedEvent event) {
+ // forward this change from a page to our site's selection provider
+ SelectionProvider provider = (SelectionProvider) getSite()
+ .getSelectionProvider();
+ if (provider != null) {
+ provider.postSelectionChanged(event);
+ }
+ }
+
+ /**
+ * Shows a page for the active workbench part.
+ */
+ private void showBootstrapPart() {
+ IWorkbenchPart part = getBootstrapPart();
+ if (part != null) {
+ partActivated(part);
+ }
+ }
+
+ /**
+ * Shows page contained in the given page record in this view. The page
+ * record must be one from this pagebook view.
+ * <p>
+ * The <code>PageBookView</code> implementation of this method asks the
+ * pagebook control to show the given page's control, and records that the
+ * given page is now current. Subclasses may extend.
+ * </p>
+ *
+ * @param pageRec
+ * the page record containing the page to show
+ */
+ protected void showPageRec(PageRec pageRec) {
+ // If already showing do nothing
+ if (activeRec == pageRec) {
+ return;
+ }
+ // If the page is the same, just set activeRec to pageRec
+ if (activeRec != null && pageRec != null
+ && activeRec.page == pageRec.page) {
+ activeRec = pageRec;
+ return;
+ }
+
+ // Hide old page.
+ if (activeRec != null) {
+ PageSite pageSite = (PageSite) mapPageToSite.get(activeRec.page);
+
+ activeRec.subActionBars.deactivate();
+
+ // deactivate the nested services
+ pageSite.deactivate();
+
+ // remove our selection listener
+ // KLUDGE!! this is a hack to get around having
+ // two Outline views...PDE editors can't handle this
+ try {
+ ISelectionProvider provider = pageSite.getSelectionProvider();
+ if (provider != null) {
+ provider
+ .removeSelectionChangedListener(selectionChangedListener);
+ if (provider instanceof IPostSelectionProvider) {
+ ((IPostSelectionProvider) provider)
+ .removePostSelectionChangedListener(postSelectionListener);
+ }
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ // Show new page.
+ activeRec = pageRec;
+ Control pageControl = activeRec.page.getControl();
+ if (pageControl != null && !pageControl.isDisposed()) {
+ PageSite pageSite = (PageSite) mapPageToSite.get(activeRec.page);
+
+ // Verify that the page control is not disposed
+ // If we are closing, it may have already been disposed
+ book.showPage(pageControl);
+ activeRec.subActionBars.activate();
+ refreshGlobalActionHandlers();
+
+ // activate the nested services
+ pageSite.activate();
+
+ // add our selection listener
+ ISelectionProvider provider = pageSite.getSelectionProvider();
+ if (provider != null) {
+ provider.addSelectionChangedListener(selectionChangedListener);
+ if (provider instanceof IPostSelectionProvider) {
+ ((IPostSelectionProvider) provider)
+ .addPostSelectionChangedListener(postSelectionListener);
+ }
+ }
+ // Update action bars.
+ getViewSite().getActionBars().updateActionBars();
+ }
+ }
+
+ /**
+ * Returns the selectionProvider for this page book view.
+ *
+ * @return a SelectionProvider
+ */
+ protected SelectionProvider getSelectionProvider() {
+ return selectionProvider;
+ }
+
+ private IPartListener2 partListener = new IPartListener2() {
+ public void partActivated(IWorkbenchPartReference partRef) {
+ IWorkbenchPart part = partRef.getPart(false);
+ PageBookView.this.partActivated(part);
+ }
+
+ public void partBroughtToTop(IWorkbenchPartReference partRef) {
+ PageBookView.this.partBroughtToTop(partRef.getPart(false));
+ }
+
+ public void partClosed(IWorkbenchPartReference partRef) {
+ PageBookView.this.partClosed(partRef.getPart(false));
+ }
+
+ public void partDeactivated(IWorkbenchPartReference partRef) {
+ PageBookView.this.partDeactivated(partRef.getPart(false));
+ }
+
+ public void partHidden(IWorkbenchPartReference partRef) {
+ PageBookView.this.partHidden(partRef.getPart(false));
+ }
+
+ public void partInputChanged(IWorkbenchPartReference partRef) {
+ }
+
+ public void partOpened(IWorkbenchPartReference partRef) {
+ PageBookView.this.partOpened(partRef.getPart(false));
+ }
+
+ public void partVisible(IWorkbenchPartReference partRef) {
+ PageBookView.this.partVisible(partRef.getPart(false));
+ }
+ };
+
+ /**
+ * Make sure that the part is not considered if it is hidden.
+ *
+ * @param part
+ * @since 3.5
+ */
+ protected void partHidden(IWorkbenchPart part) {
+ if (part == null || part != getCurrentContributingPart()) {
+ return;
+ }
+ // if we've minimized the editor stack, that's no reason to
+ // drop our content
+ if (getSite().getPage().getPartState(
+ getSite().getPage().getReference(part)) == IWorkbenchPage.STATE_MINIMIZED) {
+ return;
+ }
+ // if we're switching from a part source in our own stack,
+ // we also don't want to clear our content.
+ if (part instanceof IViewPart) {
+ final IViewPart[] viewStack = getSite().getPage()
+ .getViewStack(this);
+ if (containsPart(viewStack, part)) {
+ return;
+ }
+ }
+ hiddenPart = part;
+ showPageRec(defaultPageRec);
+ }
+
+ /**
+ * @param viewStack
+ * @param part
+ * @return <code>true</code> if the part is in the viewStack
+ */
+ private boolean containsPart(IViewPart[] viewStack, IWorkbenchPart part) {
+ if (viewStack == null) {
+ return false;
+ }
+ for (int i = 0; i < viewStack.length; i++) {
+ if (viewStack[i] == part) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Make sure that the part is not considered if it is hidden.
+ *
+ * @param part
+ * @since 3.5
+ */
+ protected void partVisible(IWorkbenchPart part) {
+ if (part == null || part != hiddenPart) {
+ return;
+ }
+ partActivated(part);
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/PageSite.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/PageSite.java
new file mode 100644
index 0000000..c401692
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/PageSite.java
@@ -0,0 +1,246 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.ui.part;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.e4.core.services.context.EclipseContextFactory;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.workbench.ui.internal.UISchedulerStrategy;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.SubActionBars;
+import org.eclipse.ui.internal.PartSite;
+import org.eclipse.ui.internal.PopupMenuExtender;
+import org.eclipse.ui.internal.ViewSite;
+import org.eclipse.ui.internal.part.IPageSiteHolder;
+import org.eclipse.ui.internal.services.INestable;
+import org.eclipse.ui.internal.services.IServiceLocatorCreator;
+import org.eclipse.ui.internal.services.IWorkbenchLocationService;
+import org.eclipse.ui.internal.services.ServiceLocator;
+import org.eclipse.ui.internal.services.WorkbenchLocationService;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.services.IServiceScopes;
+
+/**
+ * This implementation of <code>IPageSite</code> provides a site for a page
+ * within a <code>PageBookView</code>. Most methods are forwarded to the view's
+ * site.
+ */
+public class PageSite implements IPageSite, INestable {
+
+ /**
+ * The list of menu extender for each registered menu.
+ */
+ private ArrayList menuExtenders;
+
+ /**
+ * The "parent" view site
+ */
+ private IViewSite parentSite;
+
+ /**
+ * A selection provider set by the page. Value is <code>null</code> until
+ * set.
+ */
+ private ISelectionProvider selectionProvider;
+
+ /**
+ * The localized service locator for this page site. This locator is never
+ * <code>null</code>.
+ */
+ private final ServiceLocator serviceLocator;
+
+ /**
+ * The action bars for this site
+ */
+ private SubActionBars subActionBars;
+
+ private IEclipseContext e4Context;
+
+ /**
+ * Creates a new sub view site of the given parent view site.
+ *
+ * @param parentViewSite
+ * the parent view site
+ */
+ public PageSite(final IViewSite parentViewSite) {
+ Assert.isNotNull(parentViewSite);
+ parentSite = parentViewSite;
+ subActionBars = new SubActionBars(parentViewSite.getActionBars(), this);
+
+ // Initialize the service locator.
+ IServiceLocatorCreator slc = (IServiceLocatorCreator) parentSite
+ .getService(IServiceLocatorCreator.class);
+ this.serviceLocator = (ServiceLocator) slc.createServiceLocator(
+ parentViewSite, null, new IDisposable() {
+ public void dispose() {
+ final Control control = ((PartSite) parentViewSite)
+ .getPane().getControl();
+ if (control != null && !control.isDisposed()) {
+ ((PartSite) parentViewSite).getPane().doHide();
+ }
+ }
+ });
+ e4Context = EclipseContextFactory.create(
+ ((ViewSite) parentSite).getContext(), UISchedulerStrategy
+ .getInstance());
+ this.serviceLocator.setContext(e4Context);
+ initializeDefaultServices();
+ }
+
+ /**
+ * Initialize the slave services for this site.
+ */
+ private void initializeDefaultServices() {
+ serviceLocator.registerService(IWorkbenchLocationService.class,
+ new WorkbenchLocationService(IServiceScopes.PAGESITE_SCOPE,
+ getWorkbenchWindow().getWorkbench(),
+ getWorkbenchWindow(), parentSite, null, this, 3));
+ serviceLocator.registerService(IPageSiteHolder.class,
+ new IPageSiteHolder() {
+ public IPageSite getSite() {
+ return PageSite.this;
+ }
+ });
+ }
+
+ /**
+ * Disposes of the menu extender contributions.
+ */
+ protected void dispose() {
+ if (menuExtenders != null) {
+ HashSet managers = new HashSet(menuExtenders.size());
+ for (int i = 0; i < menuExtenders.size(); i++) {
+ PopupMenuExtender ext = (PopupMenuExtender) menuExtenders
+ .get(i);
+ managers.add(ext.getManager());
+ ext.dispose();
+ }
+ if (managers.size() > 0) {
+ for (Iterator iterator = managers.iterator(); iterator
+ .hasNext();) {
+ MenuManager mgr = (MenuManager) iterator.next();
+ mgr.dispose();
+ }
+ }
+ menuExtenders = null;
+ }
+ subActionBars.dispose();
+ serviceLocator.dispose();
+ }
+
+ /**
+ * The PageSite implementation of this <code>IPageSite</code> method returns
+ * the <code>SubActionBars</code> for this site.
+ *
+ * @return the subactionbars for this site
+ */
+ public IActionBars getActionBars() {
+ return subActionBars;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ public Object getAdapter(Class adapter) {
+ return Platform.getAdapterManager().getAdapter(this, adapter);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IPageSite.
+ */
+ public IWorkbenchPage getPage() {
+ return parentSite.getPage();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IPageSite.
+ */
+ public ISelectionProvider getSelectionProvider() {
+ return selectionProvider;
+ }
+
+ public final Object getService(final Class key) {
+ return serviceLocator.getService(key);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IPageSite.
+ */
+ public Shell getShell() {
+ return parentSite.getShell();
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IPageSite.
+ */
+ public IWorkbenchWindow getWorkbenchWindow() {
+ return parentSite.getWorkbenchWindow();
+ }
+
+ public final boolean hasService(final Class key) {
+ return serviceLocator.hasService(key);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IPageSite.
+ */
+ public void registerContextMenu(String menuID, MenuManager menuMgr,
+ ISelectionProvider selProvider) {
+ if (menuExtenders == null) {
+ menuExtenders = new ArrayList(1);
+ }
+ PartSite.registerContextMenu(menuID, menuMgr, selProvider, false,
+ parentSite.getPart(), menuExtenders);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IPageSite.
+ */
+ public void setSelectionProvider(ISelectionProvider provider) {
+ selectionProvider = provider;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.internal.services.INestable#activate()
+ *
+ * @since 3.2
+ */
+ public void activate() {
+ serviceLocator.activate();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.internal.services.INestable#deactivate()
+ *
+ * @since 3.2
+ */
+ public void deactivate() {
+ serviceLocator.deactivate();
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.classpath b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.project b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.project
new file mode 100644
index 0000000..2a6b80c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.e4photo.flickr.mock</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..1f4fe61
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sun Feb 14 11:25:26 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.mock/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..419d88b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Mock
+Bundle-SymbolicName: org.eclipse.e4.demo.e4photo.flickr.mock; singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.e4.demo.e4photo.flickr;bundle-version="1.0.0",
+ org.eclipse.e4.core.services;bundle-version="0.9.1",
+ org.eclipse.equinox.ds;bundle-version="1.2.0",
+ org.eclipse.e4.demo.e4photo.flickr.service;bundle-version="1.0.0",
+ org.eclipse.e4.demo.e4photo.flickr.service.rest;bundle-version="1.0.0",
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0",
+ org.eclipse.e4.core.di;bundle-version="0.9.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.mock/build.properties b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/build.properties
new file mode 100644
index 0000000..2b0d95b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = plugin.xml,\
+ META-INF/,\
+ .
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.mock/plugin.xml b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/plugin.xml
new file mode 100644
index 0000000..409a233
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/plugin.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+ <extension
+ id="application"
+ point="org.eclipse.core.runtime.applications">
+ <application>
+ <run
+ class="org.eclipse.e4.demo.e4photo.flickr.mock.Application">
+ </run>
+ </application>
+ </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.mock/src/org/eclipse/e4/demo/e4photo/flickr/mock/Application.java b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/src/org/eclipse/e4/demo/e4photo/flickr/mock/Application.java
new file mode 100644
index 0000000..8995418
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.mock/src/org/eclipse/e4/demo/e4photo/flickr/mock/Application.java
@@ -0,0 +1,48 @@
+package org.eclipse.e4.demo.e4photo.flickr.mock;
+
+import org.eclipse.e4.core.contexts.ContextInjectionFactory;
+import org.eclipse.e4.core.contexts.EclipseContextFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.demo.e4photo.flickr.ui.Flickr;
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * This class controls all aspects of the application's execution
+ */
+public class Application implements IApplication {
+
+ public Object start(IApplicationContext context) throws Exception {
+ Display display = new Display();
+ Shell shell = new Shell();
+
+ Bundle bundle = FrameworkUtil.getBundle(Application.class);
+ BundleContext bundleContext = bundle.getBundleContext();
+ IEclipseContext eclipseCtx = EclipseContextFactory.getServiceContext(bundleContext);
+ eclipseCtx.set(Composite.class.getName(), shell);
+
+ ContextInjectionFactory.make(Flickr.class, eclipseCtx);
+
+ shell.open();
+
+ while( ! shell.isDisposed() ) {
+ if( ! display.readAndDispatch() ) {
+ display.sleep();
+ }
+ }
+
+ display.dispose();
+
+ return IApplication.EXIT_OK;
+ }
+
+ public void stop() {
+ // nothing to do
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.classpath b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.project b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.project
new file mode 100644
index 0000000..21882e2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.e4photo.flickr.service.rest</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..ae4a2dc
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sat Feb 13 18:32:38 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.settings/org.eclipse.pde.core.prefs b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..39c0d2f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,4 @@
+#Sat Feb 13 18:32:38 CET 2010
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..daa16fc
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/META-INF/MANIFEST.MF
@@ -0,0 +1,10 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Rest
+Bundle-SymbolicName: org.eclipse.e4.demo.e4photo.flickr.service.rest
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.demo.e4photo.flickr.service;bundle-version="1.0.0"
+Export-Package: org.eclipse.e4.demo.e4photo.flickr.service.rest
+Service-Component: OSGI-INF/component.xml
+Bundle-ActivationPolicy: lazy
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/OSGI-INF/component.xml b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/OSGI-INF/component.xml
new file mode 100644
index 0000000..57ea162
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/OSGI-INF/component.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.eclipse.e4.demo.e4photo.flickr.service.rest">
+ <implementation class="org.eclipse.e4.demo.e4photo.flickr.service.rest.RestFlickrService"/>
+ <service>
+ <provide interface="org.eclipse.e4.demo.e4photo.flickr.service.IFlickrService"/>
+ </service>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/build.properties b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/build.properties
new file mode 100644
index 0000000..fc8c47c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/build.properties
@@ -0,0 +1,5 @@
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ OSGI-INF/component.xml
+source.. = src/
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/JSONUtil.java b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/JSONUtil.java
new file mode 100644
index 0000000..47652a8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/JSONUtil.java
@@ -0,0 +1,326 @@
+/*******************************************************************************
+ * 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.e4.demo.e4photo.flickr.service.rest;
+
+import java.math.BigDecimal;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.*;
+
+// JSON <--> Java
+//------------------
+// string <--> java.lang.String
+// number <--> java.math.Number (BigDecimal)
+// object <--> java.util.Map (HashMap)
+// array <--> java.util.Collection (ArrayList)
+// true <--> java.lang.Boolean.TRUE
+// false <--> java.lang.Boolean.FALSE
+// null <--> null
+
+public class JSONUtil {
+ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+ private static final String NULL = "null"; //$NON-NLS-1$
+
+ public static Object read(String jsonString) {
+ return parse(new StringCharacterIterator(jsonString));
+ }
+
+ public static String write(Object jsonObject) {
+ StringBuffer buffer = new StringBuffer();
+ writeValue(jsonObject, buffer);
+ return buffer.toString();
+ }
+
+ private static RuntimeException error(String message, CharacterIterator it) {
+ return new IllegalStateException("[" + it.getIndex() + "] " + message); //$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ private static RuntimeException error(String message) {
+ return new IllegalStateException(message);
+ }
+
+ private static Object parse(CharacterIterator it) {
+ parseWhitespace(it);
+ Object result = parseValue(it);
+ parseWhitespace(it);
+
+ if (it.current() != CharacterIterator.DONE)
+ throw error("should be done", it); //$NON-NLS-1$
+ return result;
+ }
+
+ private static void parseWhitespace(CharacterIterator it) {
+ char c = it.current();
+ while (Character.isWhitespace(c))
+ c = it.next();
+ }
+
+ private static Object parseValue(CharacterIterator it) {
+ switch (it.current()) {
+ case '{' :
+ return parseObject(it);
+ case '[' :
+ return parseArray(it);
+ case '"' :
+ return parseString(it);
+ case '-' :
+ case '0' :
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' :
+ return parseNumber(it);
+ case 't' :
+ parseText(Boolean.TRUE.toString(), it);
+ return Boolean.TRUE;
+ case 'f' :
+ parseText(Boolean.FALSE.toString(), it);
+ return Boolean.FALSE;
+ case 'n' :
+ parseText(NULL, it);
+ return null;
+ }
+ throw error("Bad JSON starting character '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$;
+ }
+
+ private static Map parseObject(CharacterIterator it) {
+ it.next();
+ parseWhitespace(it);
+ if (it.current() == '}') {
+ it.next();
+ return Collections.EMPTY_MAP;
+ }
+
+ Map map = new HashMap();
+ while (true) {
+ if (it.current() != '"')
+ throw error("expected a string start '\"' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+ String key = parseString(it);
+ if (map.containsKey(key))
+ throw error("' already defined" + "key '" + key, it); //$NON-NLS-1$ //$NON-NLS-2$
+ parseWhitespace(it);
+ if (it.current() != ':')
+ throw error("expected a pair separator ':' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+ it.next();
+ parseWhitespace(it);
+ Object value = parseValue(it);
+ map.put(key, value);
+ parseWhitespace(it);
+ if (it.current() == ',') {
+ it.next();
+ parseWhitespace(it);
+ continue;
+ }
+
+ if (it.current() != '}')
+ throw error("expected an object close '}' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ }
+ it.next();
+ return map;
+ }
+
+ private static List parseArray(CharacterIterator it) {
+ it.next();
+ parseWhitespace(it);
+ if (it.current() == ']') {
+ it.next();
+ return Collections.EMPTY_LIST;
+ }
+
+ List list = new ArrayList();
+ while (true) {
+ Object value = parseValue(it);
+ list.add(value);
+ parseWhitespace(it);
+ if (it.current() == ',') {
+ it.next();
+ parseWhitespace(it);
+ continue;
+ }
+
+ if (it.current() != ']')
+ throw error("expected an array close ']' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ }
+ it.next();
+ return list;
+ }
+
+ private static void parseText(String string, CharacterIterator it) {
+ int length = string.length();
+ char c = it.current();
+ for (int i = 0; i < length; i++) {
+ if (c != string.charAt(i))
+ throw error("expected to parse '" + string + "' but character " + (i + 1) + " was '" + c + "'", it); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$;
+ c = it.next();
+ }
+ }
+
+ private static Object parseNumber(CharacterIterator it) {
+ StringBuffer buffer = new StringBuffer();
+ char c = it.current();
+ while (Character.isDigit(c) || c == '-' || c == '+' || c == '.' || c == 'e' || c == 'E') {
+ buffer.append(c);
+ c = it.next();
+ }
+ try {
+ return new BigDecimal(buffer.toString());
+ } catch (NumberFormatException e) {
+ throw error("expected a number but was '" + buffer.toString() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$;
+ }
+ }
+
+ private static String parseString(CharacterIterator it) {
+ char c = it.next();
+ if (c == '"') {
+ it.next();
+ return EMPTY_STRING;
+ }
+ StringBuffer buffer = new StringBuffer();
+ while (c != '"') {
+ if (Character.isISOControl(c))
+ throw error("illegal iso control character: '" + Integer.toHexString(c) + "'", it); //$NON-NLS-1$ //$NON-NLS-2$);
+
+ if (c == '\\') {
+ c = it.next();
+ switch (c) {
+ case '"' :
+ case '\\' :
+ case '/' :
+ buffer.append(c);
+ break;
+ case 'b' :
+ buffer.append('\b');
+ break;
+ case 'f' :
+ buffer.append('\f');
+ break;
+ case 'n' :
+ buffer.append('\n');
+ break;
+ case 'r' :
+ buffer.append('\r');
+ break;
+ case 't' :
+ buffer.append('\t');
+ break;
+ case 'u' :
+ StringBuffer unicode = new StringBuffer(4);
+ for (int i = 0; i < 4; i++) {
+ unicode.append(it.next());
+ }
+ try {
+ buffer.append((char) Integer.parseInt(unicode.toString(), 16));
+ } catch (NumberFormatException e) {
+ throw error("expected a unicode hex number but was '" + unicode.toString() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$););
+ }
+ break;
+ default :
+ throw error("illegal escape character '" + c + "'", it); //$NON-NLS-1$ //$NON-NLS-2$););
+ }
+ } else
+ buffer.append(c);
+
+ c = it.next();
+ }
+ c = it.next();
+ return buffer.toString();
+ }
+
+ private static void writeValue(Object value, StringBuffer buffer) {
+ if (value == null)
+ buffer.append(NULL);
+ else if (value instanceof Boolean || value instanceof Number)
+ buffer.append(value.toString());
+ else if (value instanceof String)
+ writeString((String) value, buffer);
+ else if (value instanceof Collection)
+ writeArray((Collection) value, buffer);
+ else if (value instanceof Map)
+ writeObject((Map) value, buffer);
+ else
+ throw error("Unexpected object instance type was '" + value.getClass().getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$););
+ }
+
+ private static void writeObject(Map map, StringBuffer buffer) {
+ buffer.append('{');
+ for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) {
+ Object key = iterator.next();
+ if (!(key instanceof String))
+ throw error("Map keys must be an instance of String but was '" + key.getClass().getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$););
+ writeString((String) key, buffer);
+ buffer.append(':');
+ writeValue(map.get(key), buffer);
+ buffer.append(',');
+ }
+ if (buffer.charAt(buffer.length() - 1) == ',')
+ buffer.setCharAt(buffer.length() - 1, '}');
+ else
+ buffer.append('}');
+ }
+
+ private static void writeArray(Collection collection, StringBuffer buffer) {
+ buffer.append('[');
+ for (Iterator iterator = collection.iterator(); iterator.hasNext();) {
+ writeValue(iterator.next(), buffer);
+ buffer.append(',');
+ }
+ if (buffer.charAt(buffer.length() - 1) == ',')
+ buffer.setCharAt(buffer.length() - 1, ']');
+ else
+ buffer.append(']');
+ }
+
+ private static void writeString(String string, StringBuffer buffer) {
+ buffer.append('"');
+ int length = string.length();
+ for (int i = 0; i < length; i++) {
+ char c = string.charAt(i);
+ switch (c) {
+ case '"' :
+ case '\\' :
+ case '/' :
+ buffer.append('\\');
+ buffer.append(c);
+ break;
+ case '\b' :
+ buffer.append("\\b"); //$NON-NLS-1$
+ break;
+ case '\f' :
+ buffer.append("\\f"); //$NON-NLS-1$
+ break;
+ case '\n' :
+ buffer.append("\\n"); //$NON-NLS-1$
+ break;
+ case '\r' :
+ buffer.append("\\r"); //$NON-NLS-1$
+ break;
+ case '\t' :
+ buffer.append("\\t"); //$NON-NLS-1$
+ break;
+ default :
+ if (Character.isISOControl(c)) {
+ buffer.append("\\u"); //$NON-NLS-1$
+ String hexString = Integer.toHexString(c);
+ for (int j = hexString.length(); j < 4; j++)
+ buffer.append('0');
+ buffer.append(hexString);
+ } else
+ buffer.append(c);
+ }
+ }
+ buffer.append('"');
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/RestFlickrService.java b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/RestFlickrService.java
new file mode 100644
index 0000000..6981ae1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/RestFlickrService.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.service.rest;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.rmi.RemoteException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.e4.demo.e4photo.flickr.service.FlickrPhoto;
+import org.eclipse.e4.demo.e4photo.flickr.service.FlickrSearch;
+import org.eclipse.e4.demo.e4photo.flickr.service.IFlickrService;
+
+/**
+ * Custom implementation to access flickr through its rest API
+ */
+public class RestFlickrService implements IFlickrService {
+
+ public RestFlickrService() {
+ System.err.println("Service created");
+ }
+
+ public InputStream getPhoto(FlickrPhoto photo) throws RemoteException {
+ try {
+ String path = "http://farm" + photo.getFarm() + ".static.flickr.com/" + photo.getServer() + "/"+ photo.getId() + "_" + photo.getSecret() + ".jpg";
+ URL url = new URL(path);
+ return url.openStream();
+ } catch (MalformedURLException e) {
+ throw new RemoteException("Failed to fetch Flickr-Image.", e);
+ } catch (IOException e) {
+ throw new RemoteException("Failed to fetch Flickr-Image.", e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public FlickrSearch createTagSearch(String apiKey, String tags) throws RemoteException {
+ Map<String,Object> obj = searchByTagsRequest("flickr.photos.search", apiKey, tags, 1);
+ if( obj != null ) {
+ try {
+ Map<String,Object> o = (Map<String, Object>) obj.get("photos");
+ int pages = ((Number) o.get("pages")).intValue();
+ int pageSize = ((Number) o.get("perpage")).intValue();
+ int total = Integer.parseInt((String) o.get("total"));
+ return new RestFlickrTagSearch( apiKey, pages, pageSize, total, tags);
+ } catch (Exception e) {
+ throw new RemoteException("Failure while parsing response", e);
+ }
+ }
+
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<FlickrPhoto> getPhotos(FlickrSearch search, int page) throws RemoteException {
+ if( search instanceof RestFlickrTagSearch ) {
+ RestFlickrTagSearch tmp = (RestFlickrTagSearch) search;
+ Map<String,Object> root = searchByTagsRequest("flickr.photos.search", tmp.getApiKey(), tmp.getTags(), page);
+ if( root != null ) {
+ try {
+ Collection<Object> list = (Collection<Object>) ((Map<String,Object>)root.get("photos")).get("photo");
+ ArrayList<FlickrPhoto> rv = new ArrayList<FlickrPhoto>();
+ Iterator<Object> it = list.iterator();
+
+ while( it.hasNext() ) {
+ Map<String,Object> o = (Map<String, Object>) it.next();
+ FlickrPhoto photo = new FlickrPhoto();
+ photo.setFamily( ((Number)o.get("isfamily")).intValue() != 0);
+ photo.setFarm( ((Number)o.get("farm")).intValue() );
+ photo.setFriend(((Number)o.get("isfriend")).intValue() != 0);
+ photo.setId((String) o.get("id"));
+ photo.setOwner((String) o.get("owner"));
+ photo.setPublic(((Number)o.get("ispublic")).intValue() != 0);
+ photo.setSecret((String) o.get("secret"));
+ photo.setServer((String) o.get("server"));
+ photo.setTitle((String) o.get("title"));
+ rv.add(photo);
+ }
+ return rv;
+ } catch (Exception e) {
+ throw new RemoteException("Failure while parsing response", e);
+ }
+ }
+ }
+
+ throw new IllegalArgumentException("The search type '"+search.getClass().getName()+"' is not supported.");
+ }
+
+ @SuppressWarnings("unchecked")
+ private Map<String,Object> searchByTagsRequest(String method, String apiKey, String tags, int page) throws RemoteException {
+ String request = "http://api.flickr.com/services/rest/";
+ request += "?tags=" + tags;
+ request += "&method=flickr.photos.search";
+ request += "&api_key="+apiKey;
+ request += "&format=json";
+ request += "&page=" + page;
+
+ try {
+ URL url = new URL(request);
+ InputStream in = url.openStream();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ String line;
+ StringBuilder b = new StringBuilder();
+ while( (line = reader.readLine()) != null ) {
+ b.append(line);
+ }
+
+ String result = b.toString().substring("jsonFlickrApi(".length(), b.toString().length() - 1);
+ System.err.println("RESULT: " + b);
+ Map<String,Object> o = (Map<String, Object>) JSONUtil.read(result);
+
+ if( ! "ok".equals(o.get("stat")) ) {
+ throw new RemoteException((String)o.get("message"));
+ }
+ return o;
+ } catch (RemoteException e) {
+ throw e;
+ } catch (MalformedURLException e) {
+ throw new RemoteException("Failure fetching page '"+page+"'",e);
+ } catch (IOException e) {
+ throw new RemoteException("Failure fetching page '"+page+"'",e);
+ }
+ }
+
+ public static void main(String[] args) {
+ try {
+ RestFlickrService s = new RestFlickrService();
+ FlickrSearch search = s.createTagSearch("46d3d5269fe6513602b3f0f06d9e2b2e", "eclipsecon");
+
+ for( int page = 1; page <= search.getPages(); page++ ) {
+ System.err.println("--------------------------------");
+ System.err.println("Page " + page);
+ System.err.println("--------------------------------");
+ List<FlickrPhoto> photos = s.getPhotos(search, page);
+ for( FlickrPhoto p : photos ) {
+ System.err.println(" * " + p);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/RestFlickrTagSearch.java b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/RestFlickrTagSearch.java
new file mode 100644
index 0000000..63fb9b7
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service.rest/src/org/eclipse/e4/demo/e4photo/flickr/service/rest/RestFlickrTagSearch.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.service.rest;
+
+import org.eclipse.e4.demo.e4photo.flickr.service.FlickrSearch;
+
+public class RestFlickrTagSearch extends FlickrSearch {
+ private String tags;
+
+ public RestFlickrTagSearch(String apiKey, int pages, int pageSize, int totalItems, String tags) {
+ super(apiKey, pages, pageSize, totalItems);
+ this.tags = tags;
+ }
+
+ public String getTags() {
+ return tags;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/.classpath b/examples/org.eclipse.e4.demo.e4photo.flickr.service/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/.project b/examples/org.eclipse.e4.demo.e4photo.flickr.service/.project
new file mode 100644
index 0000000..1c17d49
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.e4photo.flickr.service</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.e4photo.flickr.service/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..432f96c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sat Feb 13 18:30:01 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/.settings/org.eclipse.pde.core.prefs b/examples/org.eclipse.e4.demo.e4photo.flickr.service/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..c8b640e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,4 @@
+#Sat Feb 13 18:30:01 CET 2010
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.e4photo.flickr.service/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..a2c7fdf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/META-INF/MANIFEST.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Service
+Bundle-SymbolicName: org.eclipse.e4.demo.e4photo.flickr.service
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.e4.demo.e4photo.flickr.service
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/build.properties b/examples/org.eclipse.e4.demo.e4photo.flickr.service/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/FlickrPhoto.java b/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/FlickrPhoto.java
new file mode 100644
index 0000000..164a46a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/FlickrPhoto.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.service;
+
+/**
+ * Domain class describing a photo on flickr
+ */
+public class FlickrPhoto {
+ private String id;
+ private String owner;
+ private String secret;
+ private String server;
+ private int farm;
+ private String title;
+ private boolean isPublic;
+ private boolean isFriend;
+ private boolean isFamily;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getOwner() {
+ return owner;
+ }
+
+ public void setOwner(String owner) {
+ this.owner = owner;
+ }
+
+ public String getSecret() {
+ return secret;
+ }
+
+ public void setSecret(String secret) {
+ this.secret = secret;
+ }
+
+ public String getServer() {
+ return server;
+ }
+
+ public void setServer(String server) {
+ this.server = server;
+ }
+
+ public int getFarm() {
+ return farm;
+ }
+
+ public void setFarm(int farm) {
+ this.farm = farm;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public boolean isPublic() {
+ return isPublic;
+ }
+
+ public void setPublic(boolean isPublic) {
+ this.isPublic = isPublic;
+ }
+
+ public boolean isFriend() {
+ return isFriend;
+ }
+
+ public void setFriend(boolean isFriend) {
+ this.isFriend = isFriend;
+ }
+
+ public boolean isFamily() {
+ return isFamily;
+ }
+
+ public void setFamily(boolean isFamily) {
+ this.isFamily = isFamily;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/FlickrSearch.java b/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/FlickrSearch.java
new file mode 100644
index 0000000..ba65612
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/FlickrSearch.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.service;
+
+/**
+ * Represents a flickr search which is used to access search pages
+ */
+public class FlickrSearch {
+ private int pages;
+ private int pageSize;
+ private int totalItems;
+ private String apiKey;
+
+ public FlickrSearch(String apiKey, int pages, int pageSize, int totalItems) {
+ this.apiKey = apiKey;
+ this.pages = pages;
+ this.pageSize = pageSize;
+ this.totalItems = totalItems;
+ }
+
+ public int getPages() {
+ return pages;
+ }
+
+ public String getApiKey() {
+ return apiKey;
+ }
+
+ public int getPageSize() {
+ return pageSize;
+ }
+
+ public int getTotalItems() {
+ return totalItems;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/IFlickrService.java b/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/IFlickrService.java
new file mode 100644
index 0000000..8d75e8d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr.service/src/org/eclipse/e4/demo/e4photo/flickr/service/IFlickrService.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.service;
+
+import java.io.InputStream;
+import java.rmi.RemoteException;
+import java.util.List;
+
+/**
+ * Service interface to access flickr
+ */
+public interface IFlickrService {
+ public FlickrSearch createTagSearch(String apiKey, String tags) throws RemoteException;
+
+ public List<FlickrPhoto> getPhotos(FlickrSearch search, int page) throws RemoteException;
+
+ public InputStream getPhoto(FlickrPhoto photo) throws RemoteException;
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/.classpath b/examples/org.eclipse.e4.demo.e4photo.flickr/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/.project b/examples/org.eclipse.e4.demo.e4photo.flickr/.project
new file mode 100644
index 0000000..d4e510c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.e4photo.flickr</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.e4photo.flickr/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..fa5bc6c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sat Feb 13 17:18:20 CET 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/.settings/org.eclipse.pde.core.prefs b/examples/org.eclipse.e4.demo.e4photo.flickr/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..2ad4a73
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,4 @@
+#Sat Feb 13 17:44:58 CET 2010
+eclipse.preferences.version=1
+pluginProject.extensions=true
+resolve.requirebundle=false
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.e4photo.flickr/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..51c915f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Flickr
+Bundle-SymbolicName: org.eclipse.e4.demo.e4photo.flickr;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.1",
+ javax.inject;bundle-version="1.0.0",
+ org.eclipse.e4.demo.e4photo.flickr.service;bundle-version="1.0.0",
+ org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.equinox.common;bundle-version="3.6.0"
+Export-Package: org.eclipse.e4.demo.e4photo.flickr.ui;x-friends:="org.eclipse.e4.demo.e4photo.flickr.mock"
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/about.html b/examples/org.eclipse.e4.demo.e4photo.flickr/about.html
new file mode 100644
index 0000000..c1343aa
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/about.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>December 3, 2009</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+<h3>Third Party Content</h3>
+
+<p>The Content includes items from third parties as set out below. If you did not
+receive this Content directly from the Eclipse Foundation, the following is provided for informational
+purposes only, and you should look to the Redistributor’s license for terms and conditions of use.</p>
+
+<h4>Silk icon set Version 1.3</h4>
+<p>
+This plugin contains icons from the Silk icon set created by Mark James. The original files can
+be found at:
+<ul>
+<a href="http://www.famfamfam.com/lab/icons/silk/">http://www.famfamfam.com/lab/icons/silk/</a></ul>
+<p>The license can be found at:</p>
+<ul>
+ <li><a href="http://creativecommons.org/licenses/by/2.5/">http://creativecommons.org/licenses/by/2.5/</a></li>
+</ul>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/build.properties b/examples/org.eclipse.e4.demo.e4photo.flickr/build.properties
new file mode 100644
index 0000000..7ae8bc7
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ xmi/
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/icons/accept.png b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/accept.png
new file mode 100644
index 0000000..89c8129
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/accept.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_end_blue.png b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_end_blue.png
new file mode 100644
index 0000000..7207935
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_end_blue.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_fastforward_blue.png b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_fastforward_blue.png
new file mode 100644
index 0000000..4a2f9d4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_fastforward_blue.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_rewind_blue.png b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_rewind_blue.png
new file mode 100644
index 0000000..15d1584
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_rewind_blue.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_start_blue.png b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_start_blue.png
new file mode 100644
index 0000000..6f11fcb
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/control_start_blue.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/icons/exclamation.png b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/exclamation.png
new file mode 100644
index 0000000..c37bd06
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/icons/exclamation.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/plugin.xml b/examples/org.eclipse.e4.demo.e4photo.flickr/plugin.xml
new file mode 100644
index 0000000..b39876c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ id="id2"
+ point="org.eclipse.e4.workbench.model">
+ <fragment
+ uri="xmi/fragment.e4xmi">
+ </fragment>
+ </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/Flickr.java b/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/Flickr.java
new file mode 100644
index 0000000..e0368b6
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/Flickr.java
@@ -0,0 +1,281 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.ui;
+
+import java.rmi.RemoteException;
+import java.util.Collections;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.e4.demo.e4photo.flickr.service.FlickrPhoto;
+import org.eclipse.e4.demo.e4photo.flickr.service.FlickrSearch;
+import org.eclipse.e4.demo.e4photo.flickr.service.IFlickrService;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.ColumnPixelData;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.ViewerCell;
+import org.eclipse.jface.window.ToolTip;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Search for images on flickr.com
+ */
+public class Flickr {
+ @Inject
+ private IFlickrService flickrService;
+
+ private Composite comp;
+
+ private PagedTable<FlickrPhoto> table;
+
+ @Inject
+ public Flickr(Composite comp) {
+ this.comp = comp;
+ comp.setLayout(new GridLayout(3, false));
+
+ final Image OK_IMG = new Image(comp.getDisplay(), getClass().getClassLoader().getResourceAsStream("icons/accept.png"));
+ final Image NOK_IMG = new Image(comp.getDisplay(), getClass().getClassLoader().getResourceAsStream("icons/exclamation.png"));
+
+ comp.addDisposeListener(new DisposeListener() {
+
+ public void widgetDisposed(DisposeEvent e) {
+ OK_IMG.dispose();
+ NOK_IMG.dispose();
+ }
+ });
+
+ comp.setBackgroundMode(SWT.INHERIT_DEFAULT);
+
+ Label l = new Label(comp, SWT.NONE);
+ l.setText("Flickr API-Key");
+ l.setLayoutData(new GridData(SWT.DEFAULT,GridData.CENTER,false,false));
+
+ final Text apiKey = new Text(comp, SWT.BORDER);
+ apiKey.setLayoutData(new GridData(GridData.FILL,GridData.CENTER,true,false,2,1));
+ apiKey.setText("46d3d5269fe6513602b3f0f06d9e2b2e");
+
+ l = new Label(comp, SWT.NONE);
+ l.setText("Search Tags");
+ l.setLayoutData(new GridData(SWT.DEFAULT,GridData.CENTER,false,false));
+
+ final Text tags = new Text(comp, SWT.BORDER);
+ tags.setLayoutData(new GridData(GridData.FILL,GridData.CENTER,true,false));
+ tags.setText("eclipsecon");
+
+ Button button = new Button(comp, SWT.PUSH);
+ button.setText("Search");
+
+ table = new PagedTable<FlickrPhoto>(comp, SWT.NONE);
+
+ button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ handleSearch(apiKey.getText(), tags.getText());
+ }
+ });
+
+ table.addColumn("Id", new PagedTable.PageColumnLabelProvider<FlickrPhoto>() {
+ @Override
+ protected String doGetText(FlickrPhoto element) {
+ return element.getId();
+ }
+ },new ColumnPixelData(120));
+ table.addColumn("Title", new PagedTable.PageColumnLabelProvider<FlickrPhoto>() {
+ @Override
+ protected String doGetText(FlickrPhoto element) {
+ return element.getTitle();
+ }
+
+ @Override
+ protected String doGetToolTipText(FlickrPhoto element) {
+ return element.getId() + " - " + element.getTitle();
+ }
+ },new ColumnWeightData(1));
+ table.addColumn("Public", new PagedTable.PageColumnLabelProvider<FlickrPhoto>() {
+ @Override
+ protected Image doGetImage(FlickrPhoto element) {
+ if( element.isPublic() ) {
+ return OK_IMG;
+ } else {
+ return NOK_IMG;
+ }
+ }
+
+ @Override
+ protected String doGetText(FlickrPhoto element) {
+ return "";
+ }
+ },new ColumnPixelData(50));
+
+ table.addColumn("Friend", new PagedTable.PageColumnLabelProvider<FlickrPhoto>() {
+ @Override
+ protected Image doGetImage(FlickrPhoto element) {
+ if( element.isFriend() ) {
+ return OK_IMG;
+ } else {
+ return NOK_IMG;
+ }
+ }
+ @Override
+ protected String doGetText(FlickrPhoto element) {
+ return "";
+ }
+
+ },new ColumnPixelData(50));
+
+ table.addColumn("Family", new PagedTable.PageColumnLabelProvider<FlickrPhoto>() {
+ @Override
+ protected Image doGetImage(FlickrPhoto element) {
+ if( element.isFamily() ) {
+ return OK_IMG;
+ } else {
+ return NOK_IMG;
+ }
+ }
+ @Override
+ protected String doGetText(FlickrPhoto element) {
+ return "";
+ }
+
+ },new ColumnPixelData(50));
+
+ table.setLayoutData(new GridData(GridData.FILL,GridData.FILL,true,true,3,1));
+
+ new ToolTipSupport(table.getViewer(), ToolTip.NO_RECREATE, false);
+ }
+
+ private void handleSearch(String apiKey, String tags) {
+ try {
+ FlickrSearch search = flickrService.createTagSearch(apiKey, tags);
+ table.setInput(new SearchInput(search));
+ } catch (RemoteException e1) {
+ Status s = new Status(IStatus.ERROR, "org.eclipse.e4.demo.e4photo.flickr", e1.getMessage(), e1);
+ ErrorDialog.openError(table.getShell(), "Searchfailure", "Failure while executing search", s);
+ }
+ }
+
+ private class ToolTipSupport extends ColumnViewerToolTipSupport {
+
+ protected ToolTipSupport(ColumnViewer viewer, int style,
+ boolean manualActivation) {
+ super(viewer, style, manualActivation);
+ }
+
+ @Override
+ protected Composite createViewerToolTipContentArea(Event event,
+ ViewerCell cell, final Composite parent) {
+ Composite comp = new Composite(parent, SWT.NONE);
+
+ parent.setBackgroundMode(SWT.INHERIT_DEFAULT);
+ if( cell == null || cell.getElement() == null ) {
+ return comp;
+ }
+ final FlickrPhoto photo = (FlickrPhoto) cell.getElement();
+
+ comp.setLayout(new GridLayout());
+ Label l = new Label(comp, SWT.NONE);
+ l.setText(getText(event));
+ l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ l = new Label(comp, SWT.SEPARATOR | SWT.HORIZONTAL);
+ l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ final Label img = new Label(comp, SWT.NONE);
+
+ Thread t = new Thread() {
+ public void run() {
+ if( parent.isDisposed() ) {
+ return;
+ }
+
+ parent.getDisplay().syncExec(new Runnable() {
+
+ public void run() {
+ if( img.isDisposed() ) {
+ return;
+ }
+
+ try {
+ img.setImage(new Image(parent.getDisplay(), flickrService.getPhoto(photo)));
+ } catch (RemoteException e) {
+ img.setText("Failed to fetch image from remote server.");
+ }
+ parent.getShell().pack(true);
+ }
+ });
+ }
+ };
+
+ t.start();
+
+ img.addDisposeListener(new DisposeListener() {
+
+ public void widgetDisposed(DisposeEvent e) {
+ if( img.getImage() != null ) {
+ img.getImage().dispose();
+ }
+ }
+ });
+
+ return comp;
+ }
+
+ }
+
+ private class SearchInput implements IPagedInput<FlickrPhoto> {
+ private FlickrSearch search;
+
+ public SearchInput(FlickrSearch search) {
+ this.search = search;
+ }
+
+ public int getPages() {
+ return search.getPages();
+ }
+
+ public int getPageSize() {
+ return search.getPageSize();
+ }
+
+ public int getTotalItems() {
+ return search.getTotalItems();
+ }
+
+ public List<FlickrPhoto> getItems(int page) {
+ try {
+ return flickrService.getPhotos(search, page);
+ } catch (RemoteException e) {
+ Status s = new Status(IStatus.ERROR, "org.eclipse.e4.demo.e4photo.flickr", e.getMessage(), e);
+ ErrorDialog.openError(comp.getShell(), "Searchfailure", "Failure while fetching photo page", s);
+ }
+
+ return Collections.emptyList();
+ }
+
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/IPagedInput.java b/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/IPagedInput.java
new file mode 100644
index 0000000..dbeb6ad
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/IPagedInput.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.ui;
+
+import java.util.List;
+
+/**
+ * Input for the paged table
+ *
+ * @param <M>
+ * the paged table
+ */
+public interface IPagedInput<M> {
+ /**
+ * @return the number of pages
+ */
+ public int getPages();
+
+ /**
+ * @return the number of elements per page
+ */
+ public int getPageSize();
+
+ /**
+ * @return the number of total items per page
+ */
+ public int getTotalItems();
+
+ /**
+ * Get the items of the page
+ *
+ * @param page
+ * the page
+ * @return the items
+ */
+ public List<M> getItems(int page);
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/PagedTable.java b/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/PagedTable.java
new file mode 100644
index 0000000..4be7fe8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/src/org/eclipse/e4/demo/e4photo/flickr/ui/PagedTable.java
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.demo.e4photo.flickr.ui;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.layout.TableColumnLayout;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ColumnLayoutData;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.ProgressBar;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * A table which shows it's items in a paged list
+ *
+ * @param <M> the object type
+ */
+public class PagedTable<M> extends Composite {
+ private TableViewer viewer;
+ private IPagedInput<M> input;
+ private Label pageLabel;
+ private TableColumnLayout tblLayout;
+ private Composite layoutFooter;
+ private Composite progressComp;
+ private Text pageField;
+ private int currentPage;
+
+ public PagedTable(Composite parent, int style) {
+ super(parent, style);
+ setLayout(new GridLayout());
+
+ Composite tabelContainer = new Composite(this, SWT.NONE);
+ tabelContainer.setLayoutData(new GridData(GridData.FILL_BOTH));
+ tblLayout = new TableColumnLayout();
+ tabelContainer.setLayout(tblLayout);
+
+ viewer = new TableViewer(tabelContainer);
+ viewer.getTable().setHeaderVisible(true);
+
+ layoutFooter = new Composite(this, SWT.NONE);
+ layoutFooter.setLayout(new GridLayout(2, false));
+ layoutFooter.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Composite navigation = new Composite(layoutFooter, SWT.NONE);
+ navigation.setLayout(new GridLayout(8, false));
+
+ Image imgFirst = new Image(navigation.getDisplay(), getClass()
+ .getClassLoader().getResourceAsStream(
+ "icons/control_start_blue.png"));
+ Image imgPrev = new Image(navigation.getDisplay(), getClass()
+ .getClassLoader().getResourceAsStream(
+ "icons/control_rewind_blue.png"));
+ Image imgNext = new Image(navigation.getDisplay(), getClass()
+ .getClassLoader().getResourceAsStream(
+ "icons/control_fastforward_blue.png"));
+ Image imgLast = new Image(navigation.getDisplay(), getClass()
+ .getClassLoader().getResourceAsStream(
+ "icons/control_end_blue.png"));
+
+ Button b = new Button(navigation, SWT.PUSH | SWT.FLAT);
+ b.setImage(imgFirst);
+ b.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (input != null) {
+ showPage(1);
+ }
+ }
+ });
+
+ b = new Button(navigation, SWT.PUSH | SWT.FLAT);
+ b.setImage(imgPrev);
+ b.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (currentPage > 1) {
+ if (input != null) {
+ showPage(--currentPage);
+ }
+ }
+
+ }
+ });
+
+ Label l = new Label(navigation, SWT.NONE);
+ l.setText("Page");
+
+ pageField = new Text(navigation, SWT.BORDER);
+ GridData gd = new GridData(50, SWT.DEFAULT);
+ gd.verticalAlignment = SWT.CENTER;
+ pageField.setLayoutData(gd);
+ pageField.addFocusListener(new FocusAdapter() {
+ @Override
+ public void focusLost(FocusEvent e) {
+ try {
+ if (input != null) {
+ int i = Integer.parseInt(pageField.getText());
+ if (i >= 1 && i <= input.getPages()) {
+ showPage(i);
+ } else {
+ pageField.setText(currentPage+"");
+ }
+ }
+ } catch (Exception ex) {
+ Status s = new Status(IStatus.ERROR, "org.eclipse.e4.demo.e4photo.flickr", ex.getMessage(), ex);
+ ErrorDialog.openError(pageField.getShell(), "Invalid number", "The entere value is not a valid page number", s);
+ pageField.setText(currentPage+"");
+ }
+
+ }
+ });
+
+ pageLabel = new Label(navigation, SWT.NONE);
+ pageLabel.setText("of ");
+
+ b = new Button(navigation, SWT.PUSH | SWT.FLAT);
+ b.setImage(imgNext);
+ b.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (input != null) {
+ if (currentPage < input.getPages()) {
+ showPage(++currentPage);
+ }
+ }
+ }
+ });
+
+ b = new Button(navigation, SWT.PUSH | SWT.FLAT);
+ b.setImage(imgLast);
+ b.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (input != null) {
+ showPage(input.getPages());
+ }
+ }
+ });
+
+ progressComp = new Composite(this, SWT.NONE);
+ progressComp.setLayout(new GridLayout(2, false));
+ progressComp.setVisible(false);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.exclude = true;
+ progressComp.setLayoutData(gd);
+
+ l = new Label(progressComp, SWT.NONE);
+ l.setText("Loading");
+
+ ProgressBar progress = new ProgressBar(progressComp, SWT.INDETERMINATE);
+ progress.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ viewer.setContentProvider(new ArrayContentProvider());
+ }
+
+ public ColumnViewer getViewer() {
+ return viewer;
+ }
+
+ public void addColumn(String label, PageColumnLabelProvider<M> labelProvider,
+ ColumnLayoutData layoutData) {
+ TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
+ column.getColumn().setText(label);
+ column.setLabelProvider(labelProvider);
+ tblLayout.setColumnData(column.getColumn(), layoutData);
+ }
+
+ public void setInput(IPagedInput<M> input) {
+ this.input = input;
+ pageLabel.setText("of " + input.getPages());
+ showPage(1);
+ }
+
+ public void showPage(final int page) {
+ ((GridData) layoutFooter.getLayoutData()).exclude = true;
+ ((GridData) progressComp.getLayoutData()).exclude = false;
+ layoutFooter.setVisible(false);
+ progressComp.setVisible(true);
+ layout(true, true);
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ final List<M> list = input.getItems(page);
+ getDisplay().syncExec(new Runnable() {
+
+ public void run() {
+ currentPage = page;
+ ((GridData) layoutFooter.getLayoutData()).exclude = false;
+ ((GridData) progressComp.getLayoutData()).exclude = true;
+ layoutFooter.setVisible(true);
+ progressComp.setVisible(false);
+ layout(true, true);
+ viewer.setInput(list);
+ pageField.setText(page + "");
+ }
+ });
+ }
+ };
+ t.start();
+ }
+
+ public static class PageColumnLabelProvider<M> extends ColumnLabelProvider {
+ @SuppressWarnings("unchecked")
+ @Override
+ public final String getText(Object element) {
+ return doGetText((M) element);
+ }
+
+ protected String doGetText(M element) {
+ return super.getText(element);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public final Image getImage(Object element) {
+ return doGetImage((M) element);
+ }
+
+ protected Image doGetImage(M element) {
+ return super.getImage(element);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public String getToolTipText(Object element) {
+ return doGetToolTipText((M) element);
+ }
+
+ protected String doGetToolTipText(M element) {
+ return super.getToolTipText(element);
+ }
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/xmi/components.e4xmi b/examples/org.eclipse.e4.demo.e4photo.flickr/xmi/components.e4xmi
new file mode 100644
index 0000000..fc6e480
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/xmi/components.e4xmi
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ASCII"?>
+<application:ModelComponents xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:application="http://www.eclipse.org/ui/2008/UIModel" xsi:schemaLocation="http://www.eclipse.org/ui/2008/UIModel ../../org.eclipse.e4.ui.model.workbench/model/UIElements.ecore" xmi:id="_UW9TZfr3Ed6gmo7caOxU9h">
+ <components xmi:id="_UW9TZfr3Ed6gmo7caOxU9q" id="" parentID="_AXU5Wu8IEd6FC9cDb6iV7g">
+ <children xsi:type="application:Part" id="flickrView" URI="bundleclass://org.eclipse.e4.demo.e4photo.flickr/org.eclipse.e4.demo.e4photo.flickr.ui.Flickr" persistedState="" label="Flickr Search"/>
+ </components>
+</application:ModelComponents>
diff --git a/examples/org.eclipse.e4.demo.e4photo.flickr/xmi/fragment.e4xmi b/examples/org.eclipse.e4.demo.e4photo.flickr/xmi/fragment.e4xmi
new file mode 100644
index 0000000..6bed8a5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.e4photo.flickr/xmi/fragment.e4xmi
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_BVHewHimEd-BhZHV_Fwq8Q">
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_PoZXIHimEd-cPe0oSIgEPQ" featurename="children" parentElementId="_sRLYgEleEd-TVO58rzJVgA">
+ <elements xsi:type="basic:Part" xmi:id="_ZyE84HimEd-cPe0oSIgEPQ" contributionURI="bundleclass://org.eclipse.e4.demo.e4photo.flickr/org.eclipse.e4.demo.e4photo.flickr.ui.Flickr" label="Flickr Search"/>
+ </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.log/.classpath b/examples/org.eclipse.e4.demo.log/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.log/.project b/examples/org.eclipse.e4.demo.log/.project
new file mode 100644
index 0000000..25d5b1a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.log</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.log/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.log/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..1956c7f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Tue Mar 16 13:43:58 EDT 2010
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
diff --git a/examples/org.eclipse.e4.demo.log/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.log/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..8395b33
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/META-INF/MANIFEST.MF
@@ -0,0 +1,26 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: e4 Demo Log
+Bundle-SymbolicName: org.eclipse.e4.demo.log;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.e4.demo.log.Activator
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Import-Package: javax.inject;version="1.0.0",
+ org.eclipse.core.commands.common,
+ org.eclipse.core.commands.contexts,
+ org.eclipse.e4.core.contexts,
+ org.eclipse.e4.core.di,
+ org.eclipse.e4.core.di.annotations,
+ org.eclipse.e4.core.services.events,
+ org.eclipse.e4.ui.bindings,
+ org.eclipse.e4.ui.bindings.internal,
+ org.eclipse.e4.ui.model.application,
+ org.eclipse.e4.ui.services,
+ org.eclipse.jface.viewers,
+ org.eclipse.swt,
+ org.eclipse.swt.custom,
+ org.eclipse.swt.layout,
+ org.eclipse.swt.widgets,
+ org.osgi.framework;version="1.5.0"
+Require-Bundle: org.eclipse.e4.ui.workbench
diff --git a/examples/org.eclipse.e4.demo.log/build.properties b/examples/org.eclipse.e4.demo.log/build.properties
new file mode 100644
index 0000000..173713b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/build.properties
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ xmi/,\
+ css/
diff --git a/examples/org.eclipse.e4.demo.log/css/default.css b/examples/org.eclipse.e4.demo.log/css/default.css
new file mode 100644
index 0000000..463625d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/css/default.css
@@ -0,0 +1,88 @@
+CTabFolder {
+ simple: true;
+ margin: 3;
+}
+
+CTabItem {
+ font: Verdana 8px;
+ color: #666666;
+ background-color: #ffffff;
+}
+CTabItem:selected {
+ background-color: #f4f4f4;
+}
+
+CTabItem.active {
+ background-color: #ffffff;
+}
+
+CTabItem.active:selected {
+ color: #ff5500;
+ background-color: #f4f4f4;
+ font-weight: bold;
+}
+
+#library {
+ background-color: #f4f4f4;
+}
+
+#preview {
+ color: #e5e5e5;
+ background-color: #ffffff;
+}
+
+.keyContextView#me {
+ color: #ff00ff;
+ background-color: #ffffff;
+}
+
+.keyContextView#app {
+ color: #ff5500;
+ background-color: #f4f4f4;
+}
+
+
+Gallery {
+ background-color: #f4f4f4;
+}
+
+GalleryItem:selected {
+ background-color: #ff884c;
+}
+
+
+#location {
+ background-color: #f4f4f4;
+}
+
+ToolBar {
+ color: #666666;
+ font: Verdana 8px;
+ background-color: #fffff3;
+}
+
+ToolItem {
+ color: #666666;
+ background-color: #fffff3;
+}
+
+SashForm {
+ background-color: white;
+}
+
+Text {
+ font: Verdana 8px;
+}
+
+Label {
+ font: Verdana 8px;
+}
+
+Tree {
+ font: Verdana 8px;
+ color: #666666;
+}
+
+Composite, Shell {
+ background-color: #ffffff;
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.log/e4-view-demo.product b/examples/org.eclipse.e4.demo.log/e4-view-demo.product
new file mode 100644
index 0000000..e095a6d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/e4-view-demo.product
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?pde version="3.5"?>
+
+<product name="Eclipse 4 IDE" id="org.eclipse.e4.demo.log.product" application="org.eclipse.e4.ui.workbench.swt.E4Application" version="1.0.0.qualifier" useFeatures="false" includeLaunchers="true">
+
+ <configIni use="default">
+ </configIni>
+
+ <launcherArgs>
+ <vmArgsMac>-XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts</vmArgsMac>
+ </launcherArgs>
+
+ <windowImages/>
+
+ <plugins>
+ <plugin id="com.ibm.icu"/>
+ <plugin id="javax.inject"/>
+ <plugin id="javax.servlet"/>
+ <plugin id="org.apache.batik.css"/>
+ <plugin id="org.apache.batik.util"/>
+ <plugin id="org.apache.batik.util.gui"/>
+ <plugin id="org.apache.commons.beanutils"/>
+ <plugin id="org.apache.commons.logging"/>
+ <plugin id="org.eclipse.ant.core"/>
+ <plugin id="org.eclipse.core.commands"/>
+ <plugin id="org.eclipse.core.contenttype"/>
+ <plugin id="org.eclipse.core.databinding"/>
+ <plugin id="org.eclipse.core.databinding.beans"/>
+ <plugin id="org.eclipse.core.databinding.observable"/>
+ <plugin id="org.eclipse.core.databinding.property"/>
+ <plugin id="org.eclipse.core.expressions"/>
+ <plugin id="org.eclipse.core.filesystem"/>
+ <plugin id="org.eclipse.core.filesystem.hpux.PA_RISC" fragment="true"/>
+ <plugin id="org.eclipse.core.filesystem.hpux.ia64_32" fragment="true"/>
+ <plugin id="org.eclipse.core.filesystem.linux.ppc" fragment="true"/>
+ <plugin id="org.eclipse.core.filesystem.linux.x86" fragment="true"/>
+ <plugin id="org.eclipse.core.filesystem.linux.x86_64" fragment="true"/>
+ <plugin id="org.eclipse.core.filesystem.macosx" fragment="true"/>
+ <plugin id="org.eclipse.core.filesystem.qnx.x86" fragment="true"/>
+ <plugin id="org.eclipse.core.filesystem.solaris.sparc" fragment="true"/>
+ <plugin id="org.eclipse.core.filesystem.win32.ia64" fragment="true"/>
+ <plugin id="org.eclipse.core.filesystem.win32.x86" fragment="true"/>
+ <plugin id="org.eclipse.core.jobs"/>
+ <plugin id="org.eclipse.core.resources"/>
+ <plugin id="org.eclipse.core.resources.compatibility" fragment="true"/>
+ <plugin id="org.eclipse.core.resources.win32.ia64" fragment="true"/>
+ <plugin id="org.eclipse.core.resources.win32.x86" fragment="true"/>
+ <plugin id="org.eclipse.core.runtime"/>
+ <plugin id="org.eclipse.core.runtime.compatibility.registry" fragment="true"/>
+ <plugin id="org.eclipse.core.variables"/>
+ <plugin id="org.eclipse.e4.core.commands"/>
+ <plugin id="org.eclipse.e4.core.services"/>
+ <plugin id="org.eclipse.e4.core.services.annotations" fragment="true"/>
+ <plugin id="org.eclipse.e4.demo.e4photo"/>
+ <plugin id="org.eclipse.e4.demo.log"/>
+ <plugin id="org.eclipse.e4.ide.application"/>
+ <plugin id="org.eclipse.e4.ui.bindings"/>
+ <plugin id="org.eclipse.e4.ui.css.core"/>
+ <plugin id="org.eclipse.e4.ui.css.nebula"/>
+ <plugin id="org.eclipse.e4.ui.css.swt"/>
+ <plugin id="org.eclipse.e4.ui.model.workbench"/>
+ <plugin id="org.eclipse.e4.ui.services"/>
+ <plugin id="org.eclipse.e4.ui.workbench"/>
+ <plugin id="org.eclipse.e4.ui.workbench.renderers.swt"/>
+ <plugin id="org.eclipse.e4.ui.workbench.renderers.swt.contributions"/>
+ <plugin id="org.eclipse.e4.ui.workbench.swt"/>
+ <plugin id="org.eclipse.e4.ui.workbench3"/>
+ <plugin id="org.eclipse.emf.common"/>
+ <plugin id="org.eclipse.emf.databinding"/>
+ <plugin id="org.eclipse.emf.ecore"/>
+ <plugin id="org.eclipse.emf.ecore.change"/>
+ <plugin id="org.eclipse.emf.ecore.xmi"/>
+ <plugin id="org.eclipse.equinox.app"/>
+ <plugin id="org.eclipse.equinox.common"/>
+ <plugin id="org.eclipse.equinox.concurrent"/>
+ <plugin id="org.eclipse.equinox.ds"/>
+ <plugin id="org.eclipse.equinox.event"/>
+ <plugin id="org.eclipse.equinox.preferences"/>
+ <plugin id="org.eclipse.equinox.registry"/>
+ <plugin id="org.eclipse.equinox.util"/>
+ <plugin id="org.eclipse.jface"/>
+ <plugin id="org.eclipse.jface.databinding"/>
+ <plugin id="org.eclipse.nebula.widgets.gallery"/>
+ <plugin id="org.eclipse.osgi"/>
+ <plugin id="org.eclipse.osgi.services"/>
+ <plugin id="org.eclipse.swt"/>
+ <plugin id="org.eclipse.swt.carbon.macosx" fragment="true"/>
+ <plugin id="org.eclipse.swt.cocoa.macosx" fragment="true"/>
+ <plugin id="org.eclipse.swt.cocoa.macosx.x86_64" fragment="true"/>
+ <plugin id="org.eclipse.swt.gtk.linux.x86" fragment="true"/>
+ <plugin id="org.eclipse.swt.win32.win32.x86" fragment="true"/>
+ <plugin id="org.w3c.css.sac"/>
+ <plugin id="org.w3c.dom.smil"/>
+ <plugin id="org.w3c.dom.svg"/>
+ </plugins>
+
+
+</product>
diff --git a/examples/org.eclipse.e4.demo.log/plugin.xml b/examples/org.eclipse.e4.demo.log/plugin.xml
new file mode 100644
index 0000000..a9cf293
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/plugin.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ id="product"
+ point="org.eclipse.core.runtime.products">
+ <product
+ application="org.eclipse.e4.ui.workbench.swt.E4Application"
+ description="Based on e4"
+ name="Eclipse 4 IDE">
+ <property
+ name="appName"
+ value="Eclipse 4 IDE">
+ </property>
+ <property
+ name="applicationXMI"
+ value="org.eclipse.e4.ide.application/Application.e4xmi">
+ </property>
+ <property
+ name="applicationCSS"
+ value="platform:/plugin/org.eclipse.e4.demo.log/css/default.css">
+ </property>
+ <property
+ name="applicationCSSResources"
+ value="platform:/plugin/org.eclipse.e4.ide.application/images/">
+ </property>
+ </product>
+ </extension>
+ <extension
+ id="id1"
+ point="org.eclipse.e4.workbench.model">
+ <snippet
+ uri="platform:/plugin/org.eclipse.e4.demo.log/xmi/components.e4xmi">
+ </snippet>
+ </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/Activator.java b/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/Activator.java
new file mode 100644
index 0000000..9e042c8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/Activator.java
@@ -0,0 +1,46 @@
+package org.eclipse.e4.demo.log;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator implements BundleActivator {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.e4.demo.log"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/KeyContextView.java b/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/KeyContextView.java
new file mode 100644
index 0000000..fe81788
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/KeyContextView.java
@@ -0,0 +1,147 @@
+package org.eclipse.e4.demo.log;
+
+import java.util.ArrayList;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.eclipse.core.commands.contexts.Context;
+import org.eclipse.core.commands.contexts.ContextManager;
+import org.eclipse.e4.core.contexts.ContextChangeEvent;
+import org.eclipse.e4.core.contexts.IRunAndTrack;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.core.di.annotations.PostConstruct;
+import org.eclipse.e4.ui.bindings.internal.ContextSet;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.e4.ui.services.IStylingEngine;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.ListViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+public class KeyContextView {
+ final private Composite parent;
+ private ListViewer myViewer;
+ private ListViewer appViewer;
+ private ContextSet myBindingContextSet = ContextSet.EMPTY;
+ private ContextSet appBindingContextSet = ContextSet.EMPTY;
+
+ /**
+ * This will not change, and is a good candidate for field injection.
+ */
+ @Inject
+ private MApplication application;
+
+ /**
+ * This will not change, and is a good candidate for field injection.
+ */
+ @Inject
+ private IStylingEngine styler;
+
+ private ContextManager contextManager;
+
+ @Inject
+ public KeyContextView(final Composite parent) {
+ this.parent = new Composite(parent, SWT.NONE);
+ this.parent.setLayout(new GridLayout(2, true));
+ }
+
+ @PostConstruct
+ private void init() {
+ Label label = new Label(parent, SWT.NONE);
+ styler.setClassname(label, "keyContextView");
+ styler.setId(label, "me");
+ label.setText("My Binding Contexts");
+ GridData data = new GridData(SWT.LEFT, SWT.TOP, true, false);
+ label.setLayoutData(data);
+
+ label = new Label(parent, SWT.NONE);
+ styler.setClassname(label, "keyContextView");
+ styler.setId(label, "app");
+ label.setText("Application Binding Contexts");
+ data = new GridData(SWT.LEFT, SWT.TOP, true, false);
+ label.setLayoutData(data);
+
+ myViewer = new ListViewer(parent);
+ data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ myViewer.getControl().setLayoutData(data);
+ myViewer.setContentProvider(ArrayContentProvider.getInstance());
+ LabelProvider labelProvider = new LabelProvider() {
+ @Override
+ public String getText(Object element) {
+ if (element instanceof Context) {
+ Context c = (Context) element;
+ return c.getId();
+ }
+ return super.getText(element);
+ }
+ };
+ myViewer.setLabelProvider(labelProvider);
+ myViewer.setInput(myBindingContextSet.getContexts());
+
+ data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ appViewer = new ListViewer(parent);
+ appViewer.getControl().setLayoutData(data);
+ appViewer.setContentProvider(ArrayContentProvider.getInstance());
+ appViewer.setLabelProvider(labelProvider);
+
+ application.getContext().runAndTrack(new IRunAndTrack() {
+ public boolean notify(ContextChangeEvent event) {
+ Set<String> set = (Set<String>) application.getContext().get(
+ IServiceConstants.ACTIVE_CONTEXTS);
+ appBindingContextSet = getContextSet(set);
+ appViewer.setInput(appBindingContextSet.getContexts());
+ return true;
+ }
+ }, null);
+ }
+
+ /**
+ * This will inject the active contexts, as seen from this view. Because we
+ * need to take action when this value changes, it is a good candidate for
+ * method injection.
+ *
+ * @param set
+ * active context IDs
+ */
+ @Inject
+ public void setBindingContextIds(
+ @Named(IServiceConstants.ACTIVE_CONTEXTS) @Optional Set<String> set) {
+ myBindingContextSet = getContextSet(set);
+ if (myViewer != null) {
+ myViewer.setInput(myBindingContextSet.getContexts());
+ }
+ }
+
+ /**
+ * This is taking advantage of method injection to set a comparator needed
+ * for this view's correct operation.
+ *
+ * @param manager
+ * The context object manager for this application.
+ */
+ @Inject
+ public void setContextManager(ContextManager manager) {
+ contextManager = manager;
+ if (manager != null && ContextSet.getComparator() == null) {
+ ContextSet.setComparator(new ContextSet.CComp(manager));
+ }
+ }
+
+ private ContextSet getContextSet(Set<String> set) {
+ if (set == null || set.isEmpty() || contextManager == null) {
+ return ContextSet.EMPTY;
+ }
+ ArrayList<Context> contexts = new ArrayList<Context>();
+ for (String id : set) {
+ contexts.add(contextManager.getContext(id));
+ }
+ return new ContextSet(contexts);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/ViewCurrentContextsHandler.java b/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/ViewCurrentContextsHandler.java
new file mode 100644
index 0000000..a2e2892
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/src/org/eclipse/e4/demo/log/ViewCurrentContextsHandler.java
@@ -0,0 +1,16 @@
+package org.eclipse.e4.demo.log;
+
+import java.util.Set;
+
+import javax.inject.Named;
+
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.ui.services.IServiceConstants;
+
+public class ViewCurrentContextsHandler {
+ public void execute(
+ @Named(IServiceConstants.ACTIVE_CONTEXTS) @Optional Set<String> set) {
+ System.out.println("Active Contexts (unordered):");
+ System.out.println(set);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.log/xmi/components.e4xmi b/examples/org.eclipse.e4.demo.log/xmi/components.e4xmi
new file mode 100644
index 0000000..9868083
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.log/xmi/components.e4xmi
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="ASCII"?>
+<application:ModelComponents xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:advanced="http://www.eclipse.org/ui/2010/UIModel/application/ui/advanced" xmlns:application="http://www.eclipse.org/ui/2010/UIModel/application" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmi:id="_UW9TZfr3Ed6gmo7caOxU9h">
+ <components xmi:id="_UW9TZfr3Ed6gmo7caOxU9q" elementId="component.add.bindingContextView" parentID="org.eclipse.e4.ide.application">
+ <descriptors xmi:id="_2JqwsDEtEd-VhpFUss_l2g" elementId="org.eclipse.e4.demo.log.contextView" contributionURI="bundleclass://org.eclipse.e4.demo.log/org.eclipse.e4.demo.log.KeyContextView" label="Binding Context View" category="org.eclipse.e4.secondaryDataStack">
+ <bindingContexts>org.eclipse.e4.ui.contexts.views</bindingContexts>
+ </descriptors>
+ <handlers xmi:id="_8DQrEDK-Ed-ltJ9rgXYhSw" elementId="bindingContexts.display.handler" contributionURI="bundleclass://org.eclipse.e4.demo.log/org.eclipse.e4.demo.log.ViewCurrentContextsHandler" command="bindingContexts.display"/>
+ <commands xmi:id="bindingContexts.display" elementId="bindingContexts.display" commandName="Display Current Contexts"/>
+ </components>
+ <components xmi:id="_UW9TZfr3Ed6gmo7caOxU9y" elementId="component.add.bindingContextView.legacy" parentID="org.eclipse.e4.legacy.ide.application">
+ <descriptors xmi:id="_2JqwsDEtEd-VhpFUss_l2g" elementId="org.eclipse.e4.demo.log.contextView" contributionURI="bundleclass://org.eclipse.e4.demo.log/org.eclipse.e4.demo.log.KeyContextView" label="Binding Context View" category="org.eclipse.e4.secondaryDataStack">
+ <bindingContexts>org.eclipse.e4.ui.contexts.views</bindingContexts>
+ </descriptors>
+ <handlers xmi:id="_8DQrEDK-Ed-ltJ9rgXYhSw" elementId="bindingContexts.display.handler" contributionURI="bundleclass://org.eclipse.e4.demo.log/org.eclipse.e4.demo.log.ViewCurrentContextsHandler" command="bindingContexts.display"/>
+ <commands xmi:id="bindingContexts.display" elementId="bindingContexts.display" commandName="Display Current Contexts"/>
+ </components>
+ <components xmi:id="_UW9TZfr3Ed6gmo7caOxU9l" elementId="component.add.menu.window" parentID="org.eclipse.e4.ide.app.menu.window">
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_UW9TZfr3Ed6gmo7ca1xU9p" elementId="_UW9TZfr3Ed6gmo7ca1xU9p" label="Display Current Contexts" command="bindingContexts.display"/>
+ </components>
+</application:ModelComponents>
diff --git a/examples/org.eclipse.e4.demo.modifier/.classpath b/examples/org.eclipse.e4.demo.modifier/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.modifier/.project b/examples/org.eclipse.e4.demo.modifier/.project
new file mode 100644
index 0000000..02634f4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.modifier</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.modifier/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.modifier/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..b6fa1be
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Fri Mar 13 14:17:49 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.modifier/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.modifier/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..9eabb47
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/META-INF/MANIFEST.MF
@@ -0,0 +1,26 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Self modifying demo (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.demo.modifier;singleton:=true
+Bundle-Version: 0.9.1.qualifier
+Bundle-Activator: org.eclipse.e4.demo.modifier.Activator
+Bundle-Vendor: Eclipse.org
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.0",
+ org.eclipse.jface;bundle-version="3.5.0",
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0",
+ org.eclipse.e4.core.services;bundle-version="0.9.0",
+ org.eclipse.e4.ui.services;bundle-version="0.9.0",
+ org.eclipse.core.databinding;bundle-version="1.2.0",
+ org.eclipse.core.databinding.observable;bundle-version="1.2.0",
+ org.eclipse.jface.databinding;bundle-version="1.3.0",
+ org.mozilla.javascript;bundle-version="1.6.6",
+ org.eclipse.emf.databinding;resolution:=optional,
+ org.eclipse.ui.workbench;resolution:=optional,
+ org.eclipse.ui.forms;resolution:=optional,
+ org.eclipse.core.databinding.property;bundle-version="1.2.0",
+ org.eclipse.ui;bundle-version="3.5.0",
+ org.eclipse.e4.ui.workbench.swt;bundle-version="0.9.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Import-Package: javax.inject;version="1.0.0"
diff --git a/examples/org.eclipse.e4.demo.modifier/build.properties b/examples/org.eclipse.e4.demo.modifier/build.properties
new file mode 100644
index 0000000..fd23492
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/build.properties
@@ -0,0 +1,8 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ icons/,\
+ modifyWorkbench.product,\
+ xmi/
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/elcl16/collapseall.gif b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/collapseall.gif
new file mode 100644
index 0000000..a2d80a9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/collapseall.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/elcl16/pin_view.gif b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/pin_view.gif
new file mode 100644
index 0000000..381c4a9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/pin_view.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/elcl16/refresh_nav.gif b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/refresh_nav.gif
new file mode 100644
index 0000000..049cac6
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/refresh_nav.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/elcl16/synced.gif b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/synced.gif
new file mode 100644
index 0000000..870934b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/synced.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/elcl16/trash.gif b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/trash.gif
new file mode 100644
index 0000000..bf961b3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/trash.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/elcl16/up_nav.gif b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/up_nav.gif
new file mode 100644
index 0000000..884952f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/elcl16/up_nav.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/etool16/copy_edit.gif b/examples/org.eclipse.e4.demo.modifier/icons/etool16/copy_edit.gif
new file mode 100644
index 0000000..71d7c95
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/etool16/copy_edit.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/etool16/cut_edit.gif b/examples/org.eclipse.e4.demo.modifier/icons/etool16/cut_edit.gif
new file mode 100644
index 0000000..d044e59
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/etool16/cut_edit.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/etool16/delete_edit.gif b/examples/org.eclipse.e4.demo.modifier/icons/etool16/delete_edit.gif
new file mode 100644
index 0000000..b6922ac
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/etool16/delete_edit.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/etool16/paste_edit.gif b/examples/org.eclipse.e4.demo.modifier/icons/etool16/paste_edit.gif
new file mode 100644
index 0000000..39dd4d9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/etool16/paste_edit.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/etool16/pin_editor.gif b/examples/org.eclipse.e4.demo.modifier/icons/etool16/pin_editor.gif
new file mode 100644
index 0000000..dfc1dab
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/etool16/pin_editor.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/etool16/print_edit.gif b/examples/org.eclipse.e4.demo.modifier/icons/etool16/print_edit.gif
new file mode 100644
index 0000000..04cb84b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/etool16/print_edit.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/mviewer.GIF b/examples/org.eclipse.e4.demo.modifier/icons/mviewer.GIF
new file mode 100644
index 0000000..3be38d4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/mviewer.GIF
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/obj16/file_obj.gif b/examples/org.eclipse.e4.demo.modifier/icons/obj16/file_obj.gif
new file mode 100644
index 0000000..7ccc6a7
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/obj16/file_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/obj16/fldr_obj.gif b/examples/org.eclipse.e4.demo.modifier/icons/obj16/fldr_obj.gif
new file mode 100644
index 0000000..51e703b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/obj16/fldr_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/icons/obj16/prj_obj.gif b/examples/org.eclipse.e4.demo.modifier/icons/obj16/prj_obj.gif
new file mode 100644
index 0000000..a4ea580
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/icons/obj16/prj_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.modifier/modifyWorkbench.product b/examples/org.eclipse.e4.demo.modifier/modifyWorkbench.product
new file mode 100644
index 0000000..7e78d97
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/modifyWorkbench.product
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?pde version="3.5"?>
+
+<product name="Modify Running Workbench" uid="modifyWorkbench" id="org.eclipse.e4.demo.modifier.modifyWorkbench" org.eclipse.e4.ui.model.application="org.eclipse.e4.ui.workbench.swt.application" version="0.9.0" useFeatures="false" includeLaunchers="true">
+
+ <configIni use="default">
+ </configIni>
+
+ <launcherArgs>
+ <vmArgsMac>-XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts</vmArgsMac>
+ </launcherArgs>
+
+ <windowImages/>
+
+ <launcher>
+ <solaris/>
+ <win useIco="false">
+ <bmp/>
+ </win>
+ </launcher>
+
+ <vm>
+ </vm>
+
+ <plugins>
+ <plugin id="com.ibm.icu"/>
+ <plugin id="javax.xml"/>
+ <plugin id="org.apache.xerces"/>
+ <plugin id="org.apache.xml.resolver"/>
+ <plugin id="org.eclipse.core.commands"/>
+ <plugin id="org.eclipse.core.contenttype"/>
+ <plugin id="org.eclipse.core.databinding"/>
+ <plugin id="org.eclipse.core.databinding.observable"/>
+ <plugin id="org.eclipse.core.databinding.property"/>
+ <plugin id="org.eclipse.core.expressions"/>
+ <plugin id="org.eclipse.core.jobs"/>
+ <plugin id="org.eclipse.core.runtime"/>
+ <plugin id="org.eclipse.core.runtime.compatibility.registry" fragment="true"/>
+ <plugin id="org.eclipse.e4.core.services"/>
+ <plugin id="org.eclipse.e4.core.services.annotations"/>
+ <plugin id="org.eclipse.e4.demo.modifier"/>
+ <plugin id="org.eclipse.e4.ui.model.workbench"/>
+ <plugin id="org.eclipse.e4.ui.services"/>
+ <plugin id="org.eclipse.e4.ui.workbench"/>
+ <plugin id="org.eclipse.e4.ui.workbench.renderers.swt"/>
+ <plugin id="org.eclipse.e4.ui.workbench.swt"/>
+ <plugin id="org.eclipse.emf.common"/>
+ <plugin id="org.eclipse.emf.databinding"/>
+ <plugin id="org.eclipse.emf.ecore"/>
+ <plugin id="org.eclipse.emf.ecore.xmi"/>
+ <plugin id="org.eclipse.equinox.app"/>
+ <plugin id="org.eclipse.equinox.common"/>
+ <plugin id="org.eclipse.equinox.concurrent"/>
+ <plugin id="org.eclipse.equinox.preferences"/>
+ <plugin id="org.eclipse.equinox.registry"/>
+ <plugin id="org.eclipse.jface"/>
+ <plugin id="org.eclipse.jface.databinding"/>
+ <plugin id="org.eclipse.osgi"/>
+ <plugin id="org.eclipse.swt"/>
+ <plugin id="org.eclipse.swt.gtk.linux.x86" fragment="true"/>
+ <plugin id="org.eclipse.swt.win32.win32.x86" fragment="true"/>
+ <plugin id="org.mozilla.javascript"/>
+ </plugins>
+
+
+</product>
diff --git a/examples/org.eclipse.e4.demo.modifier/plugin.xml b/examples/org.eclipse.e4.demo.modifier/plugin.xml
new file mode 100644
index 0000000..298cd67
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/plugin.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ id="modifyWorkbench"
+ point="org.eclipse.core.runtime.products">
+ <product
+ application="org.eclipse.e4.ui.workbench.swt.application"
+ name="Modify Running Workbench">
+ <property
+ name="appName"
+ value="Modify Running Workbench">
+ </property>
+ <property
+ name="applicationXMI"
+ value="/org.eclipse.e4.demo.modifier/xmi/modifyWorkbench.xmi">
+ </property>
+ </product>
+ </extension>
+ <extension
+ id="ModelViewer"
+ name="Model Viewer"
+ point="org.eclipse.e4.workbench.model">
+ <model
+ parentID="E4MainWindow"
+ location="xmi/modelViewer.xmi">
+ </model>
+ </extension>
+ <extension
+ point="org.eclipse.ui.commands">
+ <command
+ categoryId="org.eclipse.e4.ui.category"
+ defaultHandler="org.eclipse.e4.demo.modifier.ShowUIEditor"
+ id="org.eclipse.e4.demo.modifier.showEditor"
+ name="UI Editor">
+ </command>
+ </extension>
+ <extension
+ point="org.eclipse.ui.menus">
+ <menuContribution
+ locationURI="menu:org.eclipse.e4.samples">
+ <command
+ commandId="org.eclipse.e4.demo.modifier.showEditor"
+ label="UI Editor"
+ style="push">
+ </command>
+ </menuContribution>
+ </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/Activator.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/Activator.java
new file mode 100644
index 0000000..6d53de5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/Activator.java
@@ -0,0 +1,50 @@
+package org.eclipse.e4.demo.modifier;
+
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends Plugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.e4.demo.modifier";
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/EMFScriptable.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/EMFScriptable.java
new file mode 100644
index 0000000..9fdbc83
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/EMFScriptable.java
@@ -0,0 +1,71 @@
+package org.eclipse.e4.demo.modifier;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+
+public class EMFScriptable extends ScriptableObject {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ private EObject eObject;
+
+ public EMFScriptable(EObject eObject) {
+ this.eObject = eObject;
+ }
+
+ @Override
+ public String getClassName() {
+ return eObject.getClass().getName();
+ }
+
+ private EStructuralFeature findFeature(String name) {
+ for (EStructuralFeature f : eObject.eClass()
+ .getEAllStructuralFeatures()) {
+ if (f.getName().equals(name)) {
+ return f;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Object get(String arg0, Scriptable arg1) {
+ EStructuralFeature f = findFeature(arg0);
+
+ if (f == null)
+ return super.get(arg0, arg1);
+
+ Object rv = eObject.eGet(f);
+
+ // FIXME java.util.Date, ...
+ if (rv instanceof String || rv instanceof Boolean
+ || rv instanceof Number) {
+ return rv;
+ } else if (rv instanceof EObject) {
+ return new EMFScriptable(eObject);
+ }
+
+ return super.get(arg0, arg1);
+ }
+
+ @Override
+ public void put(String arg0, Scriptable arg1, Object arg2) {
+ EStructuralFeature f = findFeature(arg0);
+
+ // We always get a double so we have to convert to the appropriate value
+ if( arg2 instanceof Number ) {
+ if( f.getEType().getInstanceClass() == int.class ) {
+ arg2 = ((Number)arg2).intValue();
+ }
+ }
+
+ if (f == null)
+ super.put(arg0, arg1, arg2);
+ else
+ eObject.eSet(f, arg2);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ElementView.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ElementView.java
new file mode 100644
index 0000000..b9d70bd
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ElementView.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * 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.e4.demo.modifier;
+
+import javax.inject.Inject;
+
+import org.eclipse.core.databinding.observable.Observables;
+import org.eclipse.core.databinding.observable.Realm;
+import org.eclipse.core.databinding.observable.value.ComputedValue;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.databinding.observable.value.WritableValue;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.jface.databinding.swt.SWTObservables;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.ImporterTopLevel;
+import org.mozilla.javascript.ScriptableObject;
+
+public class ElementView {
+ private Realm realm;
+ private IObservableValue selectedElement = null;
+ private IObservableValue jsText;
+ private Text jsInputField;
+ private Context jsContext;
+ private ImporterTopLevel jsScope;
+
+ public ElementView(final Composite parent) {
+ realm = Realm.getDefault();
+ selectedElement = new WritableValue(realm);
+ jsText = new ComputedValue(realm) {
+ @Override
+ protected Object calculate() {
+ return formatJSField((EObject) selectedElement.getValue());
+ }
+ };
+
+ jsInputField = new Text(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL
+ | SWT.BORDER);
+
+ Observables.pipe(jsText, SWTObservables.observeText(jsInputField));
+
+ final Button runJSBtn = new Button(parent, SWT.PUSH);
+ runJSBtn.setText("Run Script"); //$NON-NLS-1$
+ runJSBtn.setBounds(10, 320, 100, 25);
+ runJSBtn.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ runJS(jsInputField.getText());
+ }
+ });
+
+ GridLayoutFactory.fillDefaults().generateLayout(parent);
+ initJS();
+ }
+
+ protected String formatJSField(EObject value) {
+ if (value == null) {
+ return "";
+ }
+ String delim = jsInputField.getLineDelimiter();
+ String jsString = "// " + value.eClass().getName()
+ + " is selected...\r\n" + "me = selectedElement;" + delim
+ + "out.println(me);" + delim;
+ for (EStructuralFeature feature : value.eClass()
+ .getEAllStructuralFeatures()) {
+ Object val = value.eGet(feature);
+
+ if (!(val instanceof String) && !(val instanceof Boolean)
+ && !(val instanceof Number)) {
+ continue;
+ }
+
+ String propName = feature.getName().substring(0, 1).toUpperCase()
+ + feature.getName().substring(1);
+ propName = feature.getName();
+ String propString;
+
+ if (val instanceof String) {
+ propString = "me." + propName + "=\"" + val + "\"";
+ } else {
+ propString = "me." + propName + "=" + val + "";
+ }
+
+ jsString += propString + delim;
+ }
+
+ return jsString;
+ }
+
+ /**
+ * TBD this method is not needed; clean it up
+ * @param selection
+ */
+ @Inject
+ public void setInput(final EObject selection) {
+ if (selection==null) {
+ return;
+ }
+ realm.asyncExec(new Runnable() {
+ public void run() {
+ selectedElement.setValue(selection);
+ }
+ });
+ }
+
+ /**
+ * @param selection
+ */
+ @Inject
+ public void setSelection(final EObject selection) {
+ if (selection==null) {
+ return;
+ }
+ realm.asyncExec(new Runnable() {
+ public void run() {
+ selectedElement.setValue(selection);
+ }
+ });
+ }
+
+ protected void runJS(String jScript) {
+ try {
+ ScriptableObject.putProperty(jsScope, "selectedElement",
+ new EMFScriptable((EObject) selectedElement.getValue()));
+ jsContext.evaluateString(jsScope, jScript,
+ "LCV Evaluator", 0, null); //$NON-NLS-1$
+ } catch (RuntimeException e) {
+ e.printStackTrace();
+ initJS();
+ }
+ }
+
+ private void initJS() {
+ if (jsContext != null)
+ Context.exit();
+
+ jsContext = Context.enter();
+ jsScope = new ImporterTopLevel(jsContext);
+ Object wrappedOut = Context.javaToJS(System.out, jsScope);
+ ScriptableObject.putProperty(jsScope, "out", wrappedOut); //$NON-NLS-1$
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ExitHandler.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ExitHandler.java
new file mode 100755
index 0000000..2f454b4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ExitHandler.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * 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.e4.demo.modifier;
+
+import org.eclipse.e4.workbench.ui.IWorkbench;
+
+/**
+ *
+ */
+public class ExitHandler {
+ public void execute(IWorkbench workbench) {
+ workbench.close();
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ModelView.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ModelView.java
new file mode 100644
index 0000000..d1453be
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ModelView.java
@@ -0,0 +1,73 @@
+package org.eclipse.e4.demo.modifier;
+
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.core.databinding.observable.Observables;
+import org.eclipse.core.databinding.observable.Realm;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.list.WritableList;
+import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.databinding.viewers.ObservableListTreeContentProvider;
+import org.eclipse.jface.databinding.viewers.TreeStructureAdvisor;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+
+public class ModelView {
+ public ModelView(final Composite parent,
+ final IEclipseContext outputContext,
+ final MApplication application) {
+ final Realm realm = Realm.getDefault();
+ TreeViewer viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL
+ | SWT.V_SCROLL);
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ outputContext.set(IServiceConstants.SELECTION,
+ ((StructuredSelection) event.getSelection())
+ .getFirstElement());
+ }
+ });
+ IObservableFactory listFactory = new IObservableFactory() {
+ public IObservable createObservable(Object element) {
+ if (element instanceof EObject
+ && !((EObject) element).eContents().isEmpty()) {
+ EObject e = (EObject) element;
+ IObservableList observableList = new WritableList(realm);
+ observableList.addAll(e.eContents());
+ return observableList;
+ } else if (element instanceof Object[]) {
+ EObject e = (EObject) ((Object[]) element)[0];
+ IObservableList observableList = new WritableList(realm);
+ observableList.add(e);
+ return observableList;
+ }
+ return Observables.emptyObservableList();
+ }
+ };
+ viewer.setContentProvider(new ObservableListTreeContentProvider(
+ listFactory, new TreeStructureAdvisor() {
+ public Boolean hasChildren(Object element) {
+ return Boolean.valueOf(element instanceof EObject);
+ }
+ }));
+ viewer.setLabelProvider(new LabelProvider() {
+ @Override
+ public String getText(Object element) {
+ if (element instanceof EObject) {
+ return ((EObject) element).eClass().getName();
+ }
+ return super.getText(element);
+ }
+ });
+ viewer.setInput(new Object[] { application });
+ GridLayoutFactory.fillDefaults().generateLayout(parent);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/SampleView.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/SampleView.java
new file mode 100755
index 0000000..3f6bce3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/SampleView.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * 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.e4.demo.modifier;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ *
+ */
+public class SampleView {
+ /**
+ * Create the sample view.
+ *
+ * @param parent
+ * @param selectionService
+ */
+ public SampleView(Composite parent, final IEclipseContext outputContext,
+ final IExtensionRegistry registry) {
+ TreeViewer viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL
+ | SWT.V_SCROLL);
+ viewer.getTree().setData("class", "navigator"); //$NON-NLS-1$ //$NON-NLS-2$
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ outputContext.set(IServiceConstants.SELECTION, event.getSelection());
+ }
+ });
+ viewer.setContentProvider(new ITreeContentProvider() {
+
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof IConfigurationElement) {
+ return ((IConfigurationElement) parentElement)
+ .getChildren();
+ }
+ return null;
+ }
+
+ public Object getParent(Object element) {
+ if (element instanceof IConfigurationElement) {
+ return ((IConfigurationElement) element).getParent();
+ }
+ return null;
+ }
+
+ public boolean hasChildren(Object element) {
+ if (element instanceof IConfigurationElement) {
+ return ((IConfigurationElement) element).getChildren().length > 0;
+ }
+ return false;
+ }
+
+ public Object[] getElements(Object inputElement) {
+ if (inputElement instanceof IExtension) {
+ return ((IExtension) inputElement)
+ .getConfigurationElements();
+ }
+ return null;
+ }
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput,
+ Object newInput) {
+ }
+ });
+ viewer.setLabelProvider(new LabelProvider() {
+ @Override
+ public String getText(Object element) {
+ if (element instanceof IConfigurationElement) {
+ IConfigurationElement c = (IConfigurationElement) element;
+ String tag = c.getName();
+ String id = c.getAttribute("id"); //$NON-NLS-1$
+ if (id == null) {
+ id = c.getAttribute("name"); //$NON-NLS-1$
+ }
+ if (id == null) {
+ id = c.getAttribute("api"); //$NON-NLS-1$
+ }
+ if (id == null) {
+ id = c.getAttribute("class"); //$NON-NLS-1$
+ }
+ return tag + "(" + id + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ // TODO update this to look for an icon or image attribute
+ return super.getImage(element);
+ }
+ });
+
+ IExtension input = null;
+ IExtension[] extensions = registry
+ .getExtensions("org.eclipse.e4.ui.workbench"); //$NON-NLS-1$
+ for (int i = 0; i < extensions.length; i++) {
+ if (extensions[i].getExtensionPointUniqueIdentifier().equals(
+ "org.eclipse.e4.services")) { //$NON-NLS-1$
+ input = extensions[i];
+ break;
+ }
+ }
+ viewer.setInput(input);
+ GridLayoutFactory.fillDefaults().generateLayout(parent);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ShowUIEditor.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ShowUIEditor.java
new file mode 100644
index 0000000..0aa2c7d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/modifier/ShowUIEditor.java
@@ -0,0 +1,38 @@
+package org.eclipse.e4.demo.modifier;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.e4.demo.viewer.ModelUtils;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MWindow;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.e4.ui.workbench.swt.internal.AbstractPartRenderer;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+
+public class ShowUIEditor extends AbstractHandler {
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ MApplication model = (MApplication) HandlerUtil.getVariable(event, MApplication.class.getName());
+ Shell curWindow = (Shell) model.getContext().get(IServiceConstants.ACTIVE_SHELL);
+ if (curWindow == null)
+ return null;
+
+ MWindow winPart = (MWindow) curWindow.getData(AbstractPartRenderer.OWNING_ME);
+ MPart uiEditor = ModelUtils.findPart(winPart, "UI Editor");
+ if (uiEditor.isVisible()) {
+ Shell editorShell = (Shell) uiEditor.getWidget();
+ if(editorShell == null) {
+ uiEditor.setVisible(false);
+ }
+ else {
+ if (!editorShell.isDisposed())
+ return null;
+ }
+ }
+ uiEditor.setVisible(true);
+ return null;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ImageManagerHelper.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ImageManagerHelper.java
new file mode 100644
index 0000000..4102fb3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ImageManagerHelper.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * 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.e4.demo.viewer;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.e4.ui.model.application.MElementContainer;
+import org.eclipse.e4.ui.model.application.MGenericTile;
+import org.eclipse.e4.ui.model.application.MWindow;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Helps manage resources.
+ */
+public class ImageManagerHelper {
+
+ static final public int IMAGE_WORKBENCH_WINDOW = 1;
+ static final public int IMAGE_SASH = 2;
+ static final public int IMAGE_STACK = 3;
+
+ static final private String IMAGE_PATH = "platform:/plugin/org.eclipse.e4.demo.modifier/icons/obj16/";
+
+ private ImageRegistry imageRegistry;
+
+ public ImageManagerHelper() {
+ imageRegistry = new ImageRegistry();
+ }
+
+ public Image getImage(String path) {
+ if (path == null || path.length() == 0)
+ return null;
+
+ Image image = imageRegistry.get(path);
+ if (image != null)
+ return image;
+ URL url;
+ try {
+ url = new URL(path);
+ } catch (MalformedURLException e) {
+ e.printStackTrace(); // report and continue
+ return null;
+ }
+ ImageDescriptor desc = ImageDescriptor.createFromURL(url);
+ image = desc.createImage();
+ if (image != null)
+ imageRegistry.put(path, image);
+ return image;
+ }
+
+ public Image getImage(int id) {
+ String registryID = Integer.toString(id);
+ Image image = imageRegistry.get(registryID);
+ if (image != null)
+ return image;
+ URL url = createURL(id);
+ ImageDescriptor desc = ImageDescriptor.createFromURL(url);
+ image = desc.createImage();
+ if (image != null)
+ imageRegistry.put(registryID, image);
+ return image;
+ }
+
+ private URL createURL(int id) {
+ String result = null;
+ switch (id) {
+ case IMAGE_WORKBENCH_WINDOW: // ISharedImages.IMG_OBJ_PROJECT
+ result = IMAGE_PATH + "prj_obj.gif";
+ break;
+ case IMAGE_SASH: // ISharedImages.IMG_OBJ_FOLDER
+ result = IMAGE_PATH + "fldr_obj.gif";
+ break;
+ case IMAGE_STACK: // ISharedImages.IMG_OBJ_FILE
+ result = IMAGE_PATH + "file_obj.gif";
+ break;
+ default:
+ }
+ try {
+ return new URL(result);
+ } catch (MalformedURLException e) {
+ e.printStackTrace(); // report and continue
+ return null;
+ }
+ }
+
+ public void dispose() {
+ imageRegistry.dispose();
+ }
+
+ public Image getElementImage(Object element) {
+ if (element instanceof MWindow)
+ return getElementImage(ImageManagerHelper.IMAGE_WORKBENCH_WINDOW);
+ else if (element instanceof MGenericTile<?>)
+ return getElementImage(ImageManagerHelper.IMAGE_SASH);
+ else if (element instanceof MElementContainer<?>)
+ return getImage(ImageManagerHelper.IMAGE_STACK);
+ return null;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ModelExplorer.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ModelExplorer.java
new file mode 100644
index 0000000..1ee20b6
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ModelExplorer.java
@@ -0,0 +1,292 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 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.e4.demo.viewer;
+
+import java.util.Iterator;
+
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.ui.model.application.MApplicationElement;
+import org.eclipse.e4.ui.model.application.MItem;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MPartSashContainer;
+import org.eclipse.e4.ui.model.application.MPartStack;
+import org.eclipse.e4.ui.model.application.MPerspective;
+import org.eclipse.e4.ui.model.application.MUIElement;
+import org.eclipse.e4.ui.model.application.MWindow;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.util.LocalSelectionTransfer;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.DragSourceListener;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.DropTargetListener;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * Tree displaying contents of the E4 model.
+ */
+public class ModelExplorer {
+
+ private IEclipseContext context;
+ private TreeViewer viewer;
+
+ MApplicationElement rootElement;
+
+ private ImageManagerHelper imageHelper;
+
+ private DragSourceListener dragListener = new DragSourceListener() {
+ public void dragFinished(DragSourceEvent event) {
+ }
+ public void dragSetData(DragSourceEvent event) {
+// IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
+// System.out.println("count: " + selection.size());
+ }
+ public void dragStart(DragSourceEvent event) {
+ IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
+ if (selection.size() != 1) {
+ event.doit = false;
+ }
+ else {
+ event.doit = selection.getFirstElement() instanceof MPart;
+ }
+ }
+ };
+
+ private DropTargetListener dropListener = new DropTargetListener() {
+ public void dragEnter(DropTargetEvent event) {
+ }
+ public void dragOver(DropTargetEvent event) {
+ event.feedback = DND.FEEDBACK_SELECT | DND.FEEDBACK_SCROLL
+ | DND.FEEDBACK_EXPAND;
+
+ Widget curItem = event.item;
+ if (curItem != null) {
+ Object curElement = curItem.getData();
+ if (curElement instanceof MPartStack) {
+ event.detail = DND.DROP_MOVE;
+ }
+ else {
+ event.detail = DND.DROP_NONE;
+ }
+ }
+ }
+
+ public void dragOperationChanged(DropTargetEvent event) {
+ if (LocalSelectionTransfer.getTransfer().isSupportedType(event.currentDataType)) {
+ if (event.detail != DND.DROP_COPY
+ && event.detail != DND.DROP_MOVE) {
+ event.detail = DND.DROP_NONE;
+ }
+ }
+ }
+
+ public void drop(DropTargetEvent event) {
+ if (LocalSelectionTransfer.getTransfer().isSupportedType(event.currentDataType)) {
+ MPartStack sm = (MPartStack) event.item.getData();
+ IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
+ MPart view = (MPart) selection.getFirstElement();
+ sm.getChildren().add(view);
+ ModelUtils.activate(view);
+ viewer.refresh();
+ }
+ }
+ public void dragLeave(DropTargetEvent event) {
+ }
+ public void dropAccept(DropTargetEvent event) {
+ }
+ };
+
+ private ITreeContentProvider contentProvider = new ITreeContentProvider() {
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ public void dispose() {
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ return null;
+ }
+
+ public Object getParent(Object element) {
+ return null;
+ }
+
+ public boolean hasChildren(Object element) {
+ return false;
+ }
+
+ public Object[] getElements(Object inputElement) {
+ return null;
+ }
+ };
+
+ class ViewLabelProvider implements ILabelProvider {
+
+ public Image getImage(Object element) {
+ if (element instanceof MItem) {
+ String iconPath = ((MItem) element).getIconURI();
+ return imageHelper.getImage(iconPath);
+ }
+
+ return imageHelper.getElementImage(element);
+ }
+
+ public String getText(Object element) {
+ if (element instanceof MItem)
+ return ((MItem)element).getName();
+ if (element instanceof MPartStack)
+ return "Stack: \"" + ((MPartStack) element).getId() + "\"";
+ if (element instanceof MPartSashContainer)
+ return "Sash: \"" + ((MPartSashContainer) element).getId() + "\"";
+ if (element instanceof MPerspective)
+ return "Perspective \"" + ((MPerspective) element).getId() + "\"";
+ if (element instanceof MWindow)
+ return "Workbench Window";
+ return element.getClass().getSimpleName();
+ }
+
+ public void addListener(ILabelProviderListener listener) {
+ }
+
+ public void dispose() {
+ }
+
+ public boolean isLabelProperty(Object element, String property) {
+ return false;
+ }
+
+ public void removeListener(ILabelProviderListener listener) {
+ }
+ }
+
+ public ModelExplorer(Composite parent) {
+ imageHelper = new ImageManagerHelper();
+
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ composite.setLayout(layout);
+ GridData data = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
+ composite.setLayoutData(data);
+
+ // add some space around the label
+ Label label = new Label(composite, SWT.NONE);
+ label.setText("&E4 Model");
+ GridData dataLabel = new GridData();
+ dataLabel.horizontalIndent = 5;
+ dataLabel.verticalIndent = 5;
+
+ viewer = new TreeViewer(composite);
+ viewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ viewer.setContentProvider(contentProvider);
+ viewer.setLabelProvider(new ViewLabelProvider());
+
+ viewer.getControl().setData("viewpart", this);
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ handleSelection(event);
+ }
+ });
+
+ // Add DnD support
+ int ops = DND.DROP_COPY | DND.DROP_MOVE;
+ Transfer[] xFers = { LocalSelectionTransfer.getTransfer() };
+ viewer.addDragSupport(ops, xFers, dragListener);
+ viewer.addDropSupport(ops, xFers, dropListener);
+
+ // TBD this really need to be replaced by an API
+ // static MApplication getApplication()
+ // on something
+ MUIElement element = ModelUtils.getElement(parent);
+ EObject topObject = ModelUtils.topObject(element);
+ viewer.setInput(topObject);
+
+ // double-clicks activate the selected part
+ viewer.addDoubleClickListener(new IDoubleClickListener() {
+ public void doubleClick(DoubleClickEvent event) {
+ TreeSelection selection = (TreeSelection) event.getSelection();
+ MPart selected = (MPart) selection.getFirstElement();
+ // TBD there should be an API to activate MPart
+ ModelUtils.activate(selected);
+ }});
+ GridLayoutFactory.fillDefaults().generateLayout(parent);
+ }
+
+ protected void handleSelection(SelectionChangedEvent event) {
+ if (event.getSelection() instanceof IStructuredSelection) {
+ IStructuredSelection sel = (IStructuredSelection) event.getSelection();
+ Object selObj = sel.getFirstElement();
+ if (selObj instanceof EObject)
+ context.modify(IServiceConstants.SELECTION, selObj);
+ }
+ }
+
+ public String[] getPropIds(EObject selObj) {
+ if (selObj == null)
+ return new String[0];
+
+ EList<EStructuralFeature> features = selObj.eClass().getEAllStructuralFeatures();
+ String[] ids = new String[features.size()];
+ int count = 0;
+ for (Iterator iterator = features.iterator(); iterator.hasNext();) {
+ EStructuralFeature structuralFeature = (EStructuralFeature) iterator
+ .next();
+ String featureName = structuralFeature.getName();
+ ids[count++] = featureName;
+ }
+
+ return ids;
+ }
+
+ public Object getProperty(EObject eObj, String id) {
+ if (eObj == null)
+ return null;
+
+ EStructuralFeature eFeature = eObj.eClass().getEStructuralFeature(id);
+ if (eFeature == null)
+ return null;
+
+ return eObj.eGet(eFeature);
+ }
+
+ public void dispose() {
+ // TBD any cleanup?
+ }
+
+ public void contextSet(IEclipseContext context) {
+ this.context = context;
+ }
+
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ModelUtils.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ModelUtils.java
new file mode 100644
index 0000000..f251bce
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/ModelUtils.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * 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.e4.demo.viewer;
+
+import java.util.Iterator;
+
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.core.contexts.IContextConstants;
+import org.eclipse.e4.ui.model.application.MContext;
+import org.eclipse.e4.ui.model.application.MElementContainer;
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MUIElement;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.e4.ui.workbench.swt.internal.AbstractPartRenderer;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Pieces of code that really should be available as APIs somewhere.
+ */
+public class ModelUtils {
+
+ /**
+ * Return a parent context for this part.
+ *
+ * @param part
+ * the part to start searching from
+ * @return the parent's closest context, or global context if none in the
+ * hierarchy
+ */
+ public static IEclipseContext getContextForParent(MUIElement part) {
+ MContext pwc = getParentWithContext(part);
+ return pwc != null ? pwc.getContext() : null;
+ }
+
+ /**
+ * Return a parent context for this part.
+ *
+ * @param part
+ * the part to start searching from
+ * @return the parent's closest context, or global context if none in the
+ * hierarchy
+ */
+ public static MContext getParentWithContext(MUIElement part) {
+ MElementContainer<MUIElement> parent = part.getParent();
+ while (parent != null) {
+ if (parent instanceof MContext) {
+ if (((MContext) parent).getContext() != null)
+ return (MContext) parent;
+ }
+ parent = parent.getParent();
+ }
+ return null;
+ }
+
+ /**
+ * Return a context for this part.
+ *
+ * @param element
+ * the part to start searching from
+ * @return the closest context, or global context if none in the hierarchy
+ */
+ public static IEclipseContext getContext(MUIElement element) {
+ if (element instanceof MContext) {
+ IEclipseContext theContext = ((MContext) element).getContext();
+ if (theContext != null)
+ return theContext;
+ }
+ return getContextForParent(element);
+ }
+
+ /**
+ * Activate the part in the hierarchy. This should either still be internal
+ * or be a public method somewhere else.
+ *
+ * @param element
+ */
+ public static void activate(MUIElement element) {
+ IEclipseContext curContext = getContext(element);
+ MUIElement curElement = element;
+ MContext pwc = getParentWithContext(element);
+ while (pwc != null) {
+ IEclipseContext parentContext = pwc.getContext();
+ if (parentContext != null) {
+ parentContext.set(IContextConstants.ACTIVE_CHILD, curContext);
+ curContext = parentContext;
+ }
+
+ // Ensure that the UI model has the part 'on top'
+ while (curElement != pwc) {
+ MElementContainer<MUIElement> parent = curElement.getParent();
+ if (parent.getActiveChild() != element)
+ parent.setActiveChild(curElement);
+ curElement = parent;
+ }
+
+ pwc = getParentWithContext((MUIElement) pwc);
+ }
+ }
+
+ /**
+ * Get model element associated with the composite or
+ * its containers.
+ * This method may return null.
+ */
+ static MUIElement getElement(Composite composite) {
+ for (Composite container = composite; container != null; container = container.getParent()) {
+ Object owner = container.getData(AbstractPartRenderer.OWNING_ME);
+ if (owner == null)
+ continue;
+ if (owner instanceof MUIElement)
+ return (MUIElement) owner;
+ }
+ return null;
+ }
+
+ /**
+ * Get context associated with the composite or its containers.
+ * This method may return null.
+ */
+ static IEclipseContext getContext(Composite composite) {
+ MUIElement element = getElement(composite);
+ return getContext(element);
+ }
+
+ /**
+ * Returns a model root for a model tree element.
+ */
+ static public EObject topObject(MUIElement part) {
+ MUIElement lastTop = part;
+ MUIElement currentTop = part.getParent();
+ while (currentTop != null) {
+ lastTop = currentTop;
+ currentTop = currentTop.getParent();
+ }
+ return ((EObject) lastTop).eContainer(); // MWindow -> MApp
+ }
+
+ private static MUIElement findElementById(MUIElement element, String id) {
+ if (id == null || id.length() == 0)
+ return null;
+
+ // is it me?
+ if (id.equals(element.getId()))
+ return element;
+
+ // Recurse
+ if (element instanceof MElementContainer<?>) {
+ MUIElement foundPart = null;
+ EList<MUIElement> children = ((MElementContainer<MUIElement>) element).getChildren();
+ for (MUIElement childPart : children) {
+ foundPart = findElementById(childPart, id);
+ if (foundPart != null)
+ return foundPart;
+ }
+ }
+
+ return null;
+ }
+
+ public static MPart findPart(MUIElement toSearch, String id) {
+ MPart found = (MPart) findElementById(toSearch, id);
+ if (found instanceof MPart)
+ return (MPart) found;
+
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesElement.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesElement.java
new file mode 100644
index 0000000..07a5527
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesElement.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * 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.e4.demo.viewer;
+
+import org.eclipse.core.databinding.Binding;
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.e4.ui.model.application.MApplicationPackage;
+import org.eclipse.emf.databinding.EMFObservables;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.jface.databinding.swt.SWTObservables;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.forms.widgets.Section;
+
+/**
+ * Basic control for model items
+ */
+public class PropertiesElement extends Composite {
+
+ protected EObject selectedObject;
+
+ protected DataBindingContext dbc;
+
+ private Text id;
+ private Binding idBinding;
+
+ protected FormToolkit toolkit;
+ protected ScrolledForm form;
+ protected Section right;
+
+ protected Composite comp;
+
+ public PropertiesElement(final Composite parent) {
+ super(parent, SWT.NONE);
+
+ toolkit = new FormToolkit(parent.getDisplay());
+ form = toolkit.createScrolledForm(this);
+ form.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));
+ form.getBody().setLayout(new GridLayout());
+
+ right = toolkit.createSection(form.getBody(), Section.TITLE_BAR
+ | Section.EXPANDED);
+ right.setText("Properties");
+ right.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL));
+
+ comp = toolkit.createComposite(right);
+ comp.setLayout(new GridLayout(2, false));
+ comp.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));
+ right.setClient(comp);
+
+ dbc = new DataBindingContext();
+
+ id = createTextControl(comp, "&ID:", SWT.NONE);
+
+ GridLayoutFactory.fillDefaults().generateLayout(this);
+ }
+
+ /**
+ * Passing the focus request to the form.
+ */
+ public boolean setFocus() {
+ boolean result = super.setFocus();
+ form.setFocus();
+ return result;
+ }
+
+ protected Text createTextControl(Composite parent, String labelText, int style) {
+
+ Label label = toolkit.createLabel(parent, labelText);
+ label.setLayoutData(new GridData());
+ Text result = toolkit.createText(parent, "", style);
+ result.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
+ return result;
+ }
+
+ protected Button createButton(Composite parent, String labelText, int style) {
+ Button result = toolkit.createButton(parent, labelText, SWT.CHECK | style);
+ return result;
+ }
+
+ protected Binding bind(Text text, EStructuralFeature feature) {
+ if (selectedObject == null)
+ return null;
+ IObservableValue observable = EMFObservables.observeValue(selectedObject, feature);
+ return dbc.bindValue(SWTObservables.observeText(text, SWT.Modify), observable, null, null);
+ }
+
+ protected Binding bind(Button button, EStructuralFeature feature) {
+ if (selectedObject == null)
+ return null;
+ IObservableValue observable = EMFObservables.observeValue(selectedObject, feature);
+ return dbc.bindValue(SWTObservables.observeSelection(button), observable, null, null);
+ }
+
+ public void selected(EObject selected) {
+ if (selected == selectedObject)
+ return;
+ clearBindings();
+ selectedObject = selected;
+
+ idBinding = bind(id, MApplicationPackage.Literals.APPLICATION_ELEMENT__ID);
+ }
+
+ protected void clearBindings() {
+ if (idBinding != null) {
+ idBinding.dispose();
+ idBinding = null;
+ }
+ }
+
+ public void dispose() {
+ clearBindings();
+ toolkit.dispose();
+ }
+
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesPart.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesPart.java
new file mode 100644
index 0000000..a350061
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesPart.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * 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.e4.demo.viewer;
+
+import org.eclipse.core.databinding.Binding;
+import org.eclipse.e4.ui.model.application.MApplicationPackage;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Basic information for the MContributedPart
+ */
+public class PropertiesPart extends PropertiesElement {
+
+ private Text name;
+ private Binding nameBinding;
+ private Text tooltip;
+ private Binding tooltipBinding;
+ private Text icon;
+ private Binding iconBinding;
+ private Button visible;
+ private Binding visibleBinding;
+
+ public PropertiesPart(final Composite parent) {
+ super(parent);
+
+ name = createTextControl(comp, "&Name:", SWT.NONE);
+ tooltip = createTextControl(comp, "&Tootip:", SWT.NONE);
+ icon = createTextControl(comp, "Icon &URI:", SWT.NONE);
+
+ visible = createButton(comp, "&Visible", SWT.NONE);
+ GridData checkboxData = new GridData(SWT.RIGHT, SWT.TOP, false, false, 2, 1);
+ visible.setLayoutData(checkboxData);
+ }
+
+ public void selected(EObject selected) {
+ super.selected(selected);
+
+ nameBinding = bind(name, MApplicationPackage.Literals.UI_ITEM__NAME);
+ tooltipBinding = bind(tooltip, MApplicationPackage.Literals.UI_ITEM__TOOLTIP);
+ iconBinding = bind(icon, MApplicationPackage.Literals.UI_ITEM__ICON_URI);
+ visibleBinding = bind(visible, MApplicationPackage.Literals.UI_ELEMENT__VISIBLE);
+ }
+
+ protected void clearBindings() {
+ super.clearBindings();
+
+ if (nameBinding != null) {
+ nameBinding.dispose();
+ nameBinding = null;
+ }
+ if (tooltipBinding != null) {
+ tooltipBinding.dispose();
+ tooltipBinding = null;
+ }
+ if (iconBinding != null) {
+ iconBinding.dispose();
+ iconBinding = null;
+ }
+ if (visibleBinding != null) {
+ visibleBinding.dispose();
+ visibleBinding = null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesSash.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesSash.java
new file mode 100644
index 0000000..d5ef01f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesSash.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * 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.e4.demo.viewer;
+
+import org.eclipse.core.databinding.Binding;
+import org.eclipse.core.databinding.UpdateValueStrategy;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.e4.ui.model.application.MApplicationPackage;
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.databinding.EMFObservables;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.jface.databinding.swt.SWTObservables;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Basic information for the MStack
+ */
+public class PropertiesSash extends PropertiesElement {
+
+ private Text policy;
+ private Text weights;
+ private Binding weightsBinding;
+ private Button visible;
+ private Binding visibleBinding;
+
+ public PropertiesSash(final Composite parent) {
+ super(parent);
+ policy = createTextControl(comp, "&Policy:", SWT.READ_ONLY);
+ weights = createTextControl(comp, "&Weights:", SWT.NONE);
+ visible = createButton(comp, "&Visible", SWT.NONE);
+ GridData checkboxData = new GridData(SWT.RIGHT, SWT.TOP, false, false, 2, 1);
+ visible.setLayoutData(checkboxData);
+ }
+
+ public void selected(EObject selected) {
+ super.selected(selected);
+ weightsBinding = bindList(weights, MApplicationPackage.Literals.GENERIC_TILE__WEIGHTS);
+ visibleBinding = bind(visible, MApplicationPackage.Literals.UI_ELEMENT__VISIBLE);
+ }
+
+ protected Binding bindList(Text text, EStructuralFeature feature) {
+ IObservableValue observable = EMFObservables.observeValue(selectedObject, feature);
+ // NOTE: Do not use SWT.Modify as it might cause StackOverflow
+ // when stack is dragged
+ return dbc.bindValue(SWTObservables.observeText(text, SWT.FocusOut), observable,
+ new UpdateValueStrategy () { // Text to EMF model
+ @Override
+ public Object convert(Object value) {
+ if (!(value instanceof String))
+ return super.convert(value);
+
+ String[] parts = ((String) value).split(", ");
+ EList<Integer> emfList = new BasicEList<Integer>(parts.length);
+ for(String part : parts) {
+ try {
+ emfList.add(Integer.decode(part));
+ } catch (NumberFormatException e) {
+ // can't process; pass to superclass
+ return super.convert(value);
+ }
+ }
+ return emfList;
+ }
+ },
+ new UpdateValueStrategy () { // EMF model to Text
+ @Override
+ public Object convert(Object value) {
+ if (!(value instanceof EList<?>))
+ return super.convert(value);
+ StringBuffer result = new StringBuffer();
+ for(Object element : (EList<?>) value) {
+ if (result.length() != 0)
+ result.append(", ");
+ result.append(element.toString());
+ }
+ return result.toString();
+ }
+ });
+ }
+
+
+ protected void clearBindings() {
+ super.clearBindings();
+ if (weightsBinding != null) {
+ weightsBinding.dispose();
+ weightsBinding = null;
+ }
+ if (visibleBinding != null) {
+ visibleBinding.dispose();
+ visibleBinding = null;
+ }
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesStack.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesStack.java
new file mode 100644
index 0000000..e3e2037
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/PropertiesStack.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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.e4.demo.viewer;
+
+import org.eclipse.core.databinding.Binding;
+import org.eclipse.e4.ui.model.application.MApplicationPackage;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Basic information for the MStack
+ */
+public class PropertiesStack extends PropertiesElement {
+
+ private Text policy;
+ private Button visible;
+ private Binding visibleBinding;
+
+ public PropertiesStack(final Composite parent) {
+ super(parent);
+ visible = createButton(comp, "&Visible", SWT.NONE);
+ GridData checkboxData = new GridData(SWT.RIGHT, SWT.TOP, false, false, 2, 1);
+ visible.setLayoutData(checkboxData);
+ }
+
+ public void selected(EObject selected) {
+ super.selected(selected);
+ visibleBinding = bind(visible, MApplicationPackage.Literals.UI_ELEMENT__VISIBLE);
+ }
+
+ protected void clearBindings() {
+ super.clearBindings();
+ if (visibleBinding != null) {
+ visibleBinding.dispose();
+ visibleBinding = null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/TabAdvanced.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/TabAdvanced.java
new file mode 100644
index 0000000..288370d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/TabAdvanced.java
@@ -0,0 +1,257 @@
+/*******************************************************************************
+ * 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.e4.demo.viewer;
+
+import java.util.Iterator;
+
+import javax.inject.Inject;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.ComboBoxCellEditor;
+import org.eclipse.jface.viewers.EditingSupport;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+
+public class TabAdvanced {
+ static private final String[] booleanValues = new String[] { "true", "false" };
+
+ private TableViewer tableViewer;
+
+ private class EObjectFeature {
+ public EObject eObj;
+ public EStructuralFeature feature;
+
+ public EObjectFeature(EObject eObj, EStructuralFeature feature) {
+ this.eObj = eObj;
+ this.feature = feature;
+ }
+ }
+
+ private class PropertiesEditingSupport extends EditingSupport {
+
+ private CellEditor textEditor;
+ private ComboBoxCellEditor booleanEditor;
+
+ public PropertiesEditingSupport(ColumnViewer viewer) {
+ super(viewer);
+ textEditor = new TextCellEditor(((TableViewer) viewer).getTable());
+ booleanEditor = new ComboBoxCellEditor(((TableViewer) viewer)
+ .getTable(), booleanValues, SWT.READ_ONLY) {
+ @Override
+ public boolean isActivated() {
+ return true;
+ }
+ };
+ }
+
+ @Override
+ protected boolean canEdit(Object element) {
+ Class<?> clazz = ((EObjectFeature) element).feature.getEType().getInstanceClass();
+ String clsStr = clazz.getName();
+ if (clsStr.equals("java.lang.String"))
+ return true;
+ if (clsStr.equals("boolean"))
+ return true;
+ return false;
+ }
+
+ @Override
+ protected CellEditor getCellEditor(Object element) {
+ if (isBoolean((EObjectFeature) element))
+ return booleanEditor;
+ else
+ return textEditor;
+ }
+
+ @Override
+ protected Object getValue(Object element) {
+ Object result = getPropertyValue((EObjectFeature) element);
+ if (isBoolean((EObjectFeature) element)) {
+ if (result.equals("true"))
+ return new Integer(0);
+ else
+ return new Integer(1);
+ }
+ return result;
+ }
+
+ @Override
+ protected void setValue(Object element, Object value) {
+ EObjectFeature dataObject = (EObjectFeature) element;
+ if (isBoolean(dataObject)) {
+ // NOTE: Workaround for the order of events:
+ // combo box first closes, then updates its selection
+ CCombo combo = (CCombo) booleanEditor.getControl();
+ int selection = combo.getSelectionIndex();
+ value = new Boolean(selection == 0);
+ }
+ dataObject.eObj.eSet(dataObject.feature, value);
+ // this is probably not the most efficient way, but it works:
+ tableViewer.refresh(true);
+ }
+ }
+
+ public TabAdvanced(final Composite parent) {
+ Table table = new Table(parent, SWT.NONE | SWT.FULL_SELECTION);
+ table.setLayoutData(new GridData(GridData.FILL_BOTH
+ | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));
+ tableViewer = new TableViewer(table);
+ TableViewerColumn columnName = new TableViewerColumn(tableViewer,
+ SWT.NONE);
+ columnName.getColumn().setText("Property");
+ columnName.getColumn().setResizable(true);
+
+ TableViewerColumn columnValue = new TableViewerColumn(tableViewer,
+ SWT.NONE);
+ columnValue.getColumn().setText("Value");
+ columnValue.getColumn().setResizable(true);
+
+ columnValue
+ .setEditingSupport(new PropertiesEditingSupport(tableViewer));
+
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+
+ TableLayout layoutLayout = new TableLayout();
+ layoutLayout.addColumnData(new ColumnWeightData(1));
+ layoutLayout.addColumnData(new ColumnWeightData(2));
+ table.setLayout(layoutLayout);
+
+ tableViewer.setContentProvider(new IStructuredContentProvider() {
+
+ private EObject eObj;
+
+ public void dispose() {
+ // TODO Auto-generated method stub
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput,
+ Object newInput) {
+ eObj = (EObject) newInput;
+ }
+
+ public Object[] getElements(Object inputElement) {
+ EList<EStructuralFeature> features = eObj.eClass()
+ .getEAllStructuralFeatures();
+ EObjectFeature[] result = new EObjectFeature[features.size()];
+ int pos = 0;
+ for (Iterator<?> iterator = features.iterator(); iterator
+ .hasNext();) {
+ EStructuralFeature feature = (EStructuralFeature) iterator
+ .next();
+ result[pos] = new EObjectFeature(eObj, feature);
+ pos++;
+ }
+ return result;
+ }
+ });
+
+ tableViewer.setLabelProvider(new ITableLabelProvider() {
+
+ public Image getColumnImage(Object element, int columnIndex) {
+ return null;
+ }
+
+ public String getColumnText(Object element, int columnIndex) {
+ switch (columnIndex) {
+ case 0:
+ return ((EObjectFeature) element).feature.getName();
+ case 1:
+ return getPropertyValue((EObjectFeature) element);
+ }
+ return null;
+ }
+
+ public void addListener(ILabelProviderListener listener) {
+ }
+
+ public void dispose() {
+ }
+
+ public boolean isLabelProperty(Object element, String property) {
+ return false;
+ }
+
+ public void removeListener(ILabelProviderListener listener) {
+ }
+ });
+ GridLayoutFactory.fillDefaults().generateLayout(parent);
+ }
+
+ private Object getProperty(EObject eObj, String id) {
+ if (eObj == null)
+ return null;
+
+ EStructuralFeature eFeature = eObj.eClass().getEStructuralFeature(id);
+ if (eFeature == null)
+ return null;
+ return eObj.eGet(eFeature);
+ }
+
+ @Inject
+ public void setSelection(final EObject selection) {
+ if (selection == null)
+ return;
+ tableViewer.setInput(selection);
+ }
+
+ private String getPropertyValue(EObjectFeature eDataObj) {
+ Class<?> clazz = eDataObj.feature.getEType().getInstanceClass();
+ String clsStr = clazz.getName();
+ Object propVal = getProperty(eDataObj.eObj, eDataObj.feature.getName());
+
+ if (clsStr.equals("java.lang.String") || clsStr.equals("int")) {
+ if (propVal == null)
+ return "<null> ";
+ else
+ return propVal.toString();
+ } else if (clsStr.equals("boolean")) {
+ if (propVal == null)
+ return "<null> ";
+ else
+ return propVal.toString();
+ }
+
+ if (propVal == null)
+ return "<null> ";
+ else
+ return propVal.getClass().getName();
+ }
+
+ private boolean isBoolean(EObjectFeature eDataObj) {
+ Class<?> clazz = eDataObj.feature.getEType().getInstanceClass();
+ String clsStr = clazz.getName();
+ return clsStr.equals("boolean");
+ }
+
+ public void dispose() {
+ // TBD any cleanup?
+ }
+
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/TabBasic.java b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/TabBasic.java
new file mode 100644
index 0000000..71598d0
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/src/org/eclipse/e4/demo/viewer/TabBasic.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * 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.e4.demo.viewer;
+
+import javax.inject.Inject;
+
+import org.eclipse.e4.ui.model.application.MPart;
+import org.eclipse.e4.ui.model.application.MPartSashContainer;
+import org.eclipse.e4.ui.model.application.MPartStack;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+// TBD contents of this control is an MStack
+
+public class TabBasic {
+
+ private EObject selectedObject;
+ private StackLayout stackLayout;
+ private Composite comp;
+
+ // Pre-made composites for common element types
+ private PropertiesElement elementProperties;
+ private PropertiesElement contribItemProperties;
+ private PropertiesElement stackProperties;
+ private PropertiesElement sashProperties;
+ private Composite noSelection;
+
+ public TabBasic(final Composite parent) {
+ comp = new Composite(parent, SWT.NONE);
+ comp.setLayout(new GridLayout());
+ comp.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ stackLayout = new StackLayout();
+ stackLayout.marginHeight = 0;
+ stackLayout.marginWidth = 0;
+ comp.setLayout(stackLayout);
+
+ noSelection = new Composite(comp, SWT.NONE);
+ noSelection.setLayout(new FillLayout());
+ new Label(noSelection, SWT.NONE).setText("No selection");
+
+ stackLayout.topControl = noSelection;
+
+ elementProperties = new PropertiesElement(comp);
+ contribItemProperties = new PropertiesPart(comp);
+ stackProperties = new PropertiesStack(comp);
+ sashProperties = new PropertiesSash(comp);
+ GridLayoutFactory.fillDefaults().generateLayout(parent);
+ }
+
+ @Inject
+ public void setSelection(final EObject selected) {
+ if (selected == null)
+ return;
+ if (selected == selectedObject)
+ return;
+ selectedObject = selected;
+
+ if (selectedObject instanceof MPartStack) {
+ stackLayout.topControl = stackProperties;
+ stackProperties.selected(selectedObject);
+ } else if (selectedObject instanceof MPartSashContainer) {
+ stackLayout.topControl = sashProperties;
+ sashProperties.selected(selectedObject);
+ } else if (selectedObject instanceof MPart){
+ stackLayout.topControl = contribItemProperties;
+ contribItemProperties.selected(selected);
+ } else {
+ stackLayout.topControl = elementProperties;
+ elementProperties.selected(selected);
+ }
+ comp.layout();
+ }
+
+ public void dispose() {
+ contribItemProperties.dispose();
+ stackProperties.dispose();
+ sashProperties.dispose();
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.modifier/xmi/NewEditor.xmi b/examples/org.eclipse.e4.demo.modifier/xmi/NewEditor.xmi
new file mode 100644
index 0000000..42b1e1f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/xmi/NewEditor.xmi
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="ASCII"?>
+<application:Application xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:application="http://www.eclipse.org/ui/2008/UIModel" xsi:schemaLocation="http://www.eclipse.org/ui/2008/UIModel ../../org.eclipse.e4.ui.model.workbench/model/UIElements.ecore"/>
diff --git a/examples/org.eclipse.e4.demo.modifier/xmi/UIModelViewer.xmi b/examples/org.eclipse.e4.demo.modifier/xmi/UIModelViewer.xmi
new file mode 100644
index 0000000..84f7ac6
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/xmi/UIModelViewer.xmi
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="ASCII"?>
+<application:Window xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:application="http://www.eclipse.org/ui/2008/UIModel" xsi:schemaLocation="http://www.eclipse.org/ui/2008/UIModel ../../org.eclipse.e4.ui.model.workbench/model/UIElements.ecore">
+ <children xsi:type="application:PartSashContainer" horizontal="true">
+ <children xsi:type="application:Part" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.viewer.ModelExplorer" name="Model View"/>
+ <children xsi:type="application:PartStack">
+ <children xsi:type="application:Part" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.viewer.TabBasic" name="&Basic"/>
+ <children xsi:type="application:Part" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.viewer.TabAdvanced" name="&Advanced"/>
+ <children xsi:type="application:Part" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.ElementView" name="&Javascript"/>
+ </children>
+ </children>
+</application:Window>
diff --git a/examples/org.eclipse.e4.demo.modifier/xmi/modelViewer.xmi b/examples/org.eclipse.e4.demo.modifier/xmi/modelViewer.xmi
new file mode 100644
index 0000000..06d1ccf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/xmi/modelViewer.xmi
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="ASCII"?>
+<org.eclipse.e4.ui.model.application:MWindow xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:org.eclipse.e4.ui.model.application="http://www.eclipse.org/ui/2008/Application" xsi:schemaLocation="http://www.eclipse.org/ui/2008/Application ../../org.eclipse.e4.ui.model.workbench/model/Application.ecore" xmi:id="_0" id="UI Editor" visible="false" name="UI Model Editor" width="600" height="500">
+ <children xsi:type="org.eclipse.e4.ui.model.application:MSashForm" policy="VerticalSash">
+ <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Model View" tooltip="" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.viewer.ModelExplorer"/>
+ <children xsi:type="org.eclipse.e4.ui.model.application:MStack">
+ <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="&Basic" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.viewer.TabBasic"/>
+ <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="&Advanced" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.viewer.TabAdvanced"/>
+ <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="&Javascript" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.ElementView"/>
+ </children>
+ <variables>selection</variables>
+ <weights>50</weights>
+ <weights>50</weights>
+ </children>
+</org.eclipse.e4.ui.model.application:MWindow>
diff --git a/examples/org.eclipse.e4.demo.modifier/xmi/modifyWorkbench.xmi b/examples/org.eclipse.e4.demo.modifier/xmi/modifyWorkbench.xmi
new file mode 100644
index 0000000..1dbfced
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.modifier/xmi/modifyWorkbench.xmi
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="ASCII"?>
+<org.eclipse.e4.ui.model.application:MApplication xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:org.eclipse.e4.ui.model.application="http://www.eclipse.org/ui/2008/Application" xsi:schemaLocation="http://www.eclipse.org/ui/2008/Application ../../org.eclipse.e4.ui.model.workbench/model/Application.ecore">
+ <windows name="Modify Model" x="100" y="100" width="800" height="600">
+ <menu>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" name="File">
+ <menu>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" id="" name="Do Nothing"/>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" iconURI="" name="---" separator="true"/>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" iconURI="" name="Exit" command="//@command.0"/>
+ </menu>
+ </items>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" name="Edit">
+ <menu>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" iconURI="" name="Exit" command="//@command.0"/>
+ </menu>
+ </items>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" name="Help">
+ <menu>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MMenuItem" iconURI="" name="Exit" command="//@command.0"/>
+ </menu>
+ </items>
+ </menu>
+ <children policy="VerticalComposite">
+ <toolBar>
+ <items xsi:type="org.eclipse.e4.ui.model.application:MToolBarItem" iconURI="platform:/plugin/org.eclipse.e4.demo.modifier/icons/elcl16/refresh_nav.gif" name="You Are Seeing The Default Application.xmi"/>
+ </toolBar>
+ <children xsi:type="org.eclipse.e4.ui.model.application:MSashForm" policy="HorizontalSash">
+ <children xsi:type="org.eclipse.e4.ui.model.application:MSashForm" policy="VerticalSash">
+ <children xsi:type="org.eclipse.e4.ui.model.application:MStack">
+ <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Model View" tooltip="" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.ModelView"/>
+ </children>
+ </children>
+ <children xsi:type="org.eclipse.e4.ui.model.application:MSashForm" policy="VerticalSash">
+ <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Preview" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.ElementView"/>
+ <children xsi:type="org.eclipse.e4.ui.model.application:MStack">
+ <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Thumbnails" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.SampleView"/>
+ <children xsi:type="org.eclipse.e4.ui.model.application:MContributedPart" name="Exif" tooltip="" URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.SampleView"/>
+ </children>
+ <weights>70</weights>
+ <weights>30</weights>
+ </children>
+ <weights>30</weights>
+ <weights>70</weights>
+ </children>
+ </children>
+ <handlers URI="bundleclass://org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.ExitHandler" command="//@command.0"/>
+ </windows>
+ <command id="org.eclipse.e4.demo.modifier.exit" name="Exit"/>
+</org.eclipse.e4.ui.model.application:MApplication>
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/.classpath b/examples/org.eclipse.e4.demo.simpleide.dialogs/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/.project b/examples/org.eclipse.e4.demo.simpleide.dialogs/.project
new file mode 100644
index 0000000..7e61f11
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.simpleide.dialogs</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.dialogs/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..a9a6fc3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sat May 22 18:21:58 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide.dialogs/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..8c0e9bf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:08:04 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.dialogs/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..672feb5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Dialogs
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.dialogs
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.core.resources;bundle-version="3.6.0",
+ org.eclipse.core.runtime;bundle-version="3.6.0",
+ org.eclipse.e4.demo.simpleide.services;bundle-version="1.0.0",
+ org.eclipse.e4.demo.simpleide.sharedimages;bundle-version="1.0.0"
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/build.properties b/examples/org.eclipse.e4.demo.simpleide.dialogs/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/ContainerSelectionDialog.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/ContainerSelectionDialog.java
new file mode 100644
index 0000000..0a9f01b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/ContainerSelectionDialog.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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
+ * Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog
+ * font should be activated and used by other components.
+ *******************************************************************************/
+
+package org.eclipse.e4.demo.simpleide.dialogs;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.e4.demo.simpleide.dialogs.internal.Messages;
+import org.eclipse.e4.demo.simpleide.dialogs.internal.components.ContainerSelectionGroup;
+import org.eclipse.e4.demo.simpleide.dialogs.internal.components.ISelectionValidator;
+import org.eclipse.e4.demo.simpleide.services.IImageService;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * A standard selection dialog which solicits a container resource from the user.
+ * The <code>getResult</code> method returns the selected container resource.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * <p>
+ * Example:
+ * <pre>
+ * ContainerSelectionDialog dialog =
+ * new ContainerSelectionDialog(getShell(), initialSelection, allowNewContainerName(), msg);
+ * dialog.open();
+ * Object[] result = dialog.getResult();
+ * </pre>
+ * </p>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ContainerSelectionDialog extends SelectionDialog<IPath> {
+ /**
+ *
+ */
+ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+
+ // the widget group;
+ ContainerSelectionGroup group;
+
+ // the root resource to populate the viewer with
+ private IContainer initialSelection;
+
+ // allow the user to type in a new container name
+ private boolean allowNewContainerName = true;
+
+ // the validation message
+ Label statusMessage;
+
+ //for validating the selection
+ ISelectionValidator validator;
+
+ // show closed projects by default
+ private boolean showClosedProjects = true;
+
+ private IImageService imageService;
+
+ /**
+ * Creates a resource container selection dialog rooted at the given resource.
+ * All selections are considered valid.
+ *
+ * @param parentShell the parent shell
+ * @param initialRoot the initial selection in the tree
+ * @param allowNewContainerName <code>true</code> to enable the user to type in
+ * a new container name, and <code>false</code> to restrict the user to just
+ * selecting from existing ones
+ * @param message the message to be displayed at the top of this dialog, or
+ * <code>null</code> to display a default message
+ */
+ public ContainerSelectionDialog(Shell parentShell, IContainer initialRoot,
+ boolean allowNewContainerName, String message, IImageService imageService) {
+ super(parentShell);
+ this.imageService = imageService;
+ setTitle(Messages.ContainerSelectionDialog_title);
+ this.initialSelection = initialRoot;
+ this.allowNewContainerName = allowNewContainerName;
+ if (message != null) {
+ setMessage(message);
+ } else {
+ setMessage(Messages.ContainerSelectionDialog_message);
+ }
+ setShellStyle(getShellStyle() | SWT.SHEET);
+ }
+
+ /* (non-Javadoc)
+ * Method declared in Window.
+ */
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+
+//FIXME We need a help system
+// PlatformUI.getWorkbench().getHelpSystem()
+// .setHelp(shell, IIDEHelpContextIds.CONTAINER_SELECTION_DIALOG);
+ }
+
+ /* (non-Javadoc)
+ * Method declared on Dialog.
+ */
+ protected Control createDialogArea(Composite parent) {
+ // create composite
+ Composite area = (Composite) super.createDialogArea(parent);
+
+ Listener listener = new Listener() {
+ public void handleEvent(Event event) {
+ if (statusMessage != null && validator != null) {
+ String errorMsg = validator.isValid(group
+ .getContainerFullPath());
+ if (errorMsg == null || errorMsg.equals(EMPTY_STRING)) {
+ statusMessage.setText(EMPTY_STRING);
+ getOkButton().setEnabled(true);
+ } else {
+ statusMessage.setText(errorMsg);
+ getOkButton().setEnabled(false);
+ }
+ }
+ }
+ };
+
+ // container selection group
+ group = new ContainerSelectionGroup(area, listener,
+ allowNewContainerName, getMessage(), showClosedProjects,imageService);
+ if (initialSelection != null) {
+ group.setSelectedContainer(initialSelection);
+ }
+
+ statusMessage = new Label(area, SWT.WRAP);
+ statusMessage.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ statusMessage.setText(" \n "); //$NON-NLS-1$
+ statusMessage.setFont(parent.getFont());
+
+ return dialogArea;
+ }
+
+ /**
+ * The <code>ContainerSelectionDialog</code> implementation of this
+ * <code>Dialog</code> method builds a list of the selected resource containers
+ * for later retrieval by the client and closes this dialog.
+ */
+ protected void okPressed() {
+
+ List<IPath> chosenContainerPathList = new ArrayList<IPath>();
+ IPath returnValue = group.getContainerFullPath();
+ if (returnValue != null) {
+ chosenContainerPathList.add(returnValue);
+ }
+ setResult(chosenContainerPathList);
+ super.okPressed();
+ }
+
+ /**
+ * Sets the validator to use.
+ *
+ * @param validator A selection validator
+ */
+ public void setValidator(ISelectionValidator validator) {
+ this.validator = validator;
+ }
+
+ /**
+ * Set whether or not closed projects should be shown
+ * in the selection dialog.
+ *
+ * @param show Whether or not to show closed projects.
+ */
+ public void showClosedProjects(boolean show) {
+ this.showClosedProjects = show;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/SelectionDialog.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/SelectionDialog.java
new file mode 100644
index 0000000..495be03
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/SelectionDialog.java
@@ -0,0 +1,303 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.e4.demo.simpleide.dialogs;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.eclipse.e4.demo.simpleide.dialogs.internal.Messages;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * The abstract implementation of a selection dialog. It can be primed with
+ * initial selections (<code>setInitialSelections</code>), and returns the
+ * final selection (via <code>getResult</code>) after completion.
+ * <p>
+ * Clients may subclass this dialog to inherit its selection facilities.
+ * </p>
+ */
+public abstract class SelectionDialog<T> extends TrayDialog {
+ // the final collection of selected elements, or null if this dialog was
+ // canceled
+ private List<T> result;
+
+ // a collection of the initially-selected elements
+ private List<T> initialSelections = new ArrayList<T>();
+
+ // title of dialog
+ private String title;
+
+ // message to show user
+ private String message = ""; //$NON-NLS-1$
+
+ // dialog bounds strategy (since 3.2)
+ private int dialogBoundsStrategy = Dialog.DIALOG_PERSISTLOCATION | Dialog.DIALOG_PERSISTSIZE;
+
+ // dialog settings for storing bounds (since 3.2)
+ private IDialogSettings dialogBoundsSettings = null;
+
+ static String SELECT_ALL_TITLE = Messages.SelectionDialog_selectLabel;
+
+ static String DESELECT_ALL_TITLE = Messages.SelectionDialog_deselectLabel;
+
+ /**
+ * Creates a dialog instance. Note that the dialog will have no visual
+ * representation (no widgets) until it is told to open.
+ *
+ * @param parentShell
+ * the parent shell
+ */
+ protected SelectionDialog(Shell parentShell) {
+ super(parentShell);
+ }
+
+ /*
+ * (non-Javadoc) Method declared in Window.
+ */
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ if (title != null) {
+ shell.setText(title);
+ }
+ }
+
+ /*
+ * (non-Javadoc) Method declared on Dialog.
+ */
+ protected void createButtonsForButtonBar(Composite parent) {
+ createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
+ true);
+ createButton(parent, IDialogConstants.CANCEL_ID,
+ IDialogConstants.CANCEL_LABEL, false);
+ }
+
+ /**
+ * Creates the message area for this dialog.
+ * <p>
+ * This method is provided to allow subclasses to decide where the message
+ * will appear on the screen.
+ * </p>
+ *
+ * @param composite
+ * the parent composite
+ * @return the message label
+ */
+ protected Label createMessageArea(Composite composite) {
+ Label label = new Label(composite, SWT.NONE);
+ if (message != null) {
+ label.setText(message);
+ }
+ label.setFont(composite.getFont());
+ return label;
+ }
+
+// /**
+// * Returns the initial selection in this selection dialog.
+// *
+// * @deprecated use getInitialElementSelections() instead
+// * @return the list of initial selected elements or null
+// */
+// protected List getInitialSelections() {
+// if (initialSelections.isEmpty()) {
+// return null;
+// }
+// return getInitialElementSelections();
+// }
+
+ /**
+ * Returns the list of initial element selections.
+ *
+ * @return List
+ */
+ protected List<T> getInitialElementSelections() {
+ return initialSelections;
+ }
+
+ /**
+ * Returns the message for this dialog.
+ *
+ * @return the message for this dialog
+ */
+ protected String getMessage() {
+ return message;
+ }
+
+ /**
+ * Returns the ok button.
+ *
+ * @return the ok button or <code>null</code> if the button is not created
+ * yet.
+ */
+ public Button getOkButton() {
+ return getButton(IDialogConstants.OK_ID);
+ }
+
+ /**
+ * Returns the list of selections made by the user, or <code>null</code>
+ * if the selection was canceled.
+ *
+ * @return the array of selected elements, or <code>null</code> if Cancel
+ * was pressed
+ */
+ public List<T> getResult() {
+ return result;
+ }
+
+ /**
+ * Sets the initial selection in this selection dialog to the given
+ * elements.
+ *
+ * @param selectedElements
+ * the array of elements to select
+ */
+ public void setInitialSelections(T[] selectedElements) {
+ initialSelections = Arrays.asList(selectedElements);
+ }
+
+ /**
+ * Sets the initial selection in this selection dialog to the given
+ * elements.
+ *
+ * @param selectedElements
+ * the List of elements to select
+ */
+ public void setInitialElementSelections(List<T> selectedElements) {
+ initialSelections = selectedElements;
+ }
+
+ /**
+ * Sets the message for this dialog.
+ *
+ * @param message
+ * the message
+ */
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ /**
+ * Set the selections made by the user, or <code>null</code> if the
+ * selection was canceled.
+ *
+ * @param newResult
+ * list of selected elements, or <code>null</code> if Cancel
+ * was pressed
+ */
+ protected void setResult(List<T> newResult) {
+ if (newResult == null) {
+ result = null;
+ } else {
+ result = new ArrayList<T>();
+ }
+ }
+
+ /**
+ * Set the selections made by the user, or <code>null</code> if the
+ * selection was canceled.
+ * <p>
+ * The selections may accessed using <code>getResult</code>.
+ * </p>
+ *
+ * @param newResult -
+ * the new values
+ * @since 2.0
+ */
+ protected void setSelectionResult(List<T> newResult) {
+ result = newResult;
+ }
+
+ /**
+ * Sets the title for this dialog.
+ *
+ * @param title
+ * the title
+ */
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ /**
+ * Set the dialog settings that should be used to save the bounds of this
+ * dialog. This method is provided so that clients that directly use
+ * SelectionDialogs without subclassing them may specify how the bounds of
+ * the dialog are to be saved.
+ *
+ * @param settings
+ * the {@link IDialogSettings} that should be used to store the
+ * bounds of the dialog
+ *
+ * @param strategy
+ * the integer constant specifying how the bounds are saved.
+ * Specified using {@link Dialog#DIALOG_PERSISTLOCATION}
+ * and {@link Dialog#DIALOG_PERSISTSIZE}.
+ *
+ * @since 3.2
+ *
+ * @see Dialog#getDialogBoundsStrategy()
+ * @see Dialog#getDialogBoundsSettings()
+ */
+ public void setDialogBoundsSettings(IDialogSettings settings, int strategy) {
+ dialogBoundsStrategy = strategy;
+ dialogBoundsSettings = settings;
+ }
+
+ /**
+ * Gets the dialog settings that should be used for remembering the bounds
+ * of the dialog, according to the dialog bounds strategy. Overridden to
+ * provide the dialog settings that were set using
+ * {@link #setDialogBoundsSettings(IDialogSettings, int)}.
+ *
+ * @return the dialog settings used to store the dialog's location and/or
+ * size, or <code>null</code> if the dialog's bounds should not be
+ * stored.
+ *
+ * @since 3.2
+ *
+ * @see Dialog#getDialogBoundsStrategy()
+ * @see #setDialogBoundsSettings(IDialogSettings, int)
+ */
+ protected IDialogSettings getDialogBoundsSettings() {
+ return dialogBoundsSettings;
+ }
+
+ /**
+ * Get the integer constant that describes the strategy for persisting the
+ * dialog bounds. Overridden to provide the dialog bounds strategy that was
+ * set using {@link #setDialogBoundsSettings(IDialogSettings, int)}.
+ *
+ * @return the constant describing the strategy for persisting the dialog
+ * bounds.
+ *
+ * @since 3.2
+ * @see Dialog#DIALOG_PERSISTLOCATION
+ * @see Dialog#DIALOG_PERSISTSIZE
+ * @see Dialog#getDialogBoundsSettings()
+ * @see #setDialogBoundsSettings(IDialogSettings, int)
+ */
+ protected int getDialogBoundsStrategy() {
+ return dialogBoundsStrategy;
+ }
+
+ /**
+ * @since 3.4
+ */
+ protected boolean isResizable() {
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/Messages.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/Messages.java
new file mode 100644
index 0000000..fa6b0e0
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/Messages.java
@@ -0,0 +1,25 @@
+package org.eclipse.e4.demo.simpleide.dialogs.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages {
+
+ public static String SelectionDialog_selectLabel;
+ public static String SelectionDialog_deselectLabel;
+
+ public static String GoHome_text;
+ public static String GoHome_toolTip;
+ public static String GoBack_toolTip;
+ public static String GoInto_text;
+ public static String GoInto_toolTip;
+ public static String GoBack_text;
+
+ public static String ContainerGroup_message;
+ public static String ContainerGroup_selectFolder;
+ public static String ContainerSelectionDialog_title;
+ public static String ContainerSelectionDialog_message;
+
+ static {
+ NLS.initializeMessages(Messages.class.getName(), Messages.class);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/Messages.properties b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/Messages.properties
new file mode 100644
index 0000000..3fdaacf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/Messages.properties
@@ -0,0 +1,9 @@
+SelectionDialog_selectLabel = &Select All
+SelectionDialog_deselectLabel = &Deselect All
+
+GoHome_text = Go &Home
+GoHome_toolTip = Home
+GoBack_text = Go &Back
+GoBack_toolTip = Back
+GoInto_text = Go &Into
+GoInto_toolTip = Go Into
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ContainerContentProvider.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ContainerContentProvider.java
new file mode 100644
index 0000000..b07016e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ContainerContentProvider.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demo.simpleide.dialogs.internal.components;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Provides content for a tree viewer that shows only containers.
+ */
+public class ContainerContentProvider implements ITreeContentProvider {
+ private boolean showClosedProjects = true;
+
+ /**
+ * Creates a new ContainerContentProvider.
+ */
+ public ContainerContentProvider() {
+ }
+
+ /**
+ * The visual part that is using this content provider is about
+ * to be disposed. Deallocate all allocated SWT resources.
+ */
+ public void dispose() {
+ }
+
+ /*
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+ */
+ public Object[] getChildren(Object element) {
+ if (element instanceof IWorkspace) {
+ // check if closed projects should be shown
+ IProject[] allProjects = ((IWorkspace) element).getRoot()
+ .getProjects();
+ if (showClosedProjects) {
+ return allProjects;
+ }
+
+ ArrayList<IProject> accessibleProjects = new ArrayList<IProject>();
+ for (int i = 0; i < allProjects.length; i++) {
+ if (allProjects[i].isOpen()) {
+ accessibleProjects.add(allProjects[i]);
+ }
+ }
+ return accessibleProjects.toArray();
+ } else if (element instanceof IContainer) {
+ IContainer container = (IContainer) element;
+ if (container.isAccessible()) {
+ try {
+ List<IResource> children = new ArrayList<IResource>();
+ IResource[] members = container.members();
+ for (int i = 0; i < members.length; i++) {
+ if (members[i].getType() != IResource.FILE) {
+ children.add(members[i]);
+ }
+ }
+ return children.toArray();
+ } catch (CoreException e) {
+ // this should never happen because we call #isAccessible before invoking #members
+ }
+ }
+ }
+ return new Object[0];
+ }
+
+ /*
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ */
+ public Object[] getElements(Object element) {
+ return getChildren(element);
+ }
+
+ /*
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+ */
+ public Object getParent(Object element) {
+ if (element instanceof IResource) {
+ return ((IResource) element).getParent();
+ }
+ return null;
+ }
+
+ /*
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+ */
+ public boolean hasChildren(Object element) {
+ return getChildren(element).length > 0;
+ }
+
+ /*
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged
+ */
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ /**
+ * Specify whether or not to show closed projects in the tree
+ * viewer. Default is to show closed projects.
+ *
+ * @param show boolean if false, do not show closed projects in the tree
+ */
+ public void showClosedProjects(boolean show) {
+ showClosedProjects = show;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ContainerSelectionGroup.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ContainerSelectionGroup.java
new file mode 100644
index 0000000..1822e1a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ContainerSelectionGroup.java
@@ -0,0 +1,355 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * Igor Fedorenko <igorfie@yahoo.com> -
+ * Fix for Bug 136921 [IDE] New File dialog locks for 20 seconds
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.dialogs.internal.components;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.e4.demo.simpleide.dialogs.internal.Messages;
+import org.eclipse.e4.demo.simpleide.services.IImageService;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.osgi.util.TextProcessor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Workbench-level composite for choosing a container.
+ */
+public class ContainerSelectionGroup extends Composite {
+ // The listener to notify of events
+ private Listener listener;
+
+ // Enable user to type in new container name
+ private boolean allowNewContainerName = true;
+
+ // show all projects by default
+ private boolean showClosedProjects = true;
+
+ // Last selection made by user
+ private IContainer selectedContainer;
+
+ // handle on parts
+ private Text containerNameField;
+
+ TreeViewer treeViewer;
+
+ private IImageService imageService;
+
+ // the message to display at the top of this dialog
+ private static final String DEFAULT_MSG_NEW_ALLOWED = Messages.ContainerGroup_message;
+
+ private static final String DEFAULT_MSG_SELECT_ONLY = Messages.ContainerGroup_selectFolder;
+
+ // sizing constants
+ private static final int SIZING_SELECTION_PANE_WIDTH = 320;
+
+ private static final int SIZING_SELECTION_PANE_HEIGHT = 300;
+
+ /**
+ * Creates a new instance of the widget.
+ *
+ * @param parent
+ * The parent widget of the group.
+ * @param listener
+ * A listener to forward events to. Can be null if no listener is
+ * required.
+ * @param allowNewContainerName
+ * Enable the user to type in a new container name instead of
+ * just selecting from the existing ones.
+ */
+ public ContainerSelectionGroup(Composite parent, Listener listener,
+ boolean allowNewContainerName, IImageService imageService) {
+ this(parent, listener, allowNewContainerName, null, imageService);
+ }
+
+ /**
+ * Creates a new instance of the widget.
+ *
+ * @param parent
+ * The parent widget of the group.
+ * @param listener
+ * A listener to forward events to. Can be null if no listener is
+ * required.
+ * @param allowNewContainerName
+ * Enable the user to type in a new container name instead of
+ * just selecting from the existing ones.
+ * @param message
+ * The text to present to the user.
+ */
+ public ContainerSelectionGroup(Composite parent, Listener listener,
+ boolean allowNewContainerName, String message, IImageService imageService) {
+ this(parent, listener, allowNewContainerName, message, true, imageService);
+ }
+
+ /**
+ * Creates a new instance of the widget.
+ *
+ * @param parent
+ * The parent widget of the group.
+ * @param listener
+ * A listener to forward events to. Can be null if no listener is
+ * required.
+ * @param allowNewContainerName
+ * Enable the user to type in a new container name instead of
+ * just selecting from the existing ones.
+ * @param message
+ * The text to present to the user.
+ * @param showClosedProjects
+ * Whether or not to show closed projects.
+ */
+ public ContainerSelectionGroup(Composite parent, Listener listener,
+ boolean allowNewContainerName, String message,
+ boolean showClosedProjects, IImageService imageService) {
+ this(parent, listener, allowNewContainerName, message,
+ showClosedProjects, SIZING_SELECTION_PANE_HEIGHT,
+ SIZING_SELECTION_PANE_WIDTH,imageService);
+ }
+
+ /**
+ * Creates a new instance of the widget.
+ *
+ * @param parent
+ * The parent widget of the group.
+ * @param listener
+ * A listener to forward events to. Can be null if no listener is
+ * required.
+ * @param allowNewContainerName
+ * Enable the user to type in a new container name instead of
+ * just selecting from the existing ones.
+ * @param message
+ * The text to present to the user.
+ * @param showClosedProjects
+ * Whether or not to show closed projects.
+ * @param heightHint
+ * height hint for the drill down composite
+ * @param widthHint
+ * width hint for the drill down composite
+ */
+ public ContainerSelectionGroup(Composite parent, Listener listener,
+ boolean allowNewContainerName, String message,
+ boolean showClosedProjects, int heightHint, int widthHint, IImageService imageService) {
+ super(parent, SWT.NONE);
+ this.imageService = imageService;
+ this.listener = listener;
+ this.allowNewContainerName = allowNewContainerName;
+ this.showClosedProjects = showClosedProjects;
+ if (message != null) {
+ createContents(message, heightHint, widthHint);
+ } else if (allowNewContainerName) {
+ createContents(DEFAULT_MSG_NEW_ALLOWED, heightHint, widthHint);
+ } else {
+ createContents(DEFAULT_MSG_SELECT_ONLY, heightHint, widthHint);
+ }
+ }
+
+ /**
+ * The container selection has changed in the tree view. Update the
+ * container name field value and notify all listeners.
+ *
+ * @param container
+ * The container that changed
+ */
+ public void containerSelectionChanged(IContainer container) {
+ selectedContainer = container;
+
+ if (allowNewContainerName) {
+ if (container == null) {
+ containerNameField.setText("");//$NON-NLS-1$
+ } else {
+ String text = TextProcessor.process(container.getFullPath()
+ .makeRelative().toString());
+ containerNameField.setText(text);
+ containerNameField.setToolTipText(text);
+ }
+ }
+
+ // fire an event so the parent can update its controls
+ if (listener != null) {
+ Event changeEvent = new Event();
+ changeEvent.type = SWT.Selection;
+ changeEvent.widget = this;
+ listener.handleEvent(changeEvent);
+ }
+ }
+
+ /**
+ * Creates the contents of the composite.
+ *
+ * @param message
+ */
+ public void createContents(String message) {
+ createContents(message, SIZING_SELECTION_PANE_HEIGHT,
+ SIZING_SELECTION_PANE_WIDTH);
+ }
+
+ /**
+ * Creates the contents of the composite.
+ *
+ * @param message
+ * @param heightHint
+ * @param widthHint
+ */
+ public void createContents(String message, int heightHint, int widthHint) {
+ GridLayout layout = new GridLayout();
+ layout.marginWidth = 0;
+ setLayout(layout);
+ setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ Label label = new Label(this, SWT.WRAP);
+ label.setText(message);
+ label.setFont(this.getFont());
+
+ if (allowNewContainerName) {
+ containerNameField = new Text(this, SWT.SINGLE | SWT.BORDER);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.widthHint = widthHint;
+ containerNameField.setLayoutData(gd);
+ containerNameField.addListener(SWT.Modify, listener);
+ containerNameField.setFont(this.getFont());
+ } else {
+ // filler...
+ new Label(this, SWT.NONE);
+ }
+
+ createTreeViewer(heightHint);
+ Dialog.applyDialogFont(this);
+ }
+
+ /**
+ * Returns a new drill down viewer for this dialog.
+ *
+ * @param heightHint
+ * height hint for the drill down composite
+ */
+ protected void createTreeViewer(int heightHint) {
+ // Create drill down.
+ DrillDownComposite drillDown = new DrillDownComposite(this, SWT.BORDER,imageService);
+ GridData spec = new GridData(SWT.FILL, SWT.FILL, true, true);
+ spec.widthHint = SIZING_SELECTION_PANE_WIDTH;
+ spec.heightHint = heightHint;
+ drillDown.setLayoutData(spec);
+
+ // Create tree viewer inside drill down.
+ treeViewer = new TreeViewer(drillDown, SWT.NONE);
+ drillDown.setChildTree(treeViewer);
+ ContainerContentProvider cp = new ContainerContentProvider();
+ cp.showClosedProjects(showClosedProjects);
+ treeViewer.setContentProvider(cp);
+
+//FIXME We need a WorkbenchLabelProvider replacement
+// treeViewer.setLabelProvider(WorkbenchLabelProvider
+// .getDecoratingWorkbenchLabelProvider());
+ treeViewer.setComparator(new ViewerComparator());
+ treeViewer.setUseHashlookup(true);
+ treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ IStructuredSelection selection = (IStructuredSelection) event
+ .getSelection();
+ containerSelectionChanged((IContainer) selection
+ .getFirstElement()); // allow null
+ }
+ });
+ treeViewer.addDoubleClickListener(new IDoubleClickListener() {
+ public void doubleClick(DoubleClickEvent event) {
+ ISelection selection = event.getSelection();
+ if (selection instanceof IStructuredSelection) {
+ Object item = ((IStructuredSelection) selection)
+ .getFirstElement();
+ if (item == null) {
+ return;
+ }
+ if (treeViewer.getExpandedState(item)) {
+ treeViewer.collapseToLevel(item, 1);
+ } else {
+ treeViewer.expandToLevel(item, 1);
+ }
+ }
+ }
+ });
+
+ // This has to be done after the viewer has been laid out
+ treeViewer.setInput(ResourcesPlugin.getWorkspace());
+ }
+
+ /**
+ * Returns the currently entered container name. Null if the field is empty.
+ * Note that the container may not exist yet if the user entered a new
+ * container name in the field.
+ *
+ * @return IPath
+ */
+ public IPath getContainerFullPath() {
+ if (allowNewContainerName) {
+ String pathName = containerNameField.getText();
+ if (pathName == null || pathName.length() < 1) {
+ return null;
+ }
+ // The user may not have made this absolute so do it for them
+ return (new Path(TextProcessor.deprocess(pathName))).makeAbsolute();
+
+ }
+ if (selectedContainer == null)
+ return null;
+ return selectedContainer.getFullPath();
+
+ }
+
+ /**
+ * Gives focus to one of the widgets in the group, as determined by the
+ * group.
+ */
+ public void setInitialFocus() {
+ if (allowNewContainerName) {
+ containerNameField.setFocus();
+ } else {
+ treeViewer.getTree().setFocus();
+ }
+ }
+
+ /**
+ * Sets the selected existing container.
+ *
+ * @param container
+ */
+ public void setSelectedContainer(IContainer container) {
+ selectedContainer = container;
+
+ // expand to and select the specified container
+ List<IContainer> itemsToExpand = new ArrayList<IContainer>();
+ IContainer parent = container.getParent();
+ while (parent != null) {
+ itemsToExpand.add(0, parent);
+ parent = parent.getParent();
+ }
+ treeViewer.setExpandedElements(itemsToExpand.toArray());
+ treeViewer.setSelection(new StructuredSelection(container), true);
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillDownAdapter.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillDownAdapter.java
new file mode 100644
index 0000000..6a241aa
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillDownAdapter.java
@@ -0,0 +1,339 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.e4.demo.simpleide.dialogs.internal.components;
+
+import java.util.Arrays;
+import java.util.List;
+import org.eclipse.e4.demo.simpleide.dialogs.internal.Messages;
+import org.eclipse.e4.demo.simpleide.services.IImageService;
+import org.eclipse.e4.demo.simpleide.services.IImageService.IImagePool;
+import org.eclipse.e4.demo.simpleide.sharedimages.SharedImageKeys;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+
+/**
+ * Implements a simple web style navigation metaphor for a <code>TreeViewer</code>.
+ * Home, back, and "drill into" functions are supported for the viewer,
+ * <p>
+ * To use the <code>DrillDownAdapter</code> ..
+ * </p>
+ * <ul>
+ * <li>Create an instance of <code>TreeViewer</code>. </li>
+ * <li>Create a <code>DrillDownAdapter</code> for the viewer. </li>
+ * <li>Create a container for your viewer with a toolbar or a popup menu.
+ * Add actions for "goBack", "goHome", and "goInto" to either one by calling
+ * </code>addNavigationActions</code> with the popup menu or toolbar.</li>
+ * </ol>
+ * <p>
+ * If the input for the underlying viewer is changed by something other than the
+ * adapter the <code>reset</code> method should be called. This will clear
+ * the drill stack and update the navigation buttons to reflect the new
+ * state of the underlying viewer.
+ * </p>
+ * </p>
+ */
+public class DrillDownAdapter implements ISelectionChangedListener {
+ private TreeViewer fChildTree;
+
+ private DrillStack fDrillStack;
+
+ private Action homeAction;
+
+ private Action backAction;
+
+ private Action forwardAction;
+
+ private IImagePool pool;
+
+ /**
+ * Allocates a new DrillDownTreePart.
+ *
+ * @param tree the target tree for refocusing
+ */
+ public DrillDownAdapter(TreeViewer tree, IImageService imageService) {
+ pool = imageService.getControlPool(tree.getControl());
+ fDrillStack = new DrillStack();
+ fChildTree = tree;
+ }
+
+ /**
+ * Adds actions for "go back", "go home", and "go into" to a menu manager.
+ *
+ * @param manager is the target manager to update
+ */
+ public void addNavigationActions(IMenuManager manager) {
+ createActions();
+ manager.add(homeAction);
+ manager.add(backAction);
+ manager.add(forwardAction);
+ updateNavigationButtons();
+ }
+
+ /**
+ * Adds actions for "go back", "go home", and "go into" to a tool bar manager.
+ *
+ * @param toolBar is the target manager to update
+ */
+ public void addNavigationActions(IToolBarManager toolBar) {
+ createActions();
+ toolBar.add(homeAction);
+ toolBar.add(backAction);
+ toolBar.add(forwardAction);
+ updateNavigationButtons();
+ }
+
+ /**
+ * Returns whether expansion is possible for the current selection. This
+ * will only be true if it has children.
+ *
+ * @param element the object to test for expansion
+ * @return <code>true</code> if expansion is possible; otherwise
+ * return <code>false</code
+ */
+ public boolean canExpand(Object element) {
+ return fChildTree.isExpandable(element);
+ }
+
+ /**
+ * Returns whether "go back" is possible for child tree. This is only possible
+ * if the client has performed one or more drilling operations.
+ *
+ * @return <code>true</code> if "go back" is possible; <code>false</code> otherwise
+ */
+ public boolean canGoBack() {
+ return fDrillStack.canGoBack();
+ }
+
+ /**
+ * Returns whether "go home" is possible for child tree. This is only possible
+ * if the client has performed one or more drilling operations.
+ *
+ * @return <code>true</code> if "go home" is possible; <code>false</code> otherwise
+ */
+ public boolean canGoHome() {
+ return fDrillStack.canGoHome();
+ }
+
+ /**
+ * Returns whether "go into" is possible for child tree. This is only possible
+ * if the current selection in the client has one item and it has children.
+ *
+ * @return <code>true</code> if "go into" is possible; <code>false</code> otherwise
+ */
+ public boolean canGoInto() {
+ IStructuredSelection oSelection = (IStructuredSelection) fChildTree
+ .getSelection();
+ if (oSelection == null || oSelection.size() != 1) {
+ return false;
+ }
+ Object anElement = oSelection.getFirstElement();
+ return canExpand(anElement);
+ }
+
+ /**
+ * Create the actions for navigation.
+ *
+ */
+ private void createActions() {
+ // Only do this once.
+ if (homeAction != null) {
+ return;
+ }
+
+ // Home.
+ homeAction = new Action(Messages.GoHome_text) {
+ public void run() {
+ goHome();
+ }
+ };
+ homeAction
+ .setToolTipText(Messages.GoHome_toolTip);
+ homeAction
+ .setImageDescriptor(ImageDescriptor.createFromImage(pool.getImageUnchecked(SharedImageKeys.IMG_TOOL_HOME_NAV)));
+
+ // Back.
+ backAction = new Action(Messages.GoBack_text) {
+ public void run() {
+ goBack();
+ }
+ };
+ backAction
+ .setToolTipText(Messages.GoBack_toolTip);
+ backAction.setImageDescriptor(ImageDescriptor.createFromImage(pool.getImageUnchecked(SharedImageKeys.IMG_TOOL_BACK)));
+ backAction.setDisabledImageDescriptor(ImageDescriptor.createFromImage(pool.getImageUnchecked(SharedImageKeys.IMG_TOOL_BACK_DISABLED)));
+
+ // Forward.
+ forwardAction = new Action(Messages.GoInto_text) {
+ public void run() {
+ goInto();
+ }
+ };
+ forwardAction.setToolTipText(Messages.GoInto_toolTip);
+ forwardAction.setImageDescriptor(ImageDescriptor.createFromImage(pool.getImageUnchecked(SharedImageKeys.IMG_TOOL_FORWARD)));
+ forwardAction.setDisabledImageDescriptor(ImageDescriptor.createFromImage(pool.getImageUnchecked(SharedImageKeys.IMG_TOOL_FORWARD_DISABLED)));
+
+ // Update the buttons when a selection change occurs.
+ fChildTree.addSelectionChangedListener(this);
+ updateNavigationButtons();
+ }
+
+ /**
+ * Expands the given items in the tree. The list of items passed should be
+ * derived by calling <code>getExpanded</code>.
+ *
+ * @param items is a list of items within the tree which should be expanded
+ */
+ private void expand(List items) {
+ fChildTree.setExpandedElements(items.toArray());
+ }
+
+ /**
+ * Returns a list of elements corresponding to expanded nodes in
+ * child tree.
+ *
+ * @return a list of expandd elements
+ */
+ private List getExpanded() {
+ return Arrays.asList(fChildTree.getExpandedElements());
+ }
+
+ /**
+ * Reverts the input for the tree back to the state when <code>goInto</code>
+ * was last called.
+ * <p>
+ * A frame is removed from the drill stack. Then that frame is used to reset the
+ * input and expansion state for the child tree.
+ * </p>
+ */
+ public void goBack() {
+ Object currentInput = fChildTree.getInput();
+ DrillFrame oFrame = fDrillStack.goBack();
+ Object input = oFrame.getElement();
+ fChildTree.setInput(input);
+ expand(oFrame.getExpansion());
+ // if there was a selection, it should have been preserved,
+ // but if not, select the element that was drilled into
+ if (fChildTree.getSelection().isEmpty()) {
+ fChildTree
+ .setSelection(new StructuredSelection(currentInput), true);
+ }
+ updateNavigationButtons();
+ }
+
+ /**
+ * Reverts the input for the tree back to the state when the adapter was
+ * created.
+ * <p>
+ * All of the frames are removed from the drill stack. Then the oldest frame is
+ * used to reset the input and expansion state for the child tree.
+ * </p>
+ */
+ public void goHome() {
+ Object currentInput = fChildTree.getInput();
+ DrillFrame oFrame = fDrillStack.goHome();
+ Object input = oFrame.getElement();
+ fChildTree.setInput(input);
+ expand(oFrame.getExpansion());
+ // if there was a selection, it should have been preserved,
+ // but if not, select the element that was last drilled into
+ if (fChildTree.getSelection().isEmpty()) {
+ fChildTree
+ .setSelection(new StructuredSelection(currentInput), true);
+ }
+ updateNavigationButtons();
+ }
+
+ /**
+ * Sets the input for the tree to the current selection.
+ * <p>
+ * The current input and expansion state are saved in a frame and added to the
+ * drill stack. Then the input for the tree is changed to be the current selection.
+ * The expansion state for the tree is maintained during the operation.
+ * </p><p>
+ * On return the client may revert back to the previous state by invoking
+ * <code>goBack</code> or <code>goHome</code>.
+ * </p>
+ */
+ public void goInto() {
+ IStructuredSelection sel = (IStructuredSelection) fChildTree
+ .getSelection();
+ Object element = sel.getFirstElement();
+ goInto(element);
+ }
+
+ /**
+ * Sets the input for the tree to a particular item in the tree.
+ * <p>
+ * The current input and expansion state are saved in a frame and added to the
+ * drill stack. Then the input for the tree is changed to be <code>newInput</code>.
+ * The expansion state for the tree is maintained during the operation.
+ * </p><p>
+ * On return the client may revert back to the previous state by invoking
+ * <code>goBack</code> or <code>goHome</code>.
+ * </p>
+ *
+ * @param newInput the new input element
+ */
+ public void goInto(Object newInput) {
+ // If we can drill ..
+ if (canExpand(newInput)) {
+ // Save the old state.
+ Object oldInput = fChildTree.getInput();
+ List expandedList = getExpanded();
+ fDrillStack.add(new DrillFrame(oldInput, "null", expandedList));//$NON-NLS-1$
+
+ // Install the new state.
+ fChildTree.setInput(newInput);
+ expand(expandedList);
+ updateNavigationButtons();
+ }
+ }
+
+ /**
+ * Resets the drill down adapter.
+ * <p>
+ * This method is typically called when the input for the underlying view
+ * is reset by something other than the adapter.
+ * On return the drill stack has been cleared and the navigation buttons
+ * reflect the new state of the underlying viewer.
+ * </p>
+ */
+ public void reset() {
+ fDrillStack.reset();
+ updateNavigationButtons();
+ }
+
+ /**
+ * Updates the navigation buttons when a selection change occurs
+ * in the tree.
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ updateNavigationButtons();
+ }
+
+ /**
+ * Updates the enabled state for each navigation button.
+ */
+ protected void updateNavigationButtons() {
+ if (homeAction != null) {
+ homeAction.setEnabled(canGoHome());
+ backAction.setEnabled(canGoBack());
+ forwardAction.setEnabled(canGoInto());
+ }
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillDownComposite.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillDownComposite.java
new file mode 100644
index 0000000..49dfa4b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillDownComposite.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demo.simpleide.dialogs.internal.components;
+
+import org.eclipse.e4.demo.simpleide.services.IImageService;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.ToolBar;
+
+/**
+ * Class <code>DrillDownComposite</code> implements a simple web
+ * style navigation metaphor. Home, back, and "drill into" buttons are
+ * added to a tree viewer for easier navigation.
+ * <p>
+ * To use the DrillDownComposite..
+ * </p>
+ * <ul>
+ * <li>Create an instance of <code>DrillDownComposite</code>.</li>
+ * <li>Create a tree viewer. </li>
+ * <li>Pass the second tree viewer into the composite by
+ * calling <code>setChildTree</code>.</li>
+ * </ol>
+ */
+public class DrillDownComposite extends Composite {
+ private ToolBarManager toolBarMgr;
+
+ private TreeViewer fChildTree;
+
+ private DrillDownAdapter adapter;
+
+ private IImageService imageService;
+
+ /**
+ * Constructs a new DrillDownTreeViewer.
+ *
+ * @param parent the parent composite for this control
+ * @param style the SWT style for this control
+ */
+ public DrillDownComposite(Composite parent, int style, IImageService imageService) {
+ super(parent, style);
+ this.imageService = imageService;
+ createNavigationButtons();
+ }
+
+ /**
+ * Creates the navigation buttons for this viewer.
+ */
+ protected void createNavigationButtons() {
+ GridData gid;
+ GridLayout layout;
+
+ // Define layout.
+ layout = new GridLayout();
+ layout.marginHeight = layout.marginWidth = layout.horizontalSpacing = layout.verticalSpacing = 0;
+ setLayout(layout);
+
+ // Create a toolbar.
+ toolBarMgr = new ToolBarManager(SWT.FLAT);
+ ToolBar toolBar = toolBarMgr.createControl(this);
+ gid = new GridData();
+ gid.horizontalAlignment = GridData.FILL;
+ gid.verticalAlignment = GridData.BEGINNING;
+ toolBar.setLayoutData(gid);
+ }
+
+ /**
+ * Sets the child viewer. This method should only be called once, after the
+ * viewer has been created.
+ *
+ * @param aViewer the new child viewer
+ */
+ public void setChildTree(TreeViewer aViewer) {
+ // Save viewer.
+ fChildTree = aViewer;
+
+ // Create adapter.
+ adapter = new DrillDownAdapter(fChildTree,imageService);
+ adapter.addNavigationActions(toolBarMgr);
+ toolBarMgr.update(true);
+
+ // Set tree layout.
+ fChildTree.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ layout();
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillFrame.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillFrame.java
new file mode 100644
index 0000000..1908181
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillFrame.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demo.simpleide.dialogs.internal.components;
+
+import java.util.List;
+
+/* (non-Javadoc)
+ * A <code>DrillFrame</code> is used to record the input element and
+ * selection state for one frame in a <code>DrillDownTreeViewer</code>.
+ * This class is not intended for use beyond the package.
+ */
+/* package */class DrillFrame {
+ Object fElement;
+
+ Object fPropertyName;
+
+ List fExpansion = null;
+
+ /**
+ * Allocates a new DrillFrame.
+ *
+ * @param oElement the tree input element
+ * @param strPropertyName the visible tree property
+ * @param vExpansion the current expansion state of the tree
+ */
+ public DrillFrame(Object oElement, Object strPropertyName, List vExpansion) {
+ fElement = oElement;
+ fPropertyName = strPropertyName;
+ fExpansion = vExpansion;
+ }
+
+ /**
+ * Compares two Objects for equality.
+ * <p>
+ *
+ * @param obj the reference object with which to compare.
+ * @return <code>true</code> if this object is the same as the obj
+ * argument; <code>false</code> otherwise.
+ */
+ public boolean equals(Object obj) {
+ // Compare handles.
+ if (this == obj) {
+ return true;
+ }
+
+ // Compare class.
+ if (!(obj instanceof DrillFrame)) {
+ return false;
+ }
+
+ // Compare contents.
+ DrillFrame oOther = (DrillFrame) obj;
+ return ((fElement == oOther.fElement) && (fPropertyName
+ .equals(oOther.fPropertyName)));
+ }
+
+ /**
+ * Returns the input element.
+ *
+ * @return the input element
+ */
+ public Object getElement() {
+ return fElement;
+ }
+
+ /**
+ * Returns the expansion state for a tree.
+ *
+ * @return the expansion state for a tree
+ */
+ public List getExpansion() {
+ return fExpansion;
+ }
+
+ /**
+ * Returns the property name.
+ *
+ * @return the property name
+ */
+ public Object getPropertyName() {
+ return fPropertyName;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillStack.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillStack.java
new file mode 100644
index 0000000..7e2343c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/DrillStack.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demo.simpleide.dialogs.internal.components;
+
+import java.util.Stack;
+
+/* (non-Javadoc)
+ * A <code>DrillStack</code> manages a stack of DrillFrames.
+ * This class is not intended for use beyond the package.
+ */
+/* package */class DrillStack {
+ Stack fStack = null;
+
+ /**
+ * Allocates a new DrillStack.
+ */
+ public DrillStack() {
+ reset();
+ }
+
+ /**
+ * Adds a drill frame to the stack.
+ *
+ * @param oRecord the new drill frame
+ */
+ public DrillFrame add(DrillFrame oRecord) {
+ fStack.push(oRecord);
+ return oRecord;
+ }
+
+ /**
+ * Returns true if backward navigation is possible. This is only true
+ * if the stack size is greater than 0.
+ *
+ * @return true if backward navigation is possible
+ */
+ public boolean canGoBack() {
+ return (fStack.size() > 0);
+ }
+
+ /**
+ * Returns true if "go home" is possible. This is only true
+ * if the stack size is greater than 0.
+ *
+ * @return true if "go home" is possible
+ */
+ public boolean canGoHome() {
+ return (fStack.size() > 0);
+ }
+
+ /**
+ * Navigate backwards one record.
+ */
+ public DrillFrame goBack() {
+ DrillFrame aFrame = (DrillFrame) fStack.pop();
+ return aFrame;
+ }
+
+ /**
+ * Navigate to the home record.
+ */
+ public DrillFrame goHome() {
+ DrillFrame aFrame = (DrillFrame) fStack.elementAt(0);
+ reset();
+ return aFrame;
+ }
+
+ /**
+ * Clears the navigation stack.
+ */
+ public void reset() {
+ fStack = new Stack();
+ }
+
+ /**
+ * Returns the stack size.
+ *
+ * @return the stack size
+ */
+ public int size() {
+ return fStack.size();
+ }
+
+ /**
+ * Returns the top element on the stack.
+ *
+ * @return the top element on the stack
+ */
+ public DrillFrame top() {
+ return (DrillFrame) fStack.peek();
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ISelectionValidator.java b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ISelectionValidator.java
new file mode 100644
index 0000000..7bc4f98
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.dialogs/src/org/eclipse/e4/demo/simpleide/dialogs/internal/components/ISelectionValidator.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demo.simpleide.dialogs.internal.components;
+
+/**
+ * For validating selections in some selection dialogs.
+ * <p>
+ * Clients should implement this interface to define specialized selection
+ * validators.
+ * </p>
+ */
+public interface ISelectionValidator {
+ /**
+ * Returns a string indicating whether the given selection is valid. If the
+ * result is <code>null</code>, the selection is considered to be valid; if the result is
+ * non-empty, it contains the error message to be displayed to the user.
+ *
+ * @param selection the selection to be validated
+ * @return the error message, or <code>null</code> indicating
+ * that the value is valid
+ */
+ public String isValid(Object selection);
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/.classpath b/examples/org.eclipse.e4.demo.simpleide.e4editor/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/.project b/examples/org.eclipse.e4.demo.simpleide.e4editor/.project
new file mode 100644
index 0000000..060aa8e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.simpleide.e4editor</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.e4editor/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..13c68fb
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Mon May 17 10:02:45 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide.e4editor/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..9f4cd72
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:07:05 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.e4editor/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..ebe8e58
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: E4editor
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.e4editor;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.ui.workbench;bundle-version="0.9.1",
+ org.eclipse.e4.demo.simpleide.model;bundle-version="1.0.0",
+ org.eclipse.e4.tools.emf.ui;bundle-version="0.9.0",
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0",
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.core.resources;bundle-version="3.7.100"
+Service-Component: OSGI-INF/xmiresourcecontextfunction.xml
+Bundle-ActivationPolicy: lazy
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/OSGI-INF/xmiresourcecontextfunction.xml b/examples/org.eclipse.e4.demo.simpleide.e4editor/OSGI-INF/xmiresourcecontextfunction.xml
new file mode 100644
index 0000000..647a333
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/OSGI-INF/xmiresourcecontextfunction.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.eclipse.e4.demo.simpleide.e4editor.xmiresourcecontextfunction">
+ <implementation class="org.eclipse.e4.demo.simpleide.e4editor.XMIResourceFunction"/>
+ <service>
+ <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/>
+ </service>
+ <property name="service.context.key" type="String" value="org.eclipse.e4.tools.emf.ui.common.IModelResource"/>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/build.properties b/examples/org.eclipse.e4.demo.simpleide.e4editor/build.properties
new file mode 100644
index 0000000..1b0981f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/build.properties
@@ -0,0 +1,6 @@
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ OSGI-INF/xmiresourcecontextfunction.xml,\
+ plugin.xml
+source.. = src/
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/icons/application_view_tile.png b/examples/org.eclipse.e4.demo.simpleide.e4editor/icons/application_view_tile.png
new file mode 100644
index 0000000..3bc0bd3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/icons/application_view_tile.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/plugin.xml b/examples/org.eclipse.e4.demo.simpleide.e4editor/plugin.xml
new file mode 100644
index 0000000..b39876c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ id="id2"
+ point="org.eclipse.e4.workbench.model">
+ <fragment
+ uri="xmi/fragment.e4xmi">
+ </fragment>
+ </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/src/org/eclipse/e4/demo/simpleide/e4editor/XMIResourceFunction.java b/examples/org.eclipse.e4.demo.simpleide.e4editor/src/org/eclipse/e4/demo/simpleide/e4editor/XMIResourceFunction.java
new file mode 100644
index 0000000..74947ae
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/src/org/eclipse/e4/demo/simpleide/e4editor/XMIResourceFunction.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.e4editor;
+
+import org.eclipse.e4.core.contexts.ContextFunction;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.tools.emf.ui.common.IModelResource.ModelListener;
+import org.eclipse.e4.tools.emf.ui.common.XMIModelResource;
+import org.eclipse.e4.ui.model.application.ui.basic.MInputPart;
+import org.eclipse.emf.common.util.URI;
+
+public class XMIResourceFunction extends ContextFunction {
+ @Override
+ public Object compute(IEclipseContext context) {
+ final MInputPart part = context.get(MInputPart.class);
+ if( part != null ) {
+ final XMIModelResource resource = new XMIModelResource(URI.createPlatformResourceURI(part.getInputURI(),false));
+ resource.addModelListener(new ModelListener() {
+
+ public void dirtyChanged() {
+ part.setDirty(resource.isDirty());
+ }
+
+ public void commandStackChanged() {
+
+ }
+ });
+ return resource;
+ }
+
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.e4editor/xmi/fragment.e4xmi b/examples/org.eclipse.e4.demo.simpleide.e4editor/xmi/fragment.e4xmi
new file mode 100644
index 0000000..d300acf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.e4editor/xmi/fragment.e4xmi
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmlns:simpleide="http://www.eclipse.org/e4/demo/simpleide" xmi:id="_Y_hlIHZiEd-iDrIYpK0HDA">
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_s3LFAHZiEd-84etnte_XqQ" featurename="editorPartDescriptors" parentElementId="app.simpleide">
+ <elements xsi:type="simpleide:EditorPartDescriptor" xmi:id="_Vg-BUHZnEd-hBfer1g14pA" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.e4editor/icons/application_view_tile.png" contributionURI="bundleclass://org.eclipse.e4.tools.emf.ui/org.eclipse.e4.tools.emf.ui.internal.wbm.ApplicationModelEditor">
+ <fileextensions>e4xmi</fileextensions>
+ </elements>
+ </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/.classpath b/examples/org.eclipse.e4.demo.simpleide.editor.text/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/.project b/examples/org.eclipse.e4.demo.simpleide.editor.text/.project
new file mode 100644
index 0000000..e381f23
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.simpleide.editor.text</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.editor.text/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..16b5b24
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Fri May 14 19:06:05 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide.editor.text/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..6ccf2e2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:07:27 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.editor.text/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..fc1bd4d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/META-INF/MANIFEST.MF
@@ -0,0 +1,15 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Text
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.editor.text;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.jface.text;bundle-version="3.6.0",
+ org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.e4.demo.simpleide.editor;bundle-version="1.0.0",
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.1",
+ org.eclipse.e4.demo.simpleide.model;bundle-version="1.0.0",
+ org.eclipse.equinox.common;bundle-version="3.6.0",
+ org.eclipse.e4.ui.di;bundle-version="0.9.0"
+Import-Package: javax.inject;version="1.0.0"
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/build.properties b/examples/org.eclipse.e4.demo.simpleide.editor.text/build.properties
new file mode 100644
index 0000000..256e212
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/build.properties
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ icons/,\
+ xmi/
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/icons/elements_obj.gif b/examples/org.eclipse.e4.demo.simpleide.editor.text/icons/elements_obj.gif
new file mode 100644
index 0000000..33be7d8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/icons/elements_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/icons/file_obj.gif b/examples/org.eclipse.e4.demo.simpleide.editor.text/icons/file_obj.gif
new file mode 100644
index 0000000..7ccc6a7
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/icons/file_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/plugin.xml b/examples/org.eclipse.e4.demo.simpleide.editor.text/plugin.xml
new file mode 100644
index 0000000..91ea859
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ id="id1"
+ point="org.eclipse.e4.workbench.model">
+ <fragment
+ uri="xmi/fragment.e4xmi">
+ </fragment>
+ </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/PlainTextEditor.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/PlainTextEditor.java
new file mode 100644
index 0000000..38f1d72
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/PlainTextEditor.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text;
+
+import javax.inject.Inject;
+import org.eclipse.e4.demo.simpleide.editor.IDocumentInput;
+import org.eclipse.e4.ui.di.Persist;
+import org.eclipse.jface.text.TextViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+
+public class PlainTextEditor {
+ private IDocumentInput input;
+
+ @Inject
+ public PlainTextEditor(Composite parent, IDocumentInput input) {
+ this.input = input;
+ parent.setLayout(new FillLayout());
+
+ int styles= SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION;
+ TextViewer viewer = new TextViewer(parent, styles);
+ viewer.setDocument(input.getDocument());
+ }
+
+ @Persist
+ public void save() {
+ input.save();
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/XMLTextEditor.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/XMLTextEditor.java
new file mode 100644
index 0000000..79eaa38
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/XMLTextEditor.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text;
+
+import javax.inject.Inject;
+import org.eclipse.e4.demo.simpleide.editor.IDocumentInput;
+import org.eclipse.e4.demo.simpleide.editor.text.xml.ColorManager;
+import org.eclipse.e4.demo.simpleide.editor.text.xml.XMLConfiguration;
+import org.eclipse.e4.demo.simpleide.editor.text.xml.XMLPartitionScanner;
+import org.eclipse.e4.ui.di.Persist;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.FastPartitioner;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.text.source.VerticalRuler;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+
+public class XMLTextEditor {
+ private static final int VERTICAL_RULER_WIDTH = 12;
+
+ private ColorManager colorManager;
+
+ private IDocumentInput input;
+
+ @Inject
+ public XMLTextEditor(Composite parent, IDocumentInput input) {
+ this.input = input;
+ parent.setLayout(new FillLayout());
+
+ colorManager = new ColorManager();
+ VerticalRuler verticalRuler = new VerticalRuler(VERTICAL_RULER_WIDTH);
+
+ int styles= SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION;
+ SourceViewer viewer = new SourceViewer(parent, verticalRuler, styles);
+ viewer.configure(new XMLConfiguration(colorManager));
+ IDocument document = input.getDocument();
+ IDocumentPartitioner partitioner =
+ new FastPartitioner(
+ new XMLPartitionScanner(),
+ new String[] {
+ XMLPartitionScanner.XML_TAG,
+ XMLPartitionScanner.XML_COMMENT });
+ partitioner.connect(document);
+ document.setDocumentPartitioner(partitioner);
+ viewer.setDocument(document);
+ }
+
+ @Persist
+ public void save() {
+ System.err.println("Saving ...");
+ input.save();
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/ColorManager.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/ColorManager.java
new file mode 100644
index 0000000..51d5085
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/ColorManager.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+public class ColorManager {
+
+ protected Map<RGB, Color> fColorTable = new HashMap<RGB, Color>(10);
+
+ public void dispose() {
+ Iterator<Color> e = fColorTable.values().iterator();
+ while (e.hasNext())
+ ((Color) e.next()).dispose();
+ }
+
+ public Color getColor(RGB rgb) {
+ Color color = (Color) fColorTable.get(rgb);
+ if (color == null) {
+ color = new Color(Display.getCurrent(), rgb);
+ fColorTable.put(rgb, color);
+ }
+ return color;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/IXMLColorConstants.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/IXMLColorConstants.java
new file mode 100644
index 0000000..5e395e8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/IXMLColorConstants.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.swt.graphics.RGB;
+
+public interface IXMLColorConstants {
+ RGB XML_COMMENT = new RGB(128, 0, 0);
+ RGB PROC_INSTR = new RGB(128, 128, 128);
+ RGB STRING = new RGB(0, 128, 0);
+ RGB DEFAULT = new RGB(0, 0, 0);
+ RGB TAG = new RGB(0, 0, 128);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/NonRuleBasedDamagerRepairer.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/NonRuleBasedDamagerRepairer.java
new file mode 100644
index 0000000..f66249c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/NonRuleBasedDamagerRepairer.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.presentation.IPresentationDamager;
+import org.eclipse.jface.text.presentation.IPresentationRepairer;
+import org.eclipse.swt.custom.StyleRange;
+
+public class NonRuleBasedDamagerRepairer
+ implements IPresentationDamager, IPresentationRepairer {
+
+ /** The document this object works on */
+ protected IDocument fDocument;
+ /** The default text attribute if non is returned as data by the current token */
+ protected TextAttribute fDefaultTextAttribute;
+
+ /**
+ * Constructor for NonRuleBasedDamagerRepairer.
+ */
+ public NonRuleBasedDamagerRepairer(TextAttribute defaultTextAttribute) {
+ Assert.isNotNull(defaultTextAttribute);
+
+ fDefaultTextAttribute = defaultTextAttribute;
+ }
+
+ /**
+ * @see IPresentationRepairer#setDocument(IDocument)
+ */
+ public void setDocument(IDocument document) {
+ fDocument = document;
+ }
+
+ /**
+ * Returns the end offset of the line that contains the specified offset or
+ * if the offset is inside a line delimiter, the end offset of the next line.
+ *
+ * @param offset the offset whose line end offset must be computed
+ * @return the line end offset for the given offset
+ * @exception BadLocationException if offset is invalid in the current document
+ */
+ protected int endOfLineOf(int offset) throws BadLocationException {
+
+ IRegion info = fDocument.getLineInformationOfOffset(offset);
+ if (offset <= info.getOffset() + info.getLength())
+ return info.getOffset() + info.getLength();
+
+ int line = fDocument.getLineOfOffset(offset);
+ try {
+ info = fDocument.getLineInformation(line + 1);
+ return info.getOffset() + info.getLength();
+ } catch (BadLocationException x) {
+ return fDocument.getLength();
+ }
+ }
+
+ /**
+ * @see IPresentationDamager#getDamageRegion(ITypedRegion, DocumentEvent, boolean)
+ */
+ public IRegion getDamageRegion(
+ ITypedRegion partition,
+ DocumentEvent event,
+ boolean documentPartitioningChanged) {
+ if (!documentPartitioningChanged) {
+ try {
+
+ IRegion info =
+ fDocument.getLineInformationOfOffset(event.getOffset());
+ int start = Math.max(partition.getOffset(), info.getOffset());
+
+ int end =
+ event.getOffset()
+ + (event.getText() == null
+ ? event.getLength()
+ : event.getText().length());
+
+ if (info.getOffset() <= end
+ && end <= info.getOffset() + info.getLength()) {
+ // optimize the case of the same line
+ end = info.getOffset() + info.getLength();
+ } else
+ end = endOfLineOf(end);
+
+ end =
+ Math.min(
+ partition.getOffset() + partition.getLength(),
+ end);
+ return new Region(start, end - start);
+
+ } catch (BadLocationException x) {
+ }
+ }
+
+ return partition;
+ }
+
+ /**
+ * @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion)
+ */
+ public void createPresentation(
+ TextPresentation presentation,
+ ITypedRegion region) {
+ addRange(
+ presentation,
+ region.getOffset(),
+ region.getLength(),
+ fDefaultTextAttribute);
+ }
+
+ /**
+ * Adds style information to the given text presentation.
+ *
+ * @param presentation the text presentation to be extended
+ * @param offset the offset of the range to be styled
+ * @param length the length of the range to be styled
+ * @param attr the attribute describing the style of the range to be styled
+ */
+ protected void addRange(
+ TextPresentation presentation,
+ int offset,
+ int length,
+ TextAttribute attr) {
+ if (attr != null)
+ presentation.addStyleRange(
+ new StyleRange(
+ offset,
+ length,
+ attr.getForeground(),
+ attr.getBackground(),
+ attr.getStyle()));
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/TagRule.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/TagRule.java
new file mode 100644
index 0000000..eb850b9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/TagRule.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.MultiLineRule;
+
+public class TagRule extends MultiLineRule {
+
+ public TagRule(IToken token) {
+ super("<", ">", token);
+ }
+ protected boolean sequenceDetected(
+ ICharacterScanner scanner,
+ char[] sequence,
+ boolean eofAllowed) {
+ int c = scanner.read();
+ if (sequence[0] == '<') {
+ if (c == '?') {
+ // processing instruction - abort
+ scanner.unread();
+ return false;
+ }
+ if (c == '!') {
+ scanner.unread();
+ // comment - abort
+ return false;
+ }
+ } else if (sequence[0] == '>') {
+ scanner.unread();
+ }
+ return super.sequenceDetected(scanner, sequence, eofAllowed);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLConfiguration.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLConfiguration.java
new file mode 100644
index 0000000..3ed744c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLConfiguration.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+public class XMLConfiguration extends SourceViewerConfiguration {
+ private XMLDoubleClickStrategy doubleClickStrategy;
+ private XMLTagScanner tagScanner;
+ private XMLScanner scanner;
+ private ColorManager colorManager;
+
+ public XMLConfiguration(ColorManager colorManager) {
+ this.colorManager = colorManager;
+ }
+ public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+ return new String[] {
+ IDocument.DEFAULT_CONTENT_TYPE,
+ XMLPartitionScanner.XML_COMMENT,
+ XMLPartitionScanner.XML_TAG };
+ }
+ public ITextDoubleClickStrategy getDoubleClickStrategy(
+ ISourceViewer sourceViewer,
+ String contentType) {
+ if (doubleClickStrategy == null)
+ doubleClickStrategy = new XMLDoubleClickStrategy();
+ return doubleClickStrategy;
+ }
+
+ protected XMLScanner getXMLScanner() {
+ if (scanner == null) {
+ scanner = new XMLScanner(colorManager);
+ scanner.setDefaultReturnToken(
+ new Token(
+ new TextAttribute(
+ colorManager.getColor(IXMLColorConstants.DEFAULT))));
+ }
+ return scanner;
+ }
+ protected XMLTagScanner getXMLTagScanner() {
+ if (tagScanner == null) {
+ tagScanner = new XMLTagScanner(colorManager);
+ tagScanner.setDefaultReturnToken(
+ new Token(
+ new TextAttribute(
+ colorManager.getColor(IXMLColorConstants.TAG))));
+ }
+ return tagScanner;
+ }
+
+ public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+ PresentationReconciler reconciler = new PresentationReconciler();
+
+ DefaultDamagerRepairer dr =
+ new DefaultDamagerRepairer(getXMLTagScanner());
+ reconciler.setDamager(dr, XMLPartitionScanner.XML_TAG);
+ reconciler.setRepairer(dr, XMLPartitionScanner.XML_TAG);
+
+ dr = new DefaultDamagerRepairer(getXMLScanner());
+ reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+ NonRuleBasedDamagerRepairer ndr =
+ new NonRuleBasedDamagerRepairer(
+ new TextAttribute(
+ colorManager.getColor(IXMLColorConstants.XML_COMMENT)));
+ reconciler.setDamager(ndr, XMLPartitionScanner.XML_COMMENT);
+ reconciler.setRepairer(ndr, XMLPartitionScanner.XML_COMMENT);
+
+ return reconciler;
+ }
+
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLDoubleClickStrategy.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLDoubleClickStrategy.java
new file mode 100644
index 0000000..411b570
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLDoubleClickStrategy.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextViewer;
+
+public class XMLDoubleClickStrategy implements ITextDoubleClickStrategy {
+ protected ITextViewer fText;
+
+ public void doubleClicked(ITextViewer part) {
+ int pos = part.getSelectedRange().x;
+
+ if (pos < 0)
+ return;
+
+ fText = part;
+
+ if (!selectComment(pos)) {
+ selectWord(pos);
+ }
+ }
+ protected boolean selectComment(int caretPos) {
+ IDocument doc = fText.getDocument();
+ int startPos, endPos;
+
+ try {
+ int pos = caretPos;
+ char c = ' ';
+
+ while (pos >= 0) {
+ c = doc.getChar(pos);
+ if (c == '\\') {
+ pos -= 2;
+ continue;
+ }
+ if (c == Character.LINE_SEPARATOR || c == '\"')
+ break;
+ --pos;
+ }
+
+ if (c != '\"')
+ return false;
+
+ startPos = pos;
+
+ pos = caretPos;
+ int length = doc.getLength();
+ c = ' ';
+
+ while (pos < length) {
+ c = doc.getChar(pos);
+ if (c == Character.LINE_SEPARATOR || c == '\"')
+ break;
+ ++pos;
+ }
+ if (c != '\"')
+ return false;
+
+ endPos = pos;
+
+ int offset = startPos + 1;
+ int len = endPos - offset;
+ fText.setSelectedRange(offset, len);
+ return true;
+ } catch (BadLocationException x) {
+ }
+
+ return false;
+ }
+ protected boolean selectWord(int caretPos) {
+
+ IDocument doc = fText.getDocument();
+ int startPos, endPos;
+
+ try {
+
+ int pos = caretPos;
+ char c;
+
+ while (pos >= 0) {
+ c = doc.getChar(pos);
+ if (!Character.isJavaIdentifierPart(c))
+ break;
+ --pos;
+ }
+
+ startPos = pos;
+
+ pos = caretPos;
+ int length = doc.getLength();
+
+ while (pos < length) {
+ c = doc.getChar(pos);
+ if (!Character.isJavaIdentifierPart(c))
+ break;
+ ++pos;
+ }
+
+ endPos = pos;
+ selectRange(startPos, endPos);
+ return true;
+
+ } catch (BadLocationException x) {
+ }
+
+ return false;
+ }
+
+ private void selectRange(int startPos, int stopPos) {
+ int offset = startPos + 1;
+ int length = stopPos - offset;
+ fText.setSelectedRange(offset, length);
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLPartitionScanner.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLPartitionScanner.java
new file mode 100644
index 0000000..a82d923
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLPartitionScanner.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.jface.text.rules.IPredicateRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
+import org.eclipse.jface.text.rules.Token;
+
+public class XMLPartitionScanner extends RuleBasedPartitionScanner {
+ public final static String XML_COMMENT = "__xml_comment";
+ public final static String XML_TAG = "__xml_tag";
+
+ public XMLPartitionScanner() {
+
+ IToken xmlComment = new Token(XML_COMMENT);
+ IToken tag = new Token(XML_TAG);
+
+ IPredicateRule[] rules = new IPredicateRule[2];
+
+ rules[0] = new MultiLineRule("<!--", "-->", xmlComment);
+ rules[1] = new TagRule(tag);
+
+ setPredicateRules(rules);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLScanner.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLScanner.java
new file mode 100644
index 0000000..6e08811
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLScanner.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+
+public class XMLScanner extends RuleBasedScanner {
+
+ public XMLScanner(ColorManager manager) {
+ IToken procInstr =
+ new Token(
+ new TextAttribute(
+ manager.getColor(IXMLColorConstants.PROC_INSTR)));
+
+ IRule[] rules = new IRule[2];
+ //Add rule for processing instructions
+ rules[0] = new SingleLineRule("<?", "?>", procInstr);
+ // Add generic whitespace rule.
+ rules[1] = new WhitespaceRule(new XMLWhitespaceDetector());
+
+ setRules(rules);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLTagScanner.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLTagScanner.java
new file mode 100644
index 0000000..bbd7a0e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLTagScanner.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+
+public class XMLTagScanner extends RuleBasedScanner {
+
+ public XMLTagScanner(ColorManager manager) {
+ IToken string =
+ new Token(
+ new TextAttribute(manager.getColor(IXMLColorConstants.STRING)));
+
+ IRule[] rules = new IRule[3];
+
+ // Add rule for double quotes
+ rules[0] = new SingleLineRule("\"", "\"", string, '\\');
+ // Add a rule for single quotes
+ rules[1] = new SingleLineRule("'", "'", string, '\\');
+ // Add generic whitespace rule.
+ rules[2] = new WhitespaceRule(new XMLWhitespaceDetector());
+
+ setRules(rules);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLWhitespaceDetector.java b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLWhitespaceDetector.java
new file mode 100644
index 0000000..0bdd6ef
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/src/org/eclipse/e4/demo/simpleide/editor/text/xml/XMLWhitespaceDetector.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor.text.xml;
+
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+
+public class XMLWhitespaceDetector implements IWhitespaceDetector {
+
+ public boolean isWhitespace(char c) {
+ return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor.text/xmi/fragment.e4xmi b/examples/org.eclipse.e4.demo.simpleide.editor.text/xmi/fragment.e4xmi
new file mode 100644
index 0000000..b327453
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor.text/xmi/fragment.e4xmi
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmlns:simpleide="http://www.eclipse.org/e4/demo/simpleide" xmi:id="_jwyiYHieEd-X-LLzc-gFOA">
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_phxCgHieEd-X-LLzc-gFOA" featurename="editorPartDescriptors" parentElementId="app.simpleide">
+ <elements xsi:type="simpleide:EditorPartDescriptor" xmi:id="_7qZb0HieEd-ivry1rGVmOg" label="Text Editor" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.editor.text/icons/file_obj.gif" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.editor.text/org.eclipse.e4.demo.simpleide.editor.text.PlainTextEditor">
+ <fileextensions>txt</fileextensions>
+ </elements>
+ <elements xsi:type="simpleide:EditorPartDescriptor" xmi:id="_ILaFUHifEd-ivry1rGVmOg" label="XML Editor" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.editor.text/icons/elements_obj.gif" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.editor.text/org.eclipse.e4.demo.simpleide.editor.text.XMLTextEditor">
+ <fileextensions>xml</fileextensions>
+ </elements>
+ </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/.classpath b/examples/org.eclipse.e4.demo.simpleide.editor/.classpath
new file mode 100644
index 0000000..304e861
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/.project b/examples/org.eclipse.e4.demo.simpleide.editor/.project
new file mode 100644
index 0000000..2fd84c1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.simpleide.editor</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.editor/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..ba74073
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Fri May 14 19:08:27 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide.editor/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..861792a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:07:17 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.editor/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..48058cb
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/META-INF/MANIFEST.MF
@@ -0,0 +1,23 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.editor;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-ClassPath: .
+Bundle-Vendor: %providerName
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.emf.ecore;visibility:=reexport,
+ org.eclipse.e4.ui.model.workbench;visibility:=reexport,
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.e4.demo.simpleide.model;bundle-version="1.0.0",
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0",
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.1",
+ org.eclipse.jface.text;bundle-version="3.6.0",
+ org.eclipse.core.resources;bundle-version="3.6.0",
+ org.eclipse.e4.ui.services;bundle-version="0.9.1"
+Bundle-ActivationPolicy: lazy
+Import-Package: javax.inject;version="1.0.0",
+ org.eclipse.e4.core.contexts
+Export-Package: org.eclipse.e4.demo.simpleide.editor
+Service-Component: OSGI-INF/documentInputProviderFunction.xml
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/OSGI-INF/documentInputProviderFunction.xml b/examples/org.eclipse.e4.demo.simpleide.editor/OSGI-INF/documentInputProviderFunction.xml
new file mode 100644
index 0000000..7d30685
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/OSGI-INF/documentInputProviderFunction.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.e4.demo.simpleide.editor.documentInputProviderFunction">
+ <implementation class="org.eclipse.e4.demo.simpleide.editor.internal.IDocumentInputProviderFunction"/>
+ <service>
+ <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/>
+ </service>
+ <property name="service.context.key" type="String" value="org.eclipse.e4.demo.simpleide.editor.IDocumentInput"/>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/build.properties b/examples/org.eclipse.e4.demo.simpleide.editor/build.properties
new file mode 100644
index 0000000..186d187
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/build.properties
@@ -0,0 +1,8 @@
+bin.includes = .,\
+ META-INF/,\
+ OSGI-INF/documentInputProviderFunction.xml,\
+ plugin.xml,\
+ xmi/
+output.. = bin/
+jars.compile.order = .
+source.. = src/
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/plugin.xml b/examples/org.eclipse.e4.demo.simpleide.editor/plugin.xml
new file mode 100644
index 0000000..b39876c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ id="id2"
+ point="org.eclipse.e4.workbench.model">
+ <fragment
+ uri="xmi/fragment.e4xmi">
+ </fragment>
+ </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/IDocumentInput.java b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/IDocumentInput.java
new file mode 100644
index 0000000..a65e480
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/IDocumentInput.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor;
+
+import org.eclipse.jface.text.IDocument;
+
+public interface IDocumentInput extends IInput {
+ public IDocument getDocument();
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/IInput.java b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/IInput.java
new file mode 100644
index 0000000..9546d41
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/IInput.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.editor;
+
+import org.eclipse.core.runtime.IStatus;
+
+public interface IInput {
+ public static final String DIRTY = IInput.class.getName() + ".dirty";
+
+ public interface Listener {
+ public void propertyChanged(String property, Object oldValue, Object newValue);
+ }
+
+ public void addListener(Listener listener);
+ public void removeListener(Listener listener);
+
+ public IStatus save();
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/handler/OpenEditor.java b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/handler/OpenEditor.java
new file mode 100644
index 0000000..e812c1c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/handler/OpenEditor.java
@@ -0,0 +1,35 @@
+package org.eclipse.e4.demo.simpleide.editor.handler;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.ui.basic.MBasicFactory;
+import org.eclipse.e4.ui.model.application.ui.basic.MInputPart;
+import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
+import org.eclipse.e4.ui.workbench.modeling.EModelService;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
+import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;
+
+public class OpenEditor {
+
+ @Execute
+ public void open(
+ IFile file,
+ MApplication application,
+ MEditorPartDescriptor model,
+ EModelService modelService,
+ EPartService partService) {
+ MPartStack stack = (MPartStack) modelService.find("org.eclipse.e4.primaryDataStack", application);
+
+ MInputPart part = MBasicFactory.INSTANCE.createInputPart();
+ part.setContributionURI(model.getContributionURI());
+ part.setInputURI(file.getFullPath().toString());
+ part.setIconURI(model.getIconURI());
+ part.setLabel(file.getName());
+ part.setTooltip(file.getFullPath().toString());
+ part.setCloseable(true);
+ stack.getChildren().add(part);
+ partService.showPart(part, PartState.ACTIVATE);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/AbstractInput.java b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/AbstractInput.java
new file mode 100644
index 0000000..0bf71db
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/AbstractInput.java
@@ -0,0 +1,34 @@
+package org.eclipse.e4.demo.simpleide.editor.internal;
+
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.e4.demo.simpleide.editor.IInput;
+
+public abstract class AbstractInput implements IInput {
+ private ListenerList listeners = new ListenerList();
+ private boolean dirty = false;
+
+ public void addListener(Listener listener) {
+ listeners.add(listener);
+ }
+
+ public void removeListener(Listener listener) {
+ listeners.remove(listener);
+ }
+
+ private void fireDirtyChange(boolean oldValue, boolean newValue) {
+ this.dirty = newValue;
+ for( Object l : listeners.getListeners() ) {
+ ((Listener)l).propertyChanged(DIRTY, oldValue, newValue);
+ }
+ }
+
+ protected void setDirty(boolean dirty) {
+ if( dirty != this.dirty ) {
+ fireDirtyChange(this.dirty, this.dirty = dirty);
+ }
+ }
+
+ protected boolean isDirty() {
+ return dirty;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/FileDocumentInput.java b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/FileDocumentInput.java
new file mode 100644
index 0000000..93729c4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/FileDocumentInput.java
@@ -0,0 +1,144 @@
+package org.eclipse.e4.demo.simpleide.editor.internal;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.e4.demo.simpleide.editor.IDocumentInput;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+
+public class FileDocumentInput extends AbstractInput implements IDocumentInput {
+ private IFile file;
+ private IDocument document;
+
+ private static final int DEFAULT_FILE_SIZE = 15 * 1024;
+
+ public FileDocumentInput(IFile file) {
+ this.file = file;
+ }
+
+ public IStatus save() {
+ System.err.println("Starting save");
+
+ String encoding = null;
+ try {
+ encoding = file.getCharset();
+ } catch (Exception e) {
+ // TODO: handle exception
+ e.printStackTrace();
+ }
+
+ if (encoding == null)
+ encoding = "UTF-8";
+
+ Charset charset= Charset.forName(encoding);
+ CharsetEncoder encoder = charset.newEncoder();
+
+ byte[] bytes;
+ ByteBuffer byteBuffer;
+ try {
+ byteBuffer = encoder.encode(CharBuffer.wrap(document.get()));
+ if (byteBuffer.hasArray())
+ bytes= byteBuffer.array();
+ else {
+ bytes= new byte[byteBuffer.limit()];
+ byteBuffer.get(bytes);
+ }
+ ByteArrayInputStream stream= new ByteArrayInputStream(bytes, 0, byteBuffer.limit());
+
+ file.setContents(stream, true, true, null);
+ setDirty(false);
+
+ } catch (CharacterCodingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ System.err.println("Saving done");
+
+ return null;
+ }
+
+ public IDocument getDocument() {
+ if (document == null) {
+ Document document = new Document();
+ Reader in = null;
+
+ InputStream contentStream = null;
+ try {
+ contentStream = file.getContents();
+ } catch (CoreException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
+
+ if (contentStream == null) {
+ return null;
+ }
+
+ try {
+ String encoding = null;
+ try {
+ encoding = file.getCharset();
+ } catch (Exception e) {
+ // TODO: handle exception
+ e.printStackTrace();
+ }
+
+ if (encoding == null)
+ encoding = "UTF-8";
+
+ in = new BufferedReader(new InputStreamReader(contentStream,
+ encoding), DEFAULT_FILE_SIZE);
+ StringBuffer buffer = new StringBuffer(DEFAULT_FILE_SIZE);
+ char[] readBuffer = new char[2048];
+ int n = in.read(readBuffer);
+ while (n > 0) {
+ buffer.append(readBuffer, 0, n);
+ n = in.read(readBuffer);
+ }
+
+ document.set(buffer.toString());
+ this.document = document;
+ document.addDocumentListener(new IDocumentListener() {
+
+ public void documentChanged(DocumentEvent event) {
+ setDirty(true);
+ }
+
+ public void documentAboutToBeChanged(DocumentEvent event) {
+
+ }
+ });
+ } catch (IOException x) {
+ x.printStackTrace();
+ } finally {
+ try {
+ if (in != null)
+ in.close();
+ else
+ contentStream.close();
+ } catch (IOException x) {
+ }
+ }
+ }
+
+ return document;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/IDocumentInputProviderFunction.java b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/IDocumentInputProviderFunction.java
new file mode 100644
index 0000000..55f1c41
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/src/org/eclipse/e4/demo/simpleide/editor/internal/IDocumentInputProviderFunction.java
@@ -0,0 +1,37 @@
+package org.eclipse.e4.demo.simpleide.editor.internal;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.e4.core.contexts.ContextFunction;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.demo.simpleide.editor.IInput;
+import org.eclipse.e4.demo.simpleide.editor.IInput.Listener;
+import org.eclipse.e4.ui.model.application.ui.basic.MInputPart;
+
+public class IDocumentInputProviderFunction extends ContextFunction {
+
+ @Override
+ public Object compute(IEclipseContext context) {
+ final MInputPart inputPart = context.get(MInputPart.class);
+
+ IWorkspace workspace = context.get(IWorkspace.class);
+
+ String uri = inputPart.getInputURI();
+ Path p = new Path(uri);
+ IFile file = workspace.getRoot().getFile(p);
+ FileDocumentInput input = new FileDocumentInput(file);
+
+ input.addListener(new Listener() {
+
+ public void propertyChanged(String property, Object oldValue,
+ Object newValue) {
+ if( IInput.DIRTY == property ) {
+ inputPart.setDirty((Boolean)newValue);
+ }
+ }
+ });
+
+ return input;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.editor/xmi/fragment.e4xmi b/examples/org.eclipse.e4.demo.simpleide.editor/xmi/fragment.e4xmi
new file mode 100644
index 0000000..0422960
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.editor/xmi/fragment.e4xmi
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:commands="http://www.eclipse.org/ui/2010/UIModel/application/commands" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_tkhKcHiXEd-pEoU9D4-ITQ">
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_xOhvUHidEd-X-LLzc-gFOA" featurename="handlers" parentElementId="app.simpleide">
+ <elements xsi:type="commands:Handler" xmi:id="_CDBAMHieEd-X-LLzc-gFOA" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.editor/org.eclipse.e4.demo.simpleide.editor.handler.OpenEditor" command="_9a6zsHidEd-X-LLzc-gFOA"/>
+ </fragments>
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_2pDeUHidEd-X-LLzc-gFOA" featurename="commands" parentElementId="app.simpleide">
+ <elements xsi:type="commands:Command" xmi:id="_9a6zsHidEd-X-LLzc-gFOA" elementId="simpleide.command.openeditor" commandName="Open Editor"/>
+ </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/.classpath b/examples/org.eclipse.e4.demo.simpleide.iconview/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/.project b/examples/org.eclipse.e4.demo.simpleide.iconview/.project
new file mode 100644
index 0000000..20df9e3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.simpleide.iconview</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.iconview/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..8952d64
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Mon May 24 16:33:09 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide.iconview/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..d33d0a8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:07:37 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.iconview/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..ce8a3cf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/META-INF/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Iconview
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.iconview;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.core.resources;bundle-version="3.6.0",
+ org.eclipse.nebula.widgets.gallery;bundle-version="0.5.3",
+ org.eclipse.e4.ui.services;bundle-version="0.9.1",
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.jface.databinding;bundle-version="1.4.0",
+ org.eclipse.equinox.common;bundle-version="3.6.0",
+ org.eclipse.core.jobs;bundle-version="3.5.0",
+ org.eclipse.core.contenttype;bundle-version="3.4.100",
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.1"
+Import-Package: javax.annotation;version="1.0.0",
+ javax.inject;version="1.0.0"
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/build.properties b/examples/org.eclipse.e4.demo.simpleide.iconview/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/icons/folder_picture.png b/examples/org.eclipse.e4.demo.simpleide.iconview/icons/folder_picture.png
new file mode 100644
index 0000000..052b336
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/icons/folder_picture.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/plugin.xml b/examples/org.eclipse.e4.demo.simpleide.iconview/plugin.xml
new file mode 100644
index 0000000..91ea859
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ id="id1"
+ point="org.eclipse.e4.workbench.model">
+ <fragment
+ uri="xmi/fragment.e4xmi">
+ </fragment>
+ </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/src/org/eclipse/e4/demo/simpleide/iconview/CustomGalleryItemRenderer.java b/examples/org.eclipse.e4.demo.simpleide.iconview/src/org/eclipse/e4/demo/simpleide/iconview/CustomGalleryItemRenderer.java
new file mode 100644
index 0000000..43ee6bc
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/src/org/eclipse/e4/demo/simpleide/iconview/CustomGalleryItemRenderer.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.iconview;
+
+import org.eclipse.nebula.widgets.gallery.AbstractGalleryItemRenderer;
+import org.eclipse.nebula.widgets.gallery.GalleryItem;
+import org.eclipse.nebula.widgets.gallery.RendererHelper;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+
+
+public class CustomGalleryItemRenderer extends
+ AbstractGalleryItemRenderer {
+ @Override
+ public void draw(GC gc, GalleryItem item, int index, int x, int y,
+ int width, int height) {
+ Image image = item.getImage();
+ gc.setFont(item.getFont());
+
+ int padding = 5;
+
+ int maxWidth = width - padding * 2;
+ int maxHeight = height - padding * 2;
+
+ if( isSelected() ) {
+ Color bg = gc.getBackground();
+ gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_LIST_SELECTION));
+ gc.fillRoundRectangle(x, y, width, height, 5, 5);
+ gc.setBackground(bg);
+ }
+
+ int maxImageHeight = maxHeight - padding - gc.getFontMetrics().getHeight();
+
+ String text = RendererHelper.createLabel(item.getText(), gc, maxWidth);
+
+ int imageWidth = image.getBounds().width;
+ int imageHeight = image.getBounds().height;
+
+ Point imageSize;
+
+ if( imageWidth <= maxWidth && imageHeight <= maxImageHeight ) {
+ imageSize = new Point(imageWidth, imageHeight);
+ } else {
+ imageSize = RendererHelper.getBestSize(imageWidth, imageHeight, maxWidth, maxImageHeight);
+ }
+
+ int imageX = x + padding;
+ int imageY = y + padding;
+
+ if( imageSize.x < maxWidth ) {
+ imageX = x + width / 2 - imageSize.x / 2;
+ }
+
+ gc.drawImage(image, imageX, imageY);
+
+ int textX = x + padding;
+ int textY = y + padding + imageSize.y + padding;
+ Point textSize = gc.textExtent(text);
+
+ if( textSize.x < maxWidth ) {
+ textX = x + width / 2 - textSize.x / 2;
+ }
+
+ gc.drawText(text, textX, textY, true);
+ }
+
+ @Override
+ public void dispose() {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/src/org/eclipse/e4/demo/simpleide/iconview/IconView.java b/examples/org.eclipse.e4.demo.simpleide.iconview/src/org/eclipse/e4/demo/simpleide/iconview/IconView.java
new file mode 100644
index 0000000..d87c96c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/src/org/eclipse/e4/demo/simpleide/iconview/IconView.java
@@ -0,0 +1,311 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.iconview;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
+import org.eclipse.e4.ui.workbench.modeling.IPartListener;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.nebula.jface.galleryviewer.GalleryTreeViewer;
+import org.eclipse.nebula.widgets.gallery.NoGroupRenderer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+
+public class IconView {
+
+ private IResourceChangeListener resourceListener = new IResourceChangeListener() {
+ public void resourceChanged(IResourceChangeEvent event) {
+ if (event.getType() == IResourceChangeEvent.POST_CHANGE) {
+ try {
+ event.getDelta().accept(new IResourceDeltaVisitor() {
+ public boolean visit(IResourceDelta delta)
+ throws CoreException {
+ if (delta.getKind() == IResourceDelta.ADDED) {
+ handleChange(delta.getResource(), delta
+ .getResource().getParent(), true);
+ } else if (delta.getKind() == IResourceDelta.REMOVED) {
+ handleChange(delta.getResource(), delta
+ .getResource().getParent(), false);
+ }
+ return true;
+ }
+
+ private void handleChange(final IResource resource,
+ final IContainer parent, final boolean added) {
+ if (parent == container) {
+ if( visible ) {
+ if (added) {
+ isImageFile(resource);
+ viewer.add(null, resource);
+ } else {
+ viewer.remove(resource);
+ Image image = imageMap.remove(resource);
+ if (image != null) {
+ image.dispose();
+ }
+ }
+ } else {
+ needsupdate = true;
+ }
+ }
+ }
+ });
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ };
+
+ private ITreeContentProvider contentProvider = new ITreeContentProvider() {
+ private List<IResource> input = new ArrayList<IResource>();
+ private String root = "Elements";
+
+ @SuppressWarnings("unchecked")
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ this.input = (List<IResource>) newInput;
+ }
+
+ public void dispose() {
+
+ }
+
+ public boolean hasChildren(Object element) {
+ return root == element;
+ }
+
+ public Object getParent(Object element) {
+ return root;
+ }
+
+ public Object[] getElements(Object inputElement) {
+ return new Object [] {root};
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ return input.toArray();
+ }
+ };
+
+ private IPartListener partListener = new IPartListener() {
+
+ public void partVisible(MPart part) {
+ if( ! visible && part == IconView.this.part ) {
+ visible = true;
+ if( needsupdate ) {
+ refreshViewer();
+ }
+ }
+ }
+
+ public void partHidden(MPart part) {
+ visible = false;
+ }
+
+ public void partDeactivated(MPart part) {
+
+ }
+
+ public void partBroughtToTop(MPart part) {
+ if( ! visible && part == IconView.this.part ) {
+ visible = true;
+ if( needsupdate ) {
+ refreshViewer();
+ }
+ }
+ }
+
+ public void partActivated(MPart part) {
+ }
+ };
+
+ private GalleryTreeViewer viewer;
+ private IContainer container;
+ private IWorkspace workspace;
+ private boolean visible = true;
+ private boolean needsupdate = false;
+
+ private Map<IResource, Image> imageMap = new HashMap<IResource, Image>();
+
+ private MPart part;
+ private EPartService partService;
+
+ @Inject
+ public IconView(Composite composite, EPartService partService, MPart part, IWorkspace workspace) {
+ composite.setLayout(new FillLayout());
+ this.partService = partService;
+ this.part = part;
+ viewer = new GalleryTreeViewer(composite, SWT.MULTI | SWT.V_SCROLL);
+ viewer.getGallery().setItemRenderer(new CustomGalleryItemRenderer());
+ partService.addPartListener(partListener);
+
+ NoGroupRenderer renderer = new NoGroupRenderer();
+ renderer.setItemHeight(50);
+
+ viewer.getGallery().setGroupRenderer(renderer);
+ viewer.setContentProvider(contentProvider);
+
+ viewer.setLabelProvider(new LabelProvider() {
+ @Override
+ public Image getImage(Object element) {
+ if( element instanceof IFile ) {
+ Image image = imageMap.get(element);
+
+ if (image == null) {
+ image = loadImage((IFile) element);
+ imageMap.put((IResource) element, image);
+ }
+
+ return image;
+ }
+ return super.getImage(element);
+ }
+
+ @Override
+ public String getText(Object element) {
+ if( element instanceof IFile ) {
+ IFile resource = (IFile) element;
+ return resource.getName();
+ }
+ return super.getText(element);
+ }
+ });
+ this.workspace = workspace;
+ this.workspace.addResourceChangeListener(resourceListener);
+ }
+
+ private Image loadImage(final IFile file) {
+ InputStream contents;
+ try {
+ contents = file.getContents();
+ try {
+ ImageData imageData = new ImageData(contents);
+ Point size = getBestSize(imageData.width, imageData.height, 16,
+ 16);
+ ImageData scaled = imageData.scaledTo(size.x, size.y);
+ return new Image(viewer.getControl().getDisplay(), scaled);
+ } catch (Exception e) {
+ // TODO: handle exception
+ e.printStackTrace();
+ }
+ } catch (Exception e) {
+ // TODO: handle exception
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ private Point getBestSize(int originalX, int originalY, int maxX, int maxY) {
+ double widthRatio = (double) originalX / (double) maxX;
+ double heightRatio = (double) originalY / (double) maxY;
+
+ double bestRatio = widthRatio > heightRatio ? widthRatio : heightRatio;
+
+ int newWidth = (int) ((double) originalX / bestRatio);
+ int newHeight = (int) ((double) originalY / bestRatio);
+
+ return new Point(newWidth, newHeight);
+ }
+
+ @PreDestroy
+ void dispose() {
+ this.workspace.removeResourceChangeListener(resourceListener);
+ this.partService.removePartListener(partListener);
+ }
+
+ private boolean isImageFile(IResource resource) {
+ if (resource.getType() == IResource.FILE) {
+ IFile file = (IFile) resource;
+ String extension = file.getFileExtension();
+ if (extension != null
+ && ("png".equalsIgnoreCase(extension)
+ || "jpg".equalsIgnoreCase(extension) || "gif"
+ .equalsIgnoreCase(extension))) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Inject
+ void setFolder(
+ @Named(IServiceConstants.SELECTION) @Optional IContainer container) {
+ this.container = container;
+//FIXME Need to investigate if( visible ) {
+ refreshViewer();
+// } else {
+// needsupdate = true;
+// }
+ }
+
+ private void refreshViewer() {
+ Map<IResource, Image> imageMap = this.imageMap;
+ this.imageMap = new HashMap<IResource, Image>();
+
+ final List<IResource> input = new ArrayList<IResource>();
+ if (container != null) {
+ try {
+ container.accept(new IResourceVisitor() {
+
+ public boolean visit(IResource resource)
+ throws CoreException {
+ if (resource.equals(IconView.this.container)) {
+ return true;
+ } else if (isImageFile(resource)) {
+ input.add(resource);
+ }
+
+ return false;
+ }
+ });
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ viewer.setInput(input);
+
+ for (Image img : imageMap.values()) {
+ img.dispose();
+ }
+ needsupdate = false;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.iconview/xmi/fragment.e4xmi b/examples/org.eclipse.e4.demo.simpleide.iconview/xmi/fragment.e4xmi
new file mode 100644
index 0000000..4c36784
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.iconview/xmi/fragment.e4xmi
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/descriptor/basic" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_DxU0wHihEd-WTYrypQ0Yjg">
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_GGkN0HihEd-WTYrypQ0Yjg" featurename="descriptors" parentElementId="app.simpleide">
+ <elements xsi:type="basic:PartDescriptor" xmi:id="_W-aUsHihEd-1hY0DgxUB9A" label="Icon Folder View" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.iconview/icons/folder_picture.png" elementId="simpleide.descriptors.iconview" category="org.eclipse.e4.secondaryDataStack" closeable="true" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.iconview/org.eclipse.e4.demo.simpleide.iconview.IconView">
+ <tags>View</tags>
+ <tags>categoryTag:Utilities</tags>
+ </elements>
+ </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/.classpath b/examples/org.eclipse.e4.demo.simpleide.jdt/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/.project b/examples/org.eclipse.e4.demo.simpleide.jdt/.project
new file mode 100644
index 0000000..e2ea6f5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.simpleide.jdt</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.jdt/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..a43bb60
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sun May 16 13:44:52 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide.jdt/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..43a4b20
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:07:46 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.jdt/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..0039a4b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/META-INF/MANIFEST.MF
@@ -0,0 +1,27 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Jdt
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.jdt;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.ui.workbench;bundle-version="0.9.1",
+ org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.equinox.common;bundle-version="3.6.0",
+ org.eclipse.core.resources;bundle-version="3.6.0",
+ org.eclipse.jdt.core;bundle-version="3.6.0",
+ org.eclipse.core.runtime;bundle-version="3.6.0",
+ org.eclipse.e4.demo.simpleide.services;bundle-version="1.0.0",
+ org.eclipse.e4.core.services;bundle-version="0.9.1",
+ org.eclipse.e4.demo.simpleide.editor;bundle-version="1.0.0",
+ org.eclipse.jface.text;bundle-version="3.6.0",
+ org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.e4.demo.simpleide.model;bundle-version="1.0.0",
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.e4.demo.simpleide.outline;bundle-version="1.0.0",
+ org.eclipse.e4.ui.services;bundle-version="0.9.1",
+ org.eclipse.e4.ui.di;bundle-version="0.9.0"
+Import-Package: javax.annotation;version="1.0.0",
+ javax.inject;version="1.0.0",
+ org.eclipse.core.runtime.jobs
+Service-Component: OSGI-INF/jdtProjectService.xml
+Bundle-ActivationPolicy: lazy
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/OSGI-INF/jdtProjectService.xml b/examples/org.eclipse.e4.demo.simpleide.jdt/OSGI-INF/jdtProjectService.xml
new file mode 100644
index 0000000..75728fd
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/OSGI-INF/jdtProjectService.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.eclipse.e4.demo.simpleide.jdt.jdtProjectService">
+ <implementation class="org.eclipse.e4.demo.simpleide.jdt.internal.JDTProjectService"/>
+ <service>
+ <provide interface="org.eclipse.e4.demo.simpleide.services.IProjectService"/>
+ </service>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/build.properties b/examples/org.eclipse.e4.demo.simpleide.jdt/build.properties
new file mode 100644
index 0000000..96be7c8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/build.properties
@@ -0,0 +1,8 @@
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ OSGI-INF/jdtProjectService.xml,\
+ icons/,\
+ xmi/
+source.. = src/
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/annotation_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/annotation_obj.gif
new file mode 100644
index 0000000..435d62e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/annotation_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/class_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/class_obj.gif
new file mode 100644
index 0000000..e4c2a83
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/class_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/enum_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/enum_obj.gif
new file mode 100644
index 0000000..15535f5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/enum_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_alt_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_alt_obj.gif
new file mode 100644
index 0000000..f47bbfc
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_alt_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_default_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_default_obj.gif
new file mode 100644
index 0000000..9a88459
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_default_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_obj.gif
new file mode 100644
index 0000000..435d62e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_private_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_private_obj.gif
new file mode 100644
index 0000000..ac01dd2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_private_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_protected_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_protected_obj.gif
new file mode 100644
index 0000000..63c8abf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/annotation_protected_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cf_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cf_obj.gif
new file mode 100644
index 0000000..562d6d4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cf_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cf_src_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cf_src_obj.gif
new file mode 100644
index 0000000..dd2e028
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cf_src_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/class_default_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/class_default_obj.gif
new file mode 100644
index 0000000..4244a7f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/class_default_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/class_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/class_obj.gif
new file mode 100644
index 0000000..e4c2a83
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/class_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/classf_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/classf_obj.gif
new file mode 100644
index 0000000..365e372
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/classf_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/classfo_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/classfo_obj.gif
new file mode 100644
index 0000000..f1ee8cf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/classfo_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cprj_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cprj_obj.gif
new file mode 100755
index 0000000..6052a86
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/cprj_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/empty_pack_fldr_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/empty_pack_fldr_obj.gif
new file mode 100644
index 0000000..989b5bf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/empty_pack_fldr_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/empty_pack_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/empty_pack_obj.gif
new file mode 100644
index 0000000..c88284a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/empty_pack_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_alt_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_alt_obj.gif
new file mode 100644
index 0000000..f470d4c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_alt_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_default_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_default_obj.gif
new file mode 100644
index 0000000..e6f557b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_default_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_obj.gif
new file mode 100644
index 0000000..15535f5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_private_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_private_obj.gif
new file mode 100644
index 0000000..4d83959
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_private_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_protected_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_protected_obj.gif
new file mode 100644
index 0000000..834aa85
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/enum_protected_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_default_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_default_obj.gif
new file mode 100644
index 0000000..6929d3d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_default_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_private_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_private_obj.gif
new file mode 100644
index 0000000..1fe064e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_private_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_protected_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_protected_obj.gif
new file mode 100644
index 0000000..3377b1e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_protected_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_public_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_public_obj.gif
new file mode 100644
index 0000000..d4cb425
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/field_public_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/imp_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/imp_obj.gif
new file mode 100644
index 0000000..9e44ce5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/imp_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/impc_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/impc_obj.gif
new file mode 100644
index 0000000..ea94702
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/impc_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_default_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_default_obj.gif
new file mode 100644
index 0000000..4244a7f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_default_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_private_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_private_obj.gif
new file mode 100644
index 0000000..7392f19
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_private_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_protected_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_protected_obj.gif
new file mode 100644
index 0000000..5105577
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_protected_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_public_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_public_obj.gif
new file mode 100644
index 0000000..e4c2a83
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerclass_public_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_default_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_default_obj.gif
new file mode 100644
index 0000000..ab1b576
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_default_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_private_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_private_obj.gif
new file mode 100644
index 0000000..a1cbff3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_private_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_protected_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_protected_obj.gif
new file mode 100644
index 0000000..f58eef0
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_protected_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_public_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_public_obj.gif
new file mode 100644
index 0000000..2ebc46e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/innerinterface_public_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/int_default_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/int_default_obj.gif
new file mode 100644
index 0000000..ab1b576
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/int_default_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/int_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/int_obj.gif
new file mode 100644
index 0000000..2ebc46e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/int_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/intf_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/intf_obj.gif
new file mode 100644
index 0000000..7d7df9e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/intf_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_l_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_l_obj.gif
new file mode 100644
index 0000000..c026f01
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_l_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_lsrc_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_lsrc_obj.gif
new file mode 100644
index 0000000..3635997
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_lsrc_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_obj.gif
new file mode 100644
index 0000000..c026f01
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_src_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_src_obj.gif
new file mode 100644
index 0000000..3635997
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jar_src_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/java_model_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/java_model_obj.gif
new file mode 100644
index 0000000..8c8a7ea
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/java_model_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jcu_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jcu_obj.gif
new file mode 100644
index 0000000..200e5ed
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/jcu_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/localvariable_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/localvariable_obj.gif
new file mode 100644
index 0000000..8adce95
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/localvariable_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methdef_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methdef_obj.gif
new file mode 100644
index 0000000..f4a1ea1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methdef_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpri_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpri_obj.gif
new file mode 100644
index 0000000..2988716
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpri_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpro_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpro_obj.gif
new file mode 100644
index 0000000..563743d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpro_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpub_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpub_obj.gif
new file mode 100644
index 0000000..7d24707
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/methpub_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/package_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/package_obj.gif
new file mode 100644
index 0000000..131c28d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/package_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/packagefolder_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/packagefolder_obj.gif
new file mode 100644
index 0000000..fca9c53
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/packagefolder_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/packd_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/packd_obj.gif
new file mode 100644
index 0000000..2556b45
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/packd_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/prj_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/prj_obj.gif
new file mode 100755
index 0000000..a4ea580
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/prj_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/typevariable_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/typevariable_obj.gif
new file mode 100644
index 0000000..d4848c0
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/typevariable_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/unknown_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/unknown_obj.gif
new file mode 100644
index 0000000..7d988f9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/obj16/unknown_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/abstract_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/abstract_co.gif
new file mode 100644
index 0000000..533acc4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/abstract_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/constr_ovr.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/constr_ovr.gif
new file mode 100644
index 0000000..3977bc0
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/constr_ovr.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/deprecated.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/deprecated.gif
new file mode 100644
index 0000000..d03b6a9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/deprecated.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/error_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/error_co.gif
new file mode 100644
index 0000000..119dccc
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/error_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/final_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/final_co.gif
new file mode 100644
index 0000000..01c580d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/final_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/implm_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/implm_co.gif
new file mode 100644
index 0000000..7766c9d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/implm_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/over_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/over_co.gif
new file mode 100644
index 0000000..8533e2e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/over_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/run_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/run_co.gif
new file mode 100644
index 0000000..13077f9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/run_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/static_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/static_co.gif
new file mode 100644
index 0000000..499664d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/static_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/sync_impl.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/sync_impl.gif
new file mode 100644
index 0000000..2a0a385
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/sync_impl.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/sync_over.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/sync_over.gif
new file mode 100644
index 0000000..52c958a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/sync_over.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/synch_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/synch_co.gif
new file mode 100644
index 0000000..5893bda
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/synch_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/transient_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/transient_co.gif
new file mode 100644
index 0000000..2a386de
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/transient_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/volatile_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/volatile_co.gif
new file mode 100644
index 0000000..4345539
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/volatile_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/warning_co.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/warning_co.gif
new file mode 100644
index 0000000..ee2dac4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/full/ovr16/warning_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/int_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/int_obj.gif
new file mode 100644
index 0000000..2ebc46e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/int_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/jcu_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/jcu_obj.gif
new file mode 100644
index 0000000..200e5ed
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/jcu_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/newjprj_wiz.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/newjprj_wiz.gif
new file mode 100644
index 0000000..bc85aaf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/newjprj_wiz.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/class_default_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/class_default_obj.gif
new file mode 100644
index 0000000..4244a7f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/class_default_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/class_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/class_obj.gif
new file mode 100644
index 0000000..e4c2a83
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/class_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/imp_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/imp_obj.gif
new file mode 100644
index 0000000..9e44ce5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/imp_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/impc_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/impc_obj.gif
new file mode 100644
index 0000000..ea94702
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/impc_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methdef_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methdef_obj.gif
new file mode 100644
index 0000000..f4a1ea1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methdef_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpri_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpri_obj.gif
new file mode 100644
index 0000000..2988716
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpri_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpro_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpro_obj.gif
new file mode 100644
index 0000000..563743d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpro_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpub_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpub_obj.gif
new file mode 100644
index 0000000..7d24707
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/methpub_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/packd_obj.gif b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/packd_obj.gif
new file mode 100644
index 0000000..2556b45
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/outline/packd_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/icons/wizard/newjprj_wiz.png b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/wizard/newjprj_wiz.png
new file mode 100644
index 0000000..dcc8c15
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/icons/wizard/newjprj_wiz.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/plugin.xml b/examples/org.eclipse.e4.demo.simpleide.jdt/plugin.xml
new file mode 100644
index 0000000..91ea859
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ id="id1"
+ point="org.eclipse.e4.workbench.model">
+ <fragment
+ uri="xmi/fragment.e4xmi">
+ </fragment>
+ </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaAnnotationHandler.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaAnnotationHandler.java
new file mode 100644
index 0000000..67b973a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaAnnotationHandler.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.handlers;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+
+public class NewJavaAnnotationHandler {
+ @Execute
+ public void createFile() {
+
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaClassHandler.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaClassHandler.java
new file mode 100644
index 0000000..81d77dd
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaClassHandler.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.handlers;
+
+public class NewJavaClassHandler {
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaEnumHandler.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaEnumHandler.java
new file mode 100644
index 0000000..93cf96b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaEnumHandler.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.handlers;
+
+public class NewJavaEnumHandler {
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaInterfaceHandler.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaInterfaceHandler.java
new file mode 100644
index 0000000..1e0676c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/handlers/NewJavaInterfaceHandler.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.handlers;
+
+public class NewJavaInterfaceHandler {
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JDTImageServiceProvider.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JDTImageServiceProvider.java
new file mode 100644
index 0000000..68b23a3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JDTImageServiceProvider.java
@@ -0,0 +1,39 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.e4.demo.simpleide.services.AbstractBundleImageProvider;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+public class JDTImageServiceProvider extends AbstractBundleImageProvider {
+ private static final Bundle BUNDLE = FrameworkUtil.getBundle(JDTImageServiceProvider.class);
+ private static final String BUNDLE_NAME = BUNDLE.getSymbolicName();
+
+ public static final String IMG_PACKAGE_DECL = BUNDLE_NAME + ".IMG_PACKAGE_DECL";
+ public static final String IMG_IMPORTCONTAINER_DECL = BUNDLE_NAME + ".IMG_IMPORTCONTAINER_DECL";
+
+ private static final Map<String, String> IMAGEMAP = Collections.unmodifiableMap(new HashMap<String, String>() {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ {
+ put(JDTImageServiceProvider.IMG_PACKAGE_DECL, "/icons/outline/packd_obj.gif");
+ put(JDTImageServiceProvider.IMG_IMPORTCONTAINER_DECL, "/icons/impc_obj.gif");
+ }
+ });
+
+ @Override
+ protected Map<String, String> getImageMap() {
+ return IMAGEMAP;
+ }
+
+ @Override
+ protected Bundle getBundle(String imageKey) {
+ return BUNDLE;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JDTProjectService.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JDTProjectService.java
new file mode 100644
index 0000000..8c7a5d5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JDTProjectService.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.core.services.statusreporter.StatusReporter;
+import org.eclipse.e4.demo.simpleide.services.IProjectService;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.swt.widgets.Shell;
+import org.osgi.framework.FrameworkUtil;
+
+public class JDTProjectService implements IProjectService {
+
+ public String getIconURI() {
+ return "platform:/plugin/" + FrameworkUtil.getBundle(getClass()).getSymbolicName() +"/icons/newjprj_wiz.gif";
+ }
+
+ public String getLabel() {
+ return "Java Project";
+ }
+
+ public void createProject(Shell shell, IWorkspace workspace, StatusReporter statusReporter, Logger looger,
+ IProgressMonitor monitor, String projectName) {
+ final IProject project = workspace.getRoot().getProject(projectName);
+ final IProjectDescription pd = workspace
+ .newProjectDescription(projectName);
+ try {
+ workspace.run(new IWorkspaceRunnable() {
+
+ public void run(IProgressMonitor monitor) throws CoreException {
+ if (!project.exists()) {
+ project.create(pd, monitor);
+ JavaCore.create(project);
+ }
+
+ if (!project.isOpen()) {
+ project.open(monitor);
+ }
+ }
+
+ },monitor);
+ } catch (CoreException e) {
+ // TODO: handle exception
+ }
+
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JavaUIMessages.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JavaUIMessages.java
new file mode 100644
index 0000000..5b41ebd
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JavaUIMessages.java
@@ -0,0 +1,17 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal;
+
+public interface JavaUIMessages {
+
+ String JavaElementLabels_onClassPathOf(String string, String lastSegment);
+
+ String JavaElementLabels_category(String string);
+
+ String JavaElementLabels_anonym_type(String supertypeName);
+
+ String JavaElementLabels_anonym();
+
+ String JavaElementLabels_initializer();
+
+ String JavaElementLabels_import_container();
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JavaUIMessages.properties b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JavaUIMessages.properties
new file mode 100644
index 0000000..3cca25b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/JavaUIMessages.properties
@@ -0,0 +1,6 @@
+JavaElementLabels_onClassPathOf=\ (from {0} of {1})
+JavaElementLabels_category=[{0}]
+JavaElementLabels_anonym_type=new {0}() '{'...}
+JavaElementLabels_anonym=new Anonymous
+JavaElementLabels_initializer={...}
+JavaElementLabels_import_container=import declarations
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/IJDTSelection.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/IJDTSelection.java
new file mode 100644
index 0000000..963f71b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/IJDTSelection.java
@@ -0,0 +1,5 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor;
+
+public interface IJDTSelection {
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/JDTOutlinePage.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/JDTOutlinePage.java
new file mode 100644
index 0000000..20b1de2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/JDTOutlinePage.java
@@ -0,0 +1,269 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor;
+
+import java.util.Vector;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.demo.simpleide.jdt.internal.JavaUIMessages;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer.AppearanceAwareLabelProvider;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer.JavaElementLabels;
+import org.eclipse.e4.demo.simpleide.services.INLSLookupFactoryService;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IParent;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+
+public class JDTOutlinePage {
+ // // FIXME We should use image service and pooling
+ // private static Image PACKAGE_DECL;
+ // private static Image IMPORT_CONTAINER_DECL;
+ // private static Image IMPORT_DECL;
+ //
+ // private static Image PUBLIC_CLASS_DECL;
+ // private static Image PACKAGE_CLASS_DECL;
+ //
+ // private static Image PUBLIC_METHOD_DECL;
+ // private static Image PACKAGE_METHOD_DECL;
+ // private static Image PROTECTED_METHOD_DECL;
+ // private static Image PRIVATE_METHOD_DECL;
+
+ private class ContentProvider implements ITreeContentProvider {
+ private final Object[] EMPTY = new Object[0];
+
+ public void dispose() {
+
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+
+ }
+
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+
+ protected boolean matches(IJavaElement element) {
+ if (element.getElementType() == IJavaElement.METHOD) {
+ String name = element.getElementName();
+ return (name != null && name.indexOf('<') >= 0);
+ }
+ return false;
+ }
+
+ protected IJavaElement[] filter(IJavaElement[] children) {
+ boolean initializers = false;
+ for (int i = 0; i < children.length; i++) {
+ if (matches(children[i])) {
+ initializers = true;
+ break;
+ }
+ }
+
+ if (!initializers)
+ return children;
+
+ Vector<IJavaElement> v = new Vector<IJavaElement>();
+ for (int i = 0; i < children.length; i++) {
+ if (matches(children[i]))
+ continue;
+ v.addElement(children[i]);
+ }
+
+ IJavaElement[] result = new IJavaElement[v.size()];
+ v.copyInto(result);
+ return result;
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof IParent) {
+ IParent c = (IParent) parentElement;
+ try {
+ return filter(c.getChildren());
+ } catch (JavaModelException x) {
+
+ }
+ }
+ return EMPTY;
+ }
+
+ public Object getParent(Object element) {
+ if (element instanceof IJavaElement) {
+ IJavaElement e = (IJavaElement) element;
+ return e.getParent();
+ }
+ return null;
+ }
+
+ public boolean hasChildren(Object element) {
+ return getChildren(element).length > 0;
+ }
+ }
+
+ // private class LabelProviderImpl extends DelegatingStyledCellLabelProvider
+ // {
+ // public LabelProviderImpl() {
+ // super();
+ // // TODO Auto-generated constructor stub
+ // }
+ //
+ // @Override
+ // public void update(ViewerCell cell) {
+ // IJavaElement obj = (IJavaElement) cell.getElement();
+ // if (obj instanceof IAnnotation) {
+ // } else if (obj instanceof IImportContainer) {
+ // cell.setImage(IMPORT_CONTAINER_DECL);
+ // cell.setText("import declarations");
+ // } else if (obj instanceof IImportDeclaration) {
+ // cell.setImage(IMPORT_DECL);
+ // cell.setText(obj.getElementName());
+ // } else if (obj instanceof IPackageDeclaration) {
+ // cell.setImage(PACKAGE_DECL);
+ // cell.setText(obj.getElementName());
+ // } else if (obj instanceof IType) {
+ // IType type = (IType) obj;
+ // try {
+ // if (type.isLocal()) {
+ // cell.setText(type.toString());
+ // System.err.println(type);
+ // } else {
+ // int flags = type.getFlags();
+ // if (Flags.isInterface(flags)) {
+ //
+ // } else {
+ // if (Flags.isPublic(flags)) {
+ // cell.setImage(PUBLIC_CLASS_DECL);
+ // } else if (Flags.isPrivate(flags)) {
+ //
+ // } else if (Flags.isPackageDefault(flags)) {
+ // cell.setImage(PACKAGE_CLASS_DECL);
+ // }
+ // }
+ //
+ // cell.setText(obj.getElementName());
+ // }
+ // } catch (JavaModelException e) {
+ // // TODO Auto-generated catch block
+ // e.printStackTrace();
+ // }
+ // } else if (obj instanceof IMethod) {
+ // IMethod type = (IMethod) obj;
+ // try {
+ // int flags = type.getFlags();
+ //
+ // if (Flags.isPrivate(flags)) {
+ // cell.setImage(PRIVATE_METHOD_DECL);
+ // } else if (Flags.isPackageDefault(flags)) {
+ // cell.setImage(PACKAGE_CLASS_DECL);
+ // } else if (Flags.isProtected(flags)) {
+ // cell.setImage(PROTECTED_METHOD_DECL);
+ // } else {
+ // cell.setImage(PUBLIC_METHOD_DECL);
+ // }
+ // } catch (JavaModelException e) {
+ // // TODO Auto-generated catch block
+ // e.printStackTrace();
+ // }
+ // cell.setText(obj.getElementName());
+ // } else if (obj instanceof IField) {
+ // cell.setText(obj.getElementName());
+ // } else {
+ // cell.setText(obj.getClass().getName());
+ // }
+ //
+ // System.err.println(obj.getClass());
+ //
+ // super.update(cell);
+ // }
+ // }
+
+ @Inject
+ public JDTOutlinePage(Composite parent,
+ @Named(IServiceConstants.ACTIVE_PART) MPart part,
+ IWorkspace workspace, Logger logger,
+ INLSLookupFactoryService nlsFactory) {
+ // if (PACKAGE_DECL == null) {
+ // initImages(parent);
+ // }
+ parent.setLayout(new FillLayout());
+
+ JavaEditor editor = (JavaEditor) part.getObject();
+
+ // FIXME We need to cache this!
+ JavaUIMessages messages = nlsFactory
+ .createNLSLookup(JavaUIMessages.class);
+
+ final AppearanceAwareLabelProvider lprovider = new AppearanceAwareLabelProvider(
+ AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS
+ | JavaElementLabels.F_APP_TYPE_SIGNATURE
+ | JavaElementLabels.ALL_CATEGORY, AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS, logger, messages);
+
+ TreeViewer viewer = new TreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL);
+ viewer.setContentProvider(new ContentProvider());
+ viewer.setLabelProvider(new DelegatingStyledCellLabelProvider(lprovider));
+ viewer.setInput(editor.getCompilationUnit());
+ viewer.expandAll();
+ }
+
+ // private void initImages(Composite parent) {
+ // PACKAGE_DECL = new Image(parent.getDisplay(), getClass()
+ // .getClassLoader().getResourceAsStream(
+ // "/icons/outline/packd_obj.gif"));
+ // IMPORT_CONTAINER_DECL = new Image(parent.getDisplay(), getClass()
+ // .getClassLoader().getResourceAsStream(
+ // "/icons/outline/impc_obj.gif"));
+ // IMPORT_DECL = new Image(parent.getDisplay(), getClass()
+ // .getClassLoader().getResourceAsStream(
+ // "/icons/outline/imp_obj.gif"));
+ // PUBLIC_CLASS_DECL = new Image(parent.getDisplay(), getClass()
+ // .getClassLoader().getResourceAsStream(
+ // "/icons/outline/class_obj.gif"));
+ // PACKAGE_CLASS_DECL = new Image(parent.getDisplay(), getClass()
+ // .getClassLoader().getResourceAsStream(
+ // "/icons/outline/class_default_obj.gif"));
+ // PUBLIC_METHOD_DECL = new Image(parent.getDisplay(), getClass()
+ // .getClassLoader().getResourceAsStream(
+ // "/icons/outline/methpub_obj.gif"));
+ // PACKAGE_METHOD_DECL = new Image(parent.getDisplay(), getClass()
+ // .getClassLoader().getResourceAsStream(
+ // "/icons/outline/methdef_obj.gif"));
+ // PROTECTED_METHOD_DECL = new Image(parent.getDisplay(), getClass()
+ // .getClassLoader().getResourceAsStream(
+ // "/icons/outline/methpro_obj.gif"));
+ // PRIVATE_METHOD_DECL = new Image(parent.getDisplay(), getClass()
+ // .getClassLoader().getResourceAsStream(
+ // "/icons/outline/methpri_obj.gif"));
+ // }
+
+ @Inject
+ public void setSelection(
+ @Optional @Named(IServiceConstants.ACTIVE_SELECTION) IJDTSelection selection) {
+ if (selection != null) {
+ System.err.println("Updating to JavaSelection '" + selection + "'");
+ }
+ }
+
+ @PreDestroy
+ public void dispose() {
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/JavaEditor.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/JavaEditor.java
new file mode 100644
index 0000000..f0910ac
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/JavaEditor.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor;
+
+import javax.inject.Inject;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.e4.demo.simpleide.editor.IDocumentInput;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.IJavaColorConstants;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.IJavaPartitions;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.JavaSourceViewerConfiguration;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.JavaTextTools;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.PreferenceConstants;
+import org.eclipse.e4.demo.simpleide.outline.IOutlinePageProvider;
+import org.eclipse.e4.ui.di.Persist;
+import org.eclipse.e4.ui.model.application.ui.basic.MInputPart;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jface.preference.PreferenceStore;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.text.source.VerticalRuler;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.widgets.Composite;
+
+public class JavaEditor implements IOutlinePageProvider {
+ private static final int VERTICAL_RULER_WIDTH = 12;
+
+ private IDocumentInput input;
+
+ private static PreferenceStore store = new PreferenceStore();
+
+ static {
+ store.setDefault(IJavaColorConstants.JAVA_MULTI_LINE_COMMENT, "102,153,102"); // 669966
+
+ store.setDefault(IJavaColorConstants.JAVA_SINGLE_LINE_COMMENT, "102,153,102"); // 669966
+
+ store.setDefault(IJavaColorConstants.JAVA_STRING, "51,0,255"); // 3300FF
+
+ store.setDefault(IJavaColorConstants.JAVADOC_DEFAULT, "51,102,204"); // 3366CC
+
+ store.setDefault(IJavaColorConstants.JAVADOC_KEYWORD, "51,102,204");
+ store.setDefault(IJavaColorConstants.JAVADOC_KEYWORD+PreferenceConstants.EDITOR_BOLD_SUFFIX, true);
+
+ store.setDefault(IJavaColorConstants.JAVADOC_LINK, "255,0,255");
+
+ store.setDefault(IJavaColorConstants.JAVADOC_TAG, "255,255,0");
+
+ store.setDefault(IJavaColorConstants.TASK_TAG, "255,100,0");
+
+ store.setDefault(IJavaColorConstants.JAVA_KEYWORD, "153,51,102"); // 993366
+ store.setDefault(IJavaColorConstants.JAVA_KEYWORD+PreferenceConstants.EDITOR_BOLD_SUFFIX, true);
+
+ store.setDefault(IJavaColorConstants.JAVA_DEFAULT, "0,0,0");
+
+ store.setDefault(IJavaColorConstants.JAVA_KEYWORD_RETURN, "153,51,102"); // 993366
+ store.setDefault(IJavaColorConstants.JAVA_KEYWORD_RETURN+PreferenceConstants.EDITOR_BOLD_SUFFIX, true);
+
+ store.setDefault(IJavaColorConstants.JAVA_OPERATOR, "0,0,0");
+ store.setDefault(IJavaColorConstants.JAVA_BRACKET, "0,0,0");
+ }
+
+ private static final JavaTextTools textTools = new JavaTextTools(store, true);
+
+ private ICompilationUnit compilationUnit;
+
+ //TODO We should try to get access to the file through injection
+ private MPart part;
+ private IWorkspace workspace;
+
+ @Inject
+ public JavaEditor(Composite parent, IDocumentInput input, IWorkspace workspace, MPart part) {
+ this.input = input;
+ this.part = part;
+ this.workspace = workspace;
+ VerticalRuler verticalRuler = new VerticalRuler(VERTICAL_RULER_WIDTH);
+
+ int styles= SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION;
+ SourceViewer viewer = new SourceViewer(parent, verticalRuler, styles);
+
+ Font f = null;
+ if( ! JFaceResources.getFontRegistry().hasValueFor("JavaEditorFont") ) {
+ if( SWT.getPlatform().equals("carbon") || SWT.getPlatform().equals("cocoa") ) {
+ JFaceResources.getFontRegistry().put("JavaEditorFont", new FontData[] {new FontData("Monaco",11,SWT.NONE)});
+ }
+ }
+
+ f = JFaceResources.getFontRegistry().get("JavaEditorFont");
+ viewer.getTextWidget().setFont(f);
+
+ viewer.configure(new JavaSourceViewerConfiguration(textTools));
+ IDocument document = input.getDocument();
+
+ textTools.setupJavaDocumentPartitioner(document, IJavaPartitions.JAVA_PARTITIONING);
+ viewer.setDocument(document);
+ }
+
+ ICompilationUnit getCompilationUnit() {
+ if( compilationUnit == null ) {
+ String uri = ((MInputPart)part).getInputURI();
+ Path p = new Path(uri);
+ IFile file = workspace.getRoot().getFile(p);
+
+ compilationUnit = (ICompilationUnit) JavaCore.create(file);
+ }
+
+ return compilationUnit;
+ }
+
+ @Persist
+ public void save() {
+ System.err.println("Saving ...");
+ input.save();
+ }
+
+ public Class<?> getOutlineClass() {
+ return JDTOutlinePage.class;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/AbstractJavaScanner.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/AbstractJavaScanner.java
new file mode 100644
index 0000000..99c0a24
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/AbstractJavaScanner.java
@@ -0,0 +1,352 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.resource.StringConverter;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+
+/**
+ * Initialized with a color manager and a preference store, its subclasses are
+ * only responsible for providing a list of preference keys for based on which tokens
+ * are generated and to use this tokens to define the rules controlling this scanner.
+ * <p>
+ * This scanner stores the color defined by the color preference key into
+ * the color manager under the same key.
+ * </p>
+ * <p>
+ * Preference color key + {@link PreferenceConstants#EDITOR_BOLD_SUFFIX} are used
+ * to retrieve whether the token is rendered in bold.
+ * </p>
+ * <p>
+ * Preference color key + {@link PreferenceConstants#EDITOR_ITALIC_SUFFIX} are used
+ * to retrieve whether the token is rendered in italic.
+ * </p>
+ * <p>
+ * Preference color key + {@link PreferenceConstants#EDITOR_STRIKETHROUGH_SUFFIX} are used
+ * to retrieve whether the token is rendered in strikethrough.
+ * </p>
+ * <p>
+ * Preference color key + {@link PreferenceConstants#EDITOR_UNDERLINE_SUFFIX} are used
+ * to retrieve whether the token is rendered in underline.
+ * </p>
+ */
+public abstract class AbstractJavaScanner extends BufferedRuleBasedScanner {
+
+
+ private IColorManager fColorManager;
+ private IPreferenceStore fPreferenceStore;
+
+ private Map<String,Token> fTokenMap= new HashMap<String,Token>();
+ private String[] fPropertyNamesColor;
+ /**
+ * Preference keys for boolean preferences which are <code>true</code>,
+ * iff the corresponding token should be rendered bold.
+ */
+ private String[] fPropertyNamesBold;
+ /**
+ * Preference keys for boolean preferences which are <code>true</code>,
+ * iff the corresponding token should be rendered italic.
+ *
+ * @since 3.0
+ */
+ private String[] fPropertyNamesItalic;
+ /**
+ * Preference keys for boolean preferences which are <code>true</code>,
+ * iff the corresponding token should be rendered strikethrough.
+ *
+ * @since 3.1
+ */
+ private String[] fPropertyNamesStrikethrough;
+ /**
+ * Preference keys for boolean preferences which are <code>true</code>,
+ * iff the corresponding token should be rendered underline.
+ *
+ * @since 3.1
+ */
+ private String[] fPropertyNamesUnderline;
+
+
+ private boolean fNeedsLazyColorLoading;
+
+ /**
+ * Returns an array of preference keys which define the tokens
+ * used in the rules of this scanner.
+ * <p>
+ * The preference key is used access the color in the preference
+ * store and in the color manager.
+ * </p>
+ * <p>
+ * Preference key + {@link PreferenceConstants#EDITOR_BOLD_SUFFIX} is used
+ * to retrieve whether the token is rendered in bold.
+ * </p>
+ * <p>
+ * Preference key + {@link PreferenceConstants#EDITOR_ITALIC_SUFFIX} is used
+ * to retrieve whether the token is rendered in italic.
+ * </p>
+ * <p>
+ * Preference key + {@link PreferenceConstants#EDITOR_UNDERLINE_SUFFIX} is used
+ * to retrieve whether the token is rendered underlined.
+ * </p>
+ * <p>
+ * Preference key + {@link PreferenceConstants#EDITOR_STRIKETHROUGH_SUFFIX} is used
+ * to retrieve whether the token is rendered stricken out.
+ * </p>
+ */
+ abstract protected String[] getTokenProperties();
+
+ /**
+ * Creates the list of rules controlling this scanner.
+ */
+ abstract protected List<IRule> createRules();
+
+
+ /**
+ * Creates an abstract Java scanner.
+ */
+ public AbstractJavaScanner(IColorManager manager, IPreferenceStore store) {
+ super();
+ fColorManager= manager;
+ fPreferenceStore= store;
+ }
+
+ /**
+ * Must be called after the constructor has been called.
+ */
+ public final void initialize() {
+
+ fPropertyNamesColor= getTokenProperties();
+ int length= fPropertyNamesColor.length;
+ fPropertyNamesBold= new String[length];
+ fPropertyNamesItalic= new String[length];
+ fPropertyNamesStrikethrough= new String[length];
+ fPropertyNamesUnderline= new String[length];
+
+ for (int i= 0; i < length; i++) {
+ fPropertyNamesBold[i]= getBoldKey(fPropertyNamesColor[i]);
+ fPropertyNamesItalic[i]= getItalicKey(fPropertyNamesColor[i]);
+ fPropertyNamesStrikethrough[i]= getStrikethroughKey(fPropertyNamesColor[i]);
+ fPropertyNamesUnderline[i]= getUnderlineKey(fPropertyNamesColor[i]);
+ }
+
+ fNeedsLazyColorLoading= Display.getCurrent() == null;
+ for (int i= 0; i < length; i++) {
+ if (fNeedsLazyColorLoading)
+ addTokenWithProxyAttribute(fPropertyNamesColor[i], fPropertyNamesBold[i], fPropertyNamesItalic[i], fPropertyNamesStrikethrough[i], fPropertyNamesUnderline[i]);
+ else
+ addToken(fPropertyNamesColor[i], fPropertyNamesBold[i], fPropertyNamesItalic[i], fPropertyNamesStrikethrough[i], fPropertyNamesUnderline[i]);
+ }
+
+ initializeRules();
+ }
+
+ protected String getBoldKey(String colorKey) {
+ return colorKey + PreferenceConstants.EDITOR_BOLD_SUFFIX;
+ }
+
+ protected String getItalicKey(String colorKey) {
+ return colorKey + PreferenceConstants.EDITOR_ITALIC_SUFFIX;
+ }
+
+ protected String getStrikethroughKey(String colorKey) {
+ return colorKey + PreferenceConstants.EDITOR_STRIKETHROUGH_SUFFIX;
+ }
+
+ protected String getUnderlineKey(String colorKey) {
+ return colorKey + PreferenceConstants.EDITOR_UNDERLINE_SUFFIX;
+ }
+
+ public IToken nextToken() {
+ if (fNeedsLazyColorLoading)
+ resolveProxyAttributes();
+ return super.nextToken();
+ }
+
+ private void resolveProxyAttributes() {
+ if (fNeedsLazyColorLoading && Display.getCurrent() != null) {
+ for (int i= 0; i < fPropertyNamesColor.length; i++) {
+ addToken(fPropertyNamesColor[i], fPropertyNamesBold[i], fPropertyNamesItalic[i], fPropertyNamesStrikethrough[i], fPropertyNamesUnderline[i]);
+ }
+ fNeedsLazyColorLoading= false;
+ }
+ }
+
+ private void addTokenWithProxyAttribute(String colorKey, String boldKey, String italicKey, String strikethroughKey, String underlineKey) {
+ fTokenMap.put(colorKey, new Token(createTextAttribute(null, boldKey, italicKey, strikethroughKey, underlineKey)));
+ }
+
+ private void addToken(String colorKey, String boldKey, String italicKey, String strikethroughKey, String underlineKey) {
+ if (fColorManager != null && colorKey != null && fColorManager.getColor(colorKey) == null) {
+ RGB rgb= PreferenceConverter.getColor(fPreferenceStore, colorKey);
+ if (fColorManager instanceof IColorManagerExtension) {
+ IColorManagerExtension ext= (IColorManagerExtension) fColorManager;
+ ext.unbindColor(colorKey);
+ ext.bindColor(colorKey, rgb);
+ }
+ }
+
+ if (!fNeedsLazyColorLoading)
+ fTokenMap.put(colorKey, new Token(createTextAttribute(colorKey, boldKey, italicKey, strikethroughKey, underlineKey)));
+ else {
+ Token token= ((Token)fTokenMap.get(colorKey));
+ if (token != null)
+ token.setData(createTextAttribute(colorKey, boldKey, italicKey, strikethroughKey, underlineKey));
+ }
+ }
+
+ /**
+ * Create a text attribute based on the given color, bold, italic, strikethrough and underline preference keys.
+ *
+ * @param colorKey the color preference key
+ * @param boldKey the bold preference key
+ * @param italicKey the italic preference key
+ * @param strikethroughKey the strikethrough preference key
+ * @param underlineKey the italic preference key
+ * @return the created text attribute
+ * @since 3.0
+ */
+ private TextAttribute createTextAttribute(String colorKey, String boldKey, String italicKey, String strikethroughKey, String underlineKey) {
+ Color color= null;
+ if (colorKey != null)
+ color= fColorManager.getColor(colorKey);
+
+ int style= fPreferenceStore.getBoolean(boldKey) ? SWT.BOLD : SWT.NORMAL;
+ if (fPreferenceStore.getBoolean(italicKey))
+ style |= SWT.ITALIC;
+
+ if (fPreferenceStore.getBoolean(strikethroughKey))
+ style |= TextAttribute.STRIKETHROUGH;
+
+ if (fPreferenceStore.getBoolean(underlineKey))
+ style |= TextAttribute.UNDERLINE;
+
+ return new TextAttribute(color, null, style);
+ }
+
+ protected Token getToken(String key) {
+ if (fNeedsLazyColorLoading)
+ resolveProxyAttributes();
+ return (Token) fTokenMap.get(key);
+ }
+
+ private void initializeRules() {
+ List<IRule> rules= createRules();
+ if (rules != null) {
+ IRule[] result= new IRule[rules.size()];
+ rules.toArray(result);
+ setRules(result);
+ }
+ }
+
+ private int indexOf(String property) {
+ if (property != null) {
+ int length= fPropertyNamesColor.length;
+ for (int i= 0; i < length; i++) {
+ if (property.equals(fPropertyNamesColor[i]) || property.equals(fPropertyNamesBold[i]) || property.equals(fPropertyNamesItalic[i]) || property.equals(fPropertyNamesStrikethrough[i]) || property.equals(fPropertyNamesUnderline[i]))
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public boolean affectsBehavior(PropertyChangeEvent event) {
+ return indexOf(event.getProperty()) >= 0;
+ }
+
+ public void adaptToPreferenceChange(PropertyChangeEvent event) {
+ String p= event.getProperty();
+ int index= indexOf(p);
+ Token token= getToken(fPropertyNamesColor[index]);
+ if (fPropertyNamesColor[index].equals(p))
+ adaptToColorChange(token, event);
+ else if (fPropertyNamesBold[index].equals(p))
+ adaptToStyleChange(token, event, SWT.BOLD);
+ else if (fPropertyNamesItalic[index].equals(p))
+ adaptToStyleChange(token, event, SWT.ITALIC);
+ else if (fPropertyNamesStrikethrough[index].equals(p))
+ adaptToStyleChange(token, event, TextAttribute.STRIKETHROUGH);
+ else if (fPropertyNamesUnderline[index].equals(p))
+ adaptToStyleChange(token, event, TextAttribute.UNDERLINE);
+ }
+
+ private void adaptToColorChange(Token token, PropertyChangeEvent event) {
+ RGB rgb= null;
+
+ Object value= event.getNewValue();
+ if (value instanceof RGB)
+ rgb= (RGB) value;
+ else if (value instanceof String)
+ rgb= StringConverter.asRGB((String) value);
+
+ if (rgb != null) {
+
+ String property= event.getProperty();
+ Color color= fColorManager.getColor(property);
+
+ if ((color == null || !rgb.equals(color.getRGB())) && fColorManager instanceof IColorManagerExtension) {
+ IColorManagerExtension ext= (IColorManagerExtension) fColorManager;
+
+ ext.unbindColor(property);
+ ext.bindColor(property, rgb);
+
+ color= fColorManager.getColor(property);
+ }
+
+ Object data= token.getData();
+ if (data instanceof TextAttribute) {
+ TextAttribute oldAttr= (TextAttribute) data;
+ token.setData(new TextAttribute(color, oldAttr.getBackground(), oldAttr.getStyle()));
+ }
+ }
+ }
+
+ private void adaptToStyleChange(Token token, PropertyChangeEvent event, int styleAttribute) {
+ boolean eventValue= false;
+ Object value= event.getNewValue();
+ if (value instanceof Boolean)
+ eventValue= ((Boolean) value).booleanValue();
+ else if (IPreferenceStore.TRUE.equals(value))
+ eventValue= true;
+
+ Object data= token.getData();
+ if (data instanceof TextAttribute) {
+ TextAttribute oldAttr= (TextAttribute) data;
+ boolean activeValue= (oldAttr.getStyle() & styleAttribute) == styleAttribute;
+ if (activeValue != eventValue)
+ token.setData(new TextAttribute(oldAttr.getForeground(), oldAttr.getBackground(), eventValue ? oldAttr.getStyle() | styleAttribute : oldAttr.getStyle() & ~styleAttribute));
+ }
+ }
+ /**
+ * Returns the preference store.
+ *
+ * @return the preference store.
+ *
+ * @since 3.0
+ */
+ protected IPreferenceStore getPreferenceStore() {
+ return fPreferenceStore;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/BufferedDocumentScanner.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/BufferedDocumentScanner.java
new file mode 100644
index 0000000..920bccd
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/BufferedDocumentScanner.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+
+
+/**
+ * A buffered document scanner. The buffer always contains a section
+ * of a fixed size of the document to be scanned.
+ */
+
+public final class BufferedDocumentScanner implements ICharacterScanner {
+
+ /** The document being scanned. */
+ private IDocument fDocument;
+ /** The offset of the document range to scan. */
+ private int fRangeOffset;
+ /** The length of the document range to scan. */
+ private int fRangeLength;
+ /** The delimiters of the document. */
+ private char[][] fDelimiters;
+
+ /** The buffer. */
+ private final char[] fBuffer;
+ /** The offset of the buffer within the document. */
+ private int fBufferOffset;
+ /** The valid length of the buffer for access. */
+ private int fBufferLength;
+ /** The offset of the scanner within the buffer. */
+ private int fOffset;
+
+
+ /**
+ * Creates a new buffered document scanner.
+ * The buffer size is set to the given number of characters.
+ *
+ * @param size the buffer size
+ */
+ public BufferedDocumentScanner(int size) {
+ Assert.isTrue(size >= 1);
+ fBuffer= new char[size];
+ }
+
+ /**
+ * Fills the buffer with the contents of the document starting at the given offset.
+ *
+ * @param offset the document offset at which the buffer starts
+ */
+ private final void updateBuffer(int offset) {
+
+ fBufferOffset= offset;
+
+ if (fBufferOffset + fBuffer.length > fRangeOffset + fRangeLength)
+ fBufferLength= fRangeLength - (fBufferOffset - fRangeOffset);
+ else
+ fBufferLength= fBuffer.length;
+
+ try {
+ final String content= fDocument.get(fBufferOffset, fBufferLength);
+ content.getChars(0, fBufferLength, fBuffer, 0);
+ } catch (BadLocationException e) {
+ }
+ }
+
+ /**
+ * Configures the scanner by providing access to the document range over which to scan.
+ *
+ * @param document the document to scan
+ * @param offset the offset of the document range to scan
+ * @param length the length of the document range to scan
+ */
+ public final void setRange(IDocument document, int offset, int length) {
+
+ fDocument= document;
+ fRangeOffset= offset;
+ fRangeLength= length;
+
+ String[] delimiters= document.getLegalLineDelimiters();
+ fDelimiters= new char[delimiters.length][];
+ for (int i= 0; i < delimiters.length; i++)
+ fDelimiters[i]= delimiters[i].toCharArray();
+
+ updateBuffer(offset);
+ fOffset= 0;
+ }
+
+ /*
+ * @see ICharacterScanner#read()
+ */
+ public final int read() {
+
+ if (fOffset == fBufferLength) {
+ int end= fBufferOffset + fBufferLength;
+ if (end == fDocument.getLength() || end == fRangeOffset + fRangeLength)
+ return EOF;
+ else {
+ updateBuffer(fBufferOffset + fBufferLength);
+ fOffset= 0;
+ }
+ }
+
+ try {
+ return fBuffer[fOffset++];
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ StringBuffer buf= new StringBuffer();
+ buf.append("Detailed state of 'BufferedDocumentScanner:'"); //$NON-NLS-1$
+ buf.append("\n\tfOffset= "); //$NON-NLS-1$
+ buf.append(fOffset);
+ buf.append("\n\tfBufferOffset= "); //$NON-NLS-1$
+ buf.append(fBufferOffset);
+ buf.append("\n\tfBufferLength= "); //$NON-NLS-1$
+ buf.append(fBufferLength);
+ buf.append("\n\tfRangeOffset= "); //$NON-NLS-1$
+ buf.append(fRangeOffset);
+ buf.append("\n\tfRangeLength= "); //$NON-NLS-1$
+ buf.append(fRangeLength);
+ System.err.println(buf.toString()); //FIXME Logging
+// JavaPlugin.logErrorMessage(buf.toString());
+ throw ex;
+ }
+ }
+
+ /*
+ * @see ICharacterScanner#unread
+ */
+ public final void unread() {
+
+ if (fOffset == 0) {
+ if (fBufferOffset == fRangeOffset) {
+ // error: BOF
+ } else {
+ updateBuffer(fBufferOffset - fBuffer.length);
+ fOffset= fBuffer.length - 1;
+ }
+ } else {
+ --fOffset;
+ }
+ }
+
+ /*
+ * @see ICharacterScanner#getColumn()
+ */
+ public final int getColumn() {
+
+ try {
+ final int offset= fBufferOffset + fOffset;
+ final int line= fDocument.getLineOfOffset(offset);
+ final int start= fDocument.getLineOffset(line);
+ return offset - start;
+ } catch (BadLocationException e) {
+ }
+
+ return -1;
+ }
+
+ /*
+ * @see ICharacterScanner#getLegalLineDelimiters()
+ */
+ public final char[][] getLegalLineDelimiters() {
+ return fDelimiters;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/CombinedWordRule.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/CombinedWordRule.java
new file mode 100644
index 0000000..c497498
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/CombinedWordRule.java
@@ -0,0 +1,370 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.Token;
+
+
+/**
+ * An implementation of <code>IRule</code> capable of detecting words.
+ * <p>
+ * Word rules also allow for the association of tokens with specific words.
+ * That is, not only can the rule be used to provide tokens for exact matches,
+ * but also for the generalized notion of a word in the context in which it is used.
+ * A word rules uses a word detector to determine what a word is.</p>
+ * <p>
+ * This word rule allows a word detector to be shared among different word matchers.
+ * Its up to the word matchers to decide if a word matches and, in this a case, which
+ * token is associated with that word.
+ * </p>
+ *
+ * @see IWordDetector
+ * @since 3.0
+ */
+public class CombinedWordRule implements IRule {
+
+ /**
+ * Word matcher, that associates matched words with tokens.
+ */
+ public static class WordMatcher {
+
+ /** The table of predefined words and token for this matcher */
+ private Map<CharacterBuffer,IToken> fWords= new HashMap<CharacterBuffer,IToken>();
+
+ /**
+ * Adds a word and the token to be returned if it is detected.
+ *
+ * @param word the word this rule will search for, may not be <code>null</code>
+ * @param token the token to be returned if the word has been found, may not be <code>null</code>
+ */
+ public void addWord(String word, IToken token) {
+ Assert.isNotNull(word);
+ Assert.isNotNull(token);
+
+ fWords.put(new CharacterBuffer(word), token);
+ }
+
+ /**
+ * Returns the token associated to the given word and the scanner state.
+ *
+ * @param scanner the scanner
+ * @param word the word
+ * @return the token or <code>null</code> if none is associated by this matcher
+ */
+ public IToken evaluate(ICharacterScanner scanner, CharacterBuffer word) {
+ IToken token= (IToken) fWords.get(word);
+ if (token != null)
+ return token;
+ return Token.UNDEFINED;
+ }
+
+ /**
+ * Removes all words.
+ */
+ public void clearWords() {
+ fWords.clear();
+ }
+ }
+
+ /**
+ * Character buffer, mutable <b>or</b> suitable for use as key in hash maps.
+ */
+ public static class CharacterBuffer {
+
+ /** Buffer content */
+ private char[] fContent;
+ /** Buffer content size */
+ private int fLength= 0;
+
+ /** Is hash code cached? */
+ private boolean fIsHashCached= false;
+ /** The hash code */
+ private int fHashCode;
+
+ /**
+ * Initialize with the given capacity.
+ *
+ * @param capacity the initial capacity
+ */
+ public CharacterBuffer(int capacity) {
+ fContent= new char[capacity];
+ }
+
+ /**
+ * Initialize with the given content.
+ *
+ * @param content the initial content
+ */
+ public CharacterBuffer(String content) {
+ fContent= content.toCharArray();
+ fLength= content.length();
+ }
+
+ /**
+ * Empties this buffer.
+ */
+ public void clear() {
+ fIsHashCached= false;
+ fLength= 0;
+ }
+
+ /**
+ * Appends the given character to the buffer.
+ *
+ * @param c the character
+ */
+ public void append(char c) {
+ fIsHashCached= false;
+ if (fLength == fContent.length) {
+ char[] old= fContent;
+ fContent= new char[old.length << 1];
+ System.arraycopy(old, 0, fContent, 0, old.length);
+ }
+ fContent[fLength++]= c;
+ }
+
+ /**
+ * Returns the length of the content.
+ *
+ * @return the length
+ */
+ public int length() {
+ return fLength;
+ }
+
+ /**
+ * Returns the content as string.
+ *
+ * @return the content
+ */
+ public String toString() {
+ return new String(fContent, 0, fLength);
+ }
+
+ /**
+ * Returns the character at the given position.
+ *
+ * @param i the position
+ * @return the character at position <code>i</code>
+ */
+ public char charAt(int i) {
+ return fContent[i];
+ }
+
+ /*
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ if (fIsHashCached)
+ return fHashCode;
+
+ int hash= 0;
+ for (int i= 0, n= fLength; i < n; i++)
+ hash= 29*hash + fContent[i];
+ fHashCode= hash;
+ fIsHashCached= true;
+ return hash;
+ }
+
+
+ /*
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ if (obj == this)
+ return true;
+ if (!(obj instanceof CharacterBuffer))
+ return false;
+ CharacterBuffer buffer= (CharacterBuffer) obj;
+ int length= buffer.length();
+ if (length != fLength)
+ return false;
+ for (int i= 0; i < length; i++)
+ if (buffer.charAt(i) != fContent[i])
+ return false;
+ return true;
+ }
+
+ /**
+ * Is the content equal to the given string?
+ *
+ * @param string the string
+ * @return <code>true</code> iff the content is the same character sequence as in the string
+ */
+ public boolean equals(String string) {
+ int length= string.length();
+ if (length != fLength)
+ return false;
+ for (int i= 0; i < length; i++)
+ if (string.charAt(i) != fContent[i])
+ return false;
+ return true;
+ }
+ }
+
+ /** Internal setting for the uninitialized column constraint */
+ private static final int UNDEFINED= -1;
+
+ /** The word detector used by this rule */
+ private IWordDetector fDetector;
+ /** The default token to be returned on success and if nothing else has been specified. */
+ private IToken fDefaultToken;
+ /** The column constraint */
+ private int fColumn= UNDEFINED;
+ /** Buffer used for pattern detection */
+ private CharacterBuffer fBuffer= new CharacterBuffer(16);
+
+ /** List of word matchers */
+ private List<WordMatcher> fMatchers= new ArrayList<WordMatcher>();
+
+ /**
+ * Creates a rule which, with the help of an word detector, will return the token
+ * associated with the detected word. If no token has been associated, the scanner
+ * will be rolled back and an undefined token will be returned in order to allow
+ * any subsequent rules to analyze the characters.
+ *
+ * @param detector the word detector to be used by this rule, may not be <code>null</code>
+ *
+ * @see WordMatcher#addWord(String, IToken)
+ */
+ public CombinedWordRule(IWordDetector detector) {
+ this(detector, null, Token.UNDEFINED);
+ }
+
+ /**
+ * Creates a rule which, with the help of an word detector, will return the token
+ * associated with the detected word. If no token has been associated, the
+ * specified default token will be returned.
+ *
+ * @param detector the word detector to be used by this rule, may not be <code>null</code>
+ * @param defaultToken the default token to be returned on success
+ * if nothing else is specified, may not be <code>null</code>
+ *
+ * @see WordMatcher#addWord(String, IToken)
+ */
+ public CombinedWordRule(IWordDetector detector, IToken defaultToken) {
+ this(detector, null, defaultToken);
+ }
+
+ /**
+ * Creates a rule which, with the help of an word detector, will return the token
+ * associated with the detected word. If no token has been associated, the scanner
+ * will be rolled back and an undefined token will be returned in order to allow
+ * any subsequent rules to analyze the characters.
+ *
+ * @param detector the word detector to be used by this rule, may not be <code>null</code>
+ * @param matcher the initial word matcher
+ *
+ * @see WordMatcher#addWord(String, IToken)
+ */
+ public CombinedWordRule(IWordDetector detector, WordMatcher matcher) {
+ this(detector, matcher, Token.UNDEFINED);
+ }
+
+ /**
+ * Creates a rule which, with the help of an word detector, will return the token
+ * associated with the detected word. If no token has been associated, the
+ * specified default token will be returned.
+ *
+ * @param detector the word detector to be used by this rule, may not be <code>null</code>
+ * @param matcher the initial word matcher
+ * @param defaultToken the default token to be returned on success
+ * if nothing else is specified, may not be <code>null</code>
+ *
+ * @see WordMatcher#addWord(String, IToken)
+ */
+ public CombinedWordRule(IWordDetector detector, WordMatcher matcher, IToken defaultToken) {
+
+ Assert.isNotNull(detector);
+ Assert.isNotNull(defaultToken);
+
+ fDetector= detector;
+ fDefaultToken= defaultToken;
+ if (matcher != null)
+ addWordMatcher(matcher);
+ }
+
+
+ /**
+ * Adds the given matcher.
+ *
+ * @param matcher the matcher
+ */
+ public void addWordMatcher(WordMatcher matcher) {
+ fMatchers.add(matcher);
+ }
+
+ /**
+ * Sets a column constraint for this rule. If set, the rule's token
+ * will only be returned if the pattern is detected starting at the
+ * specified column. If the column is smaller then 0, the column
+ * constraint is considered removed.
+ *
+ * @param column the column in which the pattern starts
+ */
+ public void setColumnConstraint(int column) {
+ if (column < 0)
+ column= UNDEFINED;
+ fColumn= column;
+ }
+
+ /*
+ * @see IRule#evaluate(ICharacterScanner)
+ */
+ public IToken evaluate(ICharacterScanner scanner) {
+ int c= scanner.read();
+ if (fDetector.isWordStart((char) c)) {
+ if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) {
+
+ fBuffer.clear();
+ do {
+ fBuffer.append((char) c);
+ c= scanner.read();
+ } while (c != ICharacterScanner.EOF && fDetector.isWordPart((char) c));
+ scanner.unread();
+
+ for (int i= 0, n= fMatchers.size(); i < n; i++) {
+ IToken token= ((WordMatcher) fMatchers.get(i)).evaluate(scanner, fBuffer);
+ if (!token.isUndefined())
+ return token;
+ }
+
+ if (fDefaultToken.isUndefined())
+ unreadBuffer(scanner);
+
+ return fDefaultToken;
+ }
+ }
+
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+
+ /**
+ * Returns the characters in the buffer to the scanner.
+ *
+ * @param scanner the scanner to be used
+ */
+ private void unreadBuffer(ICharacterScanner scanner) {
+ for (int i= fBuffer.length() - 1; i >= 0; i--)
+ scanner.unread();
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/FastJavaPartitionScanner.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/FastJavaPartitionScanner.java
new file mode 100644
index 0000000..e0617a1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/FastJavaPartitionScanner.java
@@ -0,0 +1,533 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+
+/**
+ * This scanner recognizes the JavaDoc comments, Java multi line comments, Java single line comments,
+ * Java strings and Java characters.
+ */
+public class FastJavaPartitionScanner implements IPartitionTokenScanner, IJavaPartitions {
+
+ // states
+ private static final int JAVA= 0;
+ private static final int SINGLE_LINE_COMMENT= 1;
+ private static final int MULTI_LINE_COMMENT= 2;
+ private static final int JAVADOC= 3;
+ private static final int CHARACTER= 4;
+ private static final int STRING= 5;
+
+ // beginning of prefixes and postfixes
+ private static final int NONE= 0;
+ private static final int BACKSLASH= 1; // postfix for STRING and CHARACTER
+ private static final int SLASH= 2; // prefix for SINGLE_LINE or MULTI_LINE or JAVADOC
+ private static final int SLASH_STAR= 3; // prefix for MULTI_LINE_COMMENT or JAVADOC
+ private static final int SLASH_STAR_STAR= 4; // prefix for MULTI_LINE_COMMENT or JAVADOC
+ private static final int STAR= 5; // postfix for MULTI_LINE_COMMENT or JAVADOC
+ private static final int CARRIAGE_RETURN=6; // postfix for STRING, CHARACTER and SINGLE_LINE_COMMENT
+
+ /** The scanner. */
+ private final BufferedDocumentScanner fScanner= new BufferedDocumentScanner(1000); // faster implementation
+
+ /** The offset of the last returned token. */
+ private int fTokenOffset;
+ /** The length of the last returned token. */
+ private int fTokenLength;
+
+ /** The state of the scanner. */
+ private int fState;
+ /** The last significant characters read. */
+ private int fLast;
+ /** The amount of characters already read on first call to nextToken(). */
+ private int fPrefixLength;
+
+ // emulate JavaPartitionScanner
+ private boolean fEmulate= false;
+ private int fJavaOffset;
+ private int fJavaLength;
+
+ private final IToken[] fTokens= new IToken[] {
+ new Token(null),
+ new Token(JAVA_SINGLE_LINE_COMMENT),
+ new Token(JAVA_MULTI_LINE_COMMENT),
+ new Token(JAVA_DOC),
+ new Token(JAVA_CHARACTER),
+ new Token(JAVA_STRING)
+ };
+
+ public FastJavaPartitionScanner(boolean emulate) {
+ fEmulate= emulate;
+ }
+
+ public FastJavaPartitionScanner() {
+ this(false);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
+ */
+ public IToken nextToken() {
+
+ // emulate JavaPartitionScanner
+ if (fEmulate) {
+ if (fJavaOffset != -1 && fTokenOffset + fTokenLength != fJavaOffset + fJavaLength) {
+ fTokenOffset += fTokenLength;
+ return fTokens[JAVA];
+ } else {
+ fJavaOffset= -1;
+ fJavaLength= 0;
+ }
+ }
+
+ fTokenOffset += fTokenLength;
+ fTokenLength= fPrefixLength;
+
+ while (true) {
+ final int ch= fScanner.read();
+
+ // characters
+ switch (ch) {
+ case ICharacterScanner.EOF:
+ if (fTokenLength > 0) {
+ fLast= NONE; // ignore last
+ return preFix(fState, JAVA, NONE, 0);
+
+ } else {
+ fLast= NONE;
+ fPrefixLength= 0;
+ return Token.EOF;
+ }
+
+ case '\r':
+ // emulate JavaPartitionScanner
+ if (!fEmulate && fLast != CARRIAGE_RETURN) {
+ fLast= CARRIAGE_RETURN;
+ fTokenLength++;
+ continue;
+
+ } else {
+
+ switch (fState) {
+ case SINGLE_LINE_COMMENT:
+ case CHARACTER:
+ case STRING:
+ if (fTokenLength > 0) {
+ IToken token= fTokens[fState];
+
+ // emulate JavaPartitionScanner
+ if (fEmulate) {
+ fTokenLength++;
+ fLast= NONE;
+ fPrefixLength= 0;
+ } else {
+ fLast= CARRIAGE_RETURN;
+ fPrefixLength= 1;
+ }
+
+ fState= JAVA;
+ return token;
+
+ } else {
+ consume();
+ continue;
+ }
+
+ default:
+ consume();
+ continue;
+ }
+ }
+
+ case '\n':
+ switch (fState) {
+ case SINGLE_LINE_COMMENT:
+ case CHARACTER:
+ case STRING:
+ // assert(fTokenLength > 0);
+ return postFix(fState);
+
+ default:
+ consume();
+ continue;
+ }
+
+ default:
+ if (!fEmulate && fLast == CARRIAGE_RETURN) {
+ switch (fState) {
+ case SINGLE_LINE_COMMENT:
+ case CHARACTER:
+ case STRING:
+
+ int last;
+ int newState;
+ switch (ch) {
+ case '/':
+ last= SLASH;
+ newState= JAVA;
+ break;
+
+ case '*':
+ last= STAR;
+ newState= JAVA;
+ break;
+
+ case '\'':
+ last= NONE;
+ newState= CHARACTER;
+ break;
+
+ case '"':
+ last= NONE;
+ newState= STRING;
+ break;
+
+ case '\r':
+ last= CARRIAGE_RETURN;
+ newState= JAVA;
+ break;
+
+ case '\\':
+ last= BACKSLASH;
+ newState= JAVA;
+ break;
+
+ default:
+ last= NONE;
+ newState= JAVA;
+ break;
+ }
+
+ fLast= NONE; // ignore fLast
+ return preFix(fState, newState, last, 1);
+
+ default:
+ break;
+ }
+ }
+ }
+
+ // states
+ switch (fState) {
+ case JAVA:
+ switch (ch) {
+ case '/':
+ if (fLast == SLASH) {
+ if (fTokenLength - getLastLength(fLast) > 0) {
+ return preFix(JAVA, SINGLE_LINE_COMMENT, NONE, 2);
+ } else {
+ preFix(JAVA, SINGLE_LINE_COMMENT, NONE, 2);
+ fTokenOffset += fTokenLength;
+ fTokenLength= fPrefixLength;
+ break;
+ }
+
+ } else {
+ fTokenLength++;
+ fLast= SLASH;
+ break;
+ }
+
+ case '*':
+ if (fLast == SLASH) {
+ if (fTokenLength - getLastLength(fLast) > 0)
+ return preFix(JAVA, MULTI_LINE_COMMENT, SLASH_STAR, 2);
+ else {
+ preFix(JAVA, MULTI_LINE_COMMENT, SLASH_STAR, 2);
+ fTokenOffset += fTokenLength;
+ fTokenLength= fPrefixLength;
+ break;
+ }
+
+ } else {
+ consume();
+ break;
+ }
+
+ case '\'':
+ fLast= NONE; // ignore fLast
+ if (fTokenLength > 0)
+ return preFix(JAVA, CHARACTER, NONE, 1);
+ else {
+ preFix(JAVA, CHARACTER, NONE, 1);
+ fTokenOffset += fTokenLength;
+ fTokenLength= fPrefixLength;
+ break;
+ }
+
+ case '"':
+ fLast= NONE; // ignore fLast
+ if (fTokenLength > 0)
+ return preFix(JAVA, STRING, NONE, 1);
+ else {
+ preFix(JAVA, STRING, NONE, 1);
+ fTokenOffset += fTokenLength;
+ fTokenLength= fPrefixLength;
+ break;
+ }
+
+ default:
+ consume();
+ break;
+ }
+ break;
+
+ case SINGLE_LINE_COMMENT:
+ consume();
+ break;
+
+ case JAVADOC:
+ switch (ch) {
+ case '/':
+ switch (fLast) {
+ case SLASH_STAR_STAR:
+ return postFix(MULTI_LINE_COMMENT);
+
+ case STAR:
+ return postFix(JAVADOC);
+
+ default:
+ consume();
+ break;
+ }
+ break;
+
+ case '*':
+ fTokenLength++;
+ fLast= STAR;
+ break;
+
+ default:
+ consume();
+ break;
+ }
+ break;
+
+ case MULTI_LINE_COMMENT:
+ switch (ch) {
+ case '*':
+ if (fLast == SLASH_STAR) {
+ fLast= SLASH_STAR_STAR;
+ fTokenLength++;
+ fState= JAVADOC;
+ } else {
+ fTokenLength++;
+ fLast= STAR;
+ }
+ break;
+
+ case '/':
+ if (fLast == STAR) {
+ return postFix(MULTI_LINE_COMMENT);
+ } else {
+ consume();
+ break;
+ }
+
+ default:
+ consume();
+ break;
+ }
+ break;
+
+ case STRING:
+ switch (ch) {
+ case '\\':
+ fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
+ fTokenLength++;
+ break;
+
+ case '\"':
+ if (fLast != BACKSLASH) {
+ return postFix(STRING);
+
+ } else {
+ consume();
+ break;
+ }
+
+ default:
+ consume();
+ break;
+ }
+ break;
+
+ case CHARACTER:
+ switch (ch) {
+ case '\\':
+ fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
+ fTokenLength++;
+ break;
+
+ case '\'':
+ if (fLast != BACKSLASH) {
+ return postFix(CHARACTER);
+
+ } else {
+ consume();
+ break;
+ }
+
+ default:
+ consume();
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ private static final int getLastLength(int last) {
+ switch (last) {
+ default:
+ return -1;
+
+ case NONE:
+ return 0;
+
+ case CARRIAGE_RETURN:
+ case BACKSLASH:
+ case SLASH:
+ case STAR:
+ return 1;
+
+ case SLASH_STAR:
+ return 2;
+
+ case SLASH_STAR_STAR:
+ return 3;
+ }
+ }
+
+ private final void consume() {
+ fTokenLength++;
+ fLast= NONE;
+ }
+
+ private final IToken postFix(int state) {
+ fTokenLength++;
+ fLast= NONE;
+ fState= JAVA;
+ fPrefixLength= 0;
+ return fTokens[state];
+ }
+
+ private final IToken preFix(int state, int newState, int last, int prefixLength) {
+ // emulate JavaPartitionScanner
+ if (fEmulate && state == JAVA && (fTokenLength - getLastLength(fLast) > 0)) {
+ fTokenLength -= getLastLength(fLast);
+ fJavaOffset= fTokenOffset;
+ fJavaLength= fTokenLength;
+ fTokenLength= 1;
+ fState= newState;
+ fPrefixLength= prefixLength;
+ fLast= last;
+ return fTokens[state];
+
+ } else {
+ fTokenLength -= getLastLength(fLast);
+ fLast= last;
+ fPrefixLength= prefixLength;
+ IToken token= fTokens[state];
+ fState= newState;
+ return token;
+ }
+ }
+
+ private static int getState(String contentType) {
+
+ if (contentType == null)
+ return JAVA;
+
+ else if (contentType.equals(JAVA_SINGLE_LINE_COMMENT))
+ return SINGLE_LINE_COMMENT;
+
+ else if (contentType.equals(JAVA_MULTI_LINE_COMMENT))
+ return MULTI_LINE_COMMENT;
+
+ else if (contentType.equals(JAVA_DOC))
+ return JAVADOC;
+
+ else if (contentType.equals(JAVA_STRING))
+ return STRING;
+
+ else if (contentType.equals(JAVA_CHARACTER))
+ return CHARACTER;
+
+ else
+ return JAVA;
+ }
+
+ /*
+ * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String, int)
+ */
+ public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
+
+ fScanner.setRange(document, offset, length);
+ fTokenOffset= partitionOffset;
+ fTokenLength= 0;
+ fPrefixLength= offset - partitionOffset;
+ fLast= NONE;
+
+ if (offset == partitionOffset) {
+ // restart at beginning of partition
+ fState= JAVA;
+ } else {
+ fState= getState(contentType);
+ }
+
+ // emulate JavaPartitionScanner
+ if (fEmulate) {
+ fJavaOffset= -1;
+ fJavaLength= 0;
+ }
+ }
+
+ /*
+ * @see ITokenScanner#setRange(IDocument, int, int)
+ */
+ public void setRange(IDocument document, int offset, int length) {
+
+ fScanner.setRange(document, offset, length);
+ fTokenOffset= offset;
+ fTokenLength= 0;
+ fPrefixLength= 0;
+ fLast= NONE;
+ fState= JAVA;
+
+ // emulate JavaPartitionScanner
+ if (fEmulate) {
+ fJavaOffset= -1;
+ fJavaLength= 0;
+ }
+ }
+
+ /*
+ * @see ITokenScanner#getTokenLength()
+ */
+ public int getTokenLength() {
+ return fTokenLength;
+ }
+
+ /*
+ * @see ITokenScanner#getTokenOffset()
+ */
+ public int getTokenOffset() {
+ return fTokenOffset;
+ }
+
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IColorManager.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IColorManager.java
new file mode 100644
index 0000000..aa08930
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IColorManager.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+import org.eclipse.jface.text.source.ISharedTextColors;
+import org.eclipse.swt.graphics.Color;
+
+
+/**
+ * Manages SWT color objects for the given color keys and
+ * given <code>RGB</code> objects. Until the <code>dispose</code>
+ * method is called, the same color object is returned for
+ * equal keys and equal <code>RGB</code> values.
+ * <p>
+ * In order to provide backward compatibility for clients of <code>IColorManager</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.ui.text.IColorManagerExtension} since version 2.0 introducing
+ * the ability to bind and un-bind colors.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ *
+ * @see org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.ui.text.IColorManagerExtension
+ * @see org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.ui.text.IJavaColorConstants
+ */
+public interface IColorManager extends ISharedTextColors {
+
+ /**
+ * Returns a color object for the given key. The color objects
+ * are remembered internally; the same color object is returned
+ * for equal keys.
+ *
+ * @param key the color key
+ * @return the color object for the given key
+ */
+ Color getColor(String key);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IColorManagerExtension.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IColorManagerExtension.java
new file mode 100644
index 0000000..b266f84
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IColorManagerExtension.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+import org.eclipse.swt.graphics.RGB;
+
+
+/**
+ * Extends {@link org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.ui.text.IColorManager} with
+ * the ability to bind and un-bind colors.
+ *
+ * @since 2.0
+ */
+public interface IColorManagerExtension {
+
+ /**
+ * Remembers the given color specification under the given key.
+ *
+ * @param key the color key
+ * @param rgb the color specification
+ * @throws java.lang.UnsupportedOperationException if there is already a
+ * color specification remembered under the given key
+ */
+ void bindColor(String key, RGB rgb);
+
+
+ /**
+ * Forgets the color specification remembered under the given key.
+ *
+ * @param key the color key
+ */
+ void unbindColor(String key);
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IJavaColorConstants.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IJavaColorConstants.java
new file mode 100644
index 0000000..d584438
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IJavaColorConstants.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+/**
+ * Color keys used for syntax highlighting Java
+ * code and Javadoc compliant comments.
+ * A <code>IColorManager</code> is responsible for mapping
+ * concrete colors to these keys.
+ * <p>
+ * This interface declares static final fields only; it is not intended to be
+ * implemented.
+ * </p>
+ *
+ * @see org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.ui.text.IColorManager
+ * @see org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.ui.text.IColorManagerExtension
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @noextend This interface is not intended to be extended by clients.
+ */
+public interface IJavaColorConstants {
+ /** The color key for Java keywords in Java code
+ * (value <code>"java_keyword"</code>).
+ */
+ String JAVA_KEYWORD= "java_keyword"; //$NON-NLS-1$
+
+ /**
+ * The color key for everything in Java code for which no other color is specified
+ * (value <code>"java_default"</code>).
+ */
+ String JAVA_DEFAULT= "java_default"; //$NON-NLS-1$
+
+ /** The color key for keyword 'return' in Java code
+ * (value <code>"java_keyword_return"</code>).
+ *
+ * @since 3.0
+ */
+ String JAVA_KEYWORD_RETURN= "java_keyword_return"; //$NON-NLS-1$
+
+ /** The color key for operators in Java code
+ * (value <code>"java_operator"</code>).
+ *
+ * @since 3.0
+ */
+ String JAVA_OPERATOR= "java_operator"; //$NON-NLS-1$
+
+ /** The color key for brackets in Java code
+ * (value <code>"java_bracket"</code>).
+ *
+ * @since 3.3
+ */
+ String JAVA_BRACKET= "java_bracket"; //$NON-NLS-1$
+
+ /**
+ * The color key for task tags in java comments
+ * (value <code>"java_comment_task_tag"</code>).
+ *
+ * @since 2.1
+ */
+ String TASK_TAG= "java_comment_task_tag"; //$NON-NLS-1$
+
+ /** The color key for multi-line comments in Java code
+ * (value <code>"java_multi_line_comment"</code>).
+ */
+ String JAVA_MULTI_LINE_COMMENT= "java_multi_line_comment"; //$NON-NLS-1$
+
+ /** The color key for single-line comments in Java code
+ * (value <code>"java_single_line_comment"</code>).
+ */
+ String JAVA_SINGLE_LINE_COMMENT= "java_single_line_comment"; //$NON-NLS-1$
+
+ /** The color key for string and character literals in Java code
+ * (value <code>"java_string"</code>).
+ */
+ String JAVA_STRING= "java_string"; //$NON-NLS-1$
+
+ /**
+ * The color key for JavaDoc keywords (<code>@foo</code>) in JavaDoc comments
+ * (value <code>"java_doc_keyword"</code>).
+ */
+ String JAVADOC_KEYWORD= "java_doc_keyword"; //$NON-NLS-1$
+
+ /**
+ * The color key for HTML tags (<code><foo></code>) in JavaDoc comments
+ * (value <code>"java_doc_tag"</code>).
+ */
+ String JAVADOC_TAG= "java_doc_tag"; //$NON-NLS-1$
+
+ /**
+ * The color key for JavaDoc links (<code>{foo}</code>) in JavaDoc comments
+ * (value <code>"java_doc_link"</code>).
+ */
+ String JAVADOC_LINK= "java_doc_link"; //$NON-NLS-1$
+
+ /**
+ * The color key for everything in JavaDoc comments for which no other color is specified
+ * (value <code>"java_doc_default"</code>).
+ */
+ String JAVADOC_DEFAULT= "java_doc_default"; //$NON-NLS-1$
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IJavaPartitions.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IJavaPartitions.java
new file mode 100644
index 0000000..c60cce3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/IJavaPartitions.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+/**
+ * Definition of Java partitioning and its partitions.
+ *
+ * @since 3.1
+ */
+public interface IJavaPartitions {
+ /**
+ * The identifier of the Java partitioning.
+ */
+ String JAVA_PARTITIONING= "___java_partitioning"; //$NON-NLS-1$
+ /**
+ * The identifier of the single-line (JLS2: EndOfLineComment) end comment partition content type.
+ */
+ String JAVA_SINGLE_LINE_COMMENT= "__java_singleline_comment"; //$NON-NLS-1$
+
+ /**
+ * The identifier multi-line (JLS2: TraditionalComment) comment partition content type.
+ */
+ String JAVA_MULTI_LINE_COMMENT= "__java_multiline_comment"; //$NON-NLS-1$
+
+ /**
+ * The identifier of the Javadoc (JLS2: DocumentationComment) partition content type.
+ */
+ String JAVA_DOC= "__java_javadoc"; //$NON-NLS-1$
+
+ /**
+ * The identifier of the Java string partition content type.
+ */
+ String JAVA_STRING= "__java_string"; //$NON-NLS-1$
+
+ /**
+ * The identifier of the Java character partition content type.
+ */
+ String JAVA_CHARACTER= "__java_character"; //$NON-NLS-1$
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/ISourceVersionDependent.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/ISourceVersionDependent.java
new file mode 100644
index 0000000..7f50fcc
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/ISourceVersionDependent.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+/**
+ * Mix-in for any rule that changes its behavior based on the Java source
+ * version.
+ *
+ * @since 3.1
+ */
+public interface ISourceVersionDependent {
+
+ /**
+ * Sets the configured java source version to one of the
+ * <code>JavaCore.VERSION_X_Y</code> values.
+ *
+ * @param version the new java source version
+ * @see org.eclipse.jdt.core.JavaCore
+ */
+ void setSourceVersion(String version);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaCodeScanner.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaCodeScanner.java
new file mode 100644
index 0000000..ae73426
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaCodeScanner.java
@@ -0,0 +1,553 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * Philippe Ombredanne <pombredanne@nexb.com> - https://bugs.eclipse.org/bugs/show_bug.cgi?id=150989
+ * Anton Leherbauer (Wind River Systems) - [misc] Allow custom token for WhitespaceRule - https://bugs.eclipse.org/bugs/show_bug.cgi?id=251224
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+
+/**
+ * A Java code scanner.
+ */
+public final class JavaCodeScanner extends AbstractJavaScanner {
+
+ /**
+ * Rule to detect java operators.
+ *
+ * @since 3.0
+ */
+ private static final class OperatorRule implements IRule {
+
+ /** Java operators */
+ private final char[] JAVA_OPERATORS= { ';', '.', '=', '/', '\\', '+', '-', '*', '<', '>', ':', '?', '!', ',', '|', '&', '^', '%', '~'};
+ /** Token to return for this rule */
+ private final IToken fToken;
+
+ /**
+ * Creates a new operator rule.
+ *
+ * @param token Token to use for this rule
+ */
+ public OperatorRule(IToken token) {
+ fToken= token;
+ }
+
+ /**
+ * Is this character an operator character?
+ *
+ * @param character Character to determine whether it is an operator character
+ * @return <code>true</code> iff the character is an operator, <code>false</code> otherwise.
+ */
+ public boolean isOperator(char character) {
+ for (int index= 0; index < JAVA_OPERATORS.length; index++) {
+ if (JAVA_OPERATORS[index] == character)
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner)
+ */
+ public IToken evaluate(ICharacterScanner scanner) {
+
+ int character= scanner.read();
+ if (isOperator((char) character)) {
+ do {
+ character= scanner.read();
+ } while (isOperator((char) character));
+ scanner.unread();
+ return fToken;
+ } else {
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+ }
+ }
+
+ /**
+ * Rule to detect java brackets.
+ *
+ * @since 3.3
+ */
+ private static final class BracketRule implements IRule {
+
+ /** Java brackets */
+ private final char[] JAVA_BRACKETS= { '(', ')', '{', '}', '[', ']' };
+ /** Token to return for this rule */
+ private final IToken fToken;
+
+ /**
+ * Creates a new bracket rule.
+ *
+ * @param token Token to use for this rule
+ */
+ public BracketRule(IToken token) {
+ fToken= token;
+ }
+
+ /**
+ * Is this character a bracket character?
+ *
+ * @param character Character to determine whether it is a bracket character
+ * @return <code>true</code> iff the character is a bracket, <code>false</code> otherwise.
+ */
+ public boolean isBracket(char character) {
+ for (int index= 0; index < JAVA_BRACKETS.length; index++) {
+ if (JAVA_BRACKETS[index] == character)
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner)
+ */
+ public IToken evaluate(ICharacterScanner scanner) {
+
+ int character= scanner.read();
+ if (isBracket((char) character)) {
+ do {
+ character= scanner.read();
+ } while (isBracket((char) character));
+ scanner.unread();
+ return fToken;
+ } else {
+ scanner.unread();
+ return Token.UNDEFINED;
+ }
+ }
+ }
+
+
+ private static class VersionedWordMatcher extends CombinedWordRule.WordMatcher implements ISourceVersionDependent {
+
+ private final IToken fDefaultToken;
+ private final String fVersion;
+ private boolean fIsVersionMatch;
+
+ public VersionedWordMatcher(IToken defaultToken, String version, String currentVersion) {
+ fDefaultToken= defaultToken;
+ fVersion= version;
+ setSourceVersion(currentVersion);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.ISourceVersionDependent#setSourceVersion(java.lang.String)
+ */
+ public void setSourceVersion(String version) {
+ fIsVersionMatch= fVersion.compareTo(version) <= 0;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher#evaluate(org.eclipse.jface.text.rules.ICharacterScanner, org.eclipse.jdt.internal.ui.text.CombinedWordRule.CharacterBuffer)
+ */
+ public IToken evaluate(ICharacterScanner scanner, CombinedWordRule.CharacterBuffer word) {
+ IToken token= super.evaluate(scanner, word);
+
+ if (fIsVersionMatch || token.isUndefined())
+ return token;
+
+ return fDefaultToken;
+ }
+ }
+
+ /**
+ * An annotation rule matches the '@' symbol, any following whitespace and
+ * optionally a following <code>interface</code> keyword.
+ *
+ * It does not match if there is a comment between the '@' symbol and
+ * the identifier. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=82452
+ *
+ * @since 3.1
+ */
+ private static class AnnotationRule implements IRule, ISourceVersionDependent {
+ /**
+ * A resettable scanner supports marking a position in a scanner and
+ * unreading back to the marked position.
+ */
+ private static final class ResettableScanner implements ICharacterScanner {
+ private final ICharacterScanner fDelegate;
+ private int fReadCount;
+
+ /**
+ * Creates a new resettable scanner that will forward calls
+ * to <code>scanner</code>, but store a marked position.
+ *
+ * @param scanner the delegate scanner
+ */
+ public ResettableScanner(final ICharacterScanner scanner) {
+ Assert.isNotNull(scanner);
+ fDelegate= scanner;
+ mark();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.ICharacterScanner#getColumn()
+ */
+ public int getColumn() {
+ return fDelegate.getColumn();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.ICharacterScanner#getLegalLineDelimiters()
+ */
+ public char[][] getLegalLineDelimiters() {
+ return fDelegate.getLegalLineDelimiters();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.ICharacterScanner#read()
+ */
+ public int read() {
+ int ch= fDelegate.read();
+ if (ch != ICharacterScanner.EOF)
+ fReadCount++;
+ return ch;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.ICharacterScanner#unread()
+ */
+ public void unread() {
+ if (fReadCount > 0)
+ fReadCount--;
+ fDelegate.unread();
+ }
+
+ /**
+ * Marks an offset in the scanned content.
+ */
+ public void mark() {
+ fReadCount= 0;
+ }
+
+ /**
+ * Resets the scanner to the marked position.
+ */
+ public void reset() {
+ while (fReadCount > 0)
+ unread();
+
+ while (fReadCount < 0)
+ read();
+ }
+ }
+
+ private final IWhitespaceDetector fWhitespaceDetector= new JavaWhitespaceDetector();
+ private final IWordDetector fWordDetector= new JavaWordDetector();
+ private final IToken fInterfaceToken;
+ private final IToken fAtToken;
+ private final String fVersion;
+ private boolean fIsVersionMatch;
+
+ /**
+ * Creates a new rule.
+ *
+ * @param interfaceToken the token to return if
+ * <code>'@\s*interface'</code> is matched
+ * @param atToken the token to return if <code>'@'</code>
+ * is matched, but not <code>'@\s*interface'</code>
+ * @param version the lowest <code>JavaCore.COMPILER_SOURCE</code>
+ * version that this rule is enabled
+ * @param currentVersion the current
+ * <code>JavaCore.COMPILER_SOURCE</code> version
+ */
+ public AnnotationRule(IToken interfaceToken, Token atToken, String version, String currentVersion) {
+ fInterfaceToken= interfaceToken;
+ fAtToken= atToken;
+ fVersion= version;
+ setSourceVersion(currentVersion);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner)
+ */
+ public IToken evaluate(ICharacterScanner scanner) {
+ if (!fIsVersionMatch)
+ return Token.UNDEFINED;
+
+ ResettableScanner resettable= new ResettableScanner(scanner);
+ if (resettable.read() == '@')
+ return readAnnotation(resettable);
+
+ resettable.reset();
+ return Token.UNDEFINED;
+ }
+
+ private IToken readAnnotation(ResettableScanner scanner) {
+ scanner.mark();
+ skipWhitespace(scanner);
+ if (readInterface(scanner)) {
+ return fInterfaceToken;
+ } else {
+ scanner.reset();
+ return fAtToken;
+ }
+ }
+
+ private boolean readInterface(ICharacterScanner scanner) {
+ int ch= scanner.read();
+ int i= 0;
+ while (i < INTERFACE.length() && INTERFACE.charAt(i) == ch) {
+ i++;
+ ch= scanner.read();
+ }
+ if (i < INTERFACE.length())
+ return false;
+
+ if (fWordDetector.isWordPart((char) ch))
+ return false;
+
+ if (ch != ICharacterScanner.EOF)
+ scanner.unread();
+
+ return true;
+ }
+
+ private boolean skipWhitespace(ICharacterScanner scanner) {
+ while (fWhitespaceDetector.isWhitespace((char) scanner.read())) {
+ // do nothing
+ }
+
+ scanner.unread();
+ return true;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.ISourceVersionDependent#setSourceVersion(java.lang.String)
+ */
+ public void setSourceVersion(String version) {
+ fIsVersionMatch= fVersion.compareTo(version) <= 0;
+ }
+
+ }
+
+ private static final String SOURCE_VERSION= JavaCore.COMPILER_SOURCE;
+
+ static String[] fgKeywords= {
+ "abstract", //$NON-NLS-1$
+ "break", //$NON-NLS-1$
+ "case", "catch", "class", "const", "continue", //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ "default", "do", //$NON-NLS-2$ //$NON-NLS-1$
+ "else", "extends", //$NON-NLS-2$ //$NON-NLS-1$
+ "final", "finally", "for", //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ "goto", //$NON-NLS-1$
+ "if", "implements", "import", "instanceof", "interface", //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ "native", "new", //$NON-NLS-2$ //$NON-NLS-1$
+ "package", "private", "protected", "public", //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ "static", "super", "switch", "synchronized", //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ "this", "throw", "throws", "transient", "try", //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ "volatile", //$NON-NLS-1$
+ "while" //$NON-NLS-1$
+ };
+
+ private static final String INTERFACE= "interface"; //$NON-NLS-1$
+ private static final String RETURN= "return"; //$NON-NLS-1$
+ private static String[] fgJava14Keywords= { "assert" }; //$NON-NLS-1$
+ private static String[] fgJava15Keywords= { "enum" }; //$NON-NLS-1$
+
+ private static String[] fgTypes= { "void", "boolean", "char", "byte", "short", "strictfp", "int", "long", "float", "double" }; //$NON-NLS-1$ //$NON-NLS-5$ //$NON-NLS-7$ //$NON-NLS-6$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-2$
+
+ private static String[] fgConstants= { "false", "null", "true" }; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+
+ private static final String ANNOTATION_BASE_KEY= PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + SemanticHighlightings.ANNOTATION;
+ private static final String ANNOTATION_COLOR_KEY= ANNOTATION_BASE_KEY + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX;
+
+ private static String[] fgTokenProperties= {
+ IJavaColorConstants.JAVA_KEYWORD,
+ IJavaColorConstants.JAVA_STRING,
+ IJavaColorConstants.JAVA_DEFAULT,
+ IJavaColorConstants.JAVA_KEYWORD_RETURN,
+ IJavaColorConstants.JAVA_OPERATOR,
+ IJavaColorConstants.JAVA_BRACKET,
+ ANNOTATION_COLOR_KEY,
+ };
+
+ private List<ISourceVersionDependent> fVersionDependentRules= new ArrayList<ISourceVersionDependent>(3);
+
+ /**
+ * Creates a Java code scanner
+ *
+ * @param manager the color manager
+ * @param store the preference store
+ */
+ public JavaCodeScanner(IColorManager manager, IPreferenceStore store) {
+ super(manager, store);
+ initialize();
+ }
+
+ /*
+ * @see AbstractJavaScanner#getTokenProperties()
+ */
+ protected String[] getTokenProperties() {
+ return fgTokenProperties;
+ }
+
+ /*
+ * @see AbstractJavaScanner#createRules()
+ */
+ protected List<IRule> createRules() {
+
+ List<IRule> rules= new ArrayList<IRule>();
+
+ // Add rule for character constants.
+ Token token= getToken(IJavaColorConstants.JAVA_STRING);
+ rules.add(new SingleLineRule("'", "'", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
+
+
+ Token defaultToken= getToken(IJavaColorConstants.JAVA_DEFAULT);
+
+ // Add generic whitespace rule.
+ rules.add(new WhitespaceRule(new JavaWhitespaceDetector(), defaultToken));
+
+ String version= getPreferenceStore().getString(SOURCE_VERSION);
+
+ // Add JLS3 rule for /@\s*interface/ and /@\s*\w+/
+ token= getToken(ANNOTATION_COLOR_KEY);
+ AnnotationRule atInterfaceRule= new AnnotationRule(getToken(IJavaColorConstants.JAVA_KEYWORD), token, JavaCore.VERSION_1_5, version);
+ rules.add(atInterfaceRule);
+ fVersionDependentRules.add(atInterfaceRule);
+
+ // Add word rule for new keywords, see bug 4077
+ JavaWordDetector wordDetector= new JavaWordDetector();
+ CombinedWordRule combinedWordRule= new CombinedWordRule(wordDetector, defaultToken);
+
+ VersionedWordMatcher j14Matcher= new VersionedWordMatcher(defaultToken, JavaCore.VERSION_1_4, version);
+
+ token= getToken(IJavaColorConstants.JAVA_KEYWORD);
+ for (int i=0; i<fgJava14Keywords.length; i++)
+ j14Matcher.addWord(fgJava14Keywords[i], token);
+
+ combinedWordRule.addWordMatcher(j14Matcher);
+ fVersionDependentRules.add(j14Matcher);
+
+ VersionedWordMatcher j15Matcher= new VersionedWordMatcher(defaultToken, JavaCore.VERSION_1_5, version);
+
+ token= getToken(IJavaColorConstants.JAVA_KEYWORD);
+ for (int i=0; i<fgJava15Keywords.length; i++)
+ j15Matcher.addWord(fgJava15Keywords[i], token);
+
+ combinedWordRule.addWordMatcher(j15Matcher);
+ fVersionDependentRules.add(j15Matcher);
+
+ // Add rule for operators
+ token= getToken(IJavaColorConstants.JAVA_OPERATOR);
+ rules.add(new OperatorRule(token));
+
+ // Add rule for brackets
+ token= getToken(IJavaColorConstants.JAVA_BRACKET);
+ rules.add(new BracketRule(token));
+
+ // Add word rule for keyword 'return'.
+ CombinedWordRule.WordMatcher returnWordRule= new CombinedWordRule.WordMatcher();
+ token= getToken(IJavaColorConstants.JAVA_KEYWORD_RETURN);
+ returnWordRule.addWord(RETURN, token);
+ combinedWordRule.addWordMatcher(returnWordRule);
+
+ // Add word rule for keywords, types, and constants.
+ CombinedWordRule.WordMatcher wordRule= new CombinedWordRule.WordMatcher();
+ token= getToken(IJavaColorConstants.JAVA_KEYWORD);
+ for (int i=0; i<fgKeywords.length; i++)
+ wordRule.addWord(fgKeywords[i], token);
+ for (int i=0; i<fgTypes.length; i++)
+ wordRule.addWord(fgTypes[i], token);
+ for (int i=0; i<fgConstants.length; i++)
+ wordRule.addWord(fgConstants[i], token);
+
+ combinedWordRule.addWordMatcher(wordRule);
+
+ rules.add(combinedWordRule);
+
+ setDefaultReturnToken(defaultToken);
+ return rules;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.AbstractJavaScanner#getBoldKey(java.lang.String)
+ */
+ protected String getBoldKey(String colorKey) {
+ if ((ANNOTATION_COLOR_KEY).equals(colorKey))
+ return ANNOTATION_BASE_KEY + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_BOLD_SUFFIX;
+ return super.getBoldKey(colorKey);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.AbstractJavaScanner#getItalicKey(java.lang.String)
+ */
+ protected String getItalicKey(String colorKey) {
+ if ((ANNOTATION_COLOR_KEY).equals(colorKey))
+ return ANNOTATION_BASE_KEY + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_ITALIC_SUFFIX;
+ return super.getItalicKey(colorKey);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.AbstractJavaScanner#getStrikethroughKey(java.lang.String)
+ */
+ protected String getStrikethroughKey(String colorKey) {
+ if ((ANNOTATION_COLOR_KEY).equals(colorKey))
+ return ANNOTATION_BASE_KEY + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_STRIKETHROUGH_SUFFIX;
+ return super.getStrikethroughKey(colorKey);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.AbstractJavaScanner#getUnderlineKey(java.lang.String)
+ */
+ protected String getUnderlineKey(String colorKey) {
+ if ((ANNOTATION_COLOR_KEY).equals(colorKey))
+ return ANNOTATION_BASE_KEY + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_UNDERLINE_SUFFIX;
+ return super.getUnderlineKey(colorKey);
+ }
+
+ /*
+ * @see AbstractJavaScanner#affectsBehavior(PropertyChangeEvent)
+ */
+ public boolean affectsBehavior(PropertyChangeEvent event) {
+ return event.getProperty().equals(SOURCE_VERSION) || super.affectsBehavior(event);
+ }
+
+ /*
+ * @see AbstractJavaScanner#adaptToPreferenceChange(PropertyChangeEvent)
+ */
+ public void adaptToPreferenceChange(PropertyChangeEvent event) {
+
+ if (event.getProperty().equals(SOURCE_VERSION)) {
+ Object value= event.getNewValue();
+
+ if (value instanceof String) {
+ String s= (String) value;
+
+ for (Iterator<ISourceVersionDependent> it= fVersionDependentRules.iterator(); it.hasNext();) {
+ ISourceVersionDependent dependent= (ISourceVersionDependent) it.next();
+ dependent.setSourceVersion(s);
+ }
+ }
+
+ } else if (super.affectsBehavior(event)) {
+ super.adaptToPreferenceChange(event);
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaColorManager.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaColorManager.java
new file mode 100644
index 0000000..6766aff
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaColorManager.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Java color manager.
+ */
+public class JavaColorManager implements IColorManager, IColorManagerExtension {
+
+ protected Map<String,RGB> fKeyTable= new HashMap<String,RGB>(10);
+ protected Map<Display,Map<RGB,Color>> fDisplayTable= new HashMap<Display,Map<RGB,Color>>(2);
+
+ /**
+ * Flag which tells if the colors are automatically disposed when
+ * the current display gets disposed.
+ */
+ private boolean fAutoDisposeOnDisplayDispose;
+
+
+ /**
+ * Creates a new Java color manager which automatically
+ * disposes the allocated colors when the current display
+ * gets disposed.
+ */
+ public JavaColorManager() {
+ this(true);
+ }
+
+ /**
+ * Creates a new Java color manager.
+ *
+ * @param autoDisposeOnDisplayDispose if <code>true</code> the color manager
+ * automatically disposes all managed colors when the current display gets disposed
+ * and all calls to {@link org.eclipse.jface.text.source.ISharedTextColors#dispose()} are ignored.
+ *
+ * @since 2.1
+ */
+ public JavaColorManager(boolean autoDisposeOnDisplayDispose) {
+ fAutoDisposeOnDisplayDispose= autoDisposeOnDisplayDispose;
+ }
+
+ public void dispose(Display display) {
+ Map<RGB,Color> colorTable= fDisplayTable.get(display);
+ if (colorTable != null) {
+ Iterator<Color> e= colorTable.values().iterator();
+ while (e.hasNext()) {
+ Color color= (Color)e.next();
+ if (color != null && !color.isDisposed())
+ color.dispose();
+ }
+ }
+ }
+
+ /*
+ * @see IColorManager#getColor(RGB)
+ */
+ public Color getColor(RGB rgb) {
+
+ if (rgb == null)
+ return null;
+
+ final Display display= Display.getCurrent();
+ Map<RGB,Color> colorTable= fDisplayTable.get(display);
+ if (colorTable == null) {
+ colorTable= new HashMap<RGB,Color>(10);
+ fDisplayTable.put(display, colorTable);
+ if (fAutoDisposeOnDisplayDispose) {
+ display.disposeExec(new Runnable() {
+ public void run() {
+ dispose(display);
+ }
+ });
+ }
+ }
+
+ Color color= (Color) colorTable.get(rgb);
+ if (color == null) {
+ color= new Color(Display.getCurrent(), rgb);
+ colorTable.put(rgb, color);
+ }
+
+ return color;
+ }
+
+ /*
+ * @see IColorManager#dispose
+ */
+ public void dispose() {
+ if (!fAutoDisposeOnDisplayDispose)
+ dispose(Display.getCurrent());
+ }
+
+ /*
+ * @see IColorManager#getColor(String)
+ */
+ public Color getColor(String key) {
+
+ if (key == null)
+ return null;
+
+ RGB rgb= (RGB) fKeyTable.get(key);
+ return getColor(rgb);
+ }
+
+ /*
+ * @see IColorManagerExtension#bindColor(String, RGB)
+ */
+ public void bindColor(String key, RGB rgb) {
+ Object value= fKeyTable.get(key);
+ if (value != null)
+ throw new UnsupportedOperationException();
+
+ fKeyTable.put(key, rgb);
+ }
+
+ /*
+ * @see IColorManagerExtension#unbindColor(String)
+ */
+ public void unbindColor(String key) {
+ fKeyTable.remove(key);
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaCommentScanner.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaCommentScanner.java
new file mode 100644
index 0000000..3325a38
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaCommentScanner.java
@@ -0,0 +1,248 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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
+ * Michel Ishizuka <cqw10305@nifty.com> - Bug 113266 [syntax highlighting] javadoc tag names including period is not highlighting correctly
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.CombinedWordRule.WordMatcher;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+
+/**
+ * Java comment scanner.
+ */
+public class JavaCommentScanner extends AbstractJavaScanner{
+
+ private static class AtJavaIdentifierDetector implements IWordDetector {
+
+ public boolean isWordStart(char c) {
+ return c == '@' || Character.isJavaIdentifierStart(c);
+ }
+
+ public boolean isWordPart(char c) {
+ return c == '.' || Character.isJavaIdentifierPart(c);
+ }
+ }
+
+ private class TaskTagMatcher extends CombinedWordRule.WordMatcher {
+
+ private IToken fToken;
+ /**
+ * Uppercase words
+ * @since 3.0
+ */
+ private Map<CombinedWordRule.CharacterBuffer,IToken> fUppercaseWords= new HashMap<CombinedWordRule.CharacterBuffer,IToken>();
+ /**
+ * <code>true</code> if task tag detection is case-sensitive.
+ * @since 3.0
+ */
+ private boolean fCaseSensitive= true;
+ /**
+ * Buffer for uppercase word
+ * @since 3.0
+ */
+ private CombinedWordRule.CharacterBuffer fBuffer= new CombinedWordRule.CharacterBuffer(16);
+
+ public TaskTagMatcher(IToken token) {
+ fToken= token;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher#clearWords()
+ * @since 3.0
+ */
+ public synchronized void clearWords() {
+ super.clearWords();
+ fUppercaseWords.clear();
+ }
+
+ public synchronized void addTaskTags(String value) {
+ String[] tasks= split(value, ","); //$NON-NLS-1$
+ for (int i= 0; i < tasks.length; i++) {
+ if (tasks[i].length() > 0) {
+ addWord(tasks[i], fToken);
+ }
+ }
+ }
+
+ private String[] split(String value, String delimiters) {
+ StringTokenizer tokenizer= new StringTokenizer(value, delimiters);
+ int size= tokenizer.countTokens();
+ String[] tokens= new String[size];
+ int i= 0;
+ while (i < size)
+ tokens[i++]= tokenizer.nextToken();
+ return tokens;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher#addWord(java.lang.String, org.eclipse.jface.text.rules.IToken)
+ * @since 3.0
+ */
+ public synchronized void addWord(String word, IToken token) {
+ Assert.isNotNull(word);
+ Assert.isNotNull(token);
+
+ super.addWord(word, token);
+ fUppercaseWords.put(new CombinedWordRule.CharacterBuffer(word.toUpperCase()), token);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.CombinedWordRule.WordMatcher#evaluate(org.eclipse.jface.text.rules.ICharacterScanner, org.eclipse.jdt.internal.ui.text.CombinedWordRule.CharacterBuffer)
+ * @since 3.0
+ */
+ public synchronized IToken evaluate(ICharacterScanner scanner, CombinedWordRule.CharacterBuffer word) {
+ if (fCaseSensitive)
+ return super.evaluate(scanner, word);
+
+ fBuffer.clear();
+ for (int i= 0, n= word.length(); i < n; i++)
+ fBuffer.append(Character.toUpperCase(word.charAt(i)));
+
+ IToken token= (IToken) fUppercaseWords.get(fBuffer);
+ if (token != null)
+ return token;
+ return Token.UNDEFINED;
+ }
+
+ /**
+ * Enables/disables the case-sensitivity of the task tag detection.
+ *
+ * @param caseSensitive <code>true</code> iff case-sensitivity should be enabled
+ * @since 3.0
+ */
+ public void setCaseSensitive(boolean caseSensitive) {
+ fCaseSensitive= caseSensitive;
+ }
+ }
+
+ private static final String COMPILER_TASK_TAGS = JavaCore.COMPILER_TASK_TAGS;
+ protected static final String TASK_TAG = IJavaColorConstants.TASK_TAG;
+ /**
+ * Preference key of a string preference, specifying if task tag detection is case-sensitive.
+ * @since 3.0
+ */
+ private static final String COMPILER_TASK_CASE_SENSITIVE= JavaCore.COMPILER_TASK_CASE_SENSITIVE;
+ /**
+ * Preference value of enabled preferences.
+ * @since 3.0
+ */
+ private static final String ENABLED= JavaCore.ENABLED;
+
+ private TaskTagMatcher fTaskTagMatcher;
+ private String fDefaultTokenProperty;
+ private String[] fTokenProperties;
+
+ public JavaCommentScanner(IColorManager manager, IPreferenceStore store, String defaultTokenProperty) {
+ this(manager, store, defaultTokenProperty, new String[] { defaultTokenProperty, TASK_TAG });
+ }
+
+ public JavaCommentScanner(IColorManager manager, IPreferenceStore store, String defaultTokenProperty, String[] tokenProperties) {
+ super(manager, store);
+
+ fDefaultTokenProperty= defaultTokenProperty;
+ fTokenProperties= tokenProperties;
+
+ initialize();
+ }
+
+ /*
+ * @see AbstractJavaScanner#createRules()
+ */
+ protected List<IRule> createRules() {
+ List<IRule> list= new ArrayList<IRule>();
+ Token defaultToken= getToken(fDefaultTokenProperty);
+
+ List<WordMatcher> matchers= createMatchers();
+ if (matchers.size() > 0) {
+ CombinedWordRule combinedWordRule= new CombinedWordRule(new AtJavaIdentifierDetector(), defaultToken);
+ for (int i= 0, n= matchers.size(); i < n; i++)
+ combinedWordRule.addWordMatcher((WordMatcher) matchers.get(i));
+ list.add(combinedWordRule);
+ }
+
+ setDefaultReturnToken(defaultToken);
+
+ return list;
+ }
+
+ /**
+ * Creates a list of word matchers.
+ *
+ * @return the list of word matchers
+ */
+ protected List<WordMatcher> createMatchers() {
+ List<WordMatcher> list= new ArrayList<WordMatcher>();
+
+ // Add rule for Task Tags.
+ boolean isCaseSensitive= true;
+ String tasks= null;
+ if (getPreferenceStore().contains(COMPILER_TASK_TAGS)) {
+ tasks= getPreferenceStore().getString(COMPILER_TASK_TAGS);
+ isCaseSensitive= ENABLED.equals(getPreferenceStore().getString(COMPILER_TASK_CASE_SENSITIVE));
+ }
+ if (tasks != null) {
+ fTaskTagMatcher= new TaskTagMatcher(getToken(TASK_TAG));
+ fTaskTagMatcher.addTaskTags(tasks);
+ fTaskTagMatcher.setCaseSensitive(isCaseSensitive);
+ list.add(fTaskTagMatcher);
+ }
+
+ return list;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.AbstractJavaScanner#affectsBehavior(org.eclipse.jface.util.PropertyChangeEvent)
+ */
+ public boolean affectsBehavior(PropertyChangeEvent event) {
+ return event.getProperty().equals(COMPILER_TASK_TAGS) || event.getProperty().equals(COMPILER_TASK_CASE_SENSITIVE) || super.affectsBehavior(event);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.AbstractJavaScanner#adaptToPreferenceChange(org.eclipse.jface.util.PropertyChangeEvent)
+ */
+ public void adaptToPreferenceChange(PropertyChangeEvent event) {
+ if (fTaskTagMatcher != null && event.getProperty().equals(COMPILER_TASK_TAGS)) {
+ Object value= event.getNewValue();
+ if (value instanceof String) {
+ synchronized (fTaskTagMatcher) {
+ fTaskTagMatcher.clearWords();
+ fTaskTagMatcher.addTaskTags((String) value);
+ }
+ }
+ } else if (fTaskTagMatcher != null && event.getProperty().equals(COMPILER_TASK_CASE_SENSITIVE)) {
+ Object value= event.getNewValue();
+ if (value instanceof String)
+ fTaskTagMatcher.setCaseSensitive(ENABLED.equals(value));
+ } else if (super.affectsBehavior(event))
+ super.adaptToPreferenceChange(event);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.AbstractJavaScanner#getTokenProperties()
+ */
+ protected String[] getTokenProperties() {
+ return fTokenProperties;
+ }
+
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaDocScanner.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaDocScanner.java
new file mode 100644
index 0000000..66f95d9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaDocScanner.java
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * Anton Leherbauer (Wind River Systems) - [misc] Allow custom token for WhitespaceRule - https://bugs.eclipse.org/bugs/show_bug.cgi?id=251224
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.CombinedWordRule.CharacterBuffer;
+import org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners.CombinedWordRule.WordMatcher;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+import org.eclipse.jface.text.rules.WordRule;
+
+/**
+ * A rule based JavaDoc scanner.
+ */
+public final class JavaDocScanner extends JavaCommentScanner {
+
+
+ /**
+ * Detector for HTML comment delimiters.
+ */
+ static class HTMLCommentDetector implements IWordDetector {
+
+ /**
+ * @see IWordDetector#isWordStart(char)
+ */
+ public boolean isWordStart(char c) {
+ return (c == '<' || c == '-');
+ }
+
+ /**
+ * @see IWordDetector#isWordPart(char)
+ */
+ public boolean isWordPart(char c) {
+ return (c == '-' || c == '!' || c == '>');
+ }
+ }
+
+ class TagRule extends SingleLineRule {
+
+ /*
+ * @see SingleLineRule
+ */
+ public TagRule(IToken token) {
+ super("<", ">", token, (char) 0); //$NON-NLS-2$ //$NON-NLS-1$
+ }
+
+ /*
+ * @see SingleLineRule
+ */
+ public TagRule(IToken token, char escapeCharacter) {
+ super("<", ">", token, escapeCharacter); //$NON-NLS-2$ //$NON-NLS-1$
+ }
+
+ private IToken evaluateToken() {
+ try {
+ final String token= getDocument().get(getTokenOffset(), getTokenLength()) + "."; //$NON-NLS-1$
+
+ int offset= 0;
+ char character= token.charAt(++offset);
+
+ if (character == '/')
+ character= token.charAt(++offset);
+
+ while (Character.isWhitespace(character))
+ character= token.charAt(++offset);
+
+ while (Character.isLetterOrDigit(character))
+ character= token.charAt(++offset);
+
+ while (Character.isWhitespace(character))
+ character= token.charAt(++offset);
+
+ if (offset >= 2 && token.charAt(offset) == fEndSequence[0])
+ return fToken;
+
+ } catch (BadLocationException exception) {
+ // Do nothing
+ }
+ return getToken(IJavaColorConstants.JAVADOC_DEFAULT);
+ }
+
+ /*
+ * @see PatternRule#evaluate(ICharacterScanner)
+ */
+ public IToken evaluate(ICharacterScanner scanner) {
+ IToken result= super.evaluate(scanner);
+ if (result == fToken)
+ return evaluateToken();
+ return result;
+ }
+ }
+
+ private static String[] fgTokenProperties= {
+ IJavaColorConstants.JAVADOC_KEYWORD,
+ IJavaColorConstants.JAVADOC_TAG,
+ IJavaColorConstants.JAVADOC_LINK,
+ IJavaColorConstants.JAVADOC_DEFAULT,
+ TASK_TAG
+ };
+
+
+ public JavaDocScanner(IColorManager manager, IPreferenceStore store) {
+ super(manager, store, IJavaColorConstants.JAVADOC_DEFAULT, fgTokenProperties);
+ }
+
+
+ public IDocument getDocument() {
+ return fDocument;
+ }
+
+ /*
+ * @see AbstractJavaScanner#createRules()
+ */
+ protected List<IRule> createRules() {
+
+ List<IRule> list= new ArrayList<IRule>();
+
+ // Add rule for tags.
+ Token token= getToken(IJavaColorConstants.JAVADOC_TAG);
+ list.add(new TagRule(token));
+
+
+ // Add rule for HTML comments
+ WordRule wordRule= new WordRule(new HTMLCommentDetector(), token);
+ wordRule.addWord("<!--", token); //$NON-NLS-1$
+ wordRule.addWord("--!>", token); //$NON-NLS-1$
+ list.add(wordRule);
+
+
+ // Add rule for links.
+ token= getToken(IJavaColorConstants.JAVADOC_LINK);
+ list.add(new SingleLineRule("{@link", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$
+ list.add(new SingleLineRule("{@value", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$
+ list.add(new SingleLineRule("{@inheritDoc", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$
+
+
+ // Add generic whitespace rule.
+ token= getToken(IJavaColorConstants.JAVADOC_DEFAULT);
+ list.add(new WhitespaceRule(new JavaWhitespaceDetector(), token));
+
+
+ list.addAll(super.createRules());
+ return list;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.JavaCommentScanner#createMatchers()
+ */
+ protected List<WordMatcher> createMatchers() {
+ List<WordMatcher> list= super.createMatchers();
+
+ // Add word rule for keywords.
+ final IToken token= getToken(IJavaColorConstants.JAVADOC_KEYWORD);
+ WordMatcher matcher= new WordMatcher() {
+ public IToken evaluate(ICharacterScanner scanner, CharacterBuffer word) {
+ int length= word.length();
+ if (length > 1 && word.charAt(0) == '@') {
+ int i= 0;
+ try {
+ for (; i <= length; i++)
+ scanner.unread();
+ int c= scanner.read();
+ i--;
+ if (c == '*' || Character.isWhitespace((char)c)) {
+ scanner.unread();
+ return token;
+ }
+ } finally {
+ for (; i >= 0; i--)
+ scanner.read();
+ }
+ }
+ return Token.UNDEFINED;
+ }
+ };
+ list.add(matcher);
+
+ return list;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaPresentationReconciler.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaPresentationReconciler.java
new file mode 100644
index 0000000..dc53042
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaPresentationReconciler.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+
+
+/**
+ * Presentation reconciler, adding functionality for operation without a viewer.
+ *
+ * @since 3.0
+ */
+public class JavaPresentationReconciler extends PresentationReconciler {
+
+ /** Last used document */
+ private IDocument fLastDocument;
+
+ /**
+ * Constructs a "repair description" for the given damage and returns
+ * this description as a text presentation.
+ * <p>
+ * NOTE: Should not be used if this reconciler is installed on a viewer.
+ * </p>
+ *
+ * @param damage the damage to be repaired
+ * @param document the document whose presentation must be repaired
+ * @return the presentation repair description as text presentation
+ */
+ public TextPresentation createRepairDescription(IRegion damage, IDocument document) {
+ if (document != fLastDocument) {
+ setDocumentToDamagers(document);
+ setDocumentToRepairers(document);
+ fLastDocument= document;
+ }
+ return createPresentation(damage, document);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaSourceViewerConfiguration.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaSourceViewerConfiguration.java
new file mode 100644
index 0000000..43aa2b7
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaSourceViewerConfiguration.java
@@ -0,0 +1,65 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+public class JavaSourceViewerConfiguration extends SourceViewerConfiguration {
+ private JavaTextTools textTools;
+
+ public JavaSourceViewerConfiguration(JavaTextTools textTools) {
+ this.textTools = textTools;
+ }
+
+ public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+ return new String[] {
+ IDocument.DEFAULT_CONTENT_TYPE,
+ IJavaPartitions.JAVA_DOC,
+ IJavaPartitions.JAVA_MULTI_LINE_COMMENT,
+ IJavaPartitions.JAVA_SINGLE_LINE_COMMENT,
+ IJavaPartitions.JAVA_STRING,
+ IJavaPartitions.JAVA_CHARACTER
+ };
+ }
+
+ @Override
+ public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) {
+ return IJavaPartitions.JAVA_PARTITIONING;
+ }
+
+ @Override
+ public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+ PresentationReconciler reconciler= new JavaPresentationReconciler();
+ reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+
+ DefaultDamagerRepairer dr= new DefaultDamagerRepairer(textTools.getCodeScanner());
+ reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+ dr= new DefaultDamagerRepairer(textTools.getJavaDocScanner());
+ reconciler.setDamager(dr, IJavaPartitions.JAVA_DOC);
+ reconciler.setRepairer(dr, IJavaPartitions.JAVA_DOC);
+
+ dr= new DefaultDamagerRepairer(textTools.getMultilineCommentScanner());
+ reconciler.setDamager(dr, IJavaPartitions.JAVA_MULTI_LINE_COMMENT);
+ reconciler.setRepairer(dr, IJavaPartitions.JAVA_MULTI_LINE_COMMENT);
+
+ dr= new DefaultDamagerRepairer(textTools.getSinglelineCommentScanner());
+ reconciler.setDamager(dr, IJavaPartitions.JAVA_SINGLE_LINE_COMMENT);
+ reconciler.setRepairer(dr, IJavaPartitions.JAVA_SINGLE_LINE_COMMENT);
+
+ dr= new DefaultDamagerRepairer(textTools.getStringScanner());
+ reconciler.setDamager(dr, IJavaPartitions.JAVA_STRING);
+ reconciler.setRepairer(dr, IJavaPartitions.JAVA_STRING);
+
+ dr= new DefaultDamagerRepairer(textTools.getStringScanner());
+ reconciler.setDamager(dr, IJavaPartitions.JAVA_CHARACTER);
+ reconciler.setRepairer(dr, IJavaPartitions.JAVA_CHARACTER);
+
+
+ return reconciler;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaTextTools.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaTextTools.java
new file mode 100644
index 0000000..76ab9bf
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaTextTools.java
@@ -0,0 +1,148 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension3;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.FastPartitioner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.ITokenScanner;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+
+public class JavaTextTools {
+ /**
+ * Array with legal content types.
+ * @since 3.0
+ */
+ private final static String[] LEGAL_CONTENT_TYPES= new String[] {
+ IJavaPartitions.JAVA_DOC,
+ IJavaPartitions.JAVA_MULTI_LINE_COMMENT,
+ IJavaPartitions.JAVA_SINGLE_LINE_COMMENT,
+ IJavaPartitions.JAVA_STRING,
+ IJavaPartitions.JAVA_CHARACTER
+ };
+
+ /**
+ * This tools' preference listener.
+ */
+ private class PreferenceListener implements IPropertyChangeListener {
+ public void propertyChange(PropertyChangeEvent event) {
+ adaptToPreferenceChange(event);
+ }
+ }
+
+ /** The color manager. */
+ private JavaColorManager fColorManager;
+ /** The Java source code scanner. */
+ private JavaCodeScanner fCodeScanner;
+ /** The Java multi-line comment scanner. */
+ private JavaCommentScanner fMultilineCommentScanner;
+ /** The Java single-line comment scanner. */
+ private JavaCommentScanner fSinglelineCommentScanner;
+ /** The Java string scanner. */
+ private SingleTokenJavaScanner fStringScanner;
+ /** The JavaDoc scanner. */
+ private JavaDocScanner fJavaDocScanner;
+ /** The preference store. */
+ private IPreferenceStore fPreferenceStore;
+
+ /**
+ * The core preference store.
+ * @since 2.1
+ */
+ /** The preference change listener */
+ private PreferenceListener fPreferenceListener= new PreferenceListener();
+
+ public JavaTextTools(IPreferenceStore store, boolean autoDisposeOnDisplayDispose) {
+ fPreferenceStore = store;
+ fPreferenceStore.addPropertyChangeListener(fPreferenceListener);
+
+ fColorManager= new JavaColorManager(autoDisposeOnDisplayDispose);
+ fCodeScanner= new JavaCodeScanner(fColorManager, store);
+ fMultilineCommentScanner= new JavaCommentScanner(fColorManager, store, IJavaColorConstants.JAVA_MULTI_LINE_COMMENT);
+ fSinglelineCommentScanner= new JavaCommentScanner(fColorManager, store, IJavaColorConstants.JAVA_SINGLE_LINE_COMMENT);
+ fStringScanner= new SingleTokenJavaScanner(fColorManager, store, IJavaColorConstants.JAVA_STRING);
+ fJavaDocScanner= new JavaDocScanner(fColorManager, store);
+ }
+
+ public ITokenScanner getMultilineCommentScanner() {
+ return fMultilineCommentScanner;
+ }
+
+ public ITokenScanner getSinglelineCommentScanner() {
+ return fSinglelineCommentScanner;
+ }
+
+ public ITokenScanner getStringScanner() {
+ return fStringScanner;
+ }
+
+ public ITokenScanner getJavaDocScanner() {
+ return fJavaDocScanner;
+ }
+
+ public ITokenScanner getCodeScanner() {
+ return fCodeScanner;
+ }
+
+ /**
+ * Sets up the Java document partitioner for the given document for the given partitioning.
+ *
+ * @param document the document to be set up
+ * @param partitioning the document partitioning
+ * @since 3.0
+ */
+ public void setupJavaDocumentPartitioner(IDocument document, String partitioning) {
+ IDocumentPartitioner partitioner= createDocumentPartitioner();
+ if (document instanceof IDocumentExtension3) {
+ IDocumentExtension3 extension3= (IDocumentExtension3) document;
+ extension3.setDocumentPartitioner(partitioning, partitioner);
+ } else {
+ document.setDocumentPartitioner(partitioner);
+ }
+ partitioner.connect(document);
+ }
+
+ /**
+ * Returns a scanner which is configured to scan
+ * Java-specific partitions, which are multi-line comments,
+ * Javadoc comments, and regular Java source code.
+ *
+ * @return a Java partition scanner
+ */
+ public IPartitionTokenScanner getPartitionScanner() {
+ return new FastJavaPartitionScanner();
+ }
+
+ /**
+ * Factory method for creating a Java-specific document partitioner
+ * using this object's partitions scanner. This method is a
+ * convenience method.
+ *
+ * @return a newly created Java document partitioner
+ */
+ public IDocumentPartitioner createDocumentPartitioner() {
+ return new FastPartitioner(getPartitionScanner(), LEGAL_CONTENT_TYPES);
+ }
+
+ /**
+ * Adapts the behavior of the contained components to the change
+ * encoded in the given event.
+ *
+ * @param event the event to which to adapt
+ * @since 2.0
+ */
+ private void adaptToPreferenceChange(PropertyChangeEvent event) {
+ if (fCodeScanner.affectsBehavior(event))
+ fCodeScanner.adaptToPreferenceChange(event);
+ if (fMultilineCommentScanner.affectsBehavior(event))
+ fMultilineCommentScanner.adaptToPreferenceChange(event);
+ if (fSinglelineCommentScanner.affectsBehavior(event))
+ fSinglelineCommentScanner.adaptToPreferenceChange(event);
+ if (fStringScanner.affectsBehavior(event))
+ fStringScanner.adaptToPreferenceChange(event);
+ if (fJavaDocScanner.affectsBehavior(event))
+ fJavaDocScanner.adaptToPreferenceChange(event);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaWhitespaceDetector.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaWhitespaceDetector.java
new file mode 100644
index 0000000..a14a2c1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaWhitespaceDetector.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+
+/**
+ * A java aware white space detector.
+ */
+public class JavaWhitespaceDetector implements IWhitespaceDetector {
+
+ /**
+ * @see IWhitespaceDetector#isWhitespace
+ */
+ public boolean isWhitespace(char c) {
+ return Character.isWhitespace(c);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaWordDetector.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaWordDetector.java
new file mode 100644
index 0000000..8d46705
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/JavaWordDetector.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+import org.eclipse.jface.text.rules.IWordDetector;
+
+/**
+ * A Java aware word detector.
+ */
+public class JavaWordDetector implements IWordDetector {
+
+ /*
+ * @see IWordDetector#isWordStart
+ */
+ public boolean isWordStart(char c) {
+ return Character.isJavaIdentifierStart(c);
+ }
+
+ /*
+ * @see IWordDetector#isWordPart
+ */
+ public boolean isWordPart(char c) {
+ return Character.isJavaIdentifierPart(c);
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/PreferenceConstants.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/PreferenceConstants.java
new file mode 100644
index 0000000..502568e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/PreferenceConstants.java
@@ -0,0 +1,92 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+public class PreferenceConstants {
+ /**
+ * Preference key suffix for bold text style preference keys.
+ *
+ * @since 2.1
+ */
+ public static final String EDITOR_BOLD_SUFFIX= "_bold"; //$NON-NLS-1$
+
+ /**
+ * Preference key suffix for italic text style preference keys.
+ *
+ * @since 3.0
+ */
+ public static final String EDITOR_ITALIC_SUFFIX= "_italic"; //$NON-NLS-1$
+
+ /**
+ * Preference key suffix for strikethrough text style preference keys.
+ *
+ * @since 3.1
+ */
+ public static final String EDITOR_STRIKETHROUGH_SUFFIX= "_strikethrough"; //$NON-NLS-1$
+
+ /**
+ * Preference key suffix for underline text style preference keys.
+ *
+ * @since 3.1
+ */
+ public static final String EDITOR_UNDERLINE_SUFFIX= "_underline"; //$NON-NLS-1$
+
+ /**
+ * A named preference prefix for semantic highlighting preferences.
+ *
+ * @since 3.0
+ */
+ public static final String EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX="semanticHighlighting."; //$NON-NLS-1$
+
+ /**
+ * A named preference suffix that controls a semantic highlighting's color.
+ * <p>
+ * Value is of type <code>String</code>. A RGB color value encoded as a string
+ * using class <code>PreferenceConverter</code>
+ * </p>
+ *
+ * @see org.eclipse.jface.resource.StringConverter
+ * @see org.eclipse.jface.preference.PreferenceConverter
+ * @since 3.0
+ */
+ public static final String EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX=".color"; //$NON-NLS-1$
+
+ /**
+ * A named preference suffix that controls if semantic highlighting has the text attribute bold.
+ * <p>
+ * Value is of type <code>Boolean</code>: <code>true</code> if bold.
+ * </p>
+ *
+ * @since 3.0
+ */
+ public static final String EDITOR_SEMANTIC_HIGHLIGHTING_BOLD_SUFFIX=".bold"; //$NON-NLS-1$
+
+ /**
+ * A named preference suffix that controls if semantic highlighting has the text attribute italic.
+ * <p>
+ * Value is of type <code>Boolean</code>: <code>true</code> if italic.
+ * </p>
+ *
+ * @since 3.0
+ */
+ public static final String EDITOR_SEMANTIC_HIGHLIGHTING_ITALIC_SUFFIX=".italic"; //$NON-NLS-1$
+
+ /**
+ * A named preference suffix that controls if semantic highlighting has the text attribute strikethrough.
+ * <p>
+ * Value is of type <code>Boolean</code>: <code>true</code> if strikethrough.
+ * </p>
+ *
+ * @since 3.1
+ */
+ public static final String EDITOR_SEMANTIC_HIGHLIGHTING_STRIKETHROUGH_SUFFIX=".strikethrough"; //$NON-NLS-1$
+
+ /**
+ * A named preference suffix that controls if semantic highlighting has the text attribute underline.
+ * <p>
+ * Value is of type <code>Boolean</code>: <code>true</code> if underline.
+ * </p>
+ *
+ * @since 3.1
+ */
+ public static final String EDITOR_SEMANTIC_HIGHLIGHTING_UNDERLINE_SUFFIX=".underline"; //$NON-NLS-1$
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/SemanticHighlightings.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/SemanticHighlightings.java
new file mode 100644
index 0000000..bc51f61
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/SemanticHighlightings.java
@@ -0,0 +1,10 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+public class SemanticHighlightings {
+ /**
+ * A named preference part that controls the highlighting of annotations.
+ *
+ * @since 3.2
+ */
+ public static final String ANNOTATION="annotation"; //$NON-NLS-1$
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/SingleTokenJavaScanner.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/SingleTokenJavaScanner.java
new file mode 100644
index 0000000..6df6041
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/scanners/SingleTokenJavaScanner.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.e4.demo.simpleide.jdt.internal.editor.scanners;
+
+
+import java.util.List;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.rules.IRule;
+
+
+/**
+ *
+ */
+public final class SingleTokenJavaScanner extends AbstractJavaScanner{
+
+
+ private String[] fProperty;
+
+ public SingleTokenJavaScanner(IColorManager manager, IPreferenceStore store, String property) {
+ super(manager, store);
+ fProperty= new String[] { property };
+ initialize();
+ }
+
+ /*
+ * @see AbstractJavaScanner#getTokenProperties()
+ */
+ protected String[] getTokenProperties() {
+ return fProperty;
+ }
+
+ /*
+ * @see AbstractJavaScanner#createRules()
+ */
+ protected List<IRule> createRules() {
+ setDefaultReturnToken(getToken(fProperty[0]));
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/AppearanceAwareLabelProvider.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/AppearanceAwareLabelProvider.java
new file mode 100644
index 0000000..4931a54
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/AppearanceAwareLabelProvider.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 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
+ * Guven Demir <guven.internet+eclipse@gmail.com> - [package explorer] Alternative package name shortening: abbreviation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=299514
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.demo.simpleide.jdt.internal.JavaUIMessages;
+
+public class AppearanceAwareLabelProvider extends JavaUILabelProvider {
+ public final static long DEFAULT_TEXTFLAGS = JavaElementLabels.ROOT_VARIABLE
+ | JavaElementLabels.T_TYPE_PARAMETERS
+ | JavaElementLabels.M_PARAMETER_TYPES
+ | JavaElementLabels.M_APP_TYPE_PARAMETERS
+ | JavaElementLabels.M_APP_RETURNTYPE
+ | JavaElementLabels.REFERENCED_ROOT_POST_QUALIFIED;
+ public final static int DEFAULT_IMAGEFLAGS= JavaElementImageProvider.OVERLAY_ICONS;
+
+// private long fTextFlagMask;
+
+ public AppearanceAwareLabelProvider(long textFlags, int imageFlags, Logger logger,
+ JavaUIMessages messages) {
+ super(textFlags, imageFlags, logger, messages);
+// initMasks();
+ }
+
+ /**
+ * Creates a labelProvider with DEFAULT_TEXTFLAGS and DEFAULT_IMAGEFLAGS
+ */
+ public AppearanceAwareLabelProvider(Logger logger, JavaUIMessages messages) {
+ this(DEFAULT_TEXTFLAGS, DEFAULT_IMAGEFLAGS, logger, messages);
+ }
+
+// private void initMasks() {
+// IPreferenceStore store= PreferenceConstants.getPreferenceStore();
+// fTextFlagMask= -1;
+// if (!store.getBoolean(PreferenceConstants.APPEARANCE_METHOD_RETURNTYPE)) {
+// fTextFlagMask ^= JavaElementLabels.M_APP_RETURNTYPE;
+// }
+// if (!store.getBoolean(PreferenceConstants.APPEARANCE_METHOD_TYPEPARAMETERS)) {
+// fTextFlagMask ^= JavaElementLabels.M_APP_TYPE_PARAMETERS;
+// }
+// if (!(store.getBoolean(PreferenceConstants.APPEARANCE_COMPRESS_PACKAGE_NAMES)
+// || store.getBoolean(JavaElementLabelComposer.APPEARANCE_ABBREVIATE_PACKAGE_NAMES))) {
+// fTextFlagMask ^= JavaElementLabels.P_COMPRESSED;
+// }
+// if (!store.getBoolean(PreferenceConstants.APPEARANCE_CATEGORY)) {
+// fTextFlagMask ^= JavaElementLabels.ALL_CATEGORY;
+// }
+//
+// fImageFlagMask= -1;
+// }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/ImageDescriptorRegistry.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/ImageDescriptorRegistry.java
new file mode 100644
index 0000000..22db248
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/ImageDescriptorRegistry.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * A registry that maps <code>ImageDescriptors</code> to <code>Image</code>.
+ */
+public class ImageDescriptorRegistry {
+
+ private HashMap<ImageDescriptor,Image> fRegistry= new HashMap<ImageDescriptor,Image>(10);
+ private Display fDisplay;
+
+ /**
+ * Creates a new image descriptor registry for the current or default display,
+ * respectively.
+ */
+ public ImageDescriptorRegistry() {
+ this(Display.getCurrent());
+ }
+
+ /**
+ * Creates a new image descriptor registry for the given display. All images
+ * managed by this registry will be disposed when the display gets disposed.
+ *
+ * @param display the display the images managed by this registry are allocated for
+ */
+ public ImageDescriptorRegistry(Display display) {
+ fDisplay= display;
+ Assert.isNotNull(fDisplay);
+ hookDisplay();
+ }
+
+ /**
+ * Returns the image associated with the given image descriptor.
+ *
+ * @param descriptor the image descriptor for which the registry manages an image,
+ * or <code>null</code> for a missing image descriptor
+ * @return the image associated with the image descriptor or <code>null</code>
+ * if the image descriptor can't create the requested image.
+ */
+ public Image get(ImageDescriptor descriptor) {
+ if (descriptor == null)
+ descriptor= ImageDescriptor.getMissingImageDescriptor();
+
+ Image result= (Image)fRegistry.get(descriptor);
+ if (result != null)
+ return result;
+
+ Assert.isTrue(fDisplay == Display.getCurrent(), "Allocating image for wrong display."); //$NON-NLS-1$
+ result= descriptor.createImage();
+ if (result != null)
+ fRegistry.put(descriptor, result);
+ return result;
+ }
+
+ /**
+ * Disposes all images managed by this registry.
+ */
+ public void dispose() {
+ for (Iterator<Image> iter= fRegistry.values().iterator(); iter.hasNext(); ) {
+ Image image= (Image)iter.next();
+ image.dispose();
+ }
+ fRegistry.clear();
+ }
+
+ private void hookDisplay() {
+ fDisplay.disposeExec(new Runnable() {
+ public void run() {
+ dispose();
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementImageDescriptor.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementImageDescriptor.java
new file mode 100644
index 0000000..95a2cfd
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementImageDescriptor.java
@@ -0,0 +1,274 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.jface.resource.CompositeImageDescriptor;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+
+public class JavaElementImageDescriptor extends CompositeImageDescriptor {
+ /** Flag to render the abstract adornment. */
+ public final static int ABSTRACT= 0x001;
+
+ /** Flag to render the final adornment. */
+ public final static int FINAL= 0x002;
+
+ /** Flag to render the synchronized adornment. */
+ public final static int SYNCHRONIZED= 0x004;
+
+ /** Flag to render the static adornment. */
+ public final static int STATIC= 0x008;
+
+ /** Flag to render the runnable adornment. */
+ public final static int RUNNABLE= 0x010;
+
+ /** Flag to render the warning adornment. */
+ public final static int WARNING= 0x020;
+
+ /** Flag to render the error adornment. */
+ public final static int ERROR= 0x040;
+
+ /** Flag to render the 'override' adornment. */
+ public final static int OVERRIDES= 0x080;
+
+ /** Flag to render the 'implements' adornment. */
+ public final static int IMPLEMENTS= 0x100;
+
+ /** Flag to render the 'constructor' adornment. */
+ public final static int CONSTRUCTOR= 0x200;
+
+ /**
+ * Flag to render the 'deprecated' adornment.
+ * @since 3.0
+ */
+ public final static int DEPRECATED= 0x400;
+
+ /**
+ * Flag to render the 'volatile' adornment.
+ * @since 3.3
+ */
+ public final static int VOLATILE= 0x800;
+
+ /**
+ * Flag to render the 'transient' adornment.
+ * @since 3.3
+ */
+ public final static int TRANSIENT= 0x1000;
+
+ private ImageDescriptor fBaseImage;
+ private int fFlags;
+ private Point fSize;
+ private Logger logger;
+
+ /**
+ * Creates a new JavaElementImageDescriptor.
+ *
+ * @param baseImage an image descriptor used as the base image
+ * @param flags flags indicating which adornments are to be rendered. See {@link #setAdornments(int)}
+ * for valid values.
+ * @param size the size of the resulting image
+ */
+ public JavaElementImageDescriptor(ImageDescriptor baseImage, int flags, Point size, Logger logger) {
+ this.logger = logger;
+ fBaseImage= baseImage;
+ Assert.isNotNull(fBaseImage);
+ fFlags= flags;
+ Assert.isTrue(fFlags >= 0);
+ fSize= size;
+ Assert.isNotNull(fSize);
+ }
+
+ /**
+ * Sets the descriptors adornments. Valid values are: {@link #ABSTRACT}, {@link #FINAL},
+ * {@link #SYNCHRONIZED}, {@link #STATIC}, {@link #RUNNABLE}, {@link #WARNING},
+ * {@link #ERROR}, {@link #OVERRIDES}, {@link #IMPLEMENTS}, {@link #CONSTRUCTOR},
+ * {@link #DEPRECATED}, {@link #VOLATILE}, {@link #TRANSIENT} or any combination of those.
+ *
+ * @param adornments the image descriptors adornments
+ */
+ public void setAdornments(int adornments) {
+ Assert.isTrue(adornments >= 0);
+ fFlags= adornments;
+ }
+
+ /**
+ * Returns the current adornments.
+ *
+ * @return the current adornments
+ */
+ public int getAdronments() {
+ return fFlags;
+ }
+
+ /**
+ * Sets the size of the image created by calling {@link #createImage()}.
+ *
+ * @param size the size of the image returned from calling {@link #createImage()}
+ */
+ public void setImageSize(Point size) {
+ Assert.isNotNull(size);
+ Assert.isTrue(size.x >= 0 && size.y >= 0);
+ fSize= size;
+ }
+
+ /**
+ * Returns the size of the image created by calling {@link #createImage()}.
+ *
+ * @return the size of the image created by calling {@link #createImage()}
+ */
+ public Point getImageSize() {
+ return new Point(fSize.x, fSize.y);
+ }
+
+ /* (non-Javadoc)
+ * Method declared in CompositeImageDescriptor
+ */
+ protected Point getSize() {
+ return fSize;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on Object.
+ */
+ public boolean equals(Object object) {
+ if (object == null || !JavaElementImageDescriptor.class.equals(object.getClass()))
+ return false;
+
+ JavaElementImageDescriptor other= (JavaElementImageDescriptor)object;
+ return (fBaseImage.equals(other.fBaseImage) && fFlags == other.fFlags && fSize.equals(other.fSize));
+ }
+
+ /* (non-Javadoc)
+ * Method declared on Object.
+ */
+ public int hashCode() {
+ return fBaseImage.hashCode() | fFlags | fSize.hashCode();
+ }
+
+ /* (non-Javadoc)
+ * Method declared in CompositeImageDescriptor
+ */
+ protected void drawCompositeImage(int width, int height) {
+ ImageData bg= getImageData(fBaseImage);
+
+ if ((fFlags & DEPRECATED) != 0) { // draw *behind* the full image
+ Point size= getSize();
+ ImageData data= getImageData(JavaPluginImages.DESC_OVR_DEPRECATED);
+ drawImage(data, 0, size.y - data.height);
+ }
+ drawImage(bg, 0, 0);
+
+ drawTopRight();
+ drawBottomRight();
+ drawBottomLeft();
+
+
+ }
+
+ private ImageData getImageData(ImageDescriptor descriptor) {
+ ImageData data= descriptor.getImageData(); // see bug 51965: getImageData can return null
+ if (data == null) {
+ data= DEFAULT_IMAGE_DATA;
+ logger.error("Image data not available: " + descriptor.toString());
+ }
+ return data;
+ }
+
+ private void addTopRightImage(ImageDescriptor desc, Point pos) {
+ ImageData data= getImageData(desc);
+ int x= pos.x - data.width;
+ if (x >= 0) {
+ drawImage(data, x, pos.y);
+ pos.x= x;
+ }
+ }
+
+ private void addBottomRightImage(ImageDescriptor desc, Point pos) {
+ ImageData data= getImageData(desc);
+ int x= pos.x - data.width;
+ int y= pos.y - data.height;
+ if (x >= 0 && y >= 0) {
+ drawImage(data, x, y);
+ pos.x= x;
+ }
+ }
+
+ private void addBottomLeftImage(ImageDescriptor desc, Point pos) {
+ ImageData data= getImageData(desc);
+ int x= pos.x;
+ int y= pos.y - data.height;
+ if (x + data.width < getSize().x && y >= 0) {
+ drawImage(data, x, y);
+ pos.x= x + data.width;
+ }
+ }
+
+
+ private void drawTopRight() {
+ Point pos= new Point(getSize().x, 0);
+ if ((fFlags & ABSTRACT) != 0) {
+ addTopRightImage(JavaPluginImages.DESC_OVR_ABSTRACT, pos);
+ }
+ if ((fFlags & CONSTRUCTOR) != 0) {
+ addTopRightImage(JavaPluginImages.DESC_OVR_CONSTRUCTOR, pos);
+ }
+ if ((fFlags & FINAL) != 0) {
+ addTopRightImage(JavaPluginImages.DESC_OVR_FINAL, pos);
+ }
+ if ((fFlags & VOLATILE) != 0) {
+ addTopRightImage(JavaPluginImages.DESC_OVR_VOLATILE, pos);
+ }
+ if ((fFlags & STATIC) != 0) {
+ addTopRightImage(JavaPluginImages.DESC_OVR_STATIC, pos);
+ }
+
+ }
+
+ private void drawBottomRight() {
+ Point size= getSize();
+ Point pos= new Point(size.x, size.y);
+
+ int flags= fFlags;
+
+ int syncAndOver= SYNCHRONIZED | OVERRIDES;
+ int syncAndImpl= SYNCHRONIZED | IMPLEMENTS;
+
+ if ((flags & syncAndOver) == syncAndOver) { // both flags set: merged overlay image
+ addBottomRightImage(JavaPluginImages.DESC_OVR_SYNCH_AND_OVERRIDES, pos);
+ flags &= ~syncAndOver; // clear to not render again
+ } else if ((flags & syncAndImpl) == syncAndImpl) { // both flags set: merged overlay image
+ addBottomRightImage(JavaPluginImages.DESC_OVR_SYNCH_AND_IMPLEMENTS, pos);
+ flags &= ~syncAndImpl; // clear to not render again
+ }
+ if ((flags & OVERRIDES) != 0) {
+ addBottomRightImage(JavaPluginImages.DESC_OVR_OVERRIDES, pos);
+ }
+ if ((flags & IMPLEMENTS) != 0) {
+ addBottomRightImage(JavaPluginImages.DESC_OVR_IMPLEMENTS, pos);
+ }
+ if ((flags & SYNCHRONIZED) != 0) {
+ addBottomRightImage(JavaPluginImages.DESC_OVR_SYNCH, pos);
+ }
+ if ((flags & RUNNABLE) != 0) {
+ addBottomRightImage(JavaPluginImages.DESC_OVR_RUN, pos);
+ }
+ if ((flags & TRANSIENT) != 0) {
+ addBottomRightImage(JavaPluginImages.DESC_OVR_TRANSIENT, pos);
+ }
+ }
+
+ private void drawBottomLeft() {
+ Point pos= new Point(0, getSize().y);
+ if ((fFlags & ERROR) != 0) {
+ addBottomLeftImage(JavaPluginImages.DESC_OVR_ERROR, pos);
+ }
+//FIXME if ((fFlags & PackageExplorerProblemsDecorator.BUILDPATH_ERROR) != 0) {
+// addBottomLeftImage(JavaPluginImages.DESC_OVR_BUILDPATH_ERROR, pos);
+// }
+ if ((fFlags & WARNING) != 0) {
+ addBottomLeftImage(JavaPluginImages.DESC_OVR_WARNING, pos);
+ }
+
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementImageProvider.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementImageProvider.java
new file mode 100644
index 0000000..dc86e34
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementImageProvider.java
@@ -0,0 +1,482 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+
+public class JavaElementImageProvider {
+ private Logger logger;
+
+ /**
+ * Flags for the JavaImageLabelProvider:
+ * Generate images with overlays.
+ */
+ public final static int OVERLAY_ICONS= 0x1;
+
+ /**
+ * Generate small sized images.
+ */
+ public final static int SMALL_ICONS= 0x2;
+
+ /**
+ * Use the 'light' style for rendering types.
+ */
+ public final static int LIGHT_TYPE_ICONS= 0x4;
+
+ public static final Point SMALL_SIZE= new Point(16, 16);
+ public static final Point BIG_SIZE= new Point(22, 16);
+
+// private static ImageDescriptor DESC_OBJ_PROJECT_CLOSED;
+// private static ImageDescriptor DESC_OBJ_PROJECT;
+// {
+// SharedImageKeys images = JavaPlugin.getDefault().getWorkbench().getSharedImages();
+// DESC_OBJ_PROJECT_CLOSED= images.getImageDescriptor(IDE.SharedImages.IMG_OBJ_PROJECT_CLOSED);
+// DESC_OBJ_PROJECT= images.getImageDescriptor(IDE.SharedImages.IMG_OBJ_PROJECT);
+// }
+
+ private ImageDescriptorRegistry fRegistry;
+
+ public JavaElementImageProvider(Logger logger) {
+ this.logger = logger;
+ }
+
+ /**
+ * Returns the icon for a given element. The icon depends on the element type
+ * and element properties. If configured, overlay icons are constructed for
+ * <code>ISourceReference</code>s.
+ * @param element the element
+ * @param flags Flags as defined by the JavaImageLabelProvider
+ * @return return the image or <code>null</code>
+ */
+ public Image getImageLabel(Object element, int flags, Logger logger) {
+ return getImageLabel(computeDescriptor(element, flags,logger));
+ }
+
+ private Image getImageLabel(ImageDescriptor descriptor){
+ if (descriptor == null)
+ return null;
+ return getRegistry().get(descriptor);
+ }
+
+ private ImageDescriptorRegistry getRegistry() {
+ if (fRegistry == null) {
+ fRegistry= JavaPluginImages.IMAGE_DESCRIPTOR_REGISTRY;
+ }
+ return fRegistry;
+ }
+
+
+ private ImageDescriptor computeDescriptor(Object element, int flags, Logger logger){
+ if (element instanceof IJavaElement) {
+ return getJavaImageDescriptor((IJavaElement) element, flags, logger);
+ }
+ return null;
+ }
+
+ /**
+ * Returns an image descriptor for a java element. The descriptor includes overlays, if specified.
+ * @param element the Java element
+ * @param flags the image flags
+ * @return returns the image descriptor
+ */
+ public ImageDescriptor getJavaImageDescriptor(IJavaElement element, int flags, Logger logger) {
+ Point size= useSmallSize(flags) ? SMALL_SIZE : BIG_SIZE;
+
+ ImageDescriptor baseDesc= getBaseImageDescriptor(element, flags);
+ if (baseDesc != null) {
+ int adornmentFlags= computeJavaAdornmentFlags(element, flags);
+ return new JavaElementImageDescriptor(baseDesc, adornmentFlags, size, logger);
+ }
+ return new JavaElementImageDescriptor(JavaPluginImages.DESC_OBJS_GHOST, 0, size, logger);
+ }
+
+ /**
+ * Returns an image descriptor for a java element. This is the base image, no overlays.
+ * @param element the element
+ * @param renderFlags the image flags
+ * @return returns the image descriptor
+ */
+ public ImageDescriptor getBaseImageDescriptor(IJavaElement element, int renderFlags) {
+
+ try {
+ switch (element.getElementType()) {
+ case IJavaElement.INITIALIZER:
+ return JavaPluginImages.DESC_MISC_PRIVATE; // 23479
+ case IJavaElement.METHOD: {
+ IMethod method= (IMethod) element;
+ IType declType= method.getDeclaringType();
+ int flags= method.getFlags();
+ if (declType.isEnum() && isDefaultFlag(flags) && method.isConstructor())
+ return JavaPluginImages.DESC_MISC_PRIVATE;
+ return getMethodImageDescriptor(JavaModelUtil.isInterfaceOrAnnotation(declType), flags);
+ }
+ case IJavaElement.FIELD: {
+ IMember member= (IMember) element;
+ IType declType= member.getDeclaringType();
+ return getFieldImageDescriptor(JavaModelUtil.isInterfaceOrAnnotation(declType), member.getFlags());
+ }
+ case IJavaElement.LOCAL_VARIABLE:
+ return JavaPluginImages.DESC_OBJS_LOCAL_VARIABLE;
+
+ case IJavaElement.PACKAGE_DECLARATION:
+ return JavaPluginImages.DESC_OBJS_PACKDECL;
+
+ case IJavaElement.IMPORT_DECLARATION:
+ return JavaPluginImages.DESC_OBJS_IMPDECL;
+
+ case IJavaElement.IMPORT_CONTAINER:
+ return JavaPluginImages.DESC_OBJS_IMPCONT;
+
+ case IJavaElement.TYPE: {
+ IType type= (IType) element;
+
+ IType declType= type.getDeclaringType();
+ boolean isInner= declType != null;
+ boolean isInInterfaceOrAnnotation= isInner && JavaModelUtil.isInterfaceOrAnnotation(declType);
+ return getTypeImageDescriptor(isInner, isInInterfaceOrAnnotation, type.getFlags(), useLightIcons(renderFlags));
+ }
+
+ case IJavaElement.PACKAGE_FRAGMENT_ROOT: {
+ IPackageFragmentRoot root= (IPackageFragmentRoot) element;
+ IPath attach= root.getSourceAttachmentPath();
+ if (root.getKind() == IPackageFragmentRoot.K_BINARY) {
+ if (root.isArchive()) {
+ if (root.isExternal()) {
+ if (attach == null) {
+ return JavaPluginImages.DESC_OBJS_EXTJAR;
+ } else {
+ return JavaPluginImages.DESC_OBJS_EXTJAR_WSRC;
+ }
+ } else {
+ if (attach == null) {
+ return JavaPluginImages.DESC_OBJS_JAR;
+ } else {
+ return JavaPluginImages.DESC_OBJS_JAR_WSRC;
+ }
+ }
+ } else {
+ if (attach == null) {
+ return JavaPluginImages.DESC_OBJS_CLASSFOLDER;
+ } else {
+ return JavaPluginImages.DESC_OBJS_CLASSFOLDER_WSRC;
+ }
+ }
+ } else {
+ return JavaPluginImages.DESC_OBJS_PACKFRAG_ROOT;
+ }
+ }
+
+ case IJavaElement.PACKAGE_FRAGMENT:
+ return getPackageFragmentIcon(element);
+
+
+ case IJavaElement.COMPILATION_UNIT:
+ return JavaPluginImages.DESC_OBJS_CUNIT;
+
+ case IJavaElement.CLASS_FILE:
+ /* this is too expensive for large packages
+ try {
+ IClassFile cfile= (IClassFile)element;
+ if (cfile.isClass())
+ return JavaPluginImages.IMG_OBJS_CFILECLASS;
+ return JavaPluginImages.IMG_OBJS_CFILEINT;
+ } catch(JavaModelException e) {
+ // fall through;
+ }*/
+ return JavaPluginImages.DESC_OBJS_CFILE;
+
+ case IJavaElement.JAVA_PROJECT:
+ IJavaProject jp= (IJavaProject)element;
+ if (jp.getProject().isOpen()) {
+//FIXME IProject project= jp.getProject();
+// IWorkbenchAdapter adapter= (IWorkbenchAdapter)project.getAdapter(IWorkbenchAdapter.class);
+// if (adapter != null) {
+// ImageDescriptor result= adapter.getImageDescriptor(project);
+// if (result != null)
+// return result;
+// }
+ return JavaPluginImages.DESC_OBJ_PROJECT;
+ }
+ return JavaPluginImages.DESC_OBJ_PROJECT_CLOSED;
+ case IJavaElement.JAVA_MODEL:
+ return JavaPluginImages.DESC_OBJS_JAVA_MODEL;
+
+ case IJavaElement.TYPE_PARAMETER:
+ return JavaPluginImages.DESC_OBJS_TYPEVARIABLE;
+
+ case IJavaElement.ANNOTATION:
+ return JavaPluginImages.DESC_OBJS_ANNOTATION;
+
+ default:
+ // ignore. Must be a new, yet unknown Java element
+ // give an advanced IWorkbenchAdapter the chance
+//FIXME IWorkbenchAdapter wbAdapter= (IWorkbenchAdapter) element.getAdapter(IWorkbenchAdapter.class);
+// if (wbAdapter != null && !(wbAdapter instanceof JavaWorkbenchAdapter)) { // avoid recursion
+// ImageDescriptor imageDescriptor= wbAdapter.getImageDescriptor(element);
+// if (imageDescriptor != null) {
+// return imageDescriptor;
+// }
+// }
+ return JavaPluginImages.DESC_OBJS_GHOST;
+ }
+
+ } catch (JavaModelException e) {
+ if (e.isDoesNotExist())
+ return JavaPluginImages.DESC_OBJS_UNKNOWN;
+ logger.error(e);
+ return JavaPluginImages.DESC_OBJS_GHOST;
+ }
+ }
+
+ public static ImageDescriptor getMethodImageDescriptor(boolean isInInterfaceOrAnnotation, int flags) {
+ if (Flags.isPublic(flags) || isInInterfaceOrAnnotation)
+ return JavaPluginImages.DESC_MISC_PUBLIC;
+ if (Flags.isProtected(flags))
+ return JavaPluginImages.DESC_MISC_PROTECTED;
+ if (Flags.isPrivate(flags))
+ return JavaPluginImages.DESC_MISC_PRIVATE;
+
+ return JavaPluginImages.DESC_MISC_DEFAULT;
+ }
+
+ public static ImageDescriptor getFieldImageDescriptor(boolean isInInterfaceOrAnnotation, int flags) {
+ if (Flags.isPublic(flags) || isInInterfaceOrAnnotation || Flags.isEnum(flags))
+ return JavaPluginImages.DESC_FIELD_PUBLIC;
+ if (Flags.isProtected(flags))
+ return JavaPluginImages.DESC_FIELD_PROTECTED;
+ if (Flags.isPrivate(flags))
+ return JavaPluginImages.DESC_FIELD_PRIVATE;
+
+ return JavaPluginImages.DESC_FIELD_DEFAULT;
+ }
+
+ private static boolean isDefaultFlag(int flags) {
+ return !Flags.isPublic(flags) && !Flags.isProtected(flags) && !Flags.isPrivate(flags);
+ }
+
+ private static boolean useSmallSize(int flags) {
+ return (flags & SMALL_ICONS) != 0;
+ }
+
+ private ImageDescriptor getPackageFragmentIcon(IJavaElement element) throws JavaModelException {
+ IPackageFragment fragment= (IPackageFragment)element;
+ boolean containsJavaElements= false;
+ try {
+ containsJavaElements= fragment.hasChildren();
+ } catch(JavaModelException e) {
+ // assuming no children;
+ }
+ if(!containsJavaElements && (fragment.getNonJavaResources().length > 0))
+ return JavaPluginImages.DESC_OBJS_EMPTY_PACKAGE_RESOURCES;
+ else if (!containsJavaElements)
+ return JavaPluginImages.DESC_OBJS_EMPTY_PACKAGE;
+ return JavaPluginImages.DESC_OBJS_PACKAGE;
+ }
+
+ private static boolean useLightIcons(int flags) {
+ return (flags & LIGHT_TYPE_ICONS) != 0;
+ }
+
+ public static ImageDescriptor getTypeImageDescriptor(boolean isInner, boolean isInInterfaceOrAnnotation, int flags, boolean useLightIcons) {
+ if (Flags.isEnum(flags)) {
+ if (useLightIcons) {
+ return JavaPluginImages.DESC_OBJS_ENUM_ALT;
+ }
+ if (isInner) {
+ return getInnerEnumImageDescriptor(isInInterfaceOrAnnotation, flags);
+ }
+ return getEnumImageDescriptor(flags);
+ } else if (Flags.isAnnotation(flags)) {
+ if (useLightIcons) {
+ return JavaPluginImages.DESC_OBJS_ANNOTATION_ALT;
+ }
+ if (isInner) {
+ return getInnerAnnotationImageDescriptor(isInInterfaceOrAnnotation, flags);
+ }
+ return getAnnotationImageDescriptor(flags);
+ } else if (Flags.isInterface(flags)) {
+ if (useLightIcons) {
+ return JavaPluginImages.DESC_OBJS_INTERFACEALT;
+ }
+ if (isInner) {
+ return getInnerInterfaceImageDescriptor(isInInterfaceOrAnnotation, flags);
+ }
+ return getInterfaceImageDescriptor(flags);
+ } else {
+ if (useLightIcons) {
+ return JavaPluginImages.DESC_OBJS_CLASSALT;
+ }
+ if (isInner) {
+ return getInnerClassImageDescriptor(isInInterfaceOrAnnotation, flags);
+ }
+ return getClassImageDescriptor(flags);
+ }
+ }
+
+ private static ImageDescriptor getInnerEnumImageDescriptor(boolean isInInterfaceOrAnnotation, int flags) {
+ if (Flags.isPublic(flags) || isInInterfaceOrAnnotation)
+ return JavaPluginImages.DESC_OBJS_ENUM;
+ else if (Flags.isPrivate(flags))
+ return JavaPluginImages.DESC_OBJS_ENUM_PRIVATE;
+ else if (Flags.isProtected(flags))
+ return JavaPluginImages.DESC_OBJS_ENUM_PROTECTED;
+ else
+ return JavaPluginImages.DESC_OBJS_ENUM_DEFAULT;
+ }
+
+ private static ImageDescriptor getEnumImageDescriptor(int flags) {
+ if (Flags.isPublic(flags) || Flags.isProtected(flags) || Flags.isPrivate(flags))
+ return JavaPluginImages.DESC_OBJS_ENUM;
+ else
+ return JavaPluginImages.DESC_OBJS_ENUM_DEFAULT;
+ }
+
+ private static ImageDescriptor getInnerAnnotationImageDescriptor(boolean isInInterfaceOrAnnotation, int flags) {
+ if (Flags.isPublic(flags) || isInInterfaceOrAnnotation)
+ return JavaPluginImages.DESC_OBJS_ANNOTATION;
+ else if (Flags.isPrivate(flags))
+ return JavaPluginImages.DESC_OBJS_ANNOTATION_PRIVATE;
+ else if (Flags.isProtected(flags))
+ return JavaPluginImages.DESC_OBJS_ANNOTATION_PROTECTED;
+ else
+ return JavaPluginImages.DESC_OBJS_ANNOTATION_DEFAULT;
+ }
+
+ private static ImageDescriptor getAnnotationImageDescriptor(int flags) {
+ if (Flags.isPublic(flags) || Flags.isProtected(flags) || Flags.isPrivate(flags))
+ return JavaPluginImages.DESC_OBJS_ANNOTATION;
+ else
+ return JavaPluginImages.DESC_OBJS_ANNOTATION_DEFAULT;
+ }
+
+ private static ImageDescriptor getInnerInterfaceImageDescriptor(boolean isInInterfaceOrAnnotation, int flags) {
+ if (Flags.isPublic(flags) || isInInterfaceOrAnnotation)
+ return JavaPluginImages.DESC_OBJS_INNER_INTERFACE_PUBLIC;
+ else if (Flags.isPrivate(flags))
+ return JavaPluginImages.DESC_OBJS_INNER_INTERFACE_PRIVATE;
+ else if (Flags.isProtected(flags))
+ return JavaPluginImages.DESC_OBJS_INNER_INTERFACE_PROTECTED;
+ else
+ return JavaPluginImages.DESC_OBJS_INTERFACE_DEFAULT;
+ }
+
+ private static ImageDescriptor getInterfaceImageDescriptor(int flags) {
+ if (Flags.isPublic(flags) || Flags.isProtected(flags) || Flags.isPrivate(flags))
+ return JavaPluginImages.DESC_OBJS_INTERFACE;
+ else
+ return JavaPluginImages.DESC_OBJS_INTERFACE_DEFAULT;
+ }
+
+ private static ImageDescriptor getInnerClassImageDescriptor(boolean isInInterfaceOrAnnotation, int flags) {
+ if (Flags.isPublic(flags) || isInInterfaceOrAnnotation)
+ return JavaPluginImages.DESC_OBJS_INNER_CLASS_PUBLIC;
+ else if (Flags.isPrivate(flags))
+ return JavaPluginImages.DESC_OBJS_INNER_CLASS_PRIVATE;
+ else if (Flags.isProtected(flags))
+ return JavaPluginImages.DESC_OBJS_INNER_CLASS_PROTECTED;
+ else
+ return JavaPluginImages.DESC_OBJS_INNER_CLASS_DEFAULT;
+ }
+
+ private static ImageDescriptor getClassImageDescriptor(int flags) {
+ if (Flags.isPublic(flags) || Flags.isProtected(flags) || Flags.isPrivate(flags))
+ return JavaPluginImages.DESC_OBJS_CLASS;
+ else
+ return JavaPluginImages.DESC_OBJS_CLASS_DEFAULT;
+ }
+
+ private static boolean showOverlayIcons(int flags) {
+ return (flags & OVERLAY_ICONS) != 0;
+ }
+
+ private int computeJavaAdornmentFlags(IJavaElement element, int renderFlags) {
+ int flags= 0;
+ if (showOverlayIcons(renderFlags) && element instanceof IMember) {
+ try {
+ IMember member= (IMember) element;
+
+ if (element.getElementType() == IJavaElement.METHOD && ((IMethod)element).isConstructor())
+ flags |= JavaElementImageDescriptor.CONSTRUCTOR;
+
+ int modifiers= member.getFlags();
+ if (Flags.isAbstract(modifiers) && confirmAbstract(member))
+ flags |= JavaElementImageDescriptor.ABSTRACT;
+ if (Flags.isFinal(modifiers) || isInterfaceOrAnnotationField(member) || isEnumConstant(member, modifiers))
+ flags |= JavaElementImageDescriptor.FINAL;
+ if (Flags.isSynchronized(modifiers) && confirmSynchronized(member))
+ flags |= JavaElementImageDescriptor.SYNCHRONIZED;
+ if (Flags.isStatic(modifiers) || isInterfaceOrAnnotationFieldOrType(member) || isEnumConstant(member, modifiers))
+ flags |= JavaElementImageDescriptor.STATIC;
+
+ if (Flags.isDeprecated(modifiers))
+ flags |= JavaElementImageDescriptor.DEPRECATED;
+ if (member.getElementType() == IJavaElement.TYPE) {
+ if (JavaModelUtil.hasMainMethod((IType) member)) {
+ flags |= JavaElementImageDescriptor.RUNNABLE;
+ }
+ }
+ if (member.getElementType() == IJavaElement.FIELD) {
+ if (Flags.isVolatile(modifiers))
+ flags |= JavaElementImageDescriptor.VOLATILE;
+ if (Flags.isTransient(modifiers))
+ flags |= JavaElementImageDescriptor.TRANSIENT;
+ }
+
+
+ } catch (JavaModelException e) {
+ // do nothing. Can't compute runnable adornment or get flags
+ }
+ }
+ return flags;
+ }
+
+ private static boolean confirmAbstract(IMember element) throws JavaModelException {
+ // never show the abstract symbol on interfaces or members in interfaces
+ if (element.getElementType() == IJavaElement.TYPE) {
+ return ! JavaModelUtil.isInterfaceOrAnnotation((IType) element);
+ }
+ return ! JavaModelUtil.isInterfaceOrAnnotation(element.getDeclaringType());
+ }
+
+ private static boolean isInterfaceOrAnnotationField(IMember element) throws JavaModelException {
+ // always show the final symbol on interface fields
+ if (element.getElementType() == IJavaElement.FIELD) {
+ return JavaModelUtil.isInterfaceOrAnnotation(element.getDeclaringType());
+ }
+ return false;
+ }
+
+ private static boolean confirmSynchronized(IJavaElement member) {
+ // Synchronized types are allowed but meaningless.
+ return member.getElementType() != IJavaElement.TYPE;
+ }
+
+ private static boolean isEnumConstant(IMember element, int modifiers) {
+ if (element.getElementType() == IJavaElement.FIELD) {
+ return Flags.isEnum(modifiers);
+ }
+ return false;
+ }
+
+ private static boolean isInterfaceOrAnnotationFieldOrType(IMember element) throws JavaModelException {
+ // always show the static symbol on interface fields and types
+ if (element.getElementType() == IJavaElement.FIELD) {
+ return JavaModelUtil.isInterfaceOrAnnotation(element.getDeclaringType());
+ } else if (element.getElementType() == IJavaElement.TYPE && element.getDeclaringType() != null) {
+ return JavaModelUtil.isInterfaceOrAnnotation(element.getDeclaringType());
+ }
+ return false;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementLabelComposer.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementLabelComposer.java
new file mode 100644
index 0000000..1ed4257
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementLabelComposer.java
@@ -0,0 +1,1487 @@
+/*******************************************************************************
+ * 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
+ * Guven Demir <guven.internet+eclipse@gmail.com> - [package explorer] Alternative package name shortening: abbreviation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=299514
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import java.util.jar.Attributes.Name;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.demo.simpleide.jdt.internal.JavaUIMessages;
+import org.eclipse.jdt.core.BindingKey;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IInitializer;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.ILocalVariable;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.jface.viewers.StyledString.Styler;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.graphics.TextStyle;
+import org.eclipse.swt.widgets.Display;
+
+public class JavaElementLabelComposer {
+ /**
+ * An adapter for buffer supported by the label composer.
+ */
+ public static abstract class FlexibleBuffer {
+
+ /**
+ * Appends the string representation of the given character to the
+ * buffer.
+ *
+ * @param ch
+ * the character to append
+ * @return a reference to this object
+ */
+ public abstract FlexibleBuffer append(char ch);
+
+ /**
+ * Appends the given string to the buffer.
+ *
+ * @param string
+ * the string to append
+ * @return a reference to this object
+ */
+ public abstract FlexibleBuffer append(String string);
+
+ /**
+ * Returns the length of the the buffer.
+ *
+ * @return the length of the current string
+ */
+ public abstract int length();
+
+ /**
+ * Sets a styler to use for the given source range. The range must be
+ * subrange of actual string of this buffer. Stylers previously set for
+ * that range will be overwritten.
+ *
+ * @param offset
+ * the start offset of the range
+ * @param length
+ * the length of the range
+ * @param styler
+ * the styler to set
+ *
+ * @throws StringIndexOutOfBoundsException
+ * if <code>start</code> is less than zero, or if offset
+ * plus length is greater than the length of this object.
+ */
+ public abstract void setStyle(int offset, int length, Styler styler);
+ }
+
+ public static class FlexibleStringBuffer extends FlexibleBuffer {
+ private final StringBuffer fStringBuffer;
+
+ public FlexibleStringBuffer(StringBuffer stringBuffer) {
+ fStringBuffer = stringBuffer;
+ }
+
+ public FlexibleBuffer append(char ch) {
+ fStringBuffer.append(ch);
+ return this;
+ }
+
+ public FlexibleBuffer append(String string) {
+ fStringBuffer.append(string);
+ return this;
+ }
+
+ public int length() {
+ return fStringBuffer.length();
+ }
+
+ public void setStyle(int offset, int length, Styler styler) {
+ // no style
+ }
+
+ public String toString() {
+ return fStringBuffer.toString();
+ }
+ }
+
+ public static class FlexibleStyledString extends FlexibleBuffer {
+ private final StyledString fStyledString;
+
+ public FlexibleStyledString(StyledString stringBuffer) {
+ fStyledString = stringBuffer;
+ }
+
+ public FlexibleBuffer append(char ch) {
+ fStyledString.append(ch);
+ return this;
+ }
+
+ public FlexibleBuffer append(String string) {
+ fStyledString.append(string);
+ return this;
+ }
+
+ public int length() {
+ return fStyledString.length();
+ }
+
+ public void setStyle(int offset, int length, Styler styler) {
+ fStyledString.setStyle(offset, length, styler);
+ }
+
+ public String toString() {
+ return fStyledString.toString();
+ }
+ }
+
+//TODO FIXME private static final Styler QUALIFIER_STYLE = StyledString.QUALIFIER_STYLER;
+ private static final Styler QUALIFIER_STYLE = new Styler() {
+ private Color COLOR = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY);
+
+ @Override
+ public void applyStyles(TextStyle textStyle) {
+ textStyle.foreground = COLOR;
+ }
+ };
+
+ private static final Styler COUNTER_STYLE = new Styler() {
+ private Color COLOR = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY);
+
+ @Override
+ public void applyStyles(TextStyle textStyle) {
+ textStyle.foreground = COLOR;
+ }
+ };
+ private static final Styler DECORATIONS_STYLE = new Styler() {
+ private Color COLOR = new Color(Display.getCurrent(), new RGB(149, 125, 71));
+
+ @Override
+ public void applyStyles(TextStyle textStyle) {
+ textStyle.foreground = COLOR;
+ }
+ };
+
+ private final static long QUALIFIER_FLAGS = JavaElementLabels.P_COMPRESSED
+ | JavaElementLabels.USE_RESOLVED;
+
+ private final FlexibleBuffer fBuffer;
+ private Logger logger;
+ private JavaUIMessages messages;
+
+ /**
+ * Creates a new java element composer based on the given buffer.
+ *
+ * @param buffer
+ * the buffer
+ */
+ public JavaElementLabelComposer(StringBuffer buffer, Logger logger,
+ JavaUIMessages messages) {
+ this(new FlexibleStringBuffer(buffer), logger, messages);
+ }
+
+ /**
+ * Creates a new java element composer based on the given buffer.
+ *
+ * @param buffer
+ * the buffer
+ */
+ public JavaElementLabelComposer(StyledString buffer, Logger logger,
+ JavaUIMessages messages) {
+ this(new FlexibleStyledString(buffer), logger, messages);
+ }
+
+ /**
+ * Creates a new java element composer based on the given buffer.
+ *
+ * @param buffer
+ * the buffer
+ */
+ public JavaElementLabelComposer(FlexibleBuffer buffer, Logger logger,
+ JavaUIMessages messages) {
+ fBuffer = buffer;
+ this.logger = logger;
+ this.messages = messages;
+ }
+
+ private static final boolean getFlag(long flags, long flag) {
+ return (flags & flag) != 0;
+ }
+
+ /**
+ * Appends the label for a package fragment root. Considers the ROOT_*
+ * flags.
+ *
+ * @param root
+ * the element to render
+ * @param flags
+ * the rendering flags. Flags with names starting with ROOT_' are
+ * considered.
+ */
+ public void appendPackageFragmentRootLabel(IPackageFragmentRoot root,
+ long flags) {
+ // Handle variables different
+ if (getFlag(flags, JavaElementLabels.ROOT_VARIABLE)
+ && appendVariableLabel(root, flags))
+ return;
+ if (root.isArchive())
+ appendArchiveLabel(root, flags);
+ else
+ appendFolderLabel(root, flags);
+ }
+
+ private void appendArchiveLabel(IPackageFragmentRoot root, long flags) {
+ boolean external = root.isExternal();
+ if (external)
+ appendExternalArchiveLabel(root, flags);
+ else
+ appendInternalArchiveLabel(root, flags);
+ }
+
+ private void appendExternalArchiveLabel(IPackageFragmentRoot root,
+ long flags) {
+ IPath path;
+ IClasspathEntry classpathEntry = null;
+ try {
+ classpathEntry = JavaModelUtil.getClasspathEntry(root);
+ IPath rawPath = classpathEntry.getPath();
+ if (classpathEntry.getEntryKind() != IClasspathEntry.CPE_CONTAINER
+ && !rawPath.isAbsolute())
+ path = rawPath;
+ else
+ path = root.getPath();
+ } catch (JavaModelException e) {
+ path = root.getPath();
+ }
+ if (getFlag(flags, JavaElementLabels.REFERENCED_ROOT_POST_QUALIFIED)) {
+ int segements = path.segmentCount();
+ if (segements > 0) {
+ fBuffer.append(path.segment(segements - 1));
+ int offset = fBuffer.length();
+ if (segements > 1 || path.getDevice() != null) {
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ fBuffer.append(path.removeLastSegments(1).toOSString());
+ }
+ if (classpathEntry != null) {
+ IClasspathEntry referencingEntry = classpathEntry
+ .getReferencingEntry();
+ if (referencingEntry != null) {
+ fBuffer.append(messages
+ .JavaElementLabels_onClassPathOf(
+ Name.CLASS_PATH.toString(),
+ referencingEntry.getPath()
+ .lastSegment()));
+ }
+ }
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ QUALIFIER_STYLE);
+ }
+ } else {
+ fBuffer.append(path.toOSString());
+ }
+ } else {
+ fBuffer.append(path.toOSString());
+ }
+ }
+
+ private void appendFolderLabel(IPackageFragmentRoot root, long flags) {
+ IResource resource = root.getResource();
+ if (resource == null) {
+ appendExternalArchiveLabel(root, flags);
+ return;
+ }
+
+ boolean rootQualified = getFlag(flags, JavaElementLabels.ROOT_QUALIFIED);
+ boolean referencedQualified = getFlag(flags,
+ JavaElementLabels.REFERENCED_ROOT_POST_QUALIFIED)
+ && isReferenced(root);
+ if (rootQualified) {
+ fBuffer.append(root.getPath().makeRelative().toString());
+ } else {
+ IPath projectRelativePath = resource.getProjectRelativePath();
+ if (projectRelativePath.segmentCount() == 0) {
+ fBuffer.append(resource.getName());
+ referencedQualified = false;
+ } else {
+ fBuffer.append(projectRelativePath.toString());
+ }
+
+ int offset = fBuffer.length();
+ if (referencedQualified) {
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ fBuffer.append(resource.getProject().getName());
+ } else if (getFlag(flags, JavaElementLabels.ROOT_POST_QUALIFIED)) {
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ fBuffer.append(root.getParent().getElementName());
+ } else {
+ return;
+ }
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ QUALIFIER_STYLE);
+ }
+ }
+ }
+
+ private boolean appendVariableLabel(IPackageFragmentRoot root, long flags) {
+ try {
+ IClasspathEntry rawEntry = root.getRawClasspathEntry();
+ if (rawEntry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
+ IClasspathEntry entry = JavaModelUtil.getClasspathEntry(root);
+ if (entry.getReferencingEntry() != null) {
+ return false; // not the variable entry itself, but a
+ // referenced entry
+ }
+ IPath path = rawEntry.getPath().makeRelative();
+
+ if (getFlag(flags,
+ JavaElementLabels.REFERENCED_ROOT_POST_QUALIFIED)) {
+ int segements = path.segmentCount();
+ if (segements > 0) {
+ fBuffer.append(path.segment(segements - 1));
+ if (segements > 1) {
+ int offset = fBuffer.length();
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ fBuffer.append(path.removeLastSegments(1)
+ .toOSString());
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length()
+ - offset, QUALIFIER_STYLE);
+ }
+ }
+ } else {
+ fBuffer.append(path.toString());
+ }
+ } else {
+ fBuffer.append(path.toString());
+ }
+ int offset = fBuffer.length();
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ if (root.isExternal())
+ fBuffer.append(root.getPath().toOSString());
+ else
+ fBuffer.append(root.getPath().makeRelative().toString());
+
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ QUALIFIER_STYLE);
+ }
+ return true;
+ }
+ } catch (JavaModelException e) {
+ // problems with class path, ignore (bug 202792)
+ return false;
+ }
+ return false;
+ }
+
+ /**
+ * Appends the label for a Java element with the flags as defined by this
+ * class.
+ *
+ * @param element
+ * the element to render
+ * @param flags
+ * the rendering flags.
+ */
+ public void appendElementLabel(IJavaElement element, long flags) {
+ int type = element.getElementType();
+ IPackageFragmentRoot root = null;
+
+ if (type != IJavaElement.JAVA_MODEL
+ && type != IJavaElement.JAVA_PROJECT
+ && type != IJavaElement.PACKAGE_FRAGMENT_ROOT)
+ root = JavaModelUtil.getPackageFragmentRoot(element);
+ if (root != null && getFlag(flags, JavaElementLabels.PREPEND_ROOT_PATH)) {
+ appendPackageFragmentRootLabel(root,
+ JavaElementLabels.ROOT_QUALIFIED);
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ }
+
+ switch (type) {
+ case IJavaElement.METHOD:
+ appendMethodLabel((IMethod) element, flags);
+ break;
+ case IJavaElement.FIELD:
+ appendFieldLabel((IField) element, flags);
+ break;
+ case IJavaElement.LOCAL_VARIABLE:
+ appendLocalVariableLabel((ILocalVariable) element, flags);
+ break;
+ case IJavaElement.TYPE_PARAMETER:
+ appendTypeParameterLabel((ITypeParameter) element, flags);
+ break;
+ case IJavaElement.INITIALIZER:
+ appendInitializerLabel((IInitializer) element, flags);
+ break;
+ case IJavaElement.TYPE:
+ appendTypeLabel((IType) element, flags);
+ break;
+ case IJavaElement.CLASS_FILE:
+ appendClassFileLabel((IClassFile) element, flags);
+ break;
+ case IJavaElement.COMPILATION_UNIT:
+ appendCompilationUnitLabel((ICompilationUnit) element, flags);
+ break;
+ case IJavaElement.PACKAGE_FRAGMENT:
+ appendPackageFragmentLabel((IPackageFragment) element, flags);
+ break;
+ case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+ appendPackageFragmentRootLabel((IPackageFragmentRoot) element,
+ flags);
+ break;
+ case IJavaElement.IMPORT_CONTAINER:
+ case IJavaElement.IMPORT_DECLARATION:
+ case IJavaElement.PACKAGE_DECLARATION:
+ appendDeclarationLabel(element, flags);
+ break;
+ case IJavaElement.JAVA_PROJECT:
+ case IJavaElement.JAVA_MODEL:
+ fBuffer.append(element.getElementName());
+ break;
+ default:
+ fBuffer.append(element.getElementName());
+ }
+
+ if (root != null && getFlag(flags, JavaElementLabels.APPEND_ROOT_PATH)) {
+ int offset = fBuffer.length();
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ appendPackageFragmentRootLabel(root,
+ JavaElementLabels.ROOT_QUALIFIED);
+
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ QUALIFIER_STYLE);
+ }
+
+ }
+ }
+
+ /**
+ * Appends the label for a import container, import or package declaration.
+ * Considers the D_* flags.
+ *
+ * @param declaration
+ * the element to render
+ * @param flags
+ * the rendering flags. Flags with names starting with 'D_' are
+ * considered.
+ */
+ public void appendDeclarationLabel(IJavaElement declaration, long flags) {
+ if (getFlag(flags, JavaElementLabels.D_QUALIFIED)) {
+ IJavaElement openable = (IJavaElement) declaration.getOpenable();
+ if (openable != null) {
+ appendElementLabel(openable, JavaElementLabels.CF_QUALIFIED
+ | JavaElementLabels.CU_QUALIFIED
+ | (flags & QUALIFIER_FLAGS));
+ fBuffer.append('/');
+ }
+ }
+ if (declaration.getElementType() == IJavaElement.IMPORT_CONTAINER) {
+ fBuffer.append(messages.JavaElementLabels_import_container());
+ } else {
+ fBuffer.append(declaration.getElementName());
+ }
+ // post qualification
+ if (getFlag(flags, JavaElementLabels.D_POST_QUALIFIED)) {
+ int offset = fBuffer.length();
+ IJavaElement openable = (IJavaElement) declaration.getOpenable();
+ if (openable != null) {
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ appendElementLabel(openable, JavaElementLabels.CF_QUALIFIED
+ | JavaElementLabels.CU_QUALIFIED
+ | (flags & QUALIFIER_FLAGS));
+ }
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ QUALIFIER_STYLE);
+ }
+ }
+ }
+
+ /**
+ * Appends the label for a compilation unit. Considers the CU_* flags.
+ *
+ * @param cu
+ * the element to render
+ * @param flags
+ * the rendering flags. Flags with names starting with 'CU_' are
+ * considered.
+ */
+ public void appendCompilationUnitLabel(ICompilationUnit cu, long flags) {
+ if (getFlag(flags, JavaElementLabels.CU_QUALIFIED)) {
+ IPackageFragment pack = (IPackageFragment) cu.getParent();
+ if (!pack.isDefaultPackage()) {
+ appendPackageFragmentLabel(pack, (flags & QUALIFIER_FLAGS));
+ fBuffer.append('.');
+ }
+ }
+ fBuffer.append(cu.getElementName());
+
+ if (getFlag(flags, JavaElementLabels.CU_POST_QUALIFIED)) {
+ int offset = fBuffer.length();
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ appendPackageFragmentLabel((IPackageFragment) cu.getParent(), flags
+ & QUALIFIER_FLAGS);
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ QUALIFIER_STYLE);
+ }
+ }
+ }
+
+ /**
+ * Appends the label for a class file. Considers the CF_* flags.
+ *
+ * @param classFile
+ * the element to render
+ * @param flags
+ * the rendering flags. Flags with names starting with 'CF_' are
+ * considered.
+ */
+ public void appendClassFileLabel(IClassFile classFile, long flags) {
+ if (getFlag(flags, JavaElementLabels.CF_QUALIFIED)) {
+ IPackageFragment pack = (IPackageFragment) classFile.getParent();
+ if (!pack.isDefaultPackage()) {
+ appendPackageFragmentLabel(pack, (flags & QUALIFIER_FLAGS));
+ fBuffer.append('.');
+ }
+ }
+ fBuffer.append(classFile.getElementName());
+
+ if (getFlag(flags, JavaElementLabels.CF_POST_QUALIFIED)) {
+ int offset = fBuffer.length();
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ appendPackageFragmentLabel(
+ (IPackageFragment) classFile.getParent(), flags
+ & QUALIFIER_FLAGS);
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ QUALIFIER_STYLE);
+ }
+ }
+ }
+
+ /**
+ * Appends the label for a initializer. Considers the I_* flags.
+ *
+ * @param initializer
+ * the element to render
+ * @param flags
+ * the rendering flags. Flags with names starting with 'I_' are
+ * considered.
+ */
+ public void appendInitializerLabel(IInitializer initializer, long flags) {
+ // qualification
+ if (getFlag(flags, JavaElementLabels.I_FULLY_QUALIFIED)) {
+ appendTypeLabel(initializer.getDeclaringType(),
+ JavaElementLabels.T_FULLY_QUALIFIED
+ | (flags & QUALIFIER_FLAGS));
+ fBuffer.append('.');
+ }
+ fBuffer.append(messages.JavaElementLabels_initializer());
+
+ // post qualification
+ if (getFlag(flags, JavaElementLabels.I_POST_QUALIFIED)) {
+ int offset = fBuffer.length();
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ appendTypeLabel(initializer.getDeclaringType(),
+ JavaElementLabels.T_FULLY_QUALIFIED
+ | (flags & QUALIFIER_FLAGS));
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ QUALIFIER_STYLE);
+ }
+ }
+ }
+
+ /**
+ * Appends the styled label for a type parameter.
+ *
+ * @param typeParameter
+ * the element to render
+ * @param flags
+ * the rendering flags. Flags with names starting with 'T_' are
+ * considered.
+ */
+ public void appendTypeParameterLabel(ITypeParameter typeParameter,
+ long flags) {
+ try {
+ fBuffer.append(getElementName(typeParameter));
+
+ if (typeParameter.exists()) {
+ String[] bounds = typeParameter.getBoundsSignatures();
+ if (bounds.length > 0
+ && !(bounds.length == 1 && "Ljava.lang.Object;".equals(bounds[0]))) { //$NON-NLS-1$
+ fBuffer.append(" extends "); //$NON-NLS-1$
+ for (int j = 0; j < bounds.length; j++) {
+ if (j > 0) {
+ fBuffer.append(JavaElementLabels.COMMA_STRING);
+ }
+ appendTypeSignatureLabel(typeParameter, bounds[j],
+ flags);
+ }
+ }
+ }
+
+ // post qualification
+ if (getFlag(flags, JavaElementLabels.TP_POST_QUALIFIED)) {
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ IMember declaringMember = typeParameter.getDeclaringMember();
+ appendElementLabel(declaringMember,
+ JavaElementLabels.M_PARAMETER_TYPES
+ | JavaElementLabels.M_FULLY_QUALIFIED
+ | JavaElementLabels.T_FULLY_QUALIFIED
+ | (flags & QUALIFIER_FLAGS));
+ }
+
+ } catch (JavaModelException e) {
+ logger.error(e);
+ }
+ }
+
+ /**
+ * Appends the style label for a field. Considers the F_* flags.
+ *
+ * @param field
+ * the element to render
+ * @param flags
+ * the rendering flags. Flags with names starting with 'F_' are
+ * considered.
+ */
+ public void appendFieldLabel(IField field, long flags) {
+ try {
+
+ if (getFlag(flags, JavaElementLabels.F_PRE_TYPE_SIGNATURE)
+ && field.exists() && !Flags.isEnum(field.getFlags())) {
+ if (getFlag(flags, JavaElementLabels.USE_RESOLVED)
+ && field.isResolved()) {
+ appendTypeSignatureLabel(field,
+ new BindingKey(field.getKey()).toSignature(), flags);
+ } else {
+ appendTypeSignatureLabel(field, field.getTypeSignature(),
+ flags);
+ }
+ fBuffer.append(' ');
+ }
+
+ // qualification
+ if (getFlag(flags, JavaElementLabels.F_FULLY_QUALIFIED)) {
+ appendTypeLabel(field.getDeclaringType(),
+ JavaElementLabels.T_FULLY_QUALIFIED
+ | (flags & QUALIFIER_FLAGS));
+ fBuffer.append('.');
+ }
+ fBuffer.append(getElementName(field));
+
+ if (getFlag(flags, JavaElementLabels.F_APP_TYPE_SIGNATURE)
+ && field.exists() && !Flags.isEnum(field.getFlags())) {
+ int offset = fBuffer.length();
+ fBuffer.append(JavaElementLabels.DECL_STRING);
+ if (getFlag(flags, JavaElementLabels.USE_RESOLVED)
+ && field.isResolved()) {
+ appendTypeSignatureLabel(field,
+ new BindingKey(field.getKey()).toSignature(), flags);
+ } else {
+ appendTypeSignatureLabel(field, field.getTypeSignature(),
+ flags);
+ }
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ DECORATIONS_STYLE);
+ }
+ }
+
+ // category
+ if (getFlag(flags, JavaElementLabels.F_CATEGORY) && field.exists())
+ appendCategoryLabel(field, flags);
+
+ // post qualification
+ if (getFlag(flags, JavaElementLabels.F_POST_QUALIFIED)) {
+ int offset = fBuffer.length();
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ appendTypeLabel(field.getDeclaringType(),
+ JavaElementLabels.T_FULLY_QUALIFIED
+ | (flags & QUALIFIER_FLAGS));
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ QUALIFIER_STYLE);
+ }
+ }
+
+ } catch (JavaModelException e) {
+ logger.error(e);
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if the given package fragment root is
+ * referenced. This means it is a descendant of a different project but is
+ * referenced by the root's parent. Returns <code>false</code> if the given
+ * root doesn't have an underlying resource.
+ *
+ * @param root
+ * the package fragment root
+ * @return returns <code>true</code> if the given package fragment root is
+ * referenced
+ */
+ private boolean isReferenced(IPackageFragmentRoot root) {
+ IResource resource = root.getResource();
+ if (resource != null) {
+ IProject jarProject = resource.getProject();
+ IProject container = root.getJavaProject().getProject();
+ return !container.equals(jarProject);
+ }
+ return false;
+ }
+
+ private void appendInternalArchiveLabel(IPackageFragmentRoot root,
+ long flags) {
+ IResource resource = root.getResource();
+ boolean rootQualified = getFlag(flags, JavaElementLabels.ROOT_QUALIFIED);
+ if (rootQualified) {
+ fBuffer.append(root.getPath().makeRelative().toString());
+ } else {
+ fBuffer.append(root.getElementName());
+ int offset = fBuffer.length();
+ boolean referencedPostQualified = getFlag(flags,
+ JavaElementLabels.REFERENCED_ROOT_POST_QUALIFIED);
+ if (referencedPostQualified && isReferenced(root)) {
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ fBuffer.append(resource.getParent().getFullPath()
+ .makeRelative().toString());
+ } else if (getFlag(flags, JavaElementLabels.ROOT_POST_QUALIFIED)) {
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ fBuffer.append(root.getParent().getPath().makeRelative()
+ .toString());
+ }
+ if (referencedPostQualified) {
+ try {
+ IClasspathEntry referencingEntry = JavaModelUtil
+ .getClasspathEntry(root).getReferencingEntry();
+ if (referencingEntry != null) {
+ fBuffer.append(messages
+ .JavaElementLabels_onClassPathOf(
+ Name.CLASS_PATH.toString(),
+ referencingEntry.getPath()
+ .lastSegment()));
+ }
+ } catch (JavaModelException e) {
+ // ignore
+ }
+ }
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ QUALIFIER_STYLE);
+ }
+ }
+ }
+
+ /**
+ * Appends the label for a method. Considers the M_* flags.
+ *
+ * @param method
+ * the element to render
+ * @param flags
+ * the rendering flags. Flags with names starting with 'M_' are
+ * considered.
+ */
+ public void appendMethodLabel(IMethod method, long flags) {
+ try {
+ BindingKey resolvedKey = getFlag(flags,
+ JavaElementLabels.USE_RESOLVED) && method.isResolved() ? new BindingKey(
+ method.getKey()) : null;
+ String resolvedSig = (resolvedKey != null) ? resolvedKey
+ .toSignature() : null;
+
+ // type parameters
+ if (getFlag(flags, JavaElementLabels.M_PRE_TYPE_PARAMETERS)) {
+ if (resolvedKey != null) {
+ if (resolvedKey.isParameterizedMethod()) {
+ String[] typeArgRefs = resolvedKey.getTypeArguments();
+ if (typeArgRefs.length > 0) {
+ appendTypeArgumentSignaturesLabel(method,
+ typeArgRefs, flags);
+ fBuffer.append(' ');
+ }
+ } else {
+ String[] typeParameterSigs = Signature
+ .getTypeParameters(resolvedSig);
+ if (typeParameterSigs.length > 0) {
+ appendTypeParameterSignaturesLabel(
+ typeParameterSigs, flags);
+ fBuffer.append(' ');
+ }
+ }
+ } else if (method.exists()) {
+ ITypeParameter[] typeParameters = method
+ .getTypeParameters();
+ if (typeParameters.length > 0) {
+ appendTypeParametersLabels(typeParameters, flags);
+ fBuffer.append(' ');
+ }
+ }
+ }
+
+ // return type
+ if (getFlag(flags, JavaElementLabels.M_PRE_RETURNTYPE)
+ && method.exists() && !method.isConstructor()) {
+ String returnTypeSig = resolvedSig != null ? Signature
+ .getReturnType(resolvedSig) : method.getReturnType();
+ appendTypeSignatureLabel(method, returnTypeSig, flags);
+ fBuffer.append(' ');
+ }
+
+ // qualification
+ if (getFlag(flags, JavaElementLabels.M_FULLY_QUALIFIED)) {
+ appendTypeLabel(method.getDeclaringType(),
+ JavaElementLabels.T_FULLY_QUALIFIED
+ | (flags & QUALIFIER_FLAGS));
+ fBuffer.append('.');
+ }
+
+ fBuffer.append(getElementName(method));
+
+ // parameters
+ fBuffer.append('(');
+ if (getFlag(flags, JavaElementLabels.M_PARAMETER_TYPES
+ | JavaElementLabels.M_PARAMETER_NAMES)) {
+ String[] types = null;
+ int nParams = 0;
+ boolean renderVarargs = false;
+ if (getFlag(flags, JavaElementLabels.M_PARAMETER_TYPES)) {
+ if (resolvedSig != null) {
+ types = Signature.getParameterTypes(resolvedSig);
+ } else {
+ types = method.getParameterTypes();
+ }
+ nParams = types.length;
+ renderVarargs = method.exists()
+ && Flags.isVarargs(method.getFlags());
+ }
+ String[] names = null;
+ if (getFlag(flags, JavaElementLabels.M_PARAMETER_NAMES)
+ && method.exists()) {
+ names = method.getParameterNames();
+ if (types == null) {
+ nParams = names.length;
+ } else { // types != null
+ if (nParams != names.length) {
+ if (resolvedSig != null
+ && types.length > names.length) {
+ // see
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=99137
+ nParams = names.length;
+ String[] typesWithoutSyntheticParams = new String[nParams];
+ System.arraycopy(types, types.length - nParams,
+ typesWithoutSyntheticParams, 0, nParams);
+ types = typesWithoutSyntheticParams;
+ } else {
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=101029
+ // JavaPlugin.logErrorMessage("JavaElementLabels: Number of param types(" + nParams + ") != number of names(" + names.length + "): " + method.getElementName()); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ names = null; // no names rendered
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < nParams; i++) {
+ if (i > 0) {
+ fBuffer.append(JavaElementLabels.COMMA_STRING);
+ }
+ if (types != null) {
+ String paramSig = types[i];
+ if (renderVarargs && (i == nParams - 1)) {
+ int newDim = Signature.getArrayCount(paramSig) - 1;
+ appendTypeSignatureLabel(method,
+ Signature.getElementType(paramSig), flags);
+ for (int k = 0; k < newDim; k++) {
+ fBuffer.append('[').append(']');
+ }
+ fBuffer.append(JavaElementLabels.ELLIPSIS_STRING);
+ } else {
+ appendTypeSignatureLabel(method, paramSig, flags);
+ }
+ }
+ if (names != null) {
+ if (types != null) {
+ fBuffer.append(' ');
+ }
+ fBuffer.append(names[i]);
+ }
+ }
+ } else {
+ if (method.getParameterTypes().length > 0) {
+ fBuffer.append(JavaElementLabels.ELLIPSIS_STRING);
+ }
+ }
+ fBuffer.append(')');
+
+ if (getFlag(flags, JavaElementLabels.M_EXCEPTIONS)) {
+ String[] types;
+ if (resolvedKey != null) {
+ types = resolvedKey.getThrownExceptions();
+ } else {
+ types = method.exists() ? method.getExceptionTypes()
+ : new String[0];
+ }
+ if (types.length > 0) {
+ fBuffer.append(" throws "); //$NON-NLS-1$
+ for (int i = 0; i < types.length; i++) {
+ if (i > 0) {
+ fBuffer.append(JavaElementLabels.COMMA_STRING);
+ }
+ appendTypeSignatureLabel(method, types[i], flags);
+ }
+ }
+ }
+
+ if (getFlag(flags, JavaElementLabels.M_APP_TYPE_PARAMETERS)) {
+ int offset = fBuffer.length();
+ if (resolvedKey != null) {
+ if (resolvedKey.isParameterizedMethod()) {
+ String[] typeArgRefs = resolvedKey.getTypeArguments();
+ if (typeArgRefs.length > 0) {
+ fBuffer.append(' ');
+ appendTypeArgumentSignaturesLabel(method,
+ typeArgRefs, flags);
+ }
+ } else {
+ String[] typeParameterSigs = Signature
+ .getTypeParameters(resolvedSig);
+ if (typeParameterSigs.length > 0) {
+ fBuffer.append(' ');
+ appendTypeParameterSignaturesLabel(
+ typeParameterSigs, flags);
+ }
+ }
+ } else if (method.exists()) {
+ ITypeParameter[] typeParameters = method
+ .getTypeParameters();
+ if (typeParameters.length > 0) {
+ fBuffer.append(' ');
+ appendTypeParametersLabels(typeParameters, flags);
+ }
+ }
+ if (getFlag(flags, JavaElementLabels.COLORIZE)
+ && offset != fBuffer.length()) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ DECORATIONS_STYLE);
+ }
+ }
+
+ if (getFlag(flags, JavaElementLabels.M_APP_RETURNTYPE)
+ && method.exists() && !method.isConstructor()) {
+ int offset = fBuffer.length();
+ fBuffer.append(JavaElementLabels.DECL_STRING);
+ String returnTypeSig = resolvedSig != null ? Signature
+ .getReturnType(resolvedSig) : method.getReturnType();
+ appendTypeSignatureLabel(method, returnTypeSig, flags);
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ DECORATIONS_STYLE);
+ }
+ }
+
+ // category
+ if (getFlag(flags, JavaElementLabels.M_CATEGORY) && method.exists())
+ appendCategoryLabel(method, flags);
+
+ // post qualification
+ if (getFlag(flags, JavaElementLabels.M_POST_QUALIFIED)) {
+ int offset = fBuffer.length();
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ appendTypeLabel(method.getDeclaringType(),
+ JavaElementLabels.T_FULLY_QUALIFIED
+ | (flags & QUALIFIER_FLAGS));
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ QUALIFIER_STYLE);
+ }
+ }
+
+ } catch (JavaModelException e) {
+ logger.error(e);
+ }
+ }
+
+ protected void appendTypeSignatureLabel(IJavaElement enclosingElement,
+ String typeSig, long flags) {
+ int sigKind = Signature.getTypeSignatureKind(typeSig);
+ switch (sigKind) {
+ case Signature.BASE_TYPE_SIGNATURE:
+ fBuffer.append(Signature.toString(typeSig));
+ break;
+ case Signature.ARRAY_TYPE_SIGNATURE:
+ appendTypeSignatureLabel(enclosingElement,
+ Signature.getElementType(typeSig), flags);
+ for (int dim = Signature.getArrayCount(typeSig); dim > 0; dim--) {
+ fBuffer.append('[').append(']');
+ }
+ break;
+ case Signature.CLASS_TYPE_SIGNATURE:
+ String baseType = getSimpleTypeName(enclosingElement,
+ Signature.getTypeErasure(typeSig));
+ fBuffer.append(baseType);
+
+ String[] typeArguments = Signature.getTypeArguments(typeSig);
+ appendTypeArgumentSignaturesLabel(enclosingElement, typeArguments,
+ flags);
+ break;
+ case Signature.TYPE_VARIABLE_SIGNATURE:
+ fBuffer.append(getSimpleTypeName(enclosingElement, typeSig));
+ break;
+ case Signature.WILDCARD_TYPE_SIGNATURE:
+ char ch = typeSig.charAt(0);
+ if (ch == Signature.C_STAR) { // workaround for bug 85713
+ fBuffer.append('?');
+ } else {
+ if (ch == Signature.C_EXTENDS) {
+ fBuffer.append("? extends "); //$NON-NLS-1$
+ appendTypeSignatureLabel(enclosingElement,
+ typeSig.substring(1), flags);
+ } else if (ch == Signature.C_SUPER) {
+ fBuffer.append("? super "); //$NON-NLS-1$
+ appendTypeSignatureLabel(enclosingElement,
+ typeSig.substring(1), flags);
+ }
+ }
+ break;
+ case Signature.CAPTURE_TYPE_SIGNATURE:
+ appendTypeSignatureLabel(enclosingElement, typeSig.substring(1),
+ flags);
+ break;
+ default:
+ // unknown
+ }
+ }
+
+ /**
+ * Returns the simple name of the given type signature.
+ *
+ * @param enclosingElement
+ * the enclosing element in which to resolve the signature
+ * @param typeSig
+ * a {@link Signature#CLASS_TYPE_SIGNATURE} or
+ * {@link Signature#TYPE_VARIABLE_SIGNATURE}
+ * @return the simple name of the given type signature
+ */
+ protected String getSimpleTypeName(IJavaElement enclosingElement,
+ String typeSig) {
+ return Signature.getSimpleName(Signature.toString(typeSig));
+ }
+
+ private void appendTypeArgumentSignaturesLabel(
+ IJavaElement enclosingElement, String[] typeArgsSig, long flags) {
+ if (typeArgsSig.length > 0) {
+ fBuffer.append(getLT());
+ for (int i = 0; i < typeArgsSig.length; i++) {
+ if (i > 0) {
+ fBuffer.append(JavaElementLabels.COMMA_STRING);
+ }
+ appendTypeSignatureLabel(enclosingElement, typeArgsSig[i],
+ flags);
+ }
+ fBuffer.append(getGT());
+ }
+ }
+
+ /**
+ * Returns the string for rendering the '<code><</code>' character.
+ *
+ * @return the string for rendering '<code><</code>'
+ */
+ protected String getLT() {
+ return "<"; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the string for rendering the '<code>></code>' character.
+ *
+ * @return the string for rendering '<code>></code>'
+ */
+ protected String getGT() {
+ return ">"; //$NON-NLS-1$
+ }
+
+ /**
+ * Appends labels for type parameters from a signature.
+ *
+ * @param typeParamSigs
+ * the type parameter signature
+ * @param flags
+ * flags with render options
+ */
+ private void appendTypeParameterSignaturesLabel(String[] typeParamSigs,
+ long flags) {
+ if (typeParamSigs.length > 0) {
+ fBuffer.append(getLT());
+ for (int i = 0; i < typeParamSigs.length; i++) {
+ if (i > 0) {
+ fBuffer.append(JavaElementLabels.COMMA_STRING);
+ }
+ fBuffer.append(Signature.getTypeVariable(typeParamSigs[i]));
+ }
+ fBuffer.append(getGT());
+ }
+ }
+
+ /**
+ * Appends labels for type parameters from type binding array.
+ *
+ * @param typeParameters
+ * the type parameters
+ * @param flags
+ * flags with render options
+ */
+ private void appendTypeParametersLabels(ITypeParameter[] typeParameters,
+ long flags) {
+ if (typeParameters.length > 0) {
+ fBuffer.append(getLT());
+ for (int i = 0; i < typeParameters.length; i++) {
+ if (i > 0) {
+ fBuffer.append(JavaElementLabels.COMMA_STRING);
+ }
+ fBuffer.append(getElementName(typeParameters[i]));
+ }
+ fBuffer.append(getGT());
+ }
+ }
+
+ /**
+ * Returns the string for rendering the
+ * {@link IJavaElement#getElementName() element name} of the given element.
+ *
+ * @param element
+ * the element to render
+ * @return the string for rendering the element name
+ */
+ protected String getElementName(IJavaElement element) {
+ return element.getElementName();
+ }
+
+ private void appendCategoryLabel(IMember member, long flags)
+ throws JavaModelException {
+ String[] categories = member.getCategories();
+ if (categories.length > 0) {
+ int offset = fBuffer.length();
+ StringBuffer categoriesBuf = new StringBuffer();
+ for (int i = 0; i < categories.length; i++) {
+ if (i > 0)
+ categoriesBuf
+ .append(JavaElementLabels.CATEGORY_SEPARATOR_STRING);
+ categoriesBuf.append(categories[i]);
+ }
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ fBuffer.append(messages.JavaElementLabels_category(categoriesBuf
+ .toString()));
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ COUNTER_STYLE);
+ }
+ }
+ }
+
+ /**
+ * Appends the label for a type. Considers the T_* flags.
+ *
+ * @param type
+ * the element to render
+ * @param flags
+ * the rendering flags. Flags with names starting with 'T_' are
+ * considered.
+ */
+ public void appendTypeLabel(IType type, long flags) {
+
+ if (getFlag(flags, JavaElementLabels.T_FULLY_QUALIFIED)) {
+ IPackageFragment pack = type.getPackageFragment();
+ if (!pack.isDefaultPackage()) {
+ appendPackageFragmentLabel(pack, (flags & QUALIFIER_FLAGS));
+ fBuffer.append('.');
+ }
+ }
+ if (getFlag(flags, JavaElementLabels.T_FULLY_QUALIFIED
+ | JavaElementLabels.T_CONTAINER_QUALIFIED)) {
+ IType declaringType = type.getDeclaringType();
+ if (declaringType != null) {
+ appendTypeLabel(declaringType,
+ JavaElementLabels.T_CONTAINER_QUALIFIED
+ | (flags & QUALIFIER_FLAGS));
+ fBuffer.append('.');
+ }
+ int parentType = type.getParent().getElementType();
+ if (parentType == IJavaElement.METHOD
+ || parentType == IJavaElement.FIELD
+ || parentType == IJavaElement.INITIALIZER) { // anonymous or
+ // local
+ appendElementLabel(type.getParent(), 0);
+ fBuffer.append('.');
+ }
+ }
+
+ String typeName = getElementName(type);
+ if (typeName.length() == 0) { // anonymous
+ try {
+ if (type.getParent() instanceof IField && type.isEnum()) {
+ typeName = '{' + JavaElementLabels.ELLIPSIS_STRING + '}';
+ } else {
+ String supertypeName;
+ String[] superInterfaceSignatures = type
+ .getSuperInterfaceTypeSignatures();
+ if (superInterfaceSignatures.length > 0) {
+ supertypeName = getSimpleTypeName(type,
+ superInterfaceSignatures[0]);
+ } else {
+ supertypeName = getSimpleTypeName(type,
+ type.getSuperclassTypeSignature());
+ }
+ typeName = messages
+ .JavaElementLabels_anonym_type(supertypeName);
+ }
+ } catch (JavaModelException e) {
+ // ignore
+ typeName = messages.JavaElementLabels_anonym();
+ }
+ }
+ fBuffer.append(typeName);
+ if (getFlag(flags, JavaElementLabels.T_TYPE_PARAMETERS)) {
+ if (getFlag(flags, JavaElementLabels.USE_RESOLVED)
+ && type.isResolved()) {
+ BindingKey key = new BindingKey(type.getKey());
+ if (key.isParameterizedType()) {
+ String[] typeArguments = key.getTypeArguments();
+ appendTypeArgumentSignaturesLabel(type, typeArguments,
+ flags);
+ } else {
+ String[] typeParameters = Signature.getTypeParameters(key
+ .toSignature());
+ appendTypeParameterSignaturesLabel(typeParameters, flags);
+ }
+ } else if (type.exists()) {
+ try {
+ appendTypeParametersLabels(type.getTypeParameters(), flags);
+ } catch (JavaModelException e) {
+ // ignore
+ }
+ }
+ }
+
+ // category
+ if (getFlag(flags, JavaElementLabels.T_CATEGORY) && type.exists()) {
+ try {
+ appendCategoryLabel(type, flags);
+ } catch (JavaModelException e) {
+ // ignore
+ }
+ }
+
+ // post qualification
+ if (getFlag(flags, JavaElementLabels.T_POST_QUALIFIED)) {
+ int offset = fBuffer.length();
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ IType declaringType = type.getDeclaringType();
+ if (declaringType != null) {
+ appendTypeLabel(declaringType,
+ JavaElementLabels.T_FULLY_QUALIFIED
+ | (flags & QUALIFIER_FLAGS));
+ int parentType = type.getParent().getElementType();
+ if (parentType == IJavaElement.METHOD
+ || parentType == IJavaElement.FIELD
+ || parentType == IJavaElement.INITIALIZER) { // anonymous
+ // or
+ // local
+ fBuffer.append('.');
+ appendElementLabel(type.getParent(), 0);
+ }
+ } else {
+ appendPackageFragmentLabel(type.getPackageFragment(), flags
+ & QUALIFIER_FLAGS);
+ }
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ QUALIFIER_STYLE);
+ }
+ }
+ }
+
+ /**
+ * Appends the styled label for a local variable.
+ *
+ * @param localVariable
+ * the element to render
+ * @param flags
+ * the rendering flags. Flags with names starting with 'F_' are
+ * considered.
+ */
+ public void appendLocalVariableLabel(ILocalVariable localVariable,
+ long flags) {
+ if (getFlag(flags, JavaElementLabels.F_PRE_TYPE_SIGNATURE)) {
+ appendTypeSignatureLabel(localVariable,
+ localVariable.getTypeSignature(), flags);
+ fBuffer.append(' ');
+ }
+
+ if (getFlag(flags, JavaElementLabels.F_FULLY_QUALIFIED)) {
+ appendElementLabel(localVariable.getParent(),
+ JavaElementLabels.M_PARAMETER_TYPES
+ | JavaElementLabels.M_FULLY_QUALIFIED
+ | JavaElementLabels.T_FULLY_QUALIFIED
+ | (flags & QUALIFIER_FLAGS));
+ fBuffer.append('.');
+ }
+
+ fBuffer.append(getElementName(localVariable));
+
+ if (getFlag(flags, JavaElementLabels.F_APP_TYPE_SIGNATURE)) {
+ int offset = fBuffer.length();
+ fBuffer.append(JavaElementLabels.DECL_STRING);
+ appendTypeSignatureLabel(localVariable,
+ localVariable.getTypeSignature(), flags);
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ DECORATIONS_STYLE);
+ }
+ }
+
+ // post qualification
+ if (getFlag(flags, JavaElementLabels.F_POST_QUALIFIED)) {
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ appendElementLabel(localVariable.getParent(),
+ JavaElementLabels.M_PARAMETER_TYPES
+ | JavaElementLabels.M_FULLY_QUALIFIED
+ | JavaElementLabels.T_FULLY_QUALIFIED
+ | (flags & QUALIFIER_FLAGS));
+ }
+ }
+
+ /**
+ * Appends the label for a package fragment. Considers the P_* flags.
+ *
+ * @param pack
+ * the element to render
+ * @param flags
+ * the rendering flags. Flags with names starting with P_' are
+ * considered.
+ */
+ public void appendPackageFragmentLabel(IPackageFragment pack, long flags) {
+ if (getFlag(flags, JavaElementLabels.P_QUALIFIED)) {
+ appendPackageFragmentRootLabel(
+ (IPackageFragmentRoot) pack.getParent(),
+ JavaElementLabels.ROOT_QUALIFIED);
+ fBuffer.append('/');
+ }
+ if (pack.isDefaultPackage()) {
+ fBuffer.append(JavaElementLabels.DEFAULT_PACKAGE);
+ // TODO } else if (getFlag(flags, JavaElementLabels.P_COMPRESSED)) {
+ // if (isPackageNameAbbreviationEnabled())
+ // appendAbbreviatedPackageFragment(pack);
+ // else
+ // appendCompressedPackageFragment(pack);
+ } else {
+ fBuffer.append(pack.getElementName());
+ }
+ if (getFlag(flags, JavaElementLabels.P_POST_QUALIFIED)) {
+ int offset = fBuffer.length();
+ fBuffer.append(JavaElementLabels.CONCAT_STRING);
+ appendPackageFragmentRootLabel(
+ (IPackageFragmentRoot) pack.getParent(),
+ JavaElementLabels.ROOT_QUALIFIED);
+ if (getFlag(flags, JavaElementLabels.COLORIZE)) {
+ fBuffer.setStyle(offset, fBuffer.length() - offset,
+ QUALIFIER_STYLE);
+ }
+ }
+ }
+
+ // private void appendCompressedPackageFragment(String elementName) {
+ // refreshPackageNamePattern();
+ // if (fgPkgNameLength < 0) {
+ // fBuffer.append(elementName);
+ // return;
+ // }
+ // String name= elementName;
+ // int start= 0;
+ // int dot= name.indexOf('.', start);
+ // while (dot > 0) {
+ // if (dot - start > fgPkgNameLength-1) {
+ // fBuffer.append(fgPkgNamePrefix);
+ // if (fgPkgNameChars > 0)
+ // fBuffer.append(name.substring(start, Math.min(start+ fgPkgNameChars,
+ // dot)));
+ // fBuffer.append(fgPkgNamePostfix);
+ // } else
+ // fBuffer.append(name.substring(start, dot + 1));
+ // start= dot + 1;
+ // dot= name.indexOf('.', start);
+ // }
+ // fBuffer.append(name.substring(start));
+ // }
+
+ // private boolean isPackageNameAbbreviationEnabled() {
+ // return false;
+ // //TODO IPreferenceStore store= PreferenceConstants.getPreferenceStore();
+ // // return
+ // store.getBoolean(JavaElementLabelComposer.APPEARANCE_ABBREVIATE_PACKAGE_NAMES);
+ // }
+
+ // private void appendAbbreviatedPackageFragment(IPackageFragment pack) {
+ // refreshPackageNameAbbreviation();
+ //
+ // String pkgName= pack.getElementName();
+ //
+ // if (fgPkgNameAbbreviation != null && fgPkgNameAbbreviation.length != 0) {
+ //
+ // for (int i= 0; i < fgPkgNameAbbreviation.length; i++) {
+ // PackageNameAbbreviation abbr= fgPkgNameAbbreviation[i];
+ //
+ // String abbrPrefix= abbr.getPackagePrefix();
+ // if (pkgName.startsWith(abbrPrefix)) {
+ // int abbrPrefixLength= abbrPrefix.length();
+ // int pkgLength= pkgName.length();
+ // if (!(pkgLength == abbrPrefixLength || pkgName.charAt(abbrPrefixLength)
+ // == '.'))
+ // continue;
+ //
+ // fBuffer.append(abbr.getAbbreviation());
+ //
+ // if (pkgLength > abbrPrefixLength) {
+ // fBuffer.append('.');
+ //
+ // String remaining= pkgName.substring(abbrPrefixLength + 1);
+ //
+ // if (isPackageNameCompressionEnabled())
+ // appendCompressedPackageFragment(remaining);
+ // else
+ // fBuffer.append(remaining);
+ // }
+ //
+ // return;
+ // }
+ // }
+ // }
+ //
+ // if (isPackageNameCompressionEnabled()) {
+ // appendCompressedPackageFragment(pkgName);
+ // } else {
+ // fBuffer.append(pkgName);
+ // }
+ // }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementLabels.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementLabels.java
new file mode 100644
index 0000000..78d9540
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaElementLabels.java
@@ -0,0 +1,390 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 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.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.demo.simpleide.jdt.internal.JavaUIMessages;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.osgi.util.TextProcessor;
+
+public class JavaElementLabels {
+ /**
+ * Method names contain parameter types.
+ * e.g. <code>foo(int)</code>
+ */
+ public final static long M_PARAMETER_TYPES= 1L << 0;
+
+ /**
+ * Method names contain parameter names.
+ * e.g. <code>foo(index)</code>
+ */
+ public final static long M_PARAMETER_NAMES= 1L << 1;
+
+ /**
+ * Method names contain type parameters prepended.
+ * e.g. <code><A> foo(A index)</code>
+ */
+ public final static long M_PRE_TYPE_PARAMETERS= 1L << 2;
+
+
+ /**
+ * Method names contain type parameters appended.
+ * e.g. <code>foo(A index) <A></code>
+ */
+ public final static long M_APP_TYPE_PARAMETERS= 1L << 3;
+
+ /**
+ * Method names contain thrown exceptions.
+ * e.g. <code>foo throws IOException</code>
+ */
+ public final static long M_EXCEPTIONS= 1L << 4;
+
+ /**
+ * Method names contain return type (appended)
+ * e.g. <code>foo : int</code>
+ */
+ public final static long M_APP_RETURNTYPE= 1L << 5;
+
+
+ /**
+ * Method names contain return type (appended)
+ * e.g. <code>int foo</code>
+ */
+ public final static long M_PRE_RETURNTYPE= 1L << 6;
+
+ /**
+ * Method names are fully qualified.
+ * e.g. <code>java.util.Vector.size</code>
+ */
+ public final static long M_FULLY_QUALIFIED= 1L << 7;
+
+ /**
+ * Method names are post qualified.
+ * e.g. <code>size - java.util.Vector</code>
+ */
+ public final static long M_POST_QUALIFIED= 1L << 8;
+
+ /**
+ * Initializer names are fully qualified.
+ * e.g. <code>java.util.Vector.{ ... }</code>
+ */
+ public final static long I_FULLY_QUALIFIED= 1L << 10;
+
+ /**
+ * Type names are post qualified.
+ * e.g. <code>{ ... } - java.util.Map</code>
+ */
+ public final static long I_POST_QUALIFIED= 1L << 11;
+
+ /**
+ * Field names contain the declared type (appended)
+ * e.g. <code>fHello : int</code>
+ */
+ public final static long F_APP_TYPE_SIGNATURE= 1L << 14;
+
+ /**
+ * Field names contain the declared type (prepended)
+ * e.g. <code>int fHello</code>
+ */
+ public final static long F_PRE_TYPE_SIGNATURE= 1L << 15;
+
+ /**
+ * Fields names are fully qualified.
+ * e.g. <code>java.lang.System.out</code>
+ */
+ public final static long F_FULLY_QUALIFIED= 1L << 16;
+ /**
+ * Fields names are post qualified.
+ * e.g. <code>out - java.lang.System</code>
+ */
+ public final static long F_POST_QUALIFIED= 1L << 17;
+ /**
+ * Type names are fully qualified.
+ * e.g. <code>java.util.Map.Entry</code>
+ */
+ public final static long T_FULLY_QUALIFIED= 1L << 18;
+
+ /**
+ * Type names are type container qualified.
+ * e.g. <code>Map.Entry</code>
+ */
+ public final static long T_CONTAINER_QUALIFIED= 1L << 19;
+
+ /**
+ * Type names are post qualified.
+ * e.g. <code>Entry - java.util.Map</code>
+ */
+ public final static long T_POST_QUALIFIED= 1L << 20;
+
+ /**
+ * Type names contain type parameters.
+ * e.g. <code>Map<S, T></code>
+ */
+ public final static long T_TYPE_PARAMETERS= 1L << 21;
+
+ /**
+ * Type parameters are post qualified.
+ * e.g. <code>K - java.util.Map.Entry</code>
+ *
+ * @since 3.5
+ */
+ public final static long TP_POST_QUALIFIED= 1L << 22;
+
+ /**
+ * Declarations (import container / declaration, package declaration) are qualified.
+ * e.g. <code>java.util.Vector.class/import container</code>
+ */
+ public final static long D_QUALIFIED= 1L << 24;
+
+ /**
+ * Declarations (import container / declaration, package declaration) are post qualified.
+ * e.g. <code>import container - java.util.Vector.class</code>
+ */
+ public final static long D_POST_QUALIFIED= 1L << 25;
+
+ /**
+ * Class file names are fully qualified.
+ * e.g. <code>java.util.Vector.class</code>
+ */
+ public final static long CF_QUALIFIED= 1L << 27;
+
+ /**
+ * Class file names are post qualified.
+ * e.g. <code>Vector.class - java.util</code>
+ */
+ public final static long CF_POST_QUALIFIED= 1L << 28;
+
+ /**
+ * Compilation unit names are fully qualified.
+ * e.g. <code>java.util.Vector.java</code>
+ */
+ public final static long CU_QUALIFIED= 1L << 31;
+
+ /**
+ * Compilation unit names are post qualified.
+ * e.g. <code>Vector.java - java.util</code>
+ */
+ public final static long CU_POST_QUALIFIED= 1L << 32;
+
+
+ /**
+ * Package names are qualified.
+ * e.g. <code>MyProject/src/java.util</code>
+ */
+ public final static long P_QUALIFIED= 1L << 35;
+
+ /**
+ * Package names are post qualified.
+ * e.g. <code>java.util - MyProject/src</code>
+ */
+ public final static long P_POST_QUALIFIED= 1L << 36;
+
+ /**
+ * Package names are compressed.
+ * e.g. <code>o*.e*.search</code>
+ */
+ public final static long P_COMPRESSED= 1L << 37;
+
+ /**
+ * Package Fragment Roots contain variable name if from a variable.
+ * e.g. <code>JRE_LIB - c:\java\lib\rt.jar</code>
+ */
+ public final static long ROOT_VARIABLE= 1L << 40;
+
+
+ /**
+ * Package Fragment Roots contain the project name if not an archive (prepended).
+ * e.g. <code>MyProject/src</code>
+ */
+ public final static long ROOT_QUALIFIED= 1L << 41;
+
+ /**
+ * Package Fragment Roots contain the project name if not an archive (appended).
+ * e.g. <code>src - MyProject</code>
+ */
+ public final static long ROOT_POST_QUALIFIED= 1L << 42;
+
+ /**
+ * Add root path to all elements except Package Fragment Roots and Java projects.
+ * e.g. <code>java.lang.Vector - C:\java\lib\rt.jar</code>
+ * Option only applies to getElementLabel
+ */
+ public final static long APPEND_ROOT_PATH= 1L << 43;
+
+
+ /**
+ * Add root path to all elements except Package Fragment Roots and Java projects.
+ * e.g. <code>C:\java\lib\rt.jar - java.lang.Vector</code>
+ * Option only applies to getElementLabel
+ */
+ public final static long PREPEND_ROOT_PATH= 1L << 44;
+
+ /**
+ * Post qualify referenced package fragment roots. For example
+ * <code>jdt.jar - org.eclipse.jdt.ui</code> if the jar is referenced
+ * from another project.
+ */
+ public final static long REFERENCED_ROOT_POST_QUALIFIED= 1L << 45;
+
+ /**
+ * Specifies to use the resolved information of a IType, IMethod or IField. See {@link IType#isResolved()}.
+ * If resolved information is available, types will be rendered with type parameters of the instantiated type.
+ * Resolved methods render with the parameter types of the method instance.
+ * <code>Vector<String>.get(String)</code>
+ */
+ public final static long USE_RESOLVED= 1L << 48;
+ /**
+ * Prepend first category (if any) to field.
+ * @since 3.2
+ */
+ public final static long F_CATEGORY= 1L << 49;
+ /**
+ * Prepend first category (if any) to method.
+ * @since 3.2
+ */
+ public final static long M_CATEGORY= 1L << 50;
+ /**
+ * Prepend first category (if any) to type.
+ * @since 3.2
+ */
+ public final static long T_CATEGORY= 1L << 51;
+
+ /**
+ * Specifies to apply color styles to labels. This flag only applies to methods taking or returning a {@link StyledString}.
+ *
+ * @since 3.4
+ */
+ public final static long COLORIZE= 1L << 55;
+
+ /**
+ * Show category for all elements.
+ * @since 3.2
+ */
+ public final static long ALL_CATEGORY= new Long(F_CATEGORY | M_CATEGORY | T_CATEGORY).longValue();
+
+
+ /**
+ * User-readable string for concatenating categories (e.g. " ").
+ * @since 3.5
+ */
+ public final static String CATEGORY_SEPARATOR_STRING = " "; //JavaUIMessages.JavaElementLabels_category_separator_string;
+
+ /**
+ * User-readable string for separating post qualified names (e.g. " - ").
+ */
+ public final static String CONCAT_STRING = "-"; //TODO JavaUIMessages.JavaElementLabels_concat_string;
+
+ /**
+ * User-readable string for separating list items (e.g. ", ").
+ */
+ public final static String COMMA_STRING = ", "; //TODO JavaUIMessages.JavaElementLabels_comma_string;
+
+ /**
+ * User-readable string for separating the return type (e.g. " : ").
+ */
+ public final static String DECL_STRING= ": "; //TODO JavaUIMessages.JavaElementLabels_declseparator_string;
+
+ /**
+ * User-readable string for ellipsis ("...").
+ */
+ public final static String ELLIPSIS_STRING= "..."; //$NON-NLS-1$
+
+ /**
+ * User-readable string for the default package name (e.g. "(default package)").
+ */
+ public final static String DEFAULT_PACKAGE= "(default package)"; //TODO JavaUIMessages.JavaElementLabels_default_package;
+
+ /**
+ * Default options (M_PARAMETER_TYPES, M_APP_TYPE_PARAMETERS & T_TYPE_PARAMETERS enabled)
+ */
+ public final static long ALL_DEFAULT= new Long(M_PARAMETER_TYPES | M_APP_TYPE_PARAMETERS | T_TYPE_PARAMETERS).longValue();
+
+ public static String getTextLabel(Object obj, long flags, Logger logger, JavaUIMessages messages) {
+ if (obj instanceof IJavaElement) {
+ return getElementLabel((IJavaElement) obj, flags, logger, messages);
+ }
+
+ return "UNKNOWN";
+ }
+
+ /**
+ * Returns the label for a Java element with the flags as defined by this class.
+ *
+ * @param element the element to render
+ * @param flags the rendering flags
+ * @return the label of the Java element
+ */
+ public static String getElementLabel(IJavaElement element, long flags, Logger logger, JavaUIMessages messages) {
+ StringBuffer result= new StringBuffer();
+ getElementLabel(element, flags, result, logger, messages);
+ return Strings.markJavaElementLabelLTR(result.toString());
+ }
+
+ /**
+ * Returns the label for a Java element with the flags as defined by this class.
+ *
+ * @param element the element to render
+ * @param flags the rendering flags
+ * @param buf the buffer to append the resulting label to
+ */
+ public static void getElementLabel(IJavaElement element, long flags, StringBuffer buf, Logger logger, JavaUIMessages messages) {
+ new JavaElementLabelComposer(buf,logger,messages).appendElementLabel(element, flags);
+ }
+
+ /**
+ * Returns the styled label of the given object. The object must be of type {@link IJavaElement} or adapt to {@link IWorkbenchAdapter}.
+ * If the element type is not known, the empty string is returned.
+ * The returned label is BiDi-processed with {@link TextProcessor#process(String, String)}.
+ *
+ * @param obj object to get the label for
+ * @param flags the rendering flags
+ * @return the label or the empty string if the object type is not supported
+ *
+ * @since 3.4
+ */
+ public static StyledString getStyledTextLabel(Object obj, long flags, Logger logger, JavaUIMessages messages) {
+ if (obj instanceof IJavaElement) {
+ return getStyledElementLabel((IJavaElement) obj, flags, logger, messages);
+ }
+
+ return new StyledString();
+ }
+
+ /**
+ * Returns the styled label for a Java element with the flags as defined by this class.
+ *
+ * @param element the element to render
+ * @param flags the rendering flags
+ * @return the label of the Java element
+ *
+ * @since 3.4
+ */
+ public static StyledString getStyledElementLabel(IJavaElement element, long flags, Logger logger, JavaUIMessages messages) {
+ StyledString result= new StyledString();
+ getElementLabel(element, flags, result, logger, messages);
+ return Strings.markJavaElementLabelLTR(result);
+ }
+
+ /**
+ * Returns the styled label for a Java element with the flags as defined by this class.
+ *
+ * @param element the element to render
+ * @param flags the rendering flags
+ * @param result the buffer to append the resulting label to
+ *
+ * @since 3.4
+ */
+ public static void getElementLabel(IJavaElement element, long flags, StyledString result, Logger logger, JavaUIMessages messages) {
+ new JavaElementLabelComposer(result, logger, messages).appendElementLabel(element, flags);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaModelUtil.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaModelUtil.java
new file mode 100644
index 0000000..d768f4e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaModelUtil.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 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
+ * Matt Chapman, mpchapman@gmail.com - 89977 Make JDT .java agnostic
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+
+public class JavaModelUtil {
+ /**
+ * @param type the type to test
+ * @return <code>true</code> iff the type is an interface or an annotation
+ * @throws JavaModelException thrown when the field can not be accessed
+ */
+ public static boolean isInterfaceOrAnnotation(IType type) throws JavaModelException {
+ return type.isInterface();
+ }
+
+ /**
+ * Returns the package fragment root of <code>IJavaElement</code>. If the given
+ * element is already a package fragment root, the element itself is returned.
+ * @param element the element
+ * @return the package fragment root of the element or <code>null</code>
+ */
+ public static IPackageFragmentRoot getPackageFragmentRoot(IJavaElement element) {
+ return (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+ }
+
+ /**
+ * Returns the classpath entry of the given package fragment root. This is the raw entry, except
+ * if the root is a referenced library, in which case it's the resolved entry.
+ *
+ * @param root a package fragment root
+ * @return the corresponding classpath entry
+ * @throws JavaModelException if accessing the entry failed
+ * @since 3.6
+ */
+ public static IClasspathEntry getClasspathEntry(IPackageFragmentRoot root) throws JavaModelException {
+ IClasspathEntry rawEntry= root.getRawClasspathEntry();
+ int rawEntryKind= rawEntry.getEntryKind();
+ switch (rawEntryKind) {
+ case IClasspathEntry.CPE_LIBRARY:
+ case IClasspathEntry.CPE_VARIABLE:
+ case IClasspathEntry.CPE_CONTAINER: // should not happen, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=305037
+ if (root.isArchive() && root.getKind() == IPackageFragmentRoot.K_BINARY) {
+ IClasspathEntry resolvedEntry= root.getResolvedClasspathEntry();
+ if (resolvedEntry.getReferencingEntry() != null)
+ return resolvedEntry;
+ else
+ return rawEntry;
+ }
+ }
+ return rawEntry;
+ }
+
+ /**
+ * Checks whether the given type has a valid main method or not.
+ * @param type the type to test
+ * @return returns <code>true</code> if the type has a main method
+ * @throws JavaModelException thrown when the type can not be accessed
+ */
+ public static boolean hasMainMethod(IType type) throws JavaModelException {
+ IMethod[] methods= type.getMethods();
+ for (int i= 0; i < methods.length; i++) {
+ if (methods[i].isMainMethod()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaPluginImages.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaPluginImages.java
new file mode 100644
index 0000000..5ed8fd1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaPluginImages.java
@@ -0,0 +1,235 @@
+package org.eclipse.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import java.net.URL;
+import java.util.HashMap;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.ImageData;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+public class JavaPluginImages {
+ public static final IPath ICONS_PATH= new Path("$nl$/icons/full"); //$NON-NLS-1$
+
+ private static final String T_OBJ= "obj16"; //$NON-NLS-1$
+ private static final String T_OVR= "ovr16"; //$NON-NLS-1$
+
+ private static final String NAME_PREFIX= "org.eclipse.e4.demo.simpleide.jdt."; //$NON-NLS-1$
+ private static final int NAME_PREFIX_LENGTH= NAME_PREFIX.length();
+
+ private static ImageRegistry fgImageRegistry= null;
+ private static HashMap<String,ImageDescriptor> fgAvoidSWTErrorMap= null;
+ public static ImageDescriptorRegistry IMAGE_DESCRIPTOR_REGISTRY = new ImageDescriptorRegistry();
+
+ public static final String IMG_MISC_PRIVATE= NAME_PREFIX + "methpri_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_LOCAL_VARIABLE= NAME_PREFIX + "localvariable_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_PACKDECL= NAME_PREFIX + "packd_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_IMPDECL= NAME_PREFIX + "imp_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_IMPCONT= NAME_PREFIX + "impc_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_EXTJAR= NAME_PREFIX + "jar_l_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_EXTJAR_WSRC= NAME_PREFIX + "jar_lsrc_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_JAR= NAME_PREFIX + "jar_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_JAR_WSRC= NAME_PREFIX + "jar_src_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_CLASSFOLDER= NAME_PREFIX + "cf_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_CLASSFOLDER_WSRC= NAME_PREFIX + "cf_src_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_PACKFRAG_ROOT= NAME_PREFIX + "packagefolder_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_CUNIT= NAME_PREFIX + "jcu_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_CFILE= NAME_PREFIX + "classf_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_JAVA_MODEL= NAME_PREFIX + "java_model_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_TYPEVARIABLE= NAME_PREFIX + "typevariable_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_ANNOTATION= NAME_PREFIX + "annotation_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_GHOST= NAME_PREFIX + "ghost.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_UNKNOWN= NAME_PREFIX + "unknown_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_MISC_PUBLIC= NAME_PREFIX + "methpub_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_MISC_PROTECTED= NAME_PREFIX + "methpro_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_MISC_DEFAULT= NAME_PREFIX + "methdef_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_FIELD_PUBLIC= NAME_PREFIX + "field_public_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_FIELD_PROTECTED= NAME_PREFIX + "field_protected_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_FIELD_PRIVATE= NAME_PREFIX + "field_private_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_FIELD_DEFAULT= NAME_PREFIX + "field_default_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_EMPTY_PACK_RESOURCE= NAME_PREFIX + "empty_pack_fldr_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_EMPTY_PACKAGE= NAME_PREFIX + "empty_pack_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_PACKAGE= NAME_PREFIX + "package_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_ENUM_ALT= NAME_PREFIX + "enum_alt_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_ANNOTATION_ALT= NAME_PREFIX + "annotation_alt_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_INTERFACEALT= NAME_PREFIX + "intf_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_CLASSALT= NAME_PREFIX + "classfo_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_ENUM= NAME_PREFIX + "enum_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_ENUM_DEFAULT= NAME_PREFIX + "enum_default_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_ENUM_PROTECTED= NAME_PREFIX + "enum_protected_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_ENUM_PRIVATE= NAME_PREFIX + "enum_private_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_ANNOTATION_DEFAULT= NAME_PREFIX + "annotation_default_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_ANNOTATION_PROTECTED= NAME_PREFIX + "annotation_protected_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_ANNOTATION_PRIVATE= NAME_PREFIX + "annotation_private_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_INNER_INTERFACE_PUBLIC= NAME_PREFIX + "innerinterface_public_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_INNER_INTERFACE_DEFAULT= NAME_PREFIX + "innerinterface_default_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_INNER_INTERFACE_PROTECTED= NAME_PREFIX + "innerinterface_protected_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_INNER_INTERFACE_PRIVATE= NAME_PREFIX + "innerinterface_private_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_INTERFACE_DEFAULT= NAME_PREFIX + "int_default_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_INTERFACE= NAME_PREFIX + "int_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_INNER_CLASS_PUBLIC= NAME_PREFIX + "innerclass_public_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_INNER_CLASS_DEFAULT= NAME_PREFIX + "innerclass_default_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_INNER_CLASS_PROTECTED= NAME_PREFIX + "innerclass_protected_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_INNER_CLASS_PRIVATE= NAME_PREFIX + "innerclass_private_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_CLASS= NAME_PREFIX + "class_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJS_CLASS_DEFAULT= NAME_PREFIX + "class_default_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJ_PROJECT_CLOSED = NAME_PREFIX + "cprj_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJ_PROJECT = NAME_PREFIX + "prj_obj.gif"; //$NON-NLS-1$
+
+ public static final ImageDescriptor DESC_MISC_PRIVATE= createManagedFromKey(T_OBJ, IMG_MISC_PRIVATE);
+ public static final ImageDescriptor DESC_OBJS_LOCAL_VARIABLE= createManagedFromKey(T_OBJ, IMG_OBJS_LOCAL_VARIABLE);
+ public static final ImageDescriptor DESC_OBJS_PACKDECL= createManagedFromKey(T_OBJ, IMG_OBJS_PACKDECL);
+ public static final ImageDescriptor DESC_OBJS_IMPDECL= createManagedFromKey(T_OBJ, IMG_OBJS_IMPDECL);
+ public static final ImageDescriptor DESC_OBJS_IMPCONT= createManagedFromKey(T_OBJ, IMG_OBJS_IMPCONT);
+ public static final ImageDescriptor DESC_OBJS_EXTJAR= createManagedFromKey(T_OBJ, IMG_OBJS_EXTJAR);
+ public static final ImageDescriptor DESC_OBJS_EXTJAR_WSRC= createManagedFromKey(T_OBJ, IMG_OBJS_EXTJAR_WSRC);
+ public static final ImageDescriptor DESC_OBJS_JAR= createManagedFromKey(T_OBJ, IMG_OBJS_JAR);
+ public static final ImageDescriptor DESC_OBJS_JAR_WSRC= createManagedFromKey(T_OBJ, IMG_OBJS_JAR_WSRC);
+ public static final ImageDescriptor DESC_OBJS_CLASSFOLDER= createManagedFromKey(T_OBJ, IMG_OBJS_CLASSFOLDER);
+ public static final ImageDescriptor DESC_OBJS_CLASSFOLDER_WSRC= createManagedFromKey(T_OBJ, IMG_OBJS_CLASSFOLDER_WSRC);
+ public static final ImageDescriptor DESC_OBJS_PACKFRAG_ROOT= createManagedFromKey(T_OBJ, IMG_OBJS_PACKFRAG_ROOT);
+ public static final ImageDescriptor DESC_OBJS_CUNIT= createManagedFromKey(T_OBJ, IMG_OBJS_CUNIT);
+ public static final ImageDescriptor DESC_OBJS_CFILE= createManagedFromKey(T_OBJ, IMG_OBJS_CFILE);
+ public static final ImageDescriptor DESC_OBJS_JAVA_MODEL= createManagedFromKey(T_OBJ, IMG_OBJS_JAVA_MODEL);
+ public static final ImageDescriptor DESC_OBJS_TYPEVARIABLE= createManagedFromKey(T_OBJ, IMG_OBJS_TYPEVARIABLE);
+ public static final ImageDescriptor DESC_OBJS_ANNOTATION= createManagedFromKey(T_OBJ, IMG_OBJS_ANNOTATION);
+ public static final ImageDescriptor DESC_OBJS_GHOST= createManagedFromKey(T_OBJ, IMG_OBJS_GHOST);
+ public static final ImageDescriptor DESC_OBJS_UNKNOWN= createManagedFromKey(T_OBJ, IMG_OBJS_UNKNOWN);
+ public static final ImageDescriptor DESC_MISC_PUBLIC= createManagedFromKey(T_OBJ, IMG_MISC_PUBLIC);
+ public static final ImageDescriptor DESC_MISC_PROTECTED= createManagedFromKey(T_OBJ, IMG_MISC_PROTECTED);
+ public static final ImageDescriptor DESC_MISC_DEFAULT= createManagedFromKey(T_OBJ, IMG_MISC_DEFAULT);
+ public static final ImageDescriptor DESC_FIELD_PUBLIC= createManagedFromKey(T_OBJ, IMG_FIELD_PUBLIC);
+ public static final ImageDescriptor DESC_FIELD_PROTECTED= createManagedFromKey(T_OBJ, IMG_FIELD_PROTECTED);
+ public static final ImageDescriptor DESC_FIELD_PRIVATE= createManagedFromKey(T_OBJ, IMG_FIELD_PRIVATE);
+ public static final ImageDescriptor DESC_FIELD_DEFAULT= createManagedFromKey(T_OBJ, IMG_FIELD_DEFAULT);
+ public static final ImageDescriptor DESC_OBJS_EMPTY_PACKAGE_RESOURCES= createManagedFromKey(T_OBJ, IMG_OBJS_EMPTY_PACK_RESOURCE);
+ public static final ImageDescriptor DESC_OBJS_EMPTY_PACKAGE= createManagedFromKey(T_OBJ, IMG_OBJS_EMPTY_PACKAGE);
+ public static final ImageDescriptor DESC_OBJS_PACKAGE= createManagedFromKey(T_OBJ, IMG_OBJS_PACKAGE);
+ public static final ImageDescriptor DESC_OBJS_ENUM_ALT= createManagedFromKey(T_OBJ, IMG_OBJS_ENUM_ALT);
+ public static final ImageDescriptor DESC_OBJS_ANNOTATION_ALT= createManagedFromKey(T_OBJ, IMG_OBJS_ANNOTATION_ALT);
+ public static final ImageDescriptor DESC_OBJS_INTERFACEALT= createManagedFromKey(T_OBJ, IMG_OBJS_INTERFACEALT);
+ public static final ImageDescriptor DESC_OBJS_CLASSALT= createManagedFromKey(T_OBJ, IMG_OBJS_CLASSALT);
+ public static final ImageDescriptor DESC_OBJS_ENUM= createManagedFromKey(T_OBJ, IMG_OBJS_ENUM);
+ public static final ImageDescriptor DESC_OBJS_ENUM_DEFAULT= createManagedFromKey(T_OBJ, IMG_OBJS_ENUM_DEFAULT);
+ public static final ImageDescriptor DESC_OBJS_ENUM_PROTECTED= createManagedFromKey(T_OBJ, IMG_OBJS_ENUM_PROTECTED);
+ public static final ImageDescriptor DESC_OBJS_ENUM_PRIVATE= createManagedFromKey(T_OBJ, IMG_OBJS_ENUM_PRIVATE);
+ public static final ImageDescriptor DESC_OBJS_ANNOTATION_DEFAULT= createManagedFromKey(T_OBJ, IMG_OBJS_ANNOTATION_DEFAULT);
+ public static final ImageDescriptor DESC_OBJS_ANNOTATION_PROTECTED= createManagedFromKey(T_OBJ, IMG_OBJS_ANNOTATION_PROTECTED);
+ public static final ImageDescriptor DESC_OBJS_ANNOTATION_PRIVATE= createManagedFromKey(T_OBJ, IMG_OBJS_ANNOTATION_PRIVATE);
+ public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_PUBLIC= createManagedFromKey(T_OBJ, IMG_OBJS_INNER_INTERFACE_PUBLIC);
+ public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_DEFAULT= createManagedFromKey(T_OBJ, IMG_OBJS_INNER_INTERFACE_DEFAULT);
+ public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_PROTECTED= createManagedFromKey(T_OBJ, IMG_OBJS_INNER_INTERFACE_PROTECTED);
+ public static final ImageDescriptor DESC_OBJS_INNER_INTERFACE_PRIVATE= createManagedFromKey(T_OBJ, IMG_OBJS_INNER_INTERFACE_PRIVATE);
+ public static final ImageDescriptor DESC_OBJS_INTERFACE_DEFAULT= createManagedFromKey(T_OBJ, IMG_OBJS_INTERFACE_DEFAULT);
+ public static final ImageDescriptor DESC_OBJS_INTERFACE= createManagedFromKey(T_OBJ, IMG_OBJS_INTERFACE);
+ public static final ImageDescriptor DESC_OBJS_INNER_CLASS_PUBLIC= createManagedFromKey(T_OBJ, IMG_OBJS_INNER_CLASS_PUBLIC);
+ public static final ImageDescriptor DESC_OBJS_INNER_CLASS_DEFAULT= createManagedFromKey(T_OBJ, IMG_OBJS_INNER_CLASS_DEFAULT);
+ public static final ImageDescriptor DESC_OBJS_INNER_CLASS_PROTECTED= createManagedFromKey(T_OBJ, IMG_OBJS_INNER_CLASS_PROTECTED);
+ public static final ImageDescriptor DESC_OBJS_INNER_CLASS_PRIVATE= createManagedFromKey(T_OBJ, IMG_OBJS_INNER_CLASS_PRIVATE);
+ public static final ImageDescriptor DESC_OBJS_CLASS= createManagedFromKey(T_OBJ, IMG_OBJS_CLASS);
+ public static final ImageDescriptor DESC_OBJS_CLASS_DEFAULT= createManagedFromKey(T_OBJ, IMG_OBJS_CLASS_DEFAULT);
+ public static final ImageDescriptor DESC_OVR_DEPRECATED= createUnManagedCached(T_OVR, "deprecated.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_OVR_ABSTRACT= createUnManagedCached(T_OVR, "abstract_co.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_OVR_CONSTRUCTOR= createUnManagedCached(T_OVR, "constr_ovr.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_OVR_FINAL= createUnManagedCached(T_OVR, "final_co.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_OVR_VOLATILE= createUnManagedCached(T_OVR, "volatile_co.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_OVR_STATIC= createUnManagedCached(T_OVR, "static_co.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_OVR_SYNCH_AND_OVERRIDES= createUnManagedCached(T_OVR, "sync_over.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_OVR_SYNCH_AND_IMPLEMENTS= createUnManagedCached(T_OVR, "sync_impl.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_OVR_OVERRIDES= createUnManagedCached(T_OVR, "over_co.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_OVR_IMPLEMENTS= createUnManagedCached(T_OVR, "implm_co.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_OVR_SYNCH= createUnManagedCached(T_OVR, "synch_co.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_OVR_RUN= createUnManagedCached(T_OVR, "run_co.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_OVR_TRANSIENT= createUnManagedCached(T_OVR, "transient_co.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_OVR_ERROR= createUnManagedCached(T_OVR, "error_co.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_OVR_WARNING= createUnManagedCached(T_OVR, "warning_co.gif"); //$NON-NLS-1$
+ public static final ImageDescriptor DESC_OBJ_PROJECT_CLOSED= createManagedFromKey(T_OBJ, IMG_OBJ_PROJECT_CLOSED);
+ public static final ImageDescriptor DESC_OBJ_PROJECT= createManagedFromKey(T_OBJ, IMG_OBJ_PROJECT);
+
+ private static final class CachedImageDescriptor extends ImageDescriptor {
+ private ImageDescriptor fDescriptor;
+ private ImageData fData;
+
+ public CachedImageDescriptor(ImageDescriptor descriptor) {
+ fDescriptor = descriptor;
+ }
+
+ public ImageData getImageData() {
+ if (fData == null) {
+ fData= fDescriptor.getImageData();
+ }
+ return fData;
+ }
+ }
+
+ private static ImageDescriptor createManagedFromKey(String prefix, String key) {
+ return createManaged(prefix, key.substring(NAME_PREFIX_LENGTH), key);
+ }
+
+ private static ImageDescriptor createManaged(String prefix, String name, String key) {
+ try {
+ ImageDescriptor result= create(prefix, name, true);
+
+ if (fgAvoidSWTErrorMap == null) {
+ fgAvoidSWTErrorMap= new HashMap<String,ImageDescriptor>();
+ }
+ fgAvoidSWTErrorMap.put(key, result);
+ if (fgImageRegistry != null) {
+
+ //FIXME JavaPlugin.logErrorMessage("Image registry already defined"); //$NON-NLS-1$
+ }
+ return result;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return ImageDescriptor.getMissingImageDescriptor();
+ }
+
+ /*
+ * Creates an image descriptor for the given prefix and name in the JDT UI bundle. The path can
+ * contain variables like $NL$.
+ * If no image could be found, <code>useMissingImageDescriptor</code> decides if either
+ * the 'missing image descriptor' is returned or <code>null</code>.
+ * or <code>null</code>.
+ */
+ private static ImageDescriptor create(String prefix, String name, boolean useMissingImageDescriptor) {
+ IPath path= ICONS_PATH.append(prefix).append(name);
+ return createImageDescriptor(FrameworkUtil.getBundle(JavaPluginImages.class), path, useMissingImageDescriptor);
+ }
+
+ /*
+ * Creates an image descriptor for the given path in a bundle. The path can contain variables
+ * like $NL$.
+ * If no image could be found, <code>useMissingImageDescriptor</code> decides if either
+ * the 'missing image descriptor' is returned or <code>null</code>.
+ * Added for 3.1.1.
+ */
+ public static ImageDescriptor createImageDescriptor(Bundle bundle, IPath path, boolean useMissingImageDescriptor) {
+ URL url= FileLocator.find(bundle, path, null);
+ if (url != null) {
+ return ImageDescriptor.createFromURL(url);
+ }
+ if (useMissingImageDescriptor) {
+ return ImageDescriptor.getMissingImageDescriptor();
+ }
+ return null;
+ }
+
+ /*
+ * Creates an image descriptor for the given prefix and name in the JDT UI bundle and let type descriptor cache the image data.
+ * If no image could be found, the 'missing image descriptor' is returned.
+ */
+ private static ImageDescriptor createUnManagedCached(String prefix, String name) {
+ try {
+ return new CachedImageDescriptor(create(prefix, name, true));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return ImageDescriptor.getMissingImageDescriptor();
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaUILabelProvider.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaUILabelProvider.java
new file mode 100644
index 0000000..b0dc713
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/JavaUILabelProvider.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.demo.simpleide.jdt.internal.JavaUIMessages;
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.swt.graphics.Image;
+
+public class JavaUILabelProvider extends LabelProvider implements IStyledLabelProvider {
+ private long fTextFlags;
+ private int fImageFlags;
+
+ private Logger logger;
+ private JavaUIMessages messages;
+
+ protected JavaElementImageProvider fImageLabelProvider;
+
+ /**
+ * Creates a new label provider with default flags.
+ */
+ public JavaUILabelProvider(Logger logger, JavaUIMessages messages) {
+ this(JavaElementLabels.ALL_DEFAULT,JavaElementImageProvider.OVERLAY_ICONS, logger,messages);
+ }
+
+ public JavaUILabelProvider(long textFlags, int imageFlags, Logger logger, JavaUIMessages messages) {
+ fImageLabelProvider= new JavaElementImageProvider(logger);
+
+ fTextFlags= textFlags;
+ fImageFlags = imageFlags;
+ this.logger = logger;
+ this.messages = messages;
+ }
+
+ @Override
+ public String getText(Object element) {
+ String result = JavaElementLabels.getTextLabel(element, evaluateTextFlags(element),logger,messages);
+// return decorateText(result, element);
+ return result;
+ }
+
+ public Image getImage(Object element) {
+ Image result= fImageLabelProvider.getImageLabel(element, evaluateImageFlags(element),logger);
+// return decorateImage(result, element);
+ return result;
+ }
+
+ /**
+ * Gets the image flags.
+ * Can be overwritten by super classes.
+ * @return Returns a int
+ */
+ public final int getImageFlags() {
+ return fImageFlags;
+ }
+
+ /**
+ * Evaluates the image flags for a element.
+ * Can be overwritten by super classes.
+ * @param element the element to compute the image flags for
+ * @return Returns a int
+ */
+ protected int evaluateImageFlags(Object element) {
+ return getImageFlags();
+ }
+
+ /**
+ * Evaluates the text flags for a element. Can be overwritten by super classes.
+ * @param element the element to compute the text flags for
+ * @return Returns a int
+ */
+ protected long evaluateTextFlags(Object element) {
+ return getTextFlags();
+ }
+
+ /**
+ * Gets the text flags.
+ * @return Returns a int
+ */
+ public final long getTextFlags() {
+ return fTextFlags;
+ }
+
+ public StyledString getStyledText(Object element) {
+ StyledString string= JavaElementLabels.getStyledTextLabel(element, (evaluateTextFlags(element) | JavaElementLabels.COLORIZE), logger, messages);
+// System.err.println("Styled string: " + string);
+// System.err.println(string.getStyleRanges().length);
+ return string;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/Strings.java b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/Strings.java
new file mode 100644
index 0000000..32ff24f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/src/org/eclipse/e4/demo/simpleide/jdt/internal/editor/viewer/Strings.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 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.e4.demo.simpleide.jdt.internal.editor.viewer;
+
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.osgi.util.TextProcessor;
+
+/**
+ * Helper class to provide String manipulation functions not available in standard JDK.
+ */
+public class Strings {
+ /**
+ * Tells whether we have to use the {@link TextProcessor}
+ * <p>
+ * This is used for performance optimization.
+ * </p>
+ * @since 3.4
+ */
+ public static final boolean USE_TEXT_PROCESSOR;
+ static {
+ String testString= "args : String[]"; //$NON-NLS-1$
+ USE_TEXT_PROCESSOR= testString != TextProcessor.process(testString);
+ }
+
+ private static final String JAVA_ELEMENT_DELIMITERS= TextProcessor.getDefaultDelimiters() + "<>(),?{} "; //$NON-NLS-1$
+
+ /**
+ * Adds special marks so that that the given Java element label is readable in a BiDi
+ * environment.
+ *
+ * @param string the string
+ * @return the processed styled string
+ * @since 3.6
+ */
+ public static String markJavaElementLabelLTR(String string) {
+ if (!USE_TEXT_PROCESSOR)
+ return string;
+
+ return TextProcessor.process(string, JAVA_ELEMENT_DELIMITERS);
+ }
+
+ /**
+ * Adds special marks so that that the given styled Java element label is readable in a BiDi
+ * environment.
+ *
+ * @param styledString the styled string
+ * @return the processed styled string
+ * @since 3.6
+ */
+ public static StyledString markJavaElementLabelLTR(StyledString styledString) {
+ if (!USE_TEXT_PROCESSOR)
+ return styledString;
+
+ String inputString= styledString.getString();
+ String string= TextProcessor.process(inputString, JAVA_ELEMENT_DELIMITERS);
+ if (string != inputString)
+ insertMarks(styledString, inputString, string);
+ return styledString;
+ }
+
+ /**
+ * Inserts the marks into the given styled string.
+ *
+ * @param styledString the styled string
+ * @param originalString the original string
+ * @param processedString the processed string
+ * @since 3.5
+ */
+ private static void insertMarks(StyledString styledString, String originalString, String processedString) {
+ int originalLength= originalString.length();
+ int processedStringLength= processedString.length();
+ char orig= originalLength > 0 ? originalString.charAt(0) : '\0';
+ for (int o= 0, p= 0; p < processedStringLength; p++) {
+ char processed= processedString.charAt(p);
+ if (o < originalLength) {
+ if (orig == processed) {
+ o++;
+ if (o < originalLength)
+ orig= originalString.charAt(o);
+ continue;
+ }
+ }
+ styledString.insert(processed, p);
+ }
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.jdt/xmi/fragment.e4xmi b/examples/org.eclipse.e4.demo.simpleide.jdt/xmi/fragment.e4xmi
new file mode 100644
index 0000000..8d312af
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.jdt/xmi/fragment.e4xmi
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:commands="http://www.eclipse.org/ui/2010/UIModel/application/commands" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmlns:simpleide="http://www.eclipse.org/e4/demo/simpleide" xmi:id="_37L3wHihEd-1hY0DgxUB9A">
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_J1oEEHiiEd-QLpUkCzu7EA" featurename="commands" parentElementId="app.simpleide">
+ <elements xsi:type="commands:Command" xmi:id="_Ov-eMHiiEd-QLpUkCzu7EA" elementId="simpleide.command.jdt.newclass" commandName="New Java Class"/>
+ <elements xsi:type="commands:Command" xmi:id="_SUdRkHiiEd-QLpUkCzu7EA" elementId="simpleide.command.jdt.newinterface" commandName="New Java Interface"/>
+ <elements xsi:type="commands:Command" xmi:id="_Uncn4HiiEd-QLpUkCzu7EA" elementId="simpleide.command.jdt.enum" commandName="New Java Enum"/>
+ <elements xsi:type="commands:Command" xmi:id="_WCXtwHiiEd-QLpUkCzu7EA" elementId="simpleide.command.jdt.newannotion" commandName="New Java Annotation"/>
+ </fragments>
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_aBkHMHiiEd-QLpUkCzu7EA" featurename="handlers" parentElementId="app.simpleide">
+ <elements xsi:type="commands:Handler" xmi:id="_eKIfEHiiEd-QLpUkCzu7EA" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.jdt/org.eclipse.e4.demo.simpleide.jdt.handlers.NewJavaClassHandler" command="_Ov-eMHiiEd-QLpUkCzu7EA"/>
+ <elements xsi:type="commands:Handler" xmi:id="_hb7nAHiiEd-QLpUkCzu7EA" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.jdt/org.eclipse.e4.demo.simpleide.jdt.handlers.NewJavaInterfaceHandler" command="_SUdRkHiiEd-QLpUkCzu7EA"/>
+ <elements xsi:type="commands:Handler" xmi:id="_jfZTkHiiEd-QLpUkCzu7EA" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.jdt/org.eclipse.e4.demo.simpleide.jdt.handlers.NewJavaEnumHandler" command="_Uncn4HiiEd-QLpUkCzu7EA"/>
+ <elements xsi:type="commands:Handler" xmi:id="_l6VE8HiiEd-QLpUkCzu7EA" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.jdt/org.eclipse.e4.demo.simpleide.jdt.handlers.NewJavaAnnotationHandler" command="_WCXtwHiiEd-QLpUkCzu7EA"/>
+ </fragments>
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_ppKHIHiiEd-QLpUkCzu7EA" featurename="children" parentElementId="simpleide.mainmenu.file.new">
+ <elements xsi:type="menu:HandledMenuItem" xmi:id="_wvvvUHiiEd-QLpUkCzu7EA" label="Class" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.jdt/icons/class_obj.gif" command="_Ov-eMHiiEd-QLpUkCzu7EA"/>
+ <elements xsi:type="menu:HandledMenuItem" xmi:id="_0eFCQHiiEd-QLpUkCzu7EA" label="Interface" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.jdt/icons/int_obj.gif" command="_SUdRkHiiEd-QLpUkCzu7EA"/>
+ <elements xsi:type="menu:HandledMenuItem" xmi:id="_4phH8HiiEd-QLpUkCzu7EA" label="Enum" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.jdt/icons/enum_obj.gif" command="_Uncn4HiiEd-QLpUkCzu7EA"/>
+ <elements xsi:type="menu:HandledMenuItem" xmi:id="_7TroIHiiEd-QLpUkCzu7EA" label="Annotation" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.jdt/icons/annotation_obj.gif" command="_WCXtwHiiEd-QLpUkCzu7EA"/>
+ </fragments>
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="__FnosHiiEd-QLpUkCzu7EA" featurename="editorPartDescriptors" parentElementId="app.simpleide">
+ <elements xsi:type="simpleide:EditorPartDescriptor" xmi:id="_EpikQHijEd-QLpUkCzu7EA" label="Java Source Editor" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.jdt/icons/jcu_obj.gif" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.jdt/org.eclipse.e4.demo.simpleide.jdt.internal.editor.JavaEditor">
+ <fileextensions>java</fileextensions>
+ </elements>
+ </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/.classpath b/examples/org.eclipse.e4.demo.simpleide.model/.classpath
new file mode 100644
index 0000000..304e861
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/.project b/examples/org.eclipse.e4.demo.simpleide.model/.project
new file mode 100644
index 0000000..2a72986
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.simpleide.model</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.model/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..3d32eef
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+#Wed Jun 02 15:48:37 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide.model/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..7a36451
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:08:13 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.model/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..9744b28
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.model;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-ClassPath: .
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.e4.demo.simpleide.model.simpleide,
+ org.eclipse.e4.demo.simpleide.model.simpleide.impl,
+ org.eclipse.e4.demo.simpleide.model.simpleide.util
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.emf.ecore;visibility:=reexport,
+ org.eclipse.e4.ui.model.workbench;visibility:=reexport,
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0"
+Bundle-ActivationPolicy: lazy
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/build.properties b/examples/org.eclipse.e4.demo.simpleide.model/build.properties
new file mode 100644
index 0000000..66d9c2d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/build.properties
@@ -0,0 +1,14 @@
+
+# <copyright>
+# </copyright>
+#
+# $Id$
+
+bin.includes = .,\
+ model/,\
+ META-INF/,\
+ plugin.xml,\
+ plugin.properties
+jars.compile.order = .
+source.. = src/
+output.. = bin/
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/model/SimpleIDE.ecore b/examples/org.eclipse.e4.demo.simpleide.model/model/SimpleIDE.ecore
new file mode 100644
index 0000000..e742de1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/model/SimpleIDE.ecore
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="simpleide"
+ nsURI="http://www.eclipse.org/e4/demo/simpleide" nsPrefix="simpleide">
+ <eClassifiers xsi:type="ecore:EClass" name="SimpleIDEApplication" eSuperTypes="platform:/plugin/org.eclipse.e4.ui.model.workbench/model/UIElements.ecore#//Application">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="editorPartDescriptors"
+ upperBound="-1" eType="#//EditorPartDescriptor" containment="true"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="EditorPartDescriptor" eSuperTypes="platform:/plugin/org.eclipse.e4.ui.model.workbench/model/UIElements.ecore#//ApplicationElement platform:/plugin/org.eclipse.e4.ui.model.workbench/model/UIElements.ecore#//ui/UILabel platform:/plugin/org.eclipse.e4.ui.model.workbench/model/UIElements.ecore#//commands/HandlerContainer platform:/plugin/org.eclipse.e4.ui.model.workbench/model/UIElements.ecore#//commands/Bindings">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="contributionURI" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="fileextensions" upperBound="-1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="contenttypes" upperBound="-1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ </eClassifiers>
+</ecore:EPackage>
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/model/SimpleIDE.genmodel b/examples/org.eclipse.e4.demo.simpleide.model/model/SimpleIDE.genmodel
new file mode 100644
index 0000000..30f7de0
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/model/SimpleIDE.genmodel
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<genmodel:GenModel xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+ xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.eclipse.e4.demo.simpleide.model/src"
+ modelPluginID="org.eclipse.e4.demo.simpleide.model" modelName="SimpleIDE" rootExtendsInterface=""
+ rootExtendsClass="org.eclipse.emf.ecore.impl.MinimalEObjectImpl.Container" suppressEMFTypes="true"
+ suppressEMFMetaData="true" importerID="org.eclipse.emf.importer.ecore" complianceLevel="5.0"
+ copyrightFields="false" usedGenPackages="platform:/plugin/org.eclipse.e4.ui.model.workbench/model/UIElements.genmodel#//application"
+ interfaceNamePattern="M{0}">
+ <foreignModel>SimpleIDE.ecore</foreignModel>
+ <genPackages prefix="Simpleide" basePackage="org.eclipse.e4.demo.simpleide.model"
+ disposableProviderFactory="true" ecorePackage="SimpleIDE.ecore#/">
+ <genClasses ecoreClass="SimpleIDE.ecore#//SimpleIDEApplication">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference SimpleIDE.ecore#//SimpleIDEApplication/editorPartDescriptors"/>
+ </genClasses>
+ <genClasses ecoreClass="SimpleIDE.ecore#//EditorPartDescriptor">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute SimpleIDE.ecore#//EditorPartDescriptor/contributionURI"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute SimpleIDE.ecore#//EditorPartDescriptor/fileextensions"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute SimpleIDE.ecore#//EditorPartDescriptor/contenttypes"/>
+ </genClasses>
+ </genPackages>
+</genmodel:GenModel>
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/plugin.properties b/examples/org.eclipse.e4.demo.simpleide.model/plugin.properties
new file mode 100644
index 0000000..522321c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/plugin.properties
@@ -0,0 +1,8 @@
+
+# <copyright>
+# </copyright>
+#
+# $Id$
+
+pluginName = SimpleIDE Model
+providerName = www.example.org
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/plugin.xml b/examples/org.eclipse.e4.demo.simpleide.model/plugin.xml
new file mode 100644
index 0000000..14e79e8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/plugin.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+
+<!--
+ <copyright>
+ </copyright>
+
+ $Id$
+-->
+
+<plugin>
+
+ <extension point="org.eclipse.emf.ecore.generated_package">
+ <package
+ uri="http://www.eclipse.org/e4/demo/simpleide"
+ class="org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl"
+ genModel="model/SimpleIDE.genmodel"/>
+ </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MEditorPartDescriptor.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MEditorPartDescriptor.java
new file mode 100644
index 0000000..afa7e71
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MEditorPartDescriptor.java
@@ -0,0 +1,88 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: MEditorPartDescriptor.java,v 1.3 2010/06/04 20:22:14 johna Exp $
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide;
+
+import java.util.List;
+import org.eclipse.e4.ui.model.application.MApplicationElement;
+import org.eclipse.e4.ui.model.application.commands.MBindings;
+import org.eclipse.e4.ui.model.application.commands.MHandlerContainer;
+import org.eclipse.e4.ui.model.application.ui.MUILabel;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Editor Part Descriptor</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * <ul>
+ * <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getContributionURI <em>Contribution URI</em>}</li>
+ * <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getFileextensions <em>Fileextensions</em>}</li>
+ * <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getContenttypes <em>Contenttypes</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @model
+ * @generated
+ */
+public interface MEditorPartDescriptor extends MApplicationElement, MUILabel, MHandlerContainer, MBindings {
+ /**
+ * Returns the value of the '<em><b>Contribution URI</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <p>
+ * If the meaning of the '<em>Contribution URI</em>' attribute isn't clear,
+ * there really should be more of a description here...
+ * </p>
+ * <!-- end-user-doc -->
+ * @return the value of the '<em>Contribution URI</em>' attribute.
+ * @see #setContributionURI(String)
+ * @model
+ * @generated
+ */
+ String getContributionURI();
+
+ /**
+ * Sets the value of the '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getContributionURI <em>Contribution URI</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @param value the new value of the '<em>Contribution URI</em>' attribute.
+ * @see #getContributionURI()
+ * @generated
+ */
+ void setContributionURI(String value);
+
+ /**
+ * Returns the value of the '<em><b>Fileextensions</b></em>' attribute list.
+ * The list contents are of type {@link java.lang.String}.
+ * <!-- begin-user-doc -->
+ * <p>
+ * If the meaning of the '<em>Fileextensions</em>' attribute list isn't clear,
+ * there really should be more of a description here...
+ * </p>
+ * <!-- end-user-doc -->
+ * @return the value of the '<em>Fileextensions</em>' attribute list.
+ * @model
+ * @generated
+ */
+ List<String> getFileextensions();
+
+ /**
+ * Returns the value of the '<em><b>Contenttypes</b></em>' attribute list.
+ * The list contents are of type {@link java.lang.String}.
+ * <!-- begin-user-doc -->
+ * <p>
+ * If the meaning of the '<em>Contenttypes</em>' attribute list isn't clear,
+ * there really should be more of a description here...
+ * </p>
+ * <!-- end-user-doc -->
+ * @return the value of the '<em>Contenttypes</em>' attribute list.
+ * @model
+ * @generated
+ */
+ List<String> getContenttypes();
+
+} // MEditorPartDescriptor
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MSimpleIDEApplication.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MSimpleIDEApplication.java
new file mode 100644
index 0000000..3cae580
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MSimpleIDEApplication.java
@@ -0,0 +1,43 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: MSimpleIDEApplication.java,v 1.1 2010/05/15 12:59:52 tschindl Exp $
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide;
+
+import java.util.List;
+import org.eclipse.e4.ui.model.application.MApplication;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Simple IDE Application</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * <ul>
+ * <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication#getEditorPartDescriptors <em>Editor Part Descriptors</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @model
+ * @generated
+ */
+public interface MSimpleIDEApplication extends MApplication {
+ /**
+ * Returns the value of the '<em><b>Editor Part Descriptors</b></em>' containment reference list.
+ * The list contents are of type {@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor}.
+ * <!-- begin-user-doc -->
+ * <p>
+ * If the meaning of the '<em>Editor Part Descriptors</em>' containment reference list isn't clear,
+ * there really should be more of a description here...
+ * </p>
+ * <!-- end-user-doc -->
+ * @return the value of the '<em>Editor Part Descriptors</em>' containment reference list.
+ * @model containment="true"
+ * @generated
+ */
+ List<MEditorPartDescriptor> getEditorPartDescriptors();
+
+} // MSimpleIDEApplication
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MSimpleideFactory.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MSimpleideFactory.java
new file mode 100644
index 0000000..0310c2e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/MSimpleideFactory.java
@@ -0,0 +1,44 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide;
+
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Factory</b> for the model.
+ * It provides a create method for each non-abstract class of the model.
+ * <!-- end-user-doc -->
+ * @generated
+ */
+public interface MSimpleideFactory {
+ /**
+ * The singleton instance of the factory.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ MSimpleideFactory INSTANCE = org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleideFactoryImpl.eINSTANCE;
+
+ /**
+ * Returns a new object of class '<em>Simple IDE Application</em>'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return a new object of class '<em>Simple IDE Application</em>'.
+ * @generated
+ */
+ MSimpleIDEApplication createSimpleIDEApplication();
+
+ /**
+ * Returns a new object of class '<em>Editor Part Descriptor</em>'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return a new object of class '<em>Editor Part Descriptor</em>'.
+ * @generated
+ */
+ MEditorPartDescriptor createEditorPartDescriptor();
+
+} //MSimpleideFactory
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/EditorPartDescriptorImpl.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/EditorPartDescriptorImpl.java
new file mode 100644
index 0000000..eb02589
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/EditorPartDescriptorImpl.java
@@ -0,0 +1,581 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: EditorPartDescriptorImpl.java,v 1.5 2011/01/17 12:18:07 pwebster Exp $
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide.impl;
+
+import java.util.Collection;
+import java.util.List;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.ui.model.application.commands.MBindingContext;
+import org.eclipse.e4.ui.model.application.MApplicationElement;
+import org.eclipse.e4.ui.model.application.commands.MBindings;
+import org.eclipse.e4.ui.model.application.commands.MHandler;
+import org.eclipse.e4.ui.model.application.commands.MHandlerContainer;
+import org.eclipse.e4.ui.model.application.commands.impl.CommandsPackageImpl;
+import org.eclipse.e4.ui.model.application.impl.ApplicationElementImpl;
+import org.eclipse.e4.ui.model.application.ui.MUILabel;
+import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl;
+import org.eclipse.e4.ui.model.application.impl.ApplicationPackageImpl;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.NotificationChain;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+import org.eclipse.emf.ecore.util.EDataTypeUniqueEList;
+import org.eclipse.emf.ecore.util.EObjectContainmentEList;
+import org.eclipse.emf.ecore.util.EObjectResolvingEList;
+import org.eclipse.emf.ecore.util.InternalEList;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model object '<em><b>Editor Part Descriptor</b></em>'.
+ * <!-- end-user-doc -->
+ * <p>
+ * The following features are implemented:
+ * <ul>
+ * <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl#getLabel <em>Label</em>}</li>
+ * <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl#getIconURI <em>Icon URI</em>}</li>
+ * <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl#getTooltip <em>Tooltip</em>}</li>
+ * <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl#getHandlers <em>Handlers</em>}</li>
+ * <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl#getBindingContexts <em>Binding Contexts</em>}</li>
+ * <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl#getContributionURI <em>Contribution URI</em>}</li>
+ * <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl#getFileextensions <em>Fileextensions</em>}</li>
+ * <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl#getContenttypes <em>Contenttypes</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @generated
+ */
+public class EditorPartDescriptorImpl extends ApplicationElementImpl implements MEditorPartDescriptor {
+ /**
+ * The default value of the '{@link #getLabel() <em>Label</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getLabel()
+ * @generated
+ * @ordered
+ */
+ protected static final String LABEL_EDEFAULT = null;
+
+ /**
+ * The cached value of the '{@link #getLabel() <em>Label</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getLabel()
+ * @generated
+ * @ordered
+ */
+ protected String label = LABEL_EDEFAULT;
+
+ /**
+ * The default value of the '{@link #getIconURI() <em>Icon URI</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getIconURI()
+ * @generated
+ * @ordered
+ */
+ protected static final String ICON_URI_EDEFAULT = null;
+
+ /**
+ * The cached value of the '{@link #getIconURI() <em>Icon URI</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getIconURI()
+ * @generated
+ * @ordered
+ */
+ protected String iconURI = ICON_URI_EDEFAULT;
+
+ /**
+ * The default value of the '{@link #getTooltip() <em>Tooltip</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getTooltip()
+ * @generated
+ * @ordered
+ */
+ protected static final String TOOLTIP_EDEFAULT = null;
+
+ /**
+ * The cached value of the '{@link #getTooltip() <em>Tooltip</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getTooltip()
+ * @generated
+ * @ordered
+ */
+ protected String tooltip = TOOLTIP_EDEFAULT;
+
+ /**
+ * The cached value of the '{@link #getHandlers() <em>Handlers</em>}' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getHandlers()
+ * @generated
+ * @ordered
+ */
+ protected EList<MHandler> handlers;
+
+ /**
+ * The cached value of the '{@link #getBindingContexts() <em>Binding Contexts</em>}' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getBindingContexts()
+ * @generated
+ * @ordered
+ */
+ protected EList<MBindingContext> bindingContexts;
+
+ /**
+ * The default value of the '{@link #getContributionURI() <em>Contribution URI</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getContributionURI()
+ * @generated
+ * @ordered
+ */
+ protected static final String CONTRIBUTION_URI_EDEFAULT = null;
+
+ /**
+ * The cached value of the '{@link #getContributionURI() <em>Contribution URI</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getContributionURI()
+ * @generated
+ * @ordered
+ */
+ protected String contributionURI = CONTRIBUTION_URI_EDEFAULT;
+
+ /**
+ * The cached value of the '{@link #getFileextensions() <em>Fileextensions</em>}' attribute list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getFileextensions()
+ * @generated
+ * @ordered
+ */
+ protected EList<String> fileextensions;
+
+ /**
+ * The cached value of the '{@link #getContenttypes() <em>Contenttypes</em>}' attribute list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getContenttypes()
+ * @generated
+ * @ordered
+ */
+ protected EList<String> contenttypes;
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected EditorPartDescriptorImpl() {
+ super();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ protected EClass eStaticClass() {
+ return SimpleidePackageImpl.Literals.EDITOR_PART_DESCRIPTOR;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void setLabel(String newLabel) {
+ String oldLabel = label;
+ label = newLabel;
+ if (eNotificationRequired())
+ eNotify(new ENotificationImpl(this, Notification.SET, SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__LABEL, oldLabel, label));
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public String getIconURI() {
+ return iconURI;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void setIconURI(String newIconURI) {
+ String oldIconURI = iconURI;
+ iconURI = newIconURI;
+ if (eNotificationRequired())
+ eNotify(new ENotificationImpl(this, Notification.SET, SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__ICON_URI, oldIconURI, iconURI));
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public String getTooltip() {
+ return tooltip;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void setTooltip(String newTooltip) {
+ String oldTooltip = tooltip;
+ tooltip = newTooltip;
+ if (eNotificationRequired())
+ eNotify(new ENotificationImpl(this, Notification.SET, SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__TOOLTIP, oldTooltip, tooltip));
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public List<MHandler> getHandlers() {
+ if (handlers == null) {
+ handlers = new EObjectContainmentEList<MHandler>(MHandler.class, this, SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__HANDLERS);
+ }
+ return handlers;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public List<MBindingContext> getBindingContexts() {
+ if (bindingContexts == null) {
+ bindingContexts = new EObjectResolvingEList<MBindingContext>(MBindingContext.class, this, SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__BINDING_CONTEXTS);
+ }
+ return bindingContexts;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public String getContributionURI() {
+ return contributionURI;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void setContributionURI(String newContributionURI) {
+ String oldContributionURI = contributionURI;
+ contributionURI = newContributionURI;
+ if (eNotificationRequired())
+ eNotify(new ENotificationImpl(this, Notification.SET, SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI, oldContributionURI, contributionURI));
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public List<String> getFileextensions() {
+ if (fileextensions == null) {
+ fileextensions = new EDataTypeUniqueEList<String>(String.class, this, SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS);
+ }
+ return fileextensions;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public List<String> getContenttypes() {
+ if (contenttypes == null) {
+ contenttypes = new EDataTypeUniqueEList<String>(String.class, this, SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTENTTYPES);
+ }
+ return contenttypes;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public String getLocalizedLabel() {
+ // TODO: implement this method
+ // Ensure that you remove @generated or mark it @generated NOT
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public String getLocalizedTooltip() {
+ // TODO: implement this method
+ // Ensure that you remove @generated or mark it @generated NOT
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
+ switch (featureID) {
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__HANDLERS:
+ return ((InternalEList<?>)getHandlers()).basicRemove(otherEnd, msgs);
+ }
+ return super.eInverseRemove(otherEnd, featureID, msgs);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public Object eGet(int featureID, boolean resolve, boolean coreType) {
+ switch (featureID) {
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__LABEL:
+ return getLabel();
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__ICON_URI:
+ return getIconURI();
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__TOOLTIP:
+ return getTooltip();
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__HANDLERS:
+ return getHandlers();
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__BINDING_CONTEXTS:
+ return getBindingContexts();
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI:
+ return getContributionURI();
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS:
+ return getFileextensions();
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTENTTYPES:
+ return getContenttypes();
+ }
+ return super.eGet(featureID, resolve, coreType);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public void eSet(int featureID, Object newValue) {
+ switch (featureID) {
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__LABEL:
+ setLabel((String)newValue);
+ return;
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__ICON_URI:
+ setIconURI((String)newValue);
+ return;
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__TOOLTIP:
+ setTooltip((String)newValue);
+ return;
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__HANDLERS:
+ getHandlers().clear();
+ getHandlers().addAll((Collection<? extends MHandler>)newValue);
+ return;
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__BINDING_CONTEXTS:
+ getBindingContexts().clear();
+ getBindingContexts().addAll((Collection<? extends MBindingContext>)newValue);
+ return;
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI:
+ setContributionURI((String)newValue);
+ return;
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS:
+ getFileextensions().clear();
+ getFileextensions().addAll((Collection<? extends String>)newValue);
+ return;
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTENTTYPES:
+ getContenttypes().clear();
+ getContenttypes().addAll((Collection<? extends String>)newValue);
+ return;
+ }
+ super.eSet(featureID, newValue);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public void eUnset(int featureID) {
+ switch (featureID) {
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__LABEL:
+ setLabel(LABEL_EDEFAULT);
+ return;
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__ICON_URI:
+ setIconURI(ICON_URI_EDEFAULT);
+ return;
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__TOOLTIP:
+ setTooltip(TOOLTIP_EDEFAULT);
+ return;
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__HANDLERS:
+ getHandlers().clear();
+ return;
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__BINDING_CONTEXTS:
+ getBindingContexts().clear();
+ return;
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI:
+ setContributionURI(CONTRIBUTION_URI_EDEFAULT);
+ return;
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS:
+ getFileextensions().clear();
+ return;
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTENTTYPES:
+ getContenttypes().clear();
+ return;
+ }
+ super.eUnset(featureID);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public boolean eIsSet(int featureID) {
+ switch (featureID) {
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__LABEL:
+ return LABEL_EDEFAULT == null ? label != null : !LABEL_EDEFAULT.equals(label);
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__ICON_URI:
+ return ICON_URI_EDEFAULT == null ? iconURI != null : !ICON_URI_EDEFAULT.equals(iconURI);
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__TOOLTIP:
+ return TOOLTIP_EDEFAULT == null ? tooltip != null : !TOOLTIP_EDEFAULT.equals(tooltip);
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__HANDLERS:
+ return handlers != null && !handlers.isEmpty();
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__BINDING_CONTEXTS:
+ return bindingContexts != null && !bindingContexts.isEmpty();
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI:
+ return CONTRIBUTION_URI_EDEFAULT == null ? contributionURI != null : !CONTRIBUTION_URI_EDEFAULT.equals(contributionURI);
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS:
+ return fileextensions != null && !fileextensions.isEmpty();
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__CONTENTTYPES:
+ return contenttypes != null && !contenttypes.isEmpty();
+ }
+ return super.eIsSet(featureID);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) {
+ if (baseClass == MUILabel.class) {
+ switch (derivedFeatureID) {
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__LABEL: return UiPackageImpl.UI_LABEL__LABEL;
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__ICON_URI: return UiPackageImpl.UI_LABEL__ICON_URI;
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__TOOLTIP: return UiPackageImpl.UI_LABEL__TOOLTIP;
+ default: return -1;
+ }
+ }
+ if (baseClass == MHandlerContainer.class) {
+ switch (derivedFeatureID) {
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__HANDLERS: return CommandsPackageImpl.HANDLER_CONTAINER__HANDLERS;
+ default: return -1;
+ }
+ }
+ if (baseClass == MBindings.class) {
+ switch (derivedFeatureID) {
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__BINDING_CONTEXTS: return CommandsPackageImpl.BINDINGS__BINDING_CONTEXTS;
+ default: return -1;
+ }
+ }
+ return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public int eDerivedStructuralFeatureID(int baseFeatureID, Class<?> baseClass) {
+ if (baseClass == MUILabel.class) {
+ switch (baseFeatureID) {
+ case UiPackageImpl.UI_LABEL__LABEL: return SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__LABEL;
+ case UiPackageImpl.UI_LABEL__ICON_URI: return SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__ICON_URI;
+ case UiPackageImpl.UI_LABEL__TOOLTIP: return SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__TOOLTIP;
+ default: return -1;
+ }
+ }
+ if (baseClass == MHandlerContainer.class) {
+ switch (baseFeatureID) {
+ case CommandsPackageImpl.HANDLER_CONTAINER__HANDLERS: return SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__HANDLERS;
+ default: return -1;
+ }
+ }
+ if (baseClass == MBindings.class) {
+ switch (baseFeatureID) {
+ case CommandsPackageImpl.BINDINGS__BINDING_CONTEXTS: return SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR__BINDING_CONTEXTS;
+ default: return -1;
+ }
+ }
+ return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public String toString() {
+ if (eIsProxy()) return super.toString();
+
+ StringBuffer result = new StringBuffer(super.toString());
+ result.append(" (label: ");
+ result.append(label);
+ result.append(", iconURI: ");
+ result.append(iconURI);
+ result.append(", tooltip: ");
+ result.append(tooltip);
+ result.append(", contributionURI: ");
+ result.append(contributionURI);
+ result.append(", fileextensions: ");
+ result.append(fileextensions);
+ result.append(", contenttypes: ");
+ result.append(contenttypes);
+ result.append(')');
+ return result.toString();
+ }
+
+} //EditorPartDescriptorImpl
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleIDEApplicationImpl.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleIDEApplicationImpl.java
new file mode 100644
index 0000000..663393a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleIDEApplicationImpl.java
@@ -0,0 +1,150 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: SimpleIDEApplicationImpl.java,v 1.1 2010/05/15 12:59:52 tschindl Exp $
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide.impl;
+
+import java.util.Collection;
+import java.util.List;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication;
+import org.eclipse.e4.ui.model.application.impl.ApplicationImpl;
+import org.eclipse.emf.common.notify.NotificationChain;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.util.EObjectContainmentEList;
+import org.eclipse.emf.ecore.util.InternalEList;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model object '<em><b>Simple IDE Application</b></em>'.
+ * <!-- end-user-doc -->
+ * <p>
+ * The following features are implemented:
+ * <ul>
+ * <li>{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleIDEApplicationImpl#getEditorPartDescriptors <em>Editor Part Descriptors</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @generated
+ */
+public class SimpleIDEApplicationImpl extends ApplicationImpl implements MSimpleIDEApplication {
+ /**
+ * The cached value of the '{@link #getEditorPartDescriptors() <em>Editor Part Descriptors</em>}' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getEditorPartDescriptors()
+ * @generated
+ * @ordered
+ */
+ protected EList<MEditorPartDescriptor> editorPartDescriptors;
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected SimpleIDEApplicationImpl() {
+ super();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ protected EClass eStaticClass() {
+ return SimpleidePackageImpl.Literals.SIMPLE_IDE_APPLICATION;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public List<MEditorPartDescriptor> getEditorPartDescriptors() {
+ if (editorPartDescriptors == null) {
+ editorPartDescriptors = new EObjectContainmentEList<MEditorPartDescriptor>(MEditorPartDescriptor.class, this, SimpleidePackageImpl.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS);
+ }
+ return editorPartDescriptors;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
+ switch (featureID) {
+ case SimpleidePackageImpl.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS:
+ return ((InternalEList<?>)getEditorPartDescriptors()).basicRemove(otherEnd, msgs);
+ }
+ return super.eInverseRemove(otherEnd, featureID, msgs);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public Object eGet(int featureID, boolean resolve, boolean coreType) {
+ switch (featureID) {
+ case SimpleidePackageImpl.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS:
+ return getEditorPartDescriptors();
+ }
+ return super.eGet(featureID, resolve, coreType);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public void eSet(int featureID, Object newValue) {
+ switch (featureID) {
+ case SimpleidePackageImpl.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS:
+ getEditorPartDescriptors().clear();
+ getEditorPartDescriptors().addAll((Collection<? extends MEditorPartDescriptor>)newValue);
+ return;
+ }
+ super.eSet(featureID, newValue);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public void eUnset(int featureID) {
+ switch (featureID) {
+ case SimpleidePackageImpl.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS:
+ getEditorPartDescriptors().clear();
+ return;
+ }
+ super.eUnset(featureID);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public boolean eIsSet(int featureID) {
+ switch (featureID) {
+ case SimpleidePackageImpl.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS:
+ return editorPartDescriptors != null && !editorPartDescriptors.isEmpty();
+ }
+ return super.eIsSet(featureID);
+ }
+
+} //SimpleIDEApplicationImpl
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleideFactoryImpl.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleideFactoryImpl.java
new file mode 100644
index 0000000..d97dc5a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleideFactoryImpl.java
@@ -0,0 +1,118 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: SimpleideFactoryImpl.java,v 1.2 2010/06/04 20:22:14 johna Exp $
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide.impl;
+
+import org.eclipse.e4.demo.simpleide.model.simpleide.*;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleideFactory;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.impl.EFactoryImpl;
+import org.eclipse.emf.ecore.plugin.EcorePlugin;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model <b>Factory</b>.
+ * <!-- end-user-doc -->
+ * @generated
+ */
+public class SimpleideFactoryImpl extends EFactoryImpl implements MSimpleideFactory {
+ /**
+ * The singleton instance of the factory.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public static final SimpleideFactoryImpl eINSTANCE = init();
+
+ /**
+ * Creates the default factory implementation.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public static SimpleideFactoryImpl init() {
+ try {
+ SimpleideFactoryImpl theSimpleideFactory = (SimpleideFactoryImpl)EPackage.Registry.INSTANCE.getEFactory("http://www.eclipse.org/e4/demo/simpleide");
+ if (theSimpleideFactory != null) {
+ return theSimpleideFactory;
+ }
+ }
+ catch (Exception exception) {
+ EcorePlugin.INSTANCE.log(exception);
+ }
+ return new SimpleideFactoryImpl();
+ }
+
+ /**
+ * Creates an instance of the factory.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public SimpleideFactoryImpl() {
+ super();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public EObject create(EClass eClass) {
+ switch (eClass.getClassifierID()) {
+ case SimpleidePackageImpl.SIMPLE_IDE_APPLICATION: return (EObject)createSimpleIDEApplication();
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR: return (EObject)createEditorPartDescriptor();
+ default:
+ throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier");
+ }
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public MSimpleIDEApplication createSimpleIDEApplication() {
+ SimpleIDEApplicationImpl simpleIDEApplication = new SimpleIDEApplicationImpl();
+ return simpleIDEApplication;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public MEditorPartDescriptor createEditorPartDescriptor() {
+ EditorPartDescriptorImpl editorPartDescriptor = new EditorPartDescriptorImpl();
+ return editorPartDescriptor;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public SimpleidePackageImpl getSimpleidePackage() {
+ return (SimpleidePackageImpl)getEPackage();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @deprecated
+ * @generated
+ */
+ @Deprecated
+ public static SimpleidePackageImpl getPackage() {
+ return SimpleidePackageImpl.eINSTANCE;
+ }
+
+} //SimpleideFactoryImpl
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleidePackageImpl.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleidePackageImpl.java
new file mode 100644
index 0000000..fe656d3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/impl/SimpleidePackageImpl.java
@@ -0,0 +1,791 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: SimpleidePackageImpl.java,v 1.6 2011/01/17 12:18:07 pwebster Exp $
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide.impl;
+
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleideFactory;
+import org.eclipse.e4.ui.model.application.commands.impl.CommandsPackageImpl;
+import org.eclipse.e4.ui.model.application.impl.ApplicationPackageImpl;
+import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EFactory;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.impl.EPackageImpl;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Package</b> for the model.
+ * It contains accessors for the meta objects to represent
+ * <ul>
+ * <li>each class,</li>
+ * <li>each feature of each class,</li>
+ * <li>each enum,</li>
+ * <li>and each data type</li>
+ * </ul>
+ * <!-- end-user-doc -->
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleideFactory
+ * @model kind="package"
+ * @generated
+ */
+public class SimpleidePackageImpl extends EPackageImpl {
+ /**
+ * The package name.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public static final String eNAME = "simpleide";
+
+ /**
+ * The package namespace URI.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public static final String eNS_URI = "http://www.eclipse.org/e4/demo/simpleide";
+
+ /**
+ * The package namespace name.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public static final String eNS_PREFIX = "simpleide";
+
+ /**
+ * The singleton instance of the package.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public static final SimpleidePackageImpl eINSTANCE = org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl.init();
+
+ /**
+ * The meta object id for the '{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleIDEApplicationImpl <em>Simple IDE Application</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleIDEApplicationImpl
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl#getSimpleIDEApplication()
+ * @generated
+ */
+ public static final int SIMPLE_IDE_APPLICATION = 0;
+
+ /**
+ * The feature id for the '<em><b>Element Id</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__ELEMENT_ID = ApplicationPackageImpl.APPLICATION__ELEMENT_ID;
+
+ /**
+ * The feature id for the '<em><b>Tags</b></em>' attribute list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__TAGS = ApplicationPackageImpl.APPLICATION__TAGS;
+
+ /**
+ * The feature id for the '<em><b>Contributor URI</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__CONTRIBUTOR_URI = ApplicationPackageImpl.APPLICATION__CONTRIBUTOR_URI;
+
+ /**
+ * The feature id for the '<em><b>Widget</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__WIDGET = ApplicationPackageImpl.APPLICATION__WIDGET;
+
+ /**
+ * The feature id for the '<em><b>Renderer</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__RENDERER = ApplicationPackageImpl.APPLICATION__RENDERER;
+
+ /**
+ * The feature id for the '<em><b>To Be Rendered</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__TO_BE_RENDERED = ApplicationPackageImpl.APPLICATION__TO_BE_RENDERED;
+
+ /**
+ * The feature id for the '<em><b>On Top</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__ON_TOP = ApplicationPackageImpl.APPLICATION__ON_TOP;
+
+ /**
+ * The feature id for the '<em><b>Visible</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__VISIBLE = ApplicationPackageImpl.APPLICATION__VISIBLE;
+
+ /**
+ * The feature id for the '<em><b>Parent</b></em>' container reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__PARENT = ApplicationPackageImpl.APPLICATION__PARENT;
+
+ /**
+ * The feature id for the '<em><b>Container Data</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__CONTAINER_DATA = ApplicationPackageImpl.APPLICATION__CONTAINER_DATA;
+
+ /**
+ * The feature id for the '<em><b>Cur Shared Ref</b></em>' reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__CUR_SHARED_REF = ApplicationPackageImpl.APPLICATION__CUR_SHARED_REF;
+
+ /**
+ * The feature id for the '<em><b>Visible When</b></em>' containment reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__VISIBLE_WHEN = ApplicationPackageImpl.APPLICATION__VISIBLE_WHEN;
+
+ /**
+ * The feature id for the '<em><b>Accessibility Phrase</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__ACCESSIBILITY_PHRASE = ApplicationPackageImpl.APPLICATION__ACCESSIBILITY_PHRASE;
+
+ /**
+ * The feature id for the '<em><b>Children</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__CHILDREN = ApplicationPackageImpl.APPLICATION__CHILDREN;
+
+ /**
+ * The feature id for the '<em><b>Selected Element</b></em>' reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__SELECTED_ELEMENT = ApplicationPackageImpl.APPLICATION__SELECTED_ELEMENT;
+
+ /**
+ * The feature id for the '<em><b>Context</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__CONTEXT = ApplicationPackageImpl.APPLICATION__CONTEXT;
+
+ /**
+ * The feature id for the '<em><b>Variables</b></em>' attribute list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__VARIABLES = ApplicationPackageImpl.APPLICATION__VARIABLES;
+
+ /**
+ * The feature id for the '<em><b>Properties</b></em>' map.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__PROPERTIES = ApplicationPackageImpl.APPLICATION__PROPERTIES;
+
+ /**
+ * The feature id for the '<em><b>Handlers</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__HANDLERS = ApplicationPackageImpl.APPLICATION__HANDLERS;
+
+ /**
+ * The feature id for the '<em><b>Binding Tables</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__BINDING_TABLES = ApplicationPackageImpl.APPLICATION__BINDING_TABLES;
+
+ /**
+ * The feature id for the '<em><b>Root Context</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__ROOT_CONTEXT = ApplicationPackageImpl.APPLICATION__ROOT_CONTEXT;
+
+ /**
+ * The feature id for the '<em><b>Descriptors</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__DESCRIPTORS = ApplicationPackageImpl.APPLICATION__DESCRIPTORS;
+
+ /**
+ * The feature id for the '<em><b>Binding Contexts</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__BINDING_CONTEXTS = ApplicationPackageImpl.APPLICATION__BINDING_CONTEXTS;
+
+ /**
+ * The feature id for the '<em><b>Menu Contributions</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__MENU_CONTRIBUTIONS = ApplicationPackageImpl.APPLICATION__MENU_CONTRIBUTIONS;
+
+ /**
+ * The feature id for the '<em><b>Tool Bar Contributions</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__TOOL_BAR_CONTRIBUTIONS = ApplicationPackageImpl.APPLICATION__TOOL_BAR_CONTRIBUTIONS;
+
+ /**
+ * The feature id for the '<em><b>Trim Contributions</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__TRIM_CONTRIBUTIONS = ApplicationPackageImpl.APPLICATION__TRIM_CONTRIBUTIONS;
+
+ /**
+ * The feature id for the '<em><b>Commands</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__COMMANDS = ApplicationPackageImpl.APPLICATION__COMMANDS;
+
+ /**
+ * The feature id for the '<em><b>Addons</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__ADDONS = ApplicationPackageImpl.APPLICATION__ADDONS;
+
+ /**
+ * The feature id for the '<em><b>Categories</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__CATEGORIES = ApplicationPackageImpl.APPLICATION__CATEGORIES;
+
+ /**
+ * The feature id for the '<em><b>Editor Part Descriptors</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS = ApplicationPackageImpl.APPLICATION_FEATURE_COUNT + 0;
+
+ /**
+ * The number of structural features of the '<em>Simple IDE Application</em>' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int SIMPLE_IDE_APPLICATION_FEATURE_COUNT = ApplicationPackageImpl.APPLICATION_FEATURE_COUNT + 1;
+
+ /**
+ * The meta object id for the '{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl <em>Editor Part Descriptor</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl#getEditorPartDescriptor()
+ * @generated
+ */
+ public static final int EDITOR_PART_DESCRIPTOR = 1;
+
+ /**
+ * The feature id for the '<em><b>Element Id</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int EDITOR_PART_DESCRIPTOR__ELEMENT_ID = ApplicationPackageImpl.APPLICATION_ELEMENT__ELEMENT_ID;
+
+ /**
+ * The feature id for the '<em><b>Tags</b></em>' attribute list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int EDITOR_PART_DESCRIPTOR__TAGS = ApplicationPackageImpl.APPLICATION_ELEMENT__TAGS;
+
+ /**
+ * The feature id for the '<em><b>Contributor URI</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int EDITOR_PART_DESCRIPTOR__CONTRIBUTOR_URI = ApplicationPackageImpl.APPLICATION_ELEMENT__CONTRIBUTOR_URI;
+
+ /**
+ * The feature id for the '<em><b>Label</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int EDITOR_PART_DESCRIPTOR__LABEL = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 0;
+
+ /**
+ * The feature id for the '<em><b>Icon URI</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int EDITOR_PART_DESCRIPTOR__ICON_URI = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 1;
+
+ /**
+ * The feature id for the '<em><b>Tooltip</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int EDITOR_PART_DESCRIPTOR__TOOLTIP = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 2;
+
+ /**
+ * The feature id for the '<em><b>Handlers</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int EDITOR_PART_DESCRIPTOR__HANDLERS = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 3;
+
+ /**
+ * The feature id for the '<em><b>Binding Contexts</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int EDITOR_PART_DESCRIPTOR__BINDING_CONTEXTS = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 4;
+
+ /**
+ * The feature id for the '<em><b>Contribution URI</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 5;
+
+ /**
+ * The feature id for the '<em><b>Fileextensions</b></em>' attribute list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 6;
+
+ /**
+ * The feature id for the '<em><b>Contenttypes</b></em>' attribute list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int EDITOR_PART_DESCRIPTOR__CONTENTTYPES = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 7;
+
+ /**
+ * The number of structural features of the '<em>Editor Part Descriptor</em>' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ public static final int EDITOR_PART_DESCRIPTOR_FEATURE_COUNT = ApplicationPackageImpl.APPLICATION_ELEMENT_FEATURE_COUNT + 8;
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ private EClass simpleIDEApplicationEClass = null;
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ private EClass editorPartDescriptorEClass = null;
+
+ /**
+ * Creates an instance of the model <b>Package</b>, registered with
+ * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package
+ * package URI value.
+ * <p>Note: the correct way to create the package is via the static
+ * factory method {@link #init init()}, which also performs
+ * initialization of the package, or returns the registered package,
+ * if one already exists.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.ecore.EPackage.Registry
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl#eNS_URI
+ * @see #init()
+ * @generated
+ */
+ private SimpleidePackageImpl() {
+ super(eNS_URI, ((EFactory)MSimpleideFactory.INSTANCE));
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ private static boolean isInited = false;
+
+ /**
+ * Creates, registers, and initializes the <b>Package</b> for this model, and for any others upon which it depends.
+ *
+ * <p>This method is used to initialize {@link SimpleidePackageImpl#eINSTANCE} when that field is accessed.
+ * Clients should not invoke it directly. Instead, they should simply access that field to obtain the package.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #eNS_URI
+ * @see #createPackageContents()
+ * @see #initializePackageContents()
+ * @generated
+ */
+ public static SimpleidePackageImpl init() {
+ if (isInited) return (SimpleidePackageImpl)EPackage.Registry.INSTANCE.getEPackage(SimpleidePackageImpl.eNS_URI);
+
+ // Obtain or create and register package
+ SimpleidePackageImpl theSimpleidePackage = (SimpleidePackageImpl)(EPackage.Registry.INSTANCE.get(eNS_URI) instanceof SimpleidePackageImpl ? EPackage.Registry.INSTANCE.get(eNS_URI) : new SimpleidePackageImpl());
+
+ isInited = true;
+
+ // Initialize simple dependencies
+ ApplicationPackageImpl.eINSTANCE.eClass();
+
+ // Create package meta-data objects
+ theSimpleidePackage.createPackageContents();
+
+ // Initialize created meta-data
+ theSimpleidePackage.initializePackageContents();
+
+ // Mark meta-data to indicate it can't be changed
+ theSimpleidePackage.freeze();
+
+
+ // Update the registry and return the package
+ EPackage.Registry.INSTANCE.put(SimpleidePackageImpl.eNS_URI, theSimpleidePackage);
+ return theSimpleidePackage;
+ }
+
+
+ /**
+ * Returns the meta object for class '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication <em>Simple IDE Application</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for class '<em>Simple IDE Application</em>'.
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication
+ * @generated
+ */
+ public EClass getSimpleIDEApplication() {
+ return simpleIDEApplicationEClass;
+ }
+
+ /**
+ * Returns the meta object for the containment reference list '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication#getEditorPartDescriptors <em>Editor Part Descriptors</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the containment reference list '<em>Editor Part Descriptors</em>'.
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication#getEditorPartDescriptors()
+ * @see #getSimpleIDEApplication()
+ * @generated
+ */
+ public EReference getSimpleIDEApplication_EditorPartDescriptors() {
+ return (EReference)simpleIDEApplicationEClass.getEStructuralFeatures().get(0);
+ }
+
+ /**
+ * Returns the meta object for class '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor <em>Editor Part Descriptor</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for class '<em>Editor Part Descriptor</em>'.
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor
+ * @generated
+ */
+ public EClass getEditorPartDescriptor() {
+ return editorPartDescriptorEClass;
+ }
+
+ /**
+ * Returns the meta object for the attribute '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getContributionURI <em>Contribution URI</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the attribute '<em>Contribution URI</em>'.
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getContributionURI()
+ * @see #getEditorPartDescriptor()
+ * @generated
+ */
+ public EAttribute getEditorPartDescriptor_ContributionURI() {
+ return (EAttribute)editorPartDescriptorEClass.getEStructuralFeatures().get(0);
+ }
+
+ /**
+ * Returns the meta object for the attribute list '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getFileextensions <em>Fileextensions</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the attribute list '<em>Fileextensions</em>'.
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getFileextensions()
+ * @see #getEditorPartDescriptor()
+ * @generated
+ */
+ public EAttribute getEditorPartDescriptor_Fileextensions() {
+ return (EAttribute)editorPartDescriptorEClass.getEStructuralFeatures().get(1);
+ }
+
+ /**
+ * Returns the meta object for the attribute list '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getContenttypes <em>Contenttypes</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the attribute list '<em>Contenttypes</em>'.
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor#getContenttypes()
+ * @see #getEditorPartDescriptor()
+ * @generated
+ */
+ public EAttribute getEditorPartDescriptor_Contenttypes() {
+ return (EAttribute)editorPartDescriptorEClass.getEStructuralFeatures().get(2);
+ }
+
+
+ /**
+ * Returns the factory that creates the instances of the model.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the factory that creates the instances of the model.
+ * @generated
+ */
+ public MSimpleideFactory getSimpleideFactory() {
+ return (MSimpleideFactory)getEFactoryInstance();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ private boolean isCreated = false;
+
+ /**
+ * Creates the meta-model objects for the package. This method is
+ * guarded to have no affect on any invocation but its first.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void createPackageContents() {
+ if (isCreated) return;
+ isCreated = true;
+
+ // Create classes and their features
+ simpleIDEApplicationEClass = createEClass(SIMPLE_IDE_APPLICATION);
+ createEReference(simpleIDEApplicationEClass, SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS);
+
+ editorPartDescriptorEClass = createEClass(EDITOR_PART_DESCRIPTOR);
+ createEAttribute(editorPartDescriptorEClass, EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI);
+ createEAttribute(editorPartDescriptorEClass, EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS);
+ createEAttribute(editorPartDescriptorEClass, EDITOR_PART_DESCRIPTOR__CONTENTTYPES);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ private boolean isInitialized = false;
+
+ /**
+ * Complete the initialization of the package and its meta-model. This
+ * method is guarded to have no affect on any invocation but its first.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void initializePackageContents() {
+ if (isInitialized) return;
+ isInitialized = true;
+
+ // Initialize package
+ setName(eNAME);
+ setNsPrefix(eNS_PREFIX);
+ setNsURI(eNS_URI);
+
+ // Obtain other dependent packages
+ ApplicationPackageImpl theApplicationPackage = (ApplicationPackageImpl)EPackage.Registry.INSTANCE.getEPackage(ApplicationPackageImpl.eNS_URI);
+ UiPackageImpl theUiPackage = (UiPackageImpl)EPackage.Registry.INSTANCE.getEPackage(UiPackageImpl.eNS_URI);
+ CommandsPackageImpl theCommandsPackage = (CommandsPackageImpl)EPackage.Registry.INSTANCE.getEPackage(CommandsPackageImpl.eNS_URI);
+
+ // Create type parameters
+
+ // Set bounds for type parameters
+
+ // Add supertypes to classes
+ simpleIDEApplicationEClass.getESuperTypes().add(theApplicationPackage.getApplication());
+ editorPartDescriptorEClass.getESuperTypes().add(theApplicationPackage.getApplicationElement());
+ editorPartDescriptorEClass.getESuperTypes().add(theUiPackage.getUILabel());
+ editorPartDescriptorEClass.getESuperTypes().add(theCommandsPackage.getHandlerContainer());
+ editorPartDescriptorEClass.getESuperTypes().add(theCommandsPackage.getBindings());
+
+ // Initialize classes and features; add operations and parameters
+ initEClass(simpleIDEApplicationEClass, MSimpleIDEApplication.class, "SimpleIDEApplication", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
+ initEReference(getSimpleIDEApplication_EditorPartDescriptors(), this.getEditorPartDescriptor(), null, "editorPartDescriptors", null, 0, -1, MSimpleIDEApplication.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+
+ initEClass(editorPartDescriptorEClass, MEditorPartDescriptor.class, "EditorPartDescriptor", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
+ initEAttribute(getEditorPartDescriptor_ContributionURI(), ecorePackage.getEString(), "contributionURI", null, 0, 1, MEditorPartDescriptor.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+ initEAttribute(getEditorPartDescriptor_Fileextensions(), ecorePackage.getEString(), "fileextensions", null, 0, -1, MEditorPartDescriptor.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+ initEAttribute(getEditorPartDescriptor_Contenttypes(), ecorePackage.getEString(), "contenttypes", null, 0, -1, MEditorPartDescriptor.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+
+ // Create resource
+ createResource(eNS_URI);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * Defines literals for the meta objects that represent
+ * <ul>
+ * <li>each class,</li>
+ * <li>each feature of each class,</li>
+ * <li>each enum,</li>
+ * <li>and each data type</li>
+ * </ul>
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public interface Literals {
+ /**
+ * The meta object literal for the '{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleIDEApplicationImpl <em>Simple IDE Application</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleIDEApplicationImpl
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl#getSimpleIDEApplication()
+ * @generated
+ */
+ public static final EClass SIMPLE_IDE_APPLICATION = eINSTANCE.getSimpleIDEApplication();
+
+ /**
+ * The meta object literal for the '<em><b>Editor Part Descriptors</b></em>' containment reference list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public static final EReference SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS = eINSTANCE.getSimpleIDEApplication_EditorPartDescriptors();
+
+ /**
+ * The meta object literal for the '{@link org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl <em>Editor Part Descriptor</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.EditorPartDescriptorImpl
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl#getEditorPartDescriptor()
+ * @generated
+ */
+ public static final EClass EDITOR_PART_DESCRIPTOR = eINSTANCE.getEditorPartDescriptor();
+
+ /**
+ * The meta object literal for the '<em><b>Contribution URI</b></em>' attribute feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public static final EAttribute EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI = eINSTANCE.getEditorPartDescriptor_ContributionURI();
+
+ /**
+ * The meta object literal for the '<em><b>Fileextensions</b></em>' attribute list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public static final EAttribute EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS = eINSTANCE.getEditorPartDescriptor_Fileextensions();
+
+ /**
+ * The meta object literal for the '<em><b>Contenttypes</b></em>' attribute list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public static final EAttribute EDITOR_PART_DESCRIPTOR__CONTENTTYPES = eINSTANCE.getEditorPartDescriptor_Contenttypes();
+
+ }
+
+} //SimpleidePackageImpl
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/util/SimpleideAdapterFactory.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/util/SimpleideAdapterFactory.java
new file mode 100644
index 0000000..ca132c4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/util/SimpleideAdapterFactory.java
@@ -0,0 +1,389 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: SimpleideAdapterFactory.java,v 1.3 2010/06/04 20:22:14 johna Exp $
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide.util;
+
+import org.eclipse.e4.demo.simpleide.model.simpleide.*;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication;
+import org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.MApplicationElement;
+import org.eclipse.e4.ui.model.application.commands.MBindingTableContainer;
+import org.eclipse.e4.ui.model.application.commands.MBindings;
+import org.eclipse.e4.ui.model.application.commands.MHandlerContainer;
+import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptorContainer;
+import org.eclipse.e4.ui.model.application.ui.MContext;
+import org.eclipse.e4.ui.model.application.ui.MElementContainer;
+import org.eclipse.e4.ui.model.application.ui.MUIElement;
+import org.eclipse.e4.ui.model.application.ui.MUILabel;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenuContributions;
+import org.eclipse.e4.ui.model.application.ui.menu.MToolBarContributions;
+import org.eclipse.e4.ui.model.application.ui.menu.MTrimContributions;
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Adapter Factory</b> for the model.
+ * It provides an adapter <code>createXXX</code> method for each class of the model.
+ * <!-- end-user-doc -->
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl
+ * @generated
+ */
+public class SimpleideAdapterFactory extends AdapterFactoryImpl {
+ /**
+ * The cached model package.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected static SimpleidePackageImpl modelPackage;
+
+ /**
+ * Creates an instance of the adapter factory.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public SimpleideAdapterFactory() {
+ if (modelPackage == null) {
+ modelPackage = SimpleidePackageImpl.eINSTANCE;
+ }
+ }
+
+ /**
+ * Returns whether this factory is applicable for the type of the object.
+ * <!-- begin-user-doc -->
+ * This implementation returns <code>true</code> if the object is either the model's package or is an instance object of the model.
+ * <!-- end-user-doc -->
+ * @return whether this factory is applicable for the type of the object.
+ * @generated
+ */
+ @Override
+ public boolean isFactoryForType(Object object) {
+ if (object == modelPackage) {
+ return true;
+ }
+ if (object instanceof EObject) {
+ return ((EObject)object).eClass().getEPackage() == modelPackage;
+ }
+ return false;
+ }
+
+ /**
+ * The switch that delegates to the <code>createXXX</code> methods.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected SimpleideSwitch<Adapter> modelSwitch =
+ new SimpleideSwitch<Adapter>() {
+ @Override
+ public Adapter caseSimpleIDEApplication(MSimpleIDEApplication object) {
+ return createSimpleIDEApplicationAdapter();
+ }
+ @Override
+ public Adapter caseEditorPartDescriptor(MEditorPartDescriptor object) {
+ return createEditorPartDescriptorAdapter();
+ }
+ @Override
+ public Adapter caseApplicationElement(MApplicationElement object) {
+ return createApplicationElementAdapter();
+ }
+ @Override
+ public Adapter caseUIElement(MUIElement object) {
+ return createUIElementAdapter();
+ }
+ @Override
+ public <T extends MUIElement> Adapter caseElementContainer(MElementContainer<T> object) {
+ return createElementContainerAdapter();
+ }
+ @Override
+ public Adapter caseContext(MContext object) {
+ return createContextAdapter();
+ }
+ @Override
+ public Adapter caseHandlerContainer(MHandlerContainer object) {
+ return createHandlerContainerAdapter();
+ }
+ @Override
+ public Adapter caseBindingTableContainer(MBindingTableContainer object) {
+ return createBindingTableContainerAdapter();
+ }
+ @Override
+ public Adapter casePartDescriptorContainer(MPartDescriptorContainer object) {
+ return createPartDescriptorContainerAdapter();
+ }
+ @Override
+ public Adapter caseBindings(MBindings object) {
+ return createBindingsAdapter();
+ }
+ @Override
+ public Adapter caseMenuContributions(MMenuContributions object) {
+ return createMenuContributionsAdapter();
+ }
+ @Override
+ public Adapter caseToolBarContributions(MToolBarContributions object) {
+ return createToolBarContributionsAdapter();
+ }
+ @Override
+ public Adapter caseTrimContributions(MTrimContributions object) {
+ return createTrimContributionsAdapter();
+ }
+ @Override
+ public Adapter caseApplication(MApplication object) {
+ return createApplicationAdapter();
+ }
+ @Override
+ public Adapter caseUILabel(MUILabel object) {
+ return createUILabelAdapter();
+ }
+ @Override
+ public Adapter defaultCase(EObject object) {
+ return createEObjectAdapter();
+ }
+ };
+
+ /**
+ * Creates an adapter for the <code>target</code>.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @param target the object to adapt.
+ * @return the adapter for the <code>target</code>.
+ * @generated
+ */
+ @Override
+ public Adapter createAdapter(Notifier target) {
+ return modelSwitch.doSwitch((EObject)target);
+ }
+
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication <em>Simple IDE Application</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ * @return the new adapter.
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication
+ * @generated
+ */
+ public Adapter createSimpleIDEApplicationAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor <em>Editor Part Descriptor</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ * @return the new adapter.
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor
+ * @generated
+ */
+ public Adapter createEditorPartDescriptorAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.MApplicationElement <em>Element</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ * @return the new adapter.
+ * @see org.eclipse.e4.ui.model.application.MApplicationElement
+ * @generated
+ */
+ public Adapter createApplicationElementAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.ui.MUIElement <em>UI Element</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ * @return the new adapter.
+ * @see org.eclipse.e4.ui.model.application.ui.MUIElement
+ * @generated
+ */
+ public Adapter createUIElementAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.ui.MElementContainer <em>Element Container</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ * @return the new adapter.
+ * @see org.eclipse.e4.ui.model.application.ui.MElementContainer
+ * @generated
+ */
+ public Adapter createElementContainerAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.ui.MContext <em>Context</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ * @return the new adapter.
+ * @see org.eclipse.e4.ui.model.application.ui.MContext
+ * @generated
+ */
+ public Adapter createContextAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.commands.MHandlerContainer <em>Handler Container</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ * @return the new adapter.
+ * @see org.eclipse.e4.ui.model.application.commands.MHandlerContainer
+ * @generated
+ */
+ public Adapter createHandlerContainerAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.commands.MBindingTableContainer <em>Binding Table Container</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ * @return the new adapter.
+ * @see org.eclipse.e4.ui.model.application.commands.MBindingTableContainer
+ * @generated
+ */
+ public Adapter createBindingTableContainerAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptorContainer <em>Part Descriptor Container</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ * @return the new adapter.
+ * @see org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptorContainer
+ * @generated
+ */
+ public Adapter createPartDescriptorContainerAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.commands.MBindings <em>Bindings</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ * @return the new adapter.
+ * @see org.eclipse.e4.ui.model.application.commands.MBindings
+ * @generated
+ */
+ public Adapter createBindingsAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.ui.menu.MMenuContributions <em>Contributions</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ * @return the new adapter.
+ * @see org.eclipse.e4.ui.model.application.ui.menu.MMenuContributions
+ * @generated
+ */
+ public Adapter createMenuContributionsAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.ui.menu.MToolBarContributions <em>Tool Bar Contributions</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ * @return the new adapter.
+ * @see org.eclipse.e4.ui.model.application.ui.menu.MToolBarContributions
+ * @generated
+ */
+ public Adapter createToolBarContributionsAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.ui.menu.MTrimContributions <em>Trim Contributions</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ * @return the new adapter.
+ * @see org.eclipse.e4.ui.model.application.ui.menu.MTrimContributions
+ * @generated
+ */
+ public Adapter createTrimContributionsAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.MApplication <em>Application</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ * @return the new adapter.
+ * @see org.eclipse.e4.ui.model.application.MApplication
+ * @generated
+ */
+ public Adapter createApplicationAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.e4.ui.model.application.ui.MUILabel <em>UI Label</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ * @return the new adapter.
+ * @see org.eclipse.e4.ui.model.application.ui.MUILabel
+ * @generated
+ */
+ public Adapter createUILabelAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for the default case.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null.
+ * <!-- end-user-doc -->
+ * @return the new adapter.
+ * @generated
+ */
+ public Adapter createEObjectAdapter() {
+ return null;
+ }
+
+} //SimpleideAdapterFactory
diff --git a/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/util/SimpleideSwitch.java b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/util/SimpleideSwitch.java
new file mode 100644
index 0000000..d58e412
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.model/src/org/eclipse/e4/demo/simpleide/model/simpleide/util/SimpleideSwitch.java
@@ -0,0 +1,376 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id: SimpleideSwitch.java,v 1.3 2010/06/04 20:22:14 johna Exp $
+ */
+package org.eclipse.e4.demo.simpleide.model.simpleide.util;
+
+import java.util.List;
+import org.eclipse.e4.demo.simpleide.model.simpleide.*;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication;
+import org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.MApplicationElement;
+import org.eclipse.e4.ui.model.application.commands.MBindingTableContainer;
+import org.eclipse.e4.ui.model.application.commands.MBindings;
+import org.eclipse.e4.ui.model.application.commands.MHandlerContainer;
+import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptorContainer;
+import org.eclipse.e4.ui.model.application.ui.MContext;
+import org.eclipse.e4.ui.model.application.ui.MElementContainer;
+import org.eclipse.e4.ui.model.application.ui.MUIElement;
+import org.eclipse.e4.ui.model.application.ui.MUILabel;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenuContributions;
+import org.eclipse.e4.ui.model.application.ui.menu.MToolBarContributions;
+import org.eclipse.e4.ui.model.application.ui.menu.MTrimContributions;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Switch</b> for the model's inheritance hierarchy.
+ * It supports the call {@link #doSwitch(EObject) doSwitch(object)}
+ * to invoke the <code>caseXXX</code> method for each class of the model,
+ * starting with the actual class of the object
+ * and proceeding up the inheritance hierarchy
+ * until a non-null result is returned,
+ * which is the result of the switch.
+ * <!-- end-user-doc -->
+ * @see org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl
+ * @generated
+ */
+public class SimpleideSwitch<T1> {
+ /**
+ * The cached model package
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected static SimpleidePackageImpl modelPackage;
+
+ /**
+ * Creates an instance of the switch.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public SimpleideSwitch() {
+ if (modelPackage == null) {
+ modelPackage = SimpleidePackageImpl.eINSTANCE;
+ }
+ }
+
+ /**
+ * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the first non-null result returned by a <code>caseXXX</code> call.
+ * @generated
+ */
+ public T1 doSwitch(EObject theEObject) {
+ return doSwitch(theEObject.eClass(), theEObject);
+ }
+
+ /**
+ * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the first non-null result returned by a <code>caseXXX</code> call.
+ * @generated
+ */
+ protected T1 doSwitch(EClass theEClass, EObject theEObject) {
+ if (theEClass.eContainer() == modelPackage) {
+ return doSwitch(theEClass.getClassifierID(), theEObject);
+ }
+ else {
+ List<EClass> eSuperTypes = theEClass.getESuperTypes();
+ return
+ eSuperTypes.isEmpty() ?
+ defaultCase(theEObject) :
+ doSwitch(eSuperTypes.get(0), theEObject);
+ }
+ }
+
+ /**
+ * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the first non-null result returned by a <code>caseXXX</code> call.
+ * @generated
+ */
+ protected T1 doSwitch(int classifierID, EObject theEObject) {
+ switch (classifierID) {
+ case SimpleidePackageImpl.SIMPLE_IDE_APPLICATION: {
+ MSimpleIDEApplication simpleIDEApplication = (MSimpleIDEApplication)theEObject;
+ T1 result = caseSimpleIDEApplication(simpleIDEApplication);
+ if (result == null) result = caseApplication(simpleIDEApplication);
+ if (result == null) result = caseElementContainer(simpleIDEApplication);
+ if (result == null) result = caseContext(simpleIDEApplication);
+ if (result == null) result = caseHandlerContainer(simpleIDEApplication);
+ if (result == null) result = caseBindingTableContainer(simpleIDEApplication);
+ if (result == null) result = casePartDescriptorContainer(simpleIDEApplication);
+ if (result == null) result = caseBindings(simpleIDEApplication);
+ if (result == null) result = caseMenuContributions(simpleIDEApplication);
+ if (result == null) result = caseToolBarContributions(simpleIDEApplication);
+ if (result == null) result = caseTrimContributions(simpleIDEApplication);
+ if (result == null) result = caseUIElement(simpleIDEApplication);
+ if (result == null) result = caseApplicationElement(simpleIDEApplication);
+ if (result == null) result = defaultCase(theEObject);
+ return result;
+ }
+ case SimpleidePackageImpl.EDITOR_PART_DESCRIPTOR: {
+ MEditorPartDescriptor editorPartDescriptor = (MEditorPartDescriptor)theEObject;
+ T1 result = caseEditorPartDescriptor(editorPartDescriptor);
+ if (result == null) result = caseApplicationElement(editorPartDescriptor);
+ if (result == null) result = caseUILabel(editorPartDescriptor);
+ if (result == null) result = caseHandlerContainer(editorPartDescriptor);
+ if (result == null) result = caseBindings(editorPartDescriptor);
+ if (result == null) result = defaultCase(theEObject);
+ return result;
+ }
+ default: return defaultCase(theEObject);
+ }
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>Simple IDE Application</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>Simple IDE Application</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T1 caseSimpleIDEApplication(MSimpleIDEApplication object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>Editor Part Descriptor</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>Editor Part Descriptor</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T1 caseEditorPartDescriptor(MEditorPartDescriptor object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>Element</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>Element</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T1 caseApplicationElement(MApplicationElement object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>UI Element</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>UI Element</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T1 caseUIElement(MUIElement object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>Element Container</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>Element Container</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public <T extends MUIElement> T1 caseElementContainer(MElementContainer<T> object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>Context</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>Context</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T1 caseContext(MContext object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>Handler Container</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>Handler Container</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T1 caseHandlerContainer(MHandlerContainer object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>Binding Table Container</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>Binding Table Container</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T1 caseBindingTableContainer(MBindingTableContainer object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>Part Descriptor Container</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>Part Descriptor Container</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T1 casePartDescriptorContainer(MPartDescriptorContainer object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>Bindings</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>Bindings</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T1 caseBindings(MBindings object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>Contributions</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>Contributions</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T1 caseMenuContributions(MMenuContributions object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>Tool Bar Contributions</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>Tool Bar Contributions</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T1 caseToolBarContributions(MToolBarContributions object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>Trim Contributions</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>Trim Contributions</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T1 caseTrimContributions(MTrimContributions object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>Application</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>Application</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T1 caseApplication(MApplication object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>UI Label</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>UI Label</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T1 caseUILabel(MUILabel object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>EObject</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch, but this is the last case anyway.
+ * <!-- end-user-doc -->
+ * @param object the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>EObject</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject)
+ * @generated
+ */
+ public T1 defaultCase(EObject object) {
+ return null;
+ }
+
+} //SimpleideSwitch
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/.classpath b/examples/org.eclipse.e4.demo.simpleide.navigator/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/.project b/examples/org.eclipse.e4.demo.simpleide.navigator/.project
new file mode 100644
index 0000000..c7b9ea1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.simpleide.navigator</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.navigator/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..a90d081
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,77 @@
+#Wed Jun 02 15:49:37 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide.navigator/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..a70c776
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:07:53 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.navigator/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e752b9f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/META-INF/MANIFEST.MF
@@ -0,0 +1,29 @@
+Manifest-Version: 1.0reators.exsd"/>
+Bundle-ManifestVersion: 2
+Bundle-Name: Navigator
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.navigator;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.core.resources;bundle-version="3.6.0",
+ org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.1",
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.e4.ui.services;bundle-version="0.9.1",
+ org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.equinox.common;bundle-version="3.6.0",
+ org.eclipse.osgi;bundle-version="3.6.0",
+ org.eclipse.core.databinding;bundle-version="1.3.100",
+ org.eclipse.core.databinding.observable;bundle-version="1.3.0",
+ org.eclipse.jface.databinding;bundle-version="1.4.0",
+ org.eclipse.core.databinding.property;bundle-version="1.3.0",
+ org.eclipse.e4.core.commands;bundle-version="0.9.0",
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0",
+ org.eclipse.e4.demo.simpleide.model;bundle-version="1.0.0",
+ org.eclipse.e4.demo.simpleide.services;bundle-version="1.0.0",
+ org.eclipse.e4.core.services;bundle-version="0.9.1"
+Import-Package: javax.annotation;version="1.0.0",
+ javax.inject;version="1.0.0",
+ org.eclipse.core.runtime.jobs,
+ org.eclipse.e4.ui.workbench.swt.modeling
+Service-Component: OSGI-INF/serviceRegistryComponent.xml
+Bundle-ActivationPolicy: lazy
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/OSGI-INF/serviceRegistryComponent.xml b/examples/org.eclipse.e4.demo.simpleide.navigator/OSGI-INF/serviceRegistryComponent.xml
new file mode 100644
index 0000000..78c8801
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/OSGI-INF/serviceRegistryComponent.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="false" name="org.eclipse.e4.demo.simpleide.navigator.projectCreatorComponent">
+ <implementation class="org.eclipse.e4.demo.simpleide.navigator.internal.ServiceRegistryComponent"/>
+ <service>
+ <provide interface="org.eclipse.e4.demo.simpleide.navigator.internal.ServiceRegistryComponent"/>
+ </service>
+ <reference bind="addProjectService" cardinality="0..n" interface="org.eclipse.e4.demo.simpleide.services.IProjectService" name="IProjectService" policy="dynamic" unbind="removeProjectService"/>
+ <reference bind="addImportService" cardinality="0..n" interface="org.eclipse.e4.demo.simpleide.services.IImportResourceService" name="IImportResourceService" policy="dynamic" unbind="removeImportService"/>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/build.properties b/examples/org.eclipse.e4.demo.simpleide.navigator/build.properties
new file mode 100644
index 0000000..c25a12f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/build.properties
@@ -0,0 +1,8 @@
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ OSGI-INF/,\
+ icons/,\
+ xmi/
+source.. = src/
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/icons/application_side_tree.png b/examples/org.eclipse.e4.demo.simpleide.navigator/icons/application_side_tree.png
new file mode 100644
index 0000000..f04a52b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/icons/application_side_tree.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/plugin.xml b/examples/org.eclipse.e4.demo.simpleide.navigator/plugin.xml
new file mode 100644
index 0000000..a884178
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/plugin.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ id="id1"
+ point="org.eclipse.e4.workbench.model">
+ <fragment
+ uri="xmi/fragment.e4xmi">
+ </fragment>
+ <fragment
+ uri="xmi/contextViewMenuFragment.e4xmi">
+ </fragment>
+ </extension>
+ <extension
+ point="org.eclipse.core.expressions.definitions">
+ <definition
+ id="org.eclipse.e4.demo.simpleide.menu.selection.Entry">
+ <with
+ variable="output.selection">
+ <count
+ value="1">
+ </count>
+ <iterate
+ ifEmpty="false"
+ operator="and">
+ <adapt
+ type="org.eclipse.e4.demo.simpleide.menu.ContextMenuView$Entry">
+ </adapt>
+ </iterate>
+ </with>
+ </definition>
+ </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/ContextMenuView.java b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/ContextMenuView.java
new file mode 100644
index 0000000..289afa2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/ContextMenuView.java
@@ -0,0 +1,351 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.e4.demo.simpleide.menu;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import org.eclipse.e4.core.commands.EHandlerService;
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu;
+import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
+import org.eclipse.e4.ui.workbench.swt.modeling.EMenuService;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.ListViewer;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.TreeViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.TreeColumn;
+
+public class ContextMenuView {
+ public static final String ITEMS_MENU = "ContextMenuView.treeMenu";
+ public static final String TAGS_MENU = "ContextMenuView.tags";
+ public static final String INFO_MENU = "ContextMenuView.info";
+
+ static class Entry {
+ final public Date date;
+ final public String desc;
+
+ public Entry(Date d, String s) {
+ date = d;
+ desc = s;
+ }
+ }
+
+ static class Tag {
+ final public String name;
+
+ public Tag(String s) {
+ name = s;
+ }
+ }
+
+ private TreeViewer items;
+ private ListViewer tagList;
+ private Text info;
+
+ @Inject
+ private ESelectionService selectionService;
+
+ @Inject
+ private EHandlerService handlerService;
+
+ @Inject
+ private EMenuService menuService;
+
+ @Inject
+ public ContextMenuView(final Composite parent) {
+ final Composite root = new Composite(parent, SWT.NONE);
+ root.setLayout(new GridLayout(2, true));
+ items = new TreeViewer(root, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
+ items.getControl().setLayoutData(
+ new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
+ TreeViewerColumn dateColumn = new TreeViewerColumn(items, SWT.LEFT);
+ TreeColumn dcol = dateColumn.getColumn();
+ dcol.setText("Date");
+ dcol.setWidth(200);
+ TreeViewerColumn descColumn = new TreeViewerColumn(items, SWT.LEFT);
+ TreeColumn descCol = descColumn.getColumn();
+ descCol.setText("Description");
+ descCol.setWidth(300);
+ tagList = new ListViewer(root, SWT.MULTI | SWT.V_SCROLL);
+ tagList.getControl().setLayoutData(
+ new GridData(SWT.FILL, SWT.FILL, false, true));
+ info = new Text(root, SWT.MULTI | SWT.READ_ONLY);
+ info.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
+ }
+
+ ArrayList<Entry> itemModel = new ArrayList<Entry>();
+ HashMap<Entry, String> textMap = new HashMap<Entry, String>();
+ HashMap<Entry, ArrayList<Tag>> tagMap = new HashMap<Entry, ArrayList<Tag>>();
+ private CopyHandler itemCopyHandler;
+ private CopyHandler tagCopyHandler;
+ private Object infoCopyHandler;
+
+ class ViewContentProvider implements IStructuredContentProvider,
+ ITreeContentProvider {
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ public void dispose() {
+ }
+
+ public Object[] getElements(Object inputElement) {
+ if (inputElement instanceof ArrayList<?>) {
+ return ((ArrayList<?>) inputElement).toArray();
+ }
+ return null;
+ }
+
+ public boolean hasChildren(Object element) {
+ if (element instanceof ArrayList<?>) {
+ return true;
+ }
+ return false;
+ }
+
+ public Object getParent(Object element) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof ArrayList<?>) {
+ return ((ArrayList<?>) parentElement).toArray();
+ }
+ return new Object[0];
+ }
+ }
+
+ static class CopyHandler {
+ StructuredViewer viewer;
+ Display display;
+
+ public CopyHandler(Display d, StructuredViewer v) {
+ viewer = v;
+ display = d;
+ }
+
+ @CanExecute
+ public boolean canExecute() {
+ ISelection sel = viewer.getSelection();
+ System.out.println("canExecute: " + sel);
+ return sel != null && sel instanceof IStructuredSelection
+ && !((IStructuredSelection) sel).isEmpty();
+ }
+
+ @Execute
+ public void execute() {
+ Clipboard cb = new Clipboard(display);
+ TextTransfer t = TextTransfer.getInstance();
+ String text = getText();
+ System.out.println("execute: " + text);
+ cb.setContents(new Object[] { text }, new Transfer[] { t });
+ cb.dispose();
+ }
+
+ private String getText() {
+ ISelection sel = viewer.getSelection();
+ if (sel instanceof IStructuredSelection) {
+ IStructuredSelection ssel = (IStructuredSelection) sel;
+ Object obj = ssel.getFirstElement();
+ if (obj instanceof Entry) {
+ return ((Entry) obj).desc
+ + " ("
+ + SimpleDateFormat.getInstance().format(
+ ((Entry) obj).date) + ")";
+ } else if (obj instanceof Tag) {
+ return ((Tag) obj).name;
+ }
+ }
+ return "";
+ }
+ }
+
+ @PostConstruct
+ public void init() {
+ for (int i = 1; i < 5; i++) {
+ createEntry(i);
+ }
+
+ items.setContentProvider(new ViewContentProvider());
+ items.setLabelProvider(new EntryLabelProvider());
+ items.setInput(itemModel);
+ items.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ ISelection selection = event.getSelection();
+ selectionService.setSelection(selection);
+ if (selection instanceof IStructuredSelection) {
+ Entry e = (Entry) ((IStructuredSelection) selection)
+ .getFirstElement();
+ String text = textMap.get(e);
+ info.setText(text == null ? "" : text);
+ ArrayList<Tag> list = tagMap.get(e);
+ tagList.setInput(list == null ? Collections.EMPTY_LIST
+ : list);
+ }
+ }
+ });
+
+ items.getTree().setLinesVisible(true);
+ items.getTree().setHeaderVisible(true);
+ items.getTree().layout(true);
+ menuService.registerContextMenu(items.getControl(), ITEMS_MENU);
+
+ itemCopyHandler = new CopyHandler(items.getTree().getDisplay(), items);
+ items.getTree().addListener(SWT.Activate, new Listener() {
+ public void handleEvent(Event event) {
+ handlerService.activateHandler("org.eclipse.ui.edit.copy",
+ itemCopyHandler);
+ }
+ });
+
+ tagList.setContentProvider(new ArrayContentProvider());
+ tagList.setLabelProvider(new LabelProvider() {
+ @Override
+ public String getText(Object element) {
+ if (element instanceof Tag) {
+ return ((Tag) element).name;
+ }
+ return null;
+ }
+ });
+ final MPopupMenu tagPopupMenu = menuService.registerContextMenu(tagList.getControl(),
+ TAGS_MENU);
+ tagList.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ ISelection selection = event.getSelection();
+ ESelectionService srv = tagPopupMenu.getContext().get(
+ ESelectionService.class);
+ srv.setSelection(selection);
+ }
+ });
+
+ tagCopyHandler = new CopyHandler(tagList.getControl().getDisplay(),
+ tagList);
+ tagList.getControl().addListener(SWT.Activate, new Listener() {
+ public void handleEvent(Event event) {
+ handlerService.activateHandler("org.eclipse.ui.edit.copy",
+ tagCopyHandler);
+ }
+ });
+
+ // with no handler, CTRL+C works because it delegates
+ // to the native widget. But the menu item copy
+ // doesn't, since it will not be handled.
+ // This will work as a real handler for both situations.
+ infoCopyHandler = new Object() {
+ @CanExecute
+ public boolean canExecute() {
+ return info.getSelectionCount() > 0;
+ }
+
+ @Execute
+ public void execute() {
+ info.copy();
+ }
+ };
+
+ info.addListener(SWT.Activate, new Listener() {
+ public void handleEvent(Event event) {
+ // just remove 'em both for simplicity
+ handlerService.deactivateHandler("org.eclipse.ui.edit.copy",
+ itemCopyHandler);
+ handlerService.deactivateHandler("org.eclipse.ui.edit.copy",
+ tagCopyHandler);
+ handlerService.activateHandler("org.eclipse.ui.edit.copy",
+ infoCopyHandler);
+ }
+ });
+ final MPopupMenu infoPopupMenu = menuService.registerContextMenu(info,
+ INFO_MENU);
+ // we can either publish the Text selection as a
+ // org.eclipse.jface.text.TextSelection or set it to an empty selection.
+ // I picked empty.
+ ESelectionService srv = infoPopupMenu.getContext().get(
+ ESelectionService.class);
+ srv.setSelection(StructuredSelection.EMPTY);
+ }
+
+ private static class EntryLabelProvider extends LabelProvider implements
+ ITableLabelProvider {
+ public Image getColumnImage(Object element, int columnIndex) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+ */
+ @Override
+ public String getText(Object element) {
+ return getColumnText(element, 0);
+ }
+
+ public String getColumnText(Object element, int columnIndex) {
+ switch (columnIndex) {
+ case 0:
+ return SimpleDateFormat.getInstance().format(
+ ((Entry) element).date);
+ case 1:
+ return ((Entry) element).desc;
+ }
+ return null;
+ }
+ }
+
+ private void createEntry(int index) {
+ Entry e = new Entry(new Date(), "item " + index);
+ itemModel.add(e);
+ textMap.put(e, "text for item " + index);
+ ArrayList<Tag> tags = new ArrayList<Tag>();
+ tagMap.put(e, tags);
+ for (int i = 1; i < 5; i++) {
+ createTag(tags, index, i);
+ }
+ }
+
+ private void createTag(ArrayList<Tag> tags, int index, int i) {
+ tags.add(new Tag("item_" + index + "_tag_" + i));
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/ContextMenuViewProcessor.java b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/ContextMenuViewProcessor.java
new file mode 100644
index 0000000..942b655
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/ContextMenuViewProcessor.java
@@ -0,0 +1,122 @@
+package org.eclipse.e4.demo.simpleide.menu;
+
+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.MHandler;
+import org.eclipse.e4.ui.model.application.commands.impl.CommandsFactoryImpl;
+import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor;
+import org.eclipse.e4.ui.model.application.descriptor.basic.impl.BasicFactoryImpl;
+import org.eclipse.e4.ui.model.application.ui.MCoreExpression;
+import org.eclipse.e4.ui.model.application.ui.impl.UiFactoryImpl;
+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.MMenuSeparator;
+import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuFactoryImpl;
+import org.eclipse.emf.ecore.EObject;
+
+public class ContextMenuViewProcessor {
+
+ public static final String OPEN_DIALOG_COMMAND = "org.eclipse.e4.demo.simpleide.menu.contextDialog";
+
+ public void processElement(EObject parent) {
+ if (!(parent instanceof MApplication)) {
+ return;
+ }
+ MApplication app = (MApplication) parent;
+
+ createCommand(app);
+ MPartDescriptor desc = BasicFactoryImpl.eINSTANCE
+ .createPartDescriptor();
+ desc.setLabel("Context Menu View");
+ desc.setElementId("org.eclipse.e4.demo.simpleide.menu.ContextMenuView");
+ desc.setCategory("org.eclipse.e4.secondaryDataStack");
+ desc.setContributionURI("bundleclass://org.eclipse.e4.demo.simpleide.navigator/org.eclipse.e4.demo.simpleide.menu.ContextMenuView");
+
+ MMenu menu = MenuFactoryImpl.eINSTANCE.createMenu();
+ menu.getTags().add("ViewMenu");
+ menu.setElementId("org.eclipse.e4.demo.simpleide.menu.ContextMenuView");
+
+ MHandledMenuItem item = MenuFactoryImpl.eINSTANCE
+ .createHandledMenuItem();
+ item.setElementId("e4.showView");
+ item.setLabel("Show View");
+ item.setCommand(findCommand(app, "org.eclipse.ui.views.showView"));
+ menu.getChildren().add(item);
+
+ // add it to the part
+ desc.getMenus().add(menu);
+
+ // context menu
+ menu = createPopupMenu(app, ContextMenuView.ITEMS_MENU, "Items");
+ // add it to the part
+ desc.getMenus().add(menu);
+
+ // context menu
+ menu = createPopupMenu(app, ContextMenuView.TAGS_MENU, "Tags");
+ // add it to the part
+ desc.getMenus().add(menu);
+
+ // context menu
+ menu = createPopupMenu(app, ContextMenuView.INFO_MENU, "Info");
+ // add it to the part
+ desc.getMenus().add(menu);
+
+ app.getDescriptors().add(desc);
+ }
+
+ private void createCommand(MApplication app) {
+ MCommand cmd = CommandsFactoryImpl.eINSTANCE.createCommand();
+ cmd.setElementId(OPEN_DIALOG_COMMAND);
+ cmd.setCommandName("Show Info");
+ MHandler handler = CommandsFactoryImpl.eINSTANCE.createHandler();
+ handler.setCommand(cmd);
+ handler.setElementId("open.dialog.on.selection");
+ handler.setContributionURI("bundleclass://org.eclipse.e4.demo.simpleide.navigator/org.eclipse.e4.demo.simpleide.menu.OpenDialogHandler");
+ app.getCommands().add(cmd);
+ app.getHandlers().add(handler);
+ }
+
+ private MMenu createPopupMenu(MApplication app, String id, String name) {
+ MMenu menu = MenuFactoryImpl.eINSTANCE.createPopupMenu();
+ menu.setElementId(id);
+
+ MHandledMenuItem item = MenuFactoryImpl.eINSTANCE
+ .createHandledMenuItem();
+ item.setElementId("e4.showView");
+ item.setLabel("Show View " + name);
+ item.setCommand(findCommand(app, "org.eclipse.ui.views.showView"));
+ menu.getChildren().add(item);
+
+ MMenuSeparator sep = MenuFactoryImpl.eINSTANCE.createMenuSeparator();
+ sep.setElementId("additions");
+ menu.getChildren().add(sep);
+
+ item = MenuFactoryImpl.eINSTANCE.createHandledMenuItem();
+ item.setElementId("copy");
+ item.setLabel("Copy");
+ item.setCommand(findCommand(app, "org.eclipse.ui.edit.copy"));
+ menu.getChildren().add(item);
+
+ MCoreExpression exp = UiFactoryImpl.eINSTANCE.createCoreExpression();
+ exp.setCoreExpressionId("org.eclipse.e4.demo.simpleide.menu.selection.Entry");
+ item = MenuFactoryImpl.eINSTANCE.createHandledMenuItem();
+ MCommand cmd = findCommand(app, OPEN_DIALOG_COMMAND);
+ item.setElementId(cmd.getElementId());
+ item.setLabel(cmd.getCommandName());
+ item.setCommand(cmd);
+ item.setVisibleWhen(exp);
+ menu.getChildren().add(item);
+
+ return menu;
+ }
+
+ private MCommand findCommand(MApplication app, String id) {
+ for (MCommand cmd : app.getCommands()) {
+ if (id.equals(cmd.getElementId())) {
+ return cmd;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/OpenDialogHandler.java b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/OpenDialogHandler.java
new file mode 100644
index 0000000..dc77877
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/menu/OpenDialogHandler.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.e4.demo.simpleide.menu;
+
+import javax.inject.Named;
+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.e4.ui.services.IServiceConstants;
+
+public class OpenDialogHandler {
+ @CanExecute
+ public boolean canExecute(
+ @Named(IServiceConstants.SELECTION) @Optional ContextMenuView.Tag tag) {
+ return tag != null;
+ }
+
+ @Execute
+ public void execute(
+ @Named(IServiceConstants.SELECTION) @Optional ContextMenuView.Tag tag) {
+ System.out.println(tag.name);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/navigator/internal/ResourceNavigator.java b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/navigator/internal/ResourceNavigator.java
new file mode 100644
index 0000000..5a04163
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/navigator/internal/ResourceNavigator.java
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.navigator.internal;
+
+import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import javax.inject.Inject;
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.core.databinding.observable.Observables;
+import org.eclipse.core.databinding.observable.Realm;
+import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
+import org.eclipse.core.databinding.observable.set.IObservableSet;
+import org.eclipse.core.databinding.observable.set.WritableSet;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.e4.core.commands.ECommandService;
+import org.eclipse.e4.core.commands.EHandlerService;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleIDEApplication;
+import org.eclipse.e4.demo.simpleide.services.IImportResourceService;
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.databinding.swt.SWTObservables;
+import org.eclipse.jface.databinding.viewers.ObservableSetTreeContentProvider;
+import org.eclipse.jface.databinding.viewers.TreeStructureAdvisor;
+import org.eclipse.jface.viewers.IOpenListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.OpenEvent;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+
+public class ResourceNavigator {
+ private Map<IContainer, IObservableSet> observableSets = new HashMap<IContainer, IObservableSet>();
+
+ @Inject
+ private ECommandService commandService;
+
+ @Inject
+ private EHandlerService handlerService;
+
+ private IResourceChangeListener listener = new IResourceChangeListener() {
+ public void resourceChanged(IResourceChangeEvent event) {
+ if (event.getType() == IResourceChangeEvent.POST_CHANGE) {
+ try {
+ event.getDelta().accept(new IResourceDeltaVisitor() {
+ public boolean visit(IResourceDelta delta)
+ throws CoreException {
+ if (delta.getKind() == IResourceDelta.ADDED) {
+ handleChange(delta.getResource(), delta
+ .getResource().getParent(), true);
+ } else if (delta.getKind() == IResourceDelta.REMOVED) {
+ handleChange(delta.getResource(), delta
+ .getResource().getParent(), false);
+ }
+ return true;
+ }
+
+ private void handleChange(final IResource resource,
+ final IContainer parent, final boolean added) {
+ final IObservableSet set = observableSets
+ .get(parent);
+ Realm realm = set != null ? set.getRealm() : null;
+ if (realm != null) {
+ realm.asyncExec(new Runnable() {
+ public void run() {
+ if (added) {
+ set.add(resource);
+ } else {
+ set.remove(resource);
+ }
+ }
+ });
+ }
+ }
+ });
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ };
+
+ private IEclipseContext context;
+
+ @Inject
+ private ServiceRegistryComponent serviceRegistry;
+
+ @Inject
+ private MApplication application;
+
+ @Inject
+ private ESelectionService selectionService;
+
+ @Inject
+ public ResourceNavigator(Composite parent, final IEclipseContext context, IWorkspace workspace) {
+ final Realm realm = SWTObservables.getRealm(parent.getDisplay());
+ this.context = context;
+ parent.setLayout(new FillLayout());
+ TreeViewer viewer = new TreeViewer(parent,SWT.FULL_SELECTION|SWT.H_SCROLL|SWT.V_SCROLL);
+ viewer.addSelectionChangedListener(new ISelectionChangedListener(){
+ public void selectionChanged(SelectionChangedEvent event) {
+ StructuredSelection selection = (StructuredSelection)event.getSelection();
+ selectionService.setSelection(selection.size() == 1 ? selection.getFirstElement() : selection.toArray());
+// context.modify(IServiceConstants.ACTIVE_SELECTION, selection.size() == 1 ? selection.getFirstElement() : selection.toArray());
+ }
+ });
+
+ IObservableFactory setFactory = new IObservableFactory() {
+ public IObservable createObservable(Object element) {
+ if (element instanceof IContainer
+ && ((IContainer) element).exists()) {
+ IObservableSet observableSet = observableSets.get(element);
+ if (observableSet == null) {
+ observableSet = new WritableSet(realm);
+ try {
+ observableSet.addAll(Arrays
+ .asList(((IContainer) element).members()));
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ observableSets.put((IContainer) element, observableSet);
+ }
+ return observableSet;
+ }
+ return Observables.emptyObservableSet();
+ }
+ };
+ viewer.setContentProvider(new ObservableSetTreeContentProvider(
+ setFactory, new TreeStructureAdvisor() {
+ public Boolean hasChildren(Object element) {
+ return Boolean.valueOf(element instanceof IContainer);
+ }
+ }));
+
+ viewer.setLabelProvider(new LabelProvider() {
+ public String getText(Object element) {
+ if (element instanceof IResource)
+ return ((IResource) element).getName();
+ return element == null ? "" : element.toString();
+ }
+ });
+ viewer.setSorter(new ViewerSorter());
+ viewer.setInput(workspace.getRoot());
+ viewer.addOpenListener(new IOpenListener() {
+
+ public void open(OpenEvent event) {
+ MSimpleIDEApplication app = (MSimpleIDEApplication) application;
+ IStructuredSelection s = (IStructuredSelection) event.getSelection();
+ for( Object o : s.toArray() ) {
+ if( o instanceof IFile ) {
+ IFile f = (IFile) o;
+ context.set(IFile.class, f);
+ String fExt = f.getFileExtension();
+ EDITOR: for( MEditorPartDescriptor desc : app.getEditorPartDescriptors() ) {
+ for( String ext: desc.getFileextensions() ) {
+ if( ext.equals(fExt) ) {
+ context.set(MEditorPartDescriptor.class, desc);
+ System.err.println("Opening with: " + desc);
+
+ Command cmd = commandService.getCommand("simpleide.command.openeditor");
+ ParameterizedCommand pCmd = ParameterizedCommand.generateCommand(cmd, null);
+ handlerService.executeHandler(pCmd);
+
+ break EDITOR;
+ }
+ }
+ }
+ }
+ }
+
+ }
+ });
+ setupContextMenu(viewer, parent.getShell());
+ workspace.addResourceChangeListener(listener);
+ }
+
+ private void setupContextMenu(final TreeViewer viewer, final Shell shell) {
+ MenuManager mgr = new MenuManager();
+ viewer.getControl().setMenu(mgr.createContextMenu(viewer.getControl()));
+
+ mgr.setRemoveAllWhenShown(true);
+ mgr.addMenuListener(new IMenuListener() {
+
+ public void menuAboutToShow(IMenuManager manager) {
+ MenuManager mgr = new MenuManager("Import");
+ for( IImportResourceService s : serviceRegistry.getImportServices() ) {
+ final IImportResourceService tmp = s;
+ Action a = new Action(s.getLabel()) {
+ public void run() {
+ tmp.importResource(shell, context.createChild());
+ }
+ };
+ mgr.add(a);
+ }
+
+ manager.add(mgr);
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/navigator/internal/ServiceRegistryComponent.java b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/navigator/internal/ServiceRegistryComponent.java
new file mode 100644
index 0000000..5a19917
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/src/org/eclipse/e4/demo/simpleide/navigator/internal/ServiceRegistryComponent.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.navigator.internal;
+
+import java.util.Vector;
+import org.eclipse.e4.demo.simpleide.services.IImportResourceService;
+import org.eclipse.e4.demo.simpleide.services.IProjectService;
+
+public class ServiceRegistryComponent {
+ private Vector<IProjectService> creators = new Vector<IProjectService>();
+ private Vector<IImportResourceService> importServices = new Vector<IImportResourceService>();
+
+ public void addProjectService( IProjectService creator ) {
+ creators.add(creator);
+ }
+
+ public void removeProjectService(IProjectService creator) {
+ creators.remove(creator);
+ }
+
+ public Vector<IProjectService> getCreators() {
+ return creators;
+ }
+
+ public void addImportService(IImportResourceService importService) {
+ importServices.add(importService);
+ }
+
+ public void removeImportService(IImportResourceService importService) {
+ importServices.remove(importService);
+ }
+
+ public Vector<IImportResourceService> getImportServices() {
+ return importServices;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/xmi/contextViewMenuFragment.e4xmi b/examples/org.eclipse.e4.demo.simpleide.navigator/xmi/contextViewMenuFragment.e4xmi
new file mode 100644
index 0000000..cf0225f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/xmi/contextViewMenuFragment.e4xmi
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/descriptor/basic" xmlns:commands="http://www.eclipse.org/ui/2010/UIModel/application/commands" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmlns:ui="http://www.eclipse.org/ui/2010/UIModel/application/ui" xmi:id="_uj3fEHZcEd-RApwktjxCFQ">
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_5w9CkHZcEd-RApwktjxCFQ" featurename="commands" parentElementId="app.simpleide">
+ <elements xsi:type="commands:Command" xmi:id="_NtAhUHZdEd-izNVw4-awdw" elementId="open.dialog.on.selection" commandName="Show Info"/>
+ </fragments>
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_TaVQgHZdEd-izNVw4-awdw" featurename="handlers" parentElementId="app.simpleide">
+ <elements xsi:type="commands:Handler" xmi:id="_W8wOYHZdEd-izNVw4-awdw" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.navigator/org.eclipse.e4.demo.simpleide.menu.OpenDialogHandler" command="_NtAhUHZdEd-izNVw4-awdw"/>
+ </fragments>
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_lAjq4HZeEd-R6aDhnXWjVw" featurename="descriptors" parentElementId="app.simpleide">
+ <elements xsi:type="basic:PartDescriptor" xmi:id="_wtS-0HZeEd-R6aDhnXWjVw" label="Context Menu View" elementId="org.eclipse.e4.demo.simpleide.menu.ContextMenuView" category="org.eclipse.e4.secondaryDataStack" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.navigator/org.eclipse.e4.demo.simpleide.menu.ContextMenuView">
+ <tags>View</tags>
+ <tags>categoryTag:Utilities</tags>
+ <menus xmi:id="_JWJ4wV6WEd-kocunFhpHRA" elementId="org.eclipse.e4.demo.simpleide.menu.ContextMenuView">
+ <tags>ViewMenu</tags>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kocunFhpHRA" elementId="e4.showView" label="Show View" >
+ <command href="platform:/plugin/org.eclipse.e4.demo.simpleide/Application.e4xmi#org.eclipse.ui.views.showView"/>
+ </children>
+ </menus>
+ <menus xsi:type="menu:PopupMenu" xmi:id="ContextMenuView.treeMenu" elementId="ContextMenuView.treeMenu">
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kocunFhpH" elementId="e4.showView" >
+ <command href="platform:/plugin/org.eclipse.e4.demo.simpleide/Application.e4xmi#org.eclipse.ui.views.showView"/>
+ </children>
+ <children xsi:type="menu:MenuSeparator" xmi:id="_O5FV0F6WEd-kocunFhpHY" elementId="additions"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kocuFhpH" elementId="e4.copy">
+ <command href="platform:/plugin/org.eclipse.e4.demo.simpleide/Application.e4xmi#org.eclipse.ui.edit.copy"/>
+ </children>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" elementId="e4.open.dialog" command="_NtAhUHZdEd-izNVw4-awdw">
+ <visibleWhen xsi:type="ui:CoreExpression" coreExpressionId="org.eclipse.e4.demo.simpleide.menu.selection.Entry" />
+ </children>
+ </menus>
+ <menus xsi:type="menu:PopupMenu" xmi:id="ContextMenuView.tags" elementId="ContextMenuView.tags">
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kocunFhpH" elementId="e4.showView" >
+ <command href="platform:/plugin/org.eclipse.e4.demo.simpleide/Application.e4xmi#org.eclipse.ui.views.showView"/>
+ </children>
+ <children xsi:type="menu:MenuSeparator" xmi:id="_O5FV0F6WEd-kocunFhpHY" elementId="additions"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kocuFhpH" elementId="e4.copy" >
+ <command href="platform:/plugin/org.eclipse.e4.demo.simpleide/Application.e4xmi#org.eclipse.ui.edit.copy"/>
+ </children>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" elementId="e4.open.dialog" command="_NtAhUHZdEd-izNVw4-awdw">
+ <visibleWhen xsi:type="ui:CoreExpression" coreExpressionId="org.eclipse.e4.demo.simpleide.menu.selection.Entry" />
+ </children>
+ </menus>
+ <menus xsi:type="menu:PopupMenu" xmi:id="ContextMenuView.info" elementId="ContextMenuView.info">
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kocunFhpH" elementId="e4.showView" >
+ <command href="platform:/plugin/org.eclipse.e4.demo.simpleide/Application.e4xmi#org.eclipse.ui.views.showView"/>
+ </children>
+ <children xsi:type="menu:MenuSeparator" xmi:id="_O5FV0F6WEd-kocunFhpHY" elementId="additions"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kocuFhpH" elementId="e4.copy">
+ <command href="platform:/plugin/org.eclipse.e4.demo.simpleide/Application.e4xmi#org.eclipse.ui.edit.copy"/>
+ </children>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" elementId="e4.open.dialog" command="_NtAhUHZdEd-izNVw4-awdw">
+ <visibleWhen xsi:type="ui:CoreExpression" coreExpressionId="org.eclipse.e4.demo.simpleide.menu.selection.Entry" />
+ </children>
+ </menus>
+ </elements>
+ </fragments>
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_6lwRsHZeEd-R6aDhnXWjVw" featurename="menuContributions" parentElementId="app.simpleide">
+ <elements xsi:type="menu:MenuContribution" xmi:id="_Cwp2kHZfEd-R6aDhnXWjVw" elementId="simpleide.info.popup1" parentId="popup">
+ <visibleWhen xsi:type="ui:CoreExpression" xmi:id="_O9PSwHZgEd-o_pkn-4-GGQ" coreExpressionId="org.eclipse.e4.demo.simpleide.menu.selection.Entry"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" elementId="e4.open.dialog.1" label="Popup Open 1" command="_NtAhUHZdEd-izNVw4-awdw"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" elementId="e4.open.dialog.2" label="Popup Open 2" command="_NtAhUHZdEd-izNVw4-awdw"/>
+ <children xsi:type="menu:Menu" xmi:id="simpleide.submenu" elementId="simpleide.submenu" label="Popup Sub">
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" elementId="e4.open.dialog.3" label="Popup Open 3" command="_NtAhUHZdEd-izNVw4-awdw"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" elementId="e4.open.dialog.4" label="Popup Open 4" command="_NtAhUHZdEd-izNVw4-awdw"/>
+ </children>
+ </elements>
+ <elements xsi:type="menu:MenuContribution" xmi:id="_GrRSAHZfEd-R6aDhnXWjVw" elementId="simpleide.info.contrib" parentId="_WbMXYEjUEd-v7fhjaiz65w">
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" label="Window Open 1" elementId="e4.open.dialog.5" command="_NtAhUHZdEd-izNVw4-awdw"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" label="Window Open 2" elementId="e4.open.dialog.6" command="_NtAhUHZdEd-izNVw4-awdw"/>
+ <children xsi:type="menu:Menu" xmi:id="simpleide.window.submenu" elementId="simpleide.window.submenu" label="Window Sub">
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" label="Window Open 3" elementId="e4.open.dialog.7" command="_NtAhUHZdEd-izNVw4-awdw"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" label="Window Open 4" elementId="e4.open.dialog.8" command="_NtAhUHZdEd-izNVw4-awdw"/>
+ </children>
+ </elements>
+ <elements xsi:type="menu:MenuContribution" xmi:id="_Vf3uwHZfEd-R6aDhnXWjVw" elementId="simpleide.info.contrib2" parentId="simpleide.window.submenu">
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" label="Window Open 5" elementId="e4.open.dialog.9" command="_NtAhUHZdEd-izNVw4-awdw"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" label="Window Open 6" elementId="e4.open.dialog.10" command="_NtAhUHZdEd-izNVw4-awdw"/>
+ <children xsi:type="menu:Menu" xmi:id="simpleide.window.submenu2" elementId="simpleide.window.submenu2" label="Window Sub2">
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" label="Window Open 7" elementId="e4.open.dialog.11" command="_NtAhUHZdEd-izNVw4-awdw"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_O5FV0F6WEd-kcuFhpH" label="Window Open 8" elementId="e4.open.dialog.12" command="_NtAhUHZdEd-izNVw4-awdw"/>
+ </children>
+ </elements>
+ </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.simpleide.navigator/xmi/fragment.e4xmi b/examples/org.eclipse.e4.demo.simpleide.navigator/xmi/fragment.e4xmi
new file mode 100644
index 0000000..97547ea
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.navigator/xmi/fragment.e4xmi
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_WisR8HZEEd-peaY5fFiGdQ">
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_ZN23sHZEEd-peaY5fFiGdQ" featurename="children" parentElementId="org.eclipse.e4.primaryNavigationStack">
+ <elements xsi:type="basic:Part" xmi:id="_81XEMHZbEd-Sp-lHczMPZw" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.navigator/org.eclipse.e4.demo.simpleide.navigator.internal.ResourceNavigator" label="Navigator" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.navigator/icons/application_side_tree.png"/>
+ </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/.classpath b/examples/org.eclipse.e4.demo.simpleide.outline/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/.project b/examples/org.eclipse.e4.demo.simpleide.outline/.project
new file mode 100644
index 0000000..3c58498
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.simpleide.outline</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.outline/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..9cfae69
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Wed May 26 00:00:14 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.outline/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..2574993
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Outline
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.outline;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.e4.ui.services;bundle-version="0.9.1",
+ org.eclipse.e4.ui.model.workbench;bundle-version="0.9.1",
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0",
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.1"
+Export-Package: org.eclipse.e4.demo.simpleide.outline
+Import-Package: javax.inject;version="1.0.0"
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/build.properties b/examples/org.eclipse.e4.demo.simpleide.outline/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/icons/outline_co.gif b/examples/org.eclipse.e4.demo.simpleide.outline/icons/outline_co.gif
new file mode 100644
index 0000000..0dc862c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/icons/outline_co.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/plugin.xml b/examples/org.eclipse.e4.demo.simpleide.outline/plugin.xml
new file mode 100644
index 0000000..91ea859
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/plugin.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ id="id1"
+ point="org.eclipse.e4.workbench.model">
+ <fragment
+ uri="xmi/fragment.e4xmi">
+ </fragment>
+ </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/src/org/eclipse/e4/demo/simpleide/outline/IOutlinePageProvider.java b/examples/org.eclipse.e4.demo.simpleide.outline/src/org/eclipse/e4/demo/simpleide/outline/IOutlinePageProvider.java
new file mode 100644
index 0000000..6b72161
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/src/org/eclipse/e4/demo/simpleide/outline/IOutlinePageProvider.java
@@ -0,0 +1,5 @@
+package org.eclipse.e4.demo.simpleide.outline;
+
+public interface IOutlinePageProvider {
+ public Class<?> getOutlineClass();
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/src/org/eclipse/e4/demo/simpleide/outline/internal/OutlineView.java b/examples/org.eclipse.e4.demo.simpleide.outline/src/org/eclipse/e4/demo/simpleide/outline/internal/OutlineView.java
new file mode 100644
index 0000000..ba29f30
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/src/org/eclipse/e4/demo/simpleide/outline/internal/OutlineView.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.outline.internal;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.eclipse.e4.core.contexts.ContextInjectionFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.demo.simpleide.outline.IOutlinePageProvider;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+
+public class OutlineView {
+ private Composite parent;
+
+ private Control pageControl;
+
+ private IEclipseContext pageContext;
+
+ @Inject
+ public OutlineView(Composite parent) {
+ this.parent = parent;
+ }
+
+ @Inject
+ public void setActivePart(
+ @Optional @Named(IServiceConstants.ACTIVE_PART) MPart activePart) {
+ if (parent.isDisposed()) {
+ return;
+ }
+ IEclipseContext oldPageContext = pageContext;
+ Control oldPageControl = pageControl;
+
+ if (activePart != null) {
+ if (activePart.getObject() instanceof IOutlinePageProvider) {
+ pageContext = activePart.getContext().createChild();
+ Composite comp = new Composite(parent, SWT.NONE);
+ comp.setLayout(new FillLayout());
+ pageControl = comp;
+ pageContext.set(Composite.class, comp);
+ ContextInjectionFactory.make(((IOutlinePageProvider) activePart
+ .getObject()).getOutlineClass(), pageContext);
+ } else {
+ oldPageContext = null;
+ oldPageControl = null;
+ }
+ } else {
+ Label label = new Label(parent, SWT.NONE);
+ label.setText("No outline available");
+ pageControl = label;
+ }
+
+ // Dispose afterwards which helps potential image resource pooling
+ if (oldPageContext != null) {
+ oldPageContext.dispose();
+ }
+
+ if (oldPageControl != null) {
+ oldPageControl.dispose();
+ }
+
+ parent.layout(true, true);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.outline/xmi/fragment.e4xmi b/examples/org.eclipse.e4.demo.simpleide.outline/xmi/fragment.e4xmi
new file mode 100644
index 0000000..56ad614
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.outline/xmi/fragment.e4xmi
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ASCII"?>
+<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_glJTgHijEd-QLpUkCzu7EA">
+ <fragments xsi:type="fragment:StringModelFragment" xmi:id="_ocBJIHijEd-TPIFsLcQOCg" featurename="children" parentElementId="org.eclipse.e4.secondaryNavigationStack">
+ <elements xsi:type="basic:Part" xmi:id="_tcCtcHijEd-TPIFsLcQOCg" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide.outline/org.eclipse.e4.demo.simpleide.outline.internal.OutlineView" label="Outline" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide.outline/icons/outline_co.gif"/>
+ </fragments>
+</fragment:ModelFragments>
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/.classpath b/examples/org.eclipse.e4.demo.simpleide.services/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/.project b/examples/org.eclipse.e4.demo.simpleide.services/.project
new file mode 100644
index 0000000..763561b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.simpleide.services</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.services/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..597e724
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Mon May 17 18:38:37 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.services/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..8759926
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Services
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.services
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.e4.demo.simpleide.services
+Require-Bundle: org.eclipse.swt;bundle-version="3.6.0",
+ org.eclipse.core.resources;bundle-version="3.6.0",
+ org.eclipse.equinox.common;bundle-version="3.6.0",
+ org.eclipse.e4.core.services;bundle-version="0.9.1",
+ org.eclipse.osgi;bundle-version="3.6.0",
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0"
+Import-Package: javax.inject;version="1.0.0"
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/build.properties b/examples/org.eclipse.e4.demo.simpleide.services/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/AbstractBundleImageProvider.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/AbstractBundleImageProvider.java
new file mode 100644
index 0000000..b4655e6
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/AbstractBundleImageProvider.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.services;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.osgi.framework.Bundle;
+
+public abstract class AbstractBundleImageProvider implements IImageProviderService {
+
+ public final String[] getImageKeys() {
+ return getImageMap().values().toArray(new String[0]);
+ }
+
+ public final InputStream getImageData(String imageKey) throws CoreException {
+ Map<String, String> map = getImageMap();
+
+ if( map.containsKey(imageKey) ) {
+ return getStream(imageKey, map.get(imageKey));
+ }
+
+ throw new CoreException(new Status(IStatus.ERROR, OSGiUtil.getBundleName(getClass()), "The image key '"+imageKey+"' is unknown."));
+ }
+
+ private InputStream getStream(String imageKey, String path) throws CoreException {
+ URL url = FileLocator.find(getBundle(imageKey), new Path(path), null);
+ if( url != null ) {
+ try {
+ return url.openStream();
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, OSGiUtil.getBundleName(getClass()), "Unable to open stream to URL '"+url+"'"));
+ }
+ }
+ throw new CoreException(new Status(IStatus.ERROR, OSGiUtil.getBundleName(getClass()), "The path '"+path+"' is unknown."));
+ }
+
+
+
+ protected abstract Map<String, String> getImageMap();
+ protected abstract Bundle getBundle(String imageKey);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IExportResourceService.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IExportResourceService.java
new file mode 100644
index 0000000..654fddc
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IExportResourceService.java
@@ -0,0 +1,14 @@
+package org.eclipse.e4.demo.simpleide.services;
+
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.swt.widgets.Shell;
+
+public interface IExportResourceService {
+ public String getCategoryName();
+
+ public String getIconURI();
+
+ public String getLabel();
+
+ public void exportResource(Shell shell, IEclipseContext context);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImageProviderService.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImageProviderService.java
new file mode 100644
index 0000000..4f79c57
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImageProviderService.java
@@ -0,0 +1,10 @@
+package org.eclipse.e4.demo.simpleide.services;
+
+import java.io.InputStream;
+
+import org.eclipse.core.runtime.CoreException;
+
+public interface IImageProviderService {
+// public String[] getImageKeys();
+ public InputStream getImageData(String imageKey) throws CoreException;
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImageService.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImageService.java
new file mode 100644
index 0000000..3e5517d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImageService.java
@@ -0,0 +1,40 @@
+package org.eclipse.e4.demo.simpleide.services;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Control;
+
+public interface IImageService {
+ public interface IImagePool {
+ public Image getImage(String imageKey) throws CoreException;
+ public Image getImageUnchecked(String imageKey);
+ }
+
+ public interface IDiposeableImagePool extends IImagePool {
+ public void dispose();
+ }
+
+ public interface IPooledImage {
+ public Image getImage();
+
+ public void dipose();
+ }
+
+ public Image getImage(String imageKey)
+ throws CoreException;
+
+ public IPooledImage getPooledImage(String imageKey)
+ throws CoreException;
+
+ public IDiposeableImagePool getPool();
+
+ /**
+ * Get an image pool which is connected to a control and gets disposed when
+ * the control it is connected to is disposed
+ *
+ * @param control
+ * the control it is connected to
+ * @return a new pool connected to the control
+ */
+ public IImagePool getControlPool(Control control);
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImportResourceService.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImportResourceService.java
new file mode 100644
index 0000000..eae79c8
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IImportResourceService.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.services;
+
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.swt.widgets.Shell;
+
+public interface IImportResourceService {
+ public String getCategoryName();
+ public String getIconURI();
+ public String getLabel();
+ public void importResource(Shell shell, IEclipseContext context);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/INLSLookupFactoryService.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/INLSLookupFactoryService.java
new file mode 100644
index 0000000..39e9ec1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/INLSLookupFactoryService.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.services;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.util.Locale;
+
+public interface INLSLookupFactoryService {
+ /**
+ * Creates a lookup which adapts dynamically to the current language stored
+ * in {@link Locale#getDefault()}
+ *
+ * @param <L>
+ * the interface type
+ * @param clazz
+ * the interface type
+ * @return the lookup instance
+ */
+ public <L> L createDynamicNLSLookup(Class<L> clazz);
+
+ /**
+ * Create a lookup which uses the give locale for lookups in dependently
+ * from the current default locale
+ *
+ * @param <L>
+ * the interface type
+ * @param clazz
+ * the interface type
+ * @param locale
+ * the locale
+ * @return the lookup instance
+ */
+ public <L> L createNLSLookup(Class<L> clazz, Locale locale);
+
+ /**
+ * Create a lookup which uses the give locale for lookups in dependently
+ * from the current default locale.
+ * <p>
+ * This method has the same results as
+ * <code>createNLSLookup(My.class, Locale.getDefault())</code>
+ * </p>
+ *
+ * @param <L>
+ * the interface type
+ * @param clazz
+ * the interface type
+ * @return the lookup instance
+ */
+ public <L> L createNLSLookup(Class<L> clazz);
+
+ /**
+ * Translate a value using one of the registered translation services
+ *
+ * @param category
+ * the category to identify the service
+ * @param key
+ * the key
+ * @param args
+ * the arguments for substitution
+ * @return the string in the current default locale
+ */
+ public String translate(String category, String key, Object... args);
+
+ /**
+ * Translate a value using one of the registered translation services
+ *
+ * @param category
+ * the category to identify the service
+ * @param key
+ * the key
+ * @param locale
+ * the locale to use
+ * @param args
+ * the arguments for substitution
+ * @return the translated string
+ */
+ public String translate(String category, String key, Locale locale,
+ Object... args);
+
+ /**
+ * Configures the cacheing of the Lookup class
+ */
+ @Target(ElementType.TYPE)
+ public @interface Cache {
+
+ }
+
+ /**
+ * Marks the value to be looked up through the given service class
+ */
+ @Target(ElementType.TYPE)
+ public @interface OSGiService {
+ String serviceId();
+ }
+
+ @Target(ElementType.METHOD)
+ public @interface Key {
+ String category() default "N/A";
+
+ String key();
+ }
+
+ public interface ITranslationService {
+ public String translate(String category, String key, Locale locale);
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IProjectService.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IProjectService.java
new file mode 100644
index 0000000..33f7e76
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/IProjectService.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.services;
+
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.core.services.statusreporter.StatusReporter;
+import org.eclipse.swt.widgets.Shell;
+
+public interface IProjectService {
+ public String getIconURI();
+ public String getLabel();
+ public void createProject(Shell shell, IWorkspace workspace, StatusReporter statusReporter, Logger logger, IProgressMonitor monitor, String projectName);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/ImageService.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/ImageService.java
new file mode 100644
index 0000000..3d42f40
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/ImageService.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.services;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.inject.Inject;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.demo.simpleide.services.IImageProviderService;
+import org.eclipse.e4.demo.simpleide.services.IImageService;
+import org.eclipse.e4.demo.simpleide.services.OSGiUtil;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+
+public class ImageService implements IImageService {
+
+ public static class PooledImage implements IPooledImage {
+ private int count;
+ private Image image;
+ private String imageKey;
+ private ImageService imageService;
+
+ PooledImage(ImageService imageService, String imageKey, Image image) {
+ this.count = 1;
+ this.image = image;
+ this.imageKey = imageKey;
+ }
+
+ public Image getImage() {
+ return image;
+ }
+
+ public void dipose() {
+ this.count--;
+ if( this.count == 0 ) {
+ image.dispose();
+ imageService.removePooledImage(this);
+ image = null;
+ imageService = null;
+ imageKey = null;
+ }
+ }
+ }
+
+ private static class ImagePool implements IDiposeableImagePool {
+ private ImageService imageService;
+ private List<IPooledImage> pooledImages = new ArrayList<IPooledImage>();
+
+ public ImagePool(ImageService imageService) {
+ this.imageService = imageService;
+ }
+
+ public Image getImage(String imageKey) throws CoreException {
+ if( imageService == null ) {
+ throw new CoreException(new Status(IStatus.ERROR, OSGiUtil.getBundleName(getClass()), "The pool is disposed"));
+ }
+ IPooledImage image = imageService.getPooledImage(imageKey);
+ pooledImages.add(image);
+ return image.getImage();
+ }
+
+ public Image getImageUnchecked(String imageKey) {
+ try {
+ return getImage(imageKey);
+ } catch (CoreException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void dispose() {
+ for( IPooledImage img : pooledImages ) {
+ img.dipose();
+ }
+ imageService = null;
+ pooledImages = null;
+ }
+ }
+
+ private Map<String, IImageProviderService> key2providers = new HashMap<String, IImageProviderService>();
+ private Map<String, PooledImage> imagePool = new HashMap<String, ImageService.PooledImage>();
+
+ private Logger logger;
+ private Display display;
+
+ @Inject
+ public ImageService(Logger logger, Display display) {
+ this.logger = logger;
+ this.display = display;
+ }
+
+ public void addImageProvider(IImageProviderService imageProvider, Collection<String> imageKeys) {
+ synchronized (key2providers) {
+ for( String s : imageKeys ) {
+ if( ! key2providers.containsKey(s) ) {
+ key2providers.put(s, imageProvider);
+ } else {
+ IImageProviderService tmp = key2providers.get(s);
+ logger.error("Can not register imagekey '"+s+"' for "+imageProvider+" ("+OSGiUtil.getBundleName(imageProvider.getClass())+") because is already connected to " + tmp + " ("+OSGiUtil.getBundleName(tmp.getClass())+")");
+ }
+ }
+ }
+ }
+
+ public void removeImageProvider(IImageProviderService imageProvider) {
+ synchronized (key2providers) {
+ Iterator<Entry<String, IImageProviderService>> it = key2providers.entrySet().iterator();
+ while( it.hasNext() ) {
+ if( it.next().getValue() == imageProvider ) {
+ it.remove();
+ }
+ }
+ }
+ }
+
+ public Image getImage(String imageKey) throws CoreException {
+ IImageProviderService provider = key2providers.get(imageKey);
+ if( provider != null ) {
+ InputStream stream = provider.getImageData(imageKey);
+ return new Image(display, stream);
+ } else {
+ throw new IllegalArgumentException("There's no image provider known for '"+imageKey+"'.");
+ }
+ }
+
+ public IPooledImage getPooledImage(String imageKey) throws CoreException {
+ PooledImage image = imagePool.get(imageKey);
+
+ if( image != null ) {
+ image.count++;
+
+ } else {
+ image = new PooledImage(this,imageKey,getImage(imageKey));
+ }
+
+ return image;
+ }
+
+ void removePooledImage(PooledImage image) {
+ imagePool.remove(image.imageKey);
+ }
+
+ public IDiposeableImagePool getPool() {
+ return new ImagePool(this);
+ }
+
+ public IImagePool getControlPool(Control control) {
+ final IDiposeableImagePool pool = getPool();
+ control.addDisposeListener(new DisposeListener() {
+
+ public void widgetDisposed(DisposeEvent e) {
+ pool.dispose();
+ }
+ });
+ return pool;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/OSGiUtil.java b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/OSGiUtil.java
new file mode 100644
index 0000000..aa446c0
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.services/src/org/eclipse/e4/demo/simpleide/services/OSGiUtil.java
@@ -0,0 +1,9 @@
+package org.eclipse.e4.demo.simpleide.services;
+
+import org.osgi.framework.FrameworkUtil;
+
+public class OSGiUtil {
+ public static final String getBundleName(Class<?> clazz) {
+ return FrameworkUtil.getBundle(clazz).getSymbolicName();
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/.classpath b/examples/org.eclipse.e4.demo.simpleide.sharedimages/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/.project b/examples/org.eclipse.e4.demo.simpleide.sharedimages/.project
new file mode 100644
index 0000000..593e476
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.simpleide.sharedimages</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide.sharedimages/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..d828ba6
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sun May 23 10:56:46 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide.sharedimages/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..1a3e57a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Sharedimages
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide.sharedimages
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.demo.simpleide.services;bundle-version="1.0.0",
+ org.eclipse.osgi;bundle-version="3.6.0",
+ org.eclipse.core.runtime;bundle-version="3.6.0"
+Service-Component: OSGI-INF/sharedImageProviderService.xml
+Export-Package: org.eclipse.e4.demo.simpleide.sharedimages
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/OSGI-INF/sharedImageProviderService.xml b/examples/org.eclipse.e4.demo.simpleide.sharedimages/OSGI-INF/sharedImageProviderService.xml
new file mode 100644
index 0000000..acdffb4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/OSGI-INF/sharedImageProviderService.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.e4.demo.simpleide.sharedimages.sharedImageProviderService">
+ <implementation class="org.eclipse.e4.demo.simpleide.sharedimages.internal.SharedImageProviderService"/>
+ <service>
+ <provide interface="org.eclipse.e4.demo.simpleide.services.IImageProviderService"/>
+ </service>
+ <property name="imageKey" type="String" value="org.eclipse.e4.demo.simpleide.sharedimages.IMG_ETOOL_HOME_NAV"/>
+ <property name="imageKey" type="String" value="org.eclipse.e4.demo.simpleide.sharedimages.IMG_TOOL_BACK"/>
+ <property name="imageKey" type="String" value="org.eclipse.e4.demo.simpleide.sharedimages.IMG_TOOL_BACK_DISABLED"/>
+ <property name="imageKey" type="String" value="org.eclipse.e4.demo.simpleide.sharedimages.IMG_TOOL_FORWARD"/>
+ <property name="imageKey" type="String" value="org.eclipse.e4.demo.simpleide.sharedimages.IMG_TOOL_FORWARD_DISABLED"/>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/build.properties b/examples/org.eclipse.e4.demo.simpleide.sharedimages/build.properties
new file mode 100644
index 0000000..729ad41
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/build.properties
@@ -0,0 +1,5 @@
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ OSGI-INF/sharedImageProviderService.xml
+source.. = src/
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/backward_nav_disabled.gif b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/backward_nav_disabled.gif
new file mode 100644
index 0000000..2972ff5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/backward_nav_disabled.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/backward_nav_enabled.gif b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/backward_nav_enabled.gif
new file mode 100644
index 0000000..4fb4150
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/backward_nav_enabled.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/forward_nav_disabled.gif b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/forward_nav_disabled.gif
new file mode 100644
index 0000000..319fe8d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/forward_nav_disabled.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/forward_nav_enabled.gif b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/forward_nav_enabled.gif
new file mode 100644
index 0000000..e2f8c3e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/forward_nav_enabled.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/home_nav_enabled.gif b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/home_nav_enabled.gif
new file mode 100644
index 0000000..4472e8c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/icons/home_nav_enabled.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/src/org/eclipse/e4/demo/simpleide/sharedimages/SharedImageKeys.java b/examples/org.eclipse.e4.demo.simpleide.sharedimages/src/org/eclipse/e4/demo/simpleide/sharedimages/SharedImageKeys.java
new file mode 100644
index 0000000..ec5e678
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/src/org/eclipse/e4/demo/simpleide/sharedimages/SharedImageKeys.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.sharedimages;
+
+import org.eclipse.e4.demo.simpleide.sharedimages.internal.SharedImageProviderService;
+
+public class SharedImageKeys {
+ private static final String BUNDLE_ID = SharedImageProviderService.BUNDLE.getSymbolicName();
+
+ /**
+ * Identifies the home image in the enabled state.
+ * @since 3.4
+ */
+ public final static String IMG_TOOL_HOME_NAV = BUNDLE_ID + ".IMG_ETOOL_HOME_NAV"; //$NON-NLS-1$
+
+ /**
+ * Identifies the back image in the enabled state.
+ */
+ public final static String IMG_TOOL_BACK = BUNDLE_ID + ".IMG_TOOL_BACK"; //$NON-NLS-1$
+
+ /**
+ * Identifies the back image in the disabled state.
+ */
+ public final static String IMG_TOOL_BACK_DISABLED = BUNDLE_ID + ".IMG_TOOL_BACK_DISABLED"; //$NON-NLS-1$
+
+ /**
+ * Identifies the forward image in the enabled state.
+ */
+ public final static String IMG_TOOL_FORWARD = BUNDLE_ID + ".IMG_TOOL_FORWARD"; //$NON-NLS-1$
+
+ /**
+ * Identifies the forward image in the disabled state.
+ */
+ public final static String IMG_TOOL_FORWARD_DISABLED = BUNDLE_ID + ".IMG_TOOL_FORWARD_DISABLED"; //$NON-NLS-1$
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide.sharedimages/src/org/eclipse/e4/demo/simpleide/sharedimages/internal/SharedImageProviderService.java b/examples/org.eclipse.e4.demo.simpleide.sharedimages/src/org/eclipse/e4/demo/simpleide/sharedimages/internal/SharedImageProviderService.java
new file mode 100644
index 0000000..c37c89a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide.sharedimages/src/org/eclipse/e4/demo/simpleide/sharedimages/internal/SharedImageProviderService.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.sharedimages.internal;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.e4.demo.simpleide.services.AbstractBundleImageProvider;
+import org.eclipse.e4.demo.simpleide.sharedimages.SharedImageKeys;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+public class SharedImageProviderService extends AbstractBundleImageProvider {
+ public static final Bundle BUNDLE = FrameworkUtil.getBundle(SharedImageKeys.class);
+
+ private static final Map<String, String> IMAGEMAP = Collections.unmodifiableMap(new HashMap<String, String>() {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ {
+ put(SharedImageKeys.IMG_TOOL_HOME_NAV, "/icons/home_nav_enabled.gif");
+ put(SharedImageKeys.IMG_TOOL_BACK, "/icons/backward_nav_enabled.gif");
+ put(SharedImageKeys.IMG_TOOL_BACK_DISABLED, "/icons/backward_nav_disabled.gif");
+ put(SharedImageKeys.IMG_TOOL_FORWARD, "/icons/forward_nav_enabled.gif");
+ put(SharedImageKeys.IMG_TOOL_FORWARD_DISABLED, "/icons/forward_nav_disabled.gif");
+ }
+ });
+
+
+ @Override
+ protected Map<String, String> getImageMap() {
+ return IMAGEMAP;
+ }
+
+ @Override
+ protected Bundle getBundle(String imageKey) {
+ return BUNDLE;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/.classpath b/examples/org.eclipse.e4.demo.simpleide/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.simpleide/.project b/examples/org.eclipse.e4.demo.simpleide/.project
new file mode 100644
index 0000000..7c77748
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.simpleide</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.simpleide/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.simpleide/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..588d23f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,77 @@
+#Mon May 24 23:37:20 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.simpleide/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.simpleide/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..5545bd2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Fri Jun 04 16:06:45 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.simpleide/Application.e4xmi b/examples/org.eclipse.e4.demo.simpleide/Application.e4xmi
new file mode 100644
index 0000000..7975b1c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/Application.e4xmi
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="ASCII"?>
+<simpleide:SimpleIDEApplication xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:advanced="http://www.eclipse.org/ui/2010/UIModel/application/ui/advanced" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmlns:simpleide="http://www.eclipse.org/e4/demo/simpleide" xmi:id="_r5eKcGAYEd-Bb9ra7AA28Q" elementId="app.simpleide" bindingContexts="_ui554GEgEd-A9truh9jvIg">
+ <children xsi:type="basic:TrimmedWindow" xmi:id="_tMEPMGAiEd-E_N65-FXwgA" elementId="simpleide.mainwindow" label="Simple e4 IDE" width="800" height="600">
+ <children xsi:type="advanced:PerspectiveStack" xmi:id="_NpAUQGAmEd-c1dfOhrP7Ww" elementId="">
+ <children xsi:type="advanced:Perspective" xmi:id="_TrpzMGAmEd-c1dfOhrP7Ww" elementId="simpleide.perspective.default" label="Default Perspective" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/application_split.png">
+ <children xsi:type="basic:PartSashContainer" xmi:id="_o38KwGAmEd-c1dfOhrP7Ww" horizontal="true">
+ <children xsi:type="basic:PartStack" xmi:id="_y6yIsGAmEd-c1dfOhrP7Ww" elementId="org.eclipse.e4.primaryNavigationStack">
+ <tags>org.eclipse.e4.primaryNavigationStack</tags>
+ </children>
+ <children xsi:type="basic:PartSashContainer" xmi:id="_2Cm1QGAmEd-c1dfOhrP7Ww">
+ <children xsi:type="basic:PartSashContainer" xmi:id="_3ddpsGAmEd-c1dfOhrP7Ww" horizontal="true">
+ <children xsi:type="basic:PartStack" xmi:id="_8XqS0GAmEd-c1dfOhrP7Ww" elementId="org.eclipse.e4.primaryDataStack">
+ <tags>org.eclipse.e4.primaryDataStack</tags>
+ </children>
+ <children xsi:type="basic:PartStack" xmi:id="_9JVAUGAmEd-c1dfOhrP7Ww" elementId="org.eclipse.e4.secondaryNavigationStack">
+ <tags>org.eclipse.e4.secondaryNavigationStack</tags>
+ </children>
+ </children>
+ <children xsi:type="basic:PartStack" xmi:id="_64QVkGAmEd-c1dfOhrP7Ww" elementId="org.eclipse.e4.secondaryDataStack">
+ <tags>org.eclipse.e4.secondaryDataStack</tags>
+ </children>
+ </children>
+ </children>
+ </children>
+ </children>
+ <variables>outlinepage</variables>
+ <variables>resourceselection</variables>
+ <mainMenu xmi:id="_yobKMGAiEd-E_N65-FXwgA" elementId="simpleide.mainmenu">
+ <children xsi:type="menu:Menu" xmi:id="_0BkucGAiEd-E_N65-FXwgA" elementId="simpleide.mainmenu.file" label="File">
+ <children xsi:type="menu:Menu" xmi:id="_sErgoGAzEd-_KuNHePH0xw" elementId="simpleide.mainmenu.file.new" label="New">
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_hC0PYGHYEd-_Y6o4fctqsw" label="Project ..." iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/newprj_wiz.gif" command="_CWMKAGHYEd-_Y6o4fctqsw"/>
+ <children xsi:type="menu:MenuSeparator" xmi:id="_oqi1wGHYEd-_Y6o4fctqsw"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_pbntYGHYEd-_Y6o4fctqsw" label="Text File ..." iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/newfile_wiz.gif" command="_F3JIQGHYEd-_Y6o4fctqsw"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_wkGzAGHYEd-_Y6o4fctqsw" label="Folder ..." iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/newfolder_wiz.gif" command="_IERuMGHYEd-_Y6o4fctqsw"/>
+ <children xsi:type="menu:MenuSeparator" xmi:id="_5FzuUGHYEd-_Y6o4fctqsw"/>
+ </children>
+ <children xsi:type="menu:MenuSeparator" xmi:id="_NHvfwGEiEd-A9truh9jvIg"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_OxUFoGEiEd-A9truh9jvIg" label="Save All" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/disk_multiple.png" command="_kpAnIGEhEd-A9truh9jvIg"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_mydxgGEiEd-A9truh9jvIg" label="Save" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/disk.png" command="_tl9UAGEhEd-A9truh9jvIg"/>
+ <children xsi:type="menu:MenuSeparator" xmi:id="_ukxQMGEiEd-A9truh9jvIg"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_7kftUGAiEd-E_N65-FXwgA" label="Exit" command="_oIK3gGAiEd-E_N65-FXwgA"/>
+ </children>
+ <children xsi:type="menu:Menu" xmi:id="_WbMXYEjUEd-v7fhjaiz65w" elementId="_WbMXYEjUEd-v7fhjaiz65w" label="Window">
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_UW9TUPr3Ed6gmo7caOx120" elementId="showView" label="Show &View" command="org.eclipse.ui.views.showView"/>
+ </children>
+ </mainMenu>
+ <trimBars xmi:id="_XAea0GGjEd-_qNzu9_D5ug" elementId="">
+ <children xsi:type="menu:ToolBar" xmi:id="_bf9d4GGjEd-_qNzu9_D5ug" elementId="app.simpleide.toolbar">
+ <children xsi:type="menu:HandledToolItem" xmi:id="_dBds4GGjEd-_qNzu9_D5ug" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/disk.png" command="_tl9UAGEhEd-A9truh9jvIg"/>
+ <children xsi:type="menu:HandledToolItem" xmi:id="_ioN6AGGjEd-_qNzu9_D5ug" iconURI="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/disk_multiple.png" command="_kpAnIGEhEd-A9truh9jvIg"/>
+ </children>
+ </trimBars>
+ </children>
+ <variables>org.eclipse.e4.demo.simpleide.services.IImageService</variables>
+ <handlers xmi:id="_jXCDwGAiEd-E_N65-FXwgA" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide/org.eclipse.e4.demo.simpleide.handlers.ExitHandler" command="_oIK3gGAiEd-E_N65-FXwgA"/>
+ <handlers xmi:id="_pj_6cGEhEd-A9truh9jvIg" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide/org.eclipse.e4.demo.simpleide.handlers.SaveAllHandler" command="_kpAnIGEhEd-A9truh9jvIg"/>
+ <handlers xmi:id="_w0lzMGEhEd-A9truh9jvIg" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide/org.eclipse.e4.demo.simpleide.handlers.SaveHandler" command="_tl9UAGEhEd-A9truh9jvIg"/>
+ <handlers xmi:id="_BTglAGHYEd-_Y6o4fctqsw" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide/org.eclipse.e4.demo.simpleide.handlers.NewProjectDialogHandler" command="_CWMKAGHYEd-_Y6o4fctqsw"/>
+ <handlers xmi:id="_T8XWgGHYEd-_Y6o4fctqsw" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide/org.eclipse.e4.demo.simpleide.handlers.NewTextFileDialogHandler" command="_F3JIQGHYEd-_Y6o4fctqsw"/>
+ <handlers xmi:id="_WjZDIGHYEd-_Y6o4fctqsw" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide/org.eclipse.e4.demo.simpleide.handlers.NewFolderDialogHandler" command="_IERuMGHYEd-_Y6o4fctqsw"/>
+ <handlers xmi:id="_eTBRgAFSEd-Z8rQksLwRYx" elementId="org.eclipse.ui.showViewHandler" contributionURI="bundleclass://org.eclipse.e4.ui.workbench.swt/org.eclipse.e4.ui.internal.workbench.swt.handlers.ShowViewHandler" command="org.eclipse.ui.views.showView"/>
+ <handlers xmi:id="_GuF_8GceEd-UeOvBc5sIBQ" contributionURI="bundleclass://org.eclipse.e4.demo.simpleide/org.eclipse.e4.demo.simpleide.handlers.SwitchThemeHandler" command="_VAYokGcYEd-XPd4cWNb-1Q"/>
+ <bindingTables xmi:id="_bFtE4GEhEd-A9truh9jvIg" bindingContext="_ui554GEgEd-A9truh9jvIg">
+ <bindings xmi:id="_fW-s0GEhEd-A9truh9jvIg" keySequence="M1+Q" command="_oIK3gGAiEd-E_N65-FXwgA"/>
+ <bindings xmi:id="_z1SkEGEhEd-A9truh9jvIg" keySequence="M1+M2+S" command="_kpAnIGEhEd-A9truh9jvIg"/>
+ <bindings xmi:id="_AcDQQGEiEd-A9truh9jvIg" keySequence="M1+S" command="_tl9UAGEhEd-A9truh9jvIg"/>
+ <bindings xmi:id="_tDFjkEjPEd-XR8_8rlW1bQ" elementId="_tDFjkEjPEd-XR9_8rlW1bQ" keySequence="CTRL+C" command="org.eclipse.ui.edit.copy"/>
+ </bindingTables>
+ <rootContext xmi:id="_ui554GEgEd-A9truh9jvIg" elementId="org.eclipse.ui.contexts.dialogAndWindow" name="In Dialogs And Windows" description="">
+ <children xmi:id="_LB_JoGEhEd-A9truh9jvIg" elementId="org.eclipse.ui.contexts.window" name="In Windows" description=""/>
+ <children xmi:id="_ULwKgGEhEd-A9truh9jvIg" elementId="org.eclipse.ui.contexts.dialog" name="In Dialogs" description=""/>
+ </rootContext>
+ <commands xmi:id="_oIK3gGAiEd-E_N65-FXwgA" elementId="simpleide.command.exit" commandName="Exit IDE"/>
+ <commands xmi:id="_kpAnIGEhEd-A9truh9jvIg" elementId="simpleide.command.saveall" commandName="Save All"/>
+ <commands xmi:id="_tl9UAGEhEd-A9truh9jvIg" elementId="simpleide.command.save" commandName="Save"/>
+ <commands xmi:id="_CWMKAGHYEd-_Y6o4fctqsw" elementId="simpleide.command.newproject" commandName="New Project Command"/>
+ <commands xmi:id="_F3JIQGHYEd-_Y6o4fctqsw" elementId="simpleide.command.newtxtfile" commandName="New Text File Command"/>
+ <commands xmi:id="_IERuMGHYEd-_Y6o4fctqsw" elementId="simpleide.command.newfolder" commandName="New Folder Command"/>
+ <commands xmi:id="org.eclipse.ui.views.showView" elementId="org.eclipse.ui.views.showView" commandName="Show View">
+ <parameters xmi:id="_oRr6EAFSEd-Z8rQksLwRYy" elementId="org.eclipse.ui.views.showView.viewId" name="View"/>
+ </commands>
+ <commands xmi:id="org.eclipse.ui.edit.copy" elementId="org.eclipse.ui.edit.copy" commandName="Copy"/>
+ <commands xmi:id="_VAYokGcYEd-XPd4cWNb-1Q" elementId="simpleide.command.switchtheme" commandName="Switch Theme">
+ <parameters xmi:id="_jQ1PYGcYEd-XPd4cWNb-1Q" elementId="simpleide.command.switchtheme.themeid" name="Theme Id" typeId="" optional="false"/>
+ </commands>
+ <addons xmi:id="_XGB3wPZlEd-XstlTZ6nTXg" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/>
+ <addons xmi:id="_XGB3wPZlEd-XstlTZ6nTXh" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/>
+ <addons xmi:id="_XGB3wPZlEd-XstlTZ6nTXi" elementId="org.eclipse.e4.ui.bindings.service" contributionURI="bundleclass://org.eclipse.e4.ui.bindings/org.eclipse.e4.ui.bindings.BindingServiceAddon"/>
+ <addons xmi:id="_LK0NgPZmEd-XstlTZ6nTXj" elementId="org.eclipse.e4.ui.workbench.commands.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.CommandProcessingAddon"/>
+ <addons xmi:id="_LK0NgPZmEd-XstlTZ6nTXk" elementId="org.eclipse.e4.ui.workbench.contexts.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.ContextProcessingAddon"/>
+ <addons xmi:id="_LK0NgPZmEd-XstlTZ6nTXl" elementId="org.eclipse.e4.ui.workbench.bindings.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench.swt/org.eclipse.e4.ui.workbench.swt.util.BindingProcessingAddon"/>
+</simpleide:SimpleIDEApplication>
diff --git a/examples/org.eclipse.e4.demo.simpleide/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.simpleide/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..d23c687
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/META-INF/MANIFEST.MF
@@ -0,0 +1,26 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Simpleide
+Bundle-SymbolicName: org.eclipse.e4.demo.simpleide;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.ui.workbench.swt;bundle-version="0.9.1",
+ org.eclipse.equinox.app;bundle-version="1.3.0",
+ org.eclipse.e4.ui.css.swt.theme;bundle-version="0.9.0",
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.e4.ui.workbench;bundle-version="0.9.1",
+ org.eclipse.e4.demo.simpleide.model;bundle-version="1.0.0",
+ org.eclipse.core.resources;bundle-version="3.6.0",
+ org.eclipse.equinox.common;bundle-version="3.6.0",
+ org.eclipse.e4.ui.services;bundle-version="0.9.1",
+ org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.core.jobs;bundle-version="3.5.0",
+ org.eclipse.e4.demo.simpleide.services;bundle-version="1.0.0",
+ org.eclipse.osgi;bundle-version="3.6.0",
+ org.eclipse.core.runtime;bundle-version="3.6.0",
+ org.eclipse.core.filesystem;bundle-version="1.3.0",
+ org.eclipse.e4.core.services;bundle-version="0.9.1",
+ org.eclipse.e4.core.contexts;bundle-version="0.9.0"
+Service-Component: OSGI-INF/serviceRegistryComponent.xml, OSGI-INF/defaultProjectService.xml, OSGI-INF/eclipseProjectImporterService.xml, OSGI-INF/imageServiceFunction.xml, OSGI-INF/nlsLookupFactoryService.xml
+Bundle-ActivationPolicy: lazy
+Import-Package: javax.inject;version="1.0.0"
diff --git a/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/defaultProjectService.xml b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/defaultProjectService.xml
new file mode 100644
index 0000000..c7bd13d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/defaultProjectService.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.eclipse.e4.demo.simpleide.defaultcreator">
+ <implementation class="org.eclipse.e4.demo.simpleide.internal.DefaultProjectService"/>
+ <service>
+ <provide interface="org.eclipse.e4.demo.simpleide.services.IProjectService"/>
+ </service>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/eclipseProjectImporterService.xml b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/eclipseProjectImporterService.xml
new file mode 100644
index 0000000..22b57ca
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/eclipseProjectImporterService.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.e4.demo.simpleide.eclipseProjectImporterService">
+ <implementation class="org.eclipse.e4.demo.simpleide.internal.EclipseProjectImportService"/>
+ <service>
+ <provide interface="org.eclipse.e4.demo.simpleide.services.IImportResourceService"/>
+ </service>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/imageServiceFunction.xml b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/imageServiceFunction.xml
new file mode 100644
index 0000000..e3bb17b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/imageServiceFunction.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.e4.demo.simpleide.imageServiceFunction">
+ <implementation class="org.eclipse.e4.demo.simpleide.internal.ImageServiceFunction"/>
+ <service>
+ <provide interface="org.eclipse.e4.core.contexts.IContextFunction"/>
+ </service>
+ <property name="service.context.key" type="String" value="org.eclipse.e4.demo.simpleide.services.IImageService"/>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/nlsLookupFactoryService.xml b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/nlsLookupFactoryService.xml
new file mode 100644
index 0000000..29eac63
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/nlsLookupFactoryService.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.e4.demo.simpleide.nlsLookupFactoryService">
+ <implementation class="org.eclipse.e4.demo.simpleide.internal.NLSLookupFactoryServiceImpl"/>
+ <service>
+ <provide interface="org.eclipse.e4.demo.simpleide.services.INLSLookupFactoryService"/>
+ </service>
+ <reference bind="addTranslationService" cardinality="0..n" interface="org.eclipse.e4.demo.simpleide.services.INLSLookupFactoryService$ITranslationService" name="INLSLookupFactoryService$ITranslationService" policy="dynamic" unbind="removeTranslationService"/>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/serviceRegistryComponent.xml b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/serviceRegistryComponent.xml
new file mode 100644
index 0000000..5d2a026
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/OSGI-INF/serviceRegistryComponent.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="false" name="org.eclipse.e4.demo.simpleide.projectCreatorComponent">
+ <implementation class="org.eclipse.e4.demo.simpleide.internal.ServiceRegistryComponent"/>
+ <service>
+ <provide interface="org.eclipse.e4.demo.simpleide.internal.ServiceRegistryComponent"/>
+ </service>
+ <reference bind="addProjectService" cardinality="0..n" interface="org.eclipse.e4.demo.simpleide.services.IProjectService" name="IProjectService" policy="dynamic" unbind="removeProjectService"/>
+</scr:component>
diff --git a/examples/org.eclipse.e4.demo.simpleide/SimpleIDE.product b/examples/org.eclipse.e4.demo.simpleide/SimpleIDE.product
new file mode 100644
index 0000000..a7a1d4d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/SimpleIDE.product
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?pde version="3.5"?>
+
+<product name="SimpleIDE" id="org.eclipse.e4.demo.simpleide.product" application="org.eclipse.e4.ui.workbench.swt.E4Application" useFeatures="false" includeLaunchers="true">
+
+ <configIni use="default">
+ </configIni>
+
+ <launcherArgs>
+ <vmArgsMac>-XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts</vmArgsMac>
+ </launcherArgs>
+
+ <plugins>
+ <plugin id="com.ibm.icu"/>
+ <plugin id="javax.annotation"/>
+ <plugin id="javax.inject"/>
+ <plugin id="org.apache.batik.css"/>
+ <plugin id="org.apache.batik.util"/>
+ <plugin id="org.apache.batik.util.gui"/>
+ <plugin id="org.apache.commons.beanutils" fragment=""/>
+ <plugin id="org.apache.commons.logging"/>
+ <plugin id="org.eclipse.core.commands"/>
+ <plugin id="org.eclipse.core.contenttype"/>
+ <plugin id="org.eclipse.core.databinding"/>
+ <plugin id="org.eclipse.core.databinding.observable"/>
+ <plugin id="org.eclipse.core.databinding.property"/>
+ <plugin id="org.eclipse.core.expressions"/>
+ <plugin id="org.eclipse.core.filesystem"/>
+ <plugin id="org.eclipse.core.filesystem.linux.x86" fragment="true"/>
+ <plugin id="org.eclipse.core.filesystem.macosx" fragment="true"/>
+ <plugin id="org.eclipse.core.jobs"/>
+ <plugin id="org.eclipse.core.resources"/>
+ <plugin id="org.eclipse.core.runtime"/>
+ <plugin id="org.eclipse.core.runtime.compatibility.registry" fragment="true"/>
+ <plugin id="org.eclipse.e4.core.commands"/>
+ <plugin id="org.eclipse.e4.core.contexts"/>
+ <plugin id="org.eclipse.e4.core.di"/>
+ <plugin id="org.eclipse.e4.core.di.extensions"/>
+ <plugin id="org.eclipse.e4.core.services"/>
+ <plugin id="org.eclipse.e4.demo.simpleide"/>
+ <plugin id="org.eclipse.e4.demo.simpleide.e4editor"/>
+ <plugin id="org.eclipse.e4.demo.simpleide.editor"/>
+ <plugin id="org.eclipse.e4.demo.simpleide.editor.text"/>
+ <plugin id="org.eclipse.e4.demo.simpleide.iconview"/>
+ <plugin id="org.eclipse.e4.demo.simpleide.jdt"/>
+ <plugin id="org.eclipse.e4.demo.simpleide.model"/>
+ <plugin id="org.eclipse.e4.demo.simpleide.navigator"/>
+ <plugin id="org.eclipse.e4.demo.simpleide.outline"/>
+ <plugin id="org.eclipse.e4.demo.simpleide.services"/>
+ <plugin id="org.eclipse.e4.demo.tools.simpleide"/>
+ <plugin id="org.eclipse.e4.tools.emf.ui"/>
+ <plugin id="org.eclipse.e4.ui.bindings"/>
+ <plugin id="org.eclipse.e4.ui.css.core"/>
+ <plugin id="org.eclipse.e4.ui.css.swt"/>
+ <plugin id="org.eclipse.e4.ui.css.swt.theme"/>
+ <plugin id="org.eclipse.e4.ui.di"/>
+ <plugin id="org.eclipse.e4.ui.model.workbench"/>
+ <plugin id="org.eclipse.e4.ui.model.workbench.edit"/>
+ <plugin id="org.eclipse.e4.ui.services"/>
+ <plugin id="org.eclipse.e4.ui.workbench"/>
+ <plugin id="org.eclipse.e4.ui.workbench.renderers.swt"/>
+ <plugin id="org.eclipse.e4.ui.workbench.swt"/>
+ <plugin id="org.eclipse.e4.ui.workbench3"/>
+ <plugin id="org.eclipse.emf.common"/>
+ <plugin id="org.eclipse.emf.databinding"/>
+ <plugin id="org.eclipse.emf.databinding.edit"/>
+ <plugin id="org.eclipse.emf.ecore"/>
+ <plugin id="org.eclipse.emf.ecore.change"/>
+ <plugin id="org.eclipse.emf.ecore.xmi"/>
+ <plugin id="org.eclipse.emf.edit"/>
+ <plugin id="org.eclipse.equinox.app"/>
+ <plugin id="org.eclipse.equinox.common"/>
+ <plugin id="org.eclipse.equinox.concurrent"/>
+ <plugin id="org.eclipse.equinox.ds"/>
+ <plugin id="org.eclipse.equinox.event"/>
+ <plugin id="org.eclipse.equinox.preferences"/>
+ <plugin id="org.eclipse.equinox.registry"/>
+ <plugin id="org.eclipse.equinox.util"/>
+ <plugin id="org.eclipse.jdt.compiler.apt" fragment="true"/>
+ <plugin id="org.eclipse.jdt.compiler.tool" fragment="true"/>
+ <plugin id="org.eclipse.jdt.core"/>
+ <plugin id="org.eclipse.jface"/>
+ <plugin id="org.eclipse.jface.databinding"/>
+ <plugin id="org.eclipse.jface.text"/>
+ <plugin id="org.eclipse.nebula.widgets.gallery"/>
+ <plugin id="org.eclipse.osgi"/>
+ <plugin id="org.eclipse.osgi.services"/>
+ <plugin id="org.eclipse.swt"/>
+ <plugin id="org.eclipse.swt.cocoa.macosx.x86_64" fragment="true"/>
+ <plugin id="org.eclipse.swt.gtk.linux.x86" fragment="true"/>
+ <plugin id="org.eclipse.text"/>
+ <plugin id="org.w3c.css.sac"/>
+ <plugin id="org.w3c.dom.smil"/>
+ <plugin id="org.w3c.dom.svg"/>
+ </plugins>
+
+
+</product>
diff --git a/examples/org.eclipse.e4.demo.simpleide/build.properties b/examples/org.eclipse.e4.demo.simpleide/build.properties
new file mode 100644
index 0000000..f9ec2aa
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/build.properties
@@ -0,0 +1,11 @@
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ Application.e4xmi,\
+ css/,\
+ icons/,\
+ OSGI-INF/,\
+ OSGI-INF/imageServiceFunction.xml,\
+ OSGI-INF/nlsLookupFactoryService.xml
+source.. = src/
diff --git a/examples/org.eclipse.e4.demo.simpleide/css/e4_default.css b/examples/org.eclipse.e4.demo.simpleide/css/e4_default.css
new file mode 100644
index 0000000..839cf31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/css/e4_default.css
@@ -0,0 +1,28 @@
+
+.MWindow {
+ background-color: #EEF2F7 #DEEBF3 100%;
+}
+
+.MTrimmedWindow {
+ margin-top: 12px;
+ margin-bottom: 2px;
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+.MPartStack {
+ tab-renderer: url('bundleclass://org.eclipse.e4.ui.workbench.renderers.swt/org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering');
+ unselected-tabs-color: #FFFFFF #FFFFFF #FFFFFF 100% 100%;
+ outer-keyline-color: #FFFFFF;
+ inner-keyline-color: #FFFFFF;
+}
+
+.MTrimBar {
+ background-image: url(./winXPBlue.PNG);
+}
+
+.MPartStack.active {
+ unselected-tabs-color: #CEDEF4 #D2E2F9 #FFFFFF 100% 100%;
+ outer-keyline-color: #C3D0E9;
+ inner-keyline-color: #FFFFFF;
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/css/e4_default_gtk.css b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_gtk.css
new file mode 100644
index 0000000..d54b392
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_gtk.css
@@ -0,0 +1,25 @@
+
+.MTrimmedWindow {
+ background-color: #E2E2E2;
+ margin-top: 12px;
+ margin-bottom: 2px;
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+.MPartStack {
+ tab-renderer: url('bundleclass://org.eclipse.e4.ui.workbench.renderers.swt/org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering');
+ unselected-tabs-color: #FFFFFF #FFFFFF #FFFFFF 100% 100%;
+ outer-keyline-color: #FFFFFF;
+ inner-keyline-color: #FFFFFF;
+}
+
+.MTrimBar {
+ background-image: url(./gtkGrey.PNG);
+}
+
+.MPartStack.active {
+ unselected-tabs-color: #DCDCDC #E1E1E1 #FFFFFF 100% 100%;
+ outer-keyline-color: #C4C5C1;
+ inner-keyline-color: #FFFFFF;
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/css/e4_default_mac.css b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_mac.css
new file mode 100644
index 0000000..dbc7c7f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_mac.css
@@ -0,0 +1,25 @@
+
+.MTrimmedWindow {
+ background-color: #F0F0F0 #E5E5E5 100%;
+ margin-top: 12px;
+ margin-bottom: 2px;
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+.MPartStack {
+ tab-renderer: url('bundleclass://org.eclipse.e4.ui.workbench.renderers.swt/org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering');
+ unselected-tabs-color: #FFFFFF #FFFFFF #FFFFFF 100% 100%;
+ outer-keyline-color: #FFFFFF;
+ inner-keyline-color: #FFFFFF;
+}
+
+.MTrimBar {
+ background-image: url(./macGrey.PNG);
+}
+
+.MPartStack.active {
+ unselected-tabs-color: #E2E2E2 #EBEBEC #FFFFFF 100% 100%;
+ outer-keyline-color: #C4C5C1;
+ inner-keyline-color: #FFFFFF;
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/css/e4_default_win7.css b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_win7.css
new file mode 100644
index 0000000..7ebcb1d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_win7.css
@@ -0,0 +1,25 @@
+
+.MTrimmedWindow {
+ background-color: #E6EAF7;
+ margin-top: 12px;
+ margin-bottom: 2px;
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+.MPartStack {
+ tab-renderer: url('bundleclass://org.eclipse.e4.ui.workbench.renderers.swt/org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering');
+ unselected-tabs-color: #FFFFFF #FFFFFF #FFFFFF 100% 100%;
+ outer-keyline-color: #FFFFFF;
+ inner-keyline-color: #FFFFFF;
+}
+
+.MTrimBar {
+ background-image: url(./win7.PNG);
+}
+
+.MPartStack.active {
+ unselected-tabs-color: #F3F9ff #D0DFEE #CEDDED #D2E1F0 #FFFFFF 30% 50% 100% 100%;
+ outer-keyline-color: #C4C5C1;
+ inner-keyline-color: #FFFFFF;
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/css/e4_default_winxp_blu.css b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_winxp_blu.css
new file mode 100644
index 0000000..161b355
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_winxp_blu.css
@@ -0,0 +1,24 @@
+
+.MTrimmedWindow {
+ margin-top: 12px;
+ margin-bottom: 2px;
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+.MPartStack {
+ tab-renderer: url('bundleclass://org.eclipse.e4.ui.workbench.renderers.swt/org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering');
+ unselected-tabs-color: #FFFFFF #FFFFFF #FFFFFF 100% 100%;
+ outer-keyline-color: #FFFFFF;
+ inner-keyline-color: #FFFFFF;
+}
+
+.MTrimBar {
+ background-image: url(./winXPBlue.PNG);
+}
+
+.MPartStack.active {
+ unselected-tabs-color: #CEDEF4 #D2E2F9 #FFFFFF 100% 100%;
+ outer-keyline-color: #C3D0E9;
+ inner-keyline-color: #FFFFFF;
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/css/e4_default_winxp_olv.css b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_winxp_olv.css
new file mode 100644
index 0000000..7b67f9e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/css/e4_default_winxp_olv.css
@@ -0,0 +1,25 @@
+
+
+.MTrimmedWindow {
+ margin-top: 12px;
+ margin-bottom: 2px;
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+.MPartStack {
+ tab-renderer: url('bundleclass://org.eclipse.e4.ui.workbench.renderers.swt/org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering');
+ unselected-tabs-color: #FFFFFF #FFFFFF #FFFFFF 100% 100%;
+ outer-keyline-color: #FFFFFF;
+ inner-keyline-color: #FFFFFF;
+}
+
+.MTrimBar {
+ background-image: url(./winXPOlive.PNG);
+}
+
+.MPartStack.active {
+ unselected-tabs-color: #E6E3C3 #EDEACA #FFFFFF 100% 100%;
+ outer-keyline-color: #BFCDA4;
+ inner-keyline-color: #FFFFFF;
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/application_split.png b/examples/org.eclipse.e4.demo.simpleide/icons/application_split.png
new file mode 100644
index 0000000..a91c78a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/application_split.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/css/gtkGrey.PNG b/examples/org.eclipse.e4.demo.simpleide/icons/css/gtkGrey.PNG
new file mode 100644
index 0000000..c559dbb
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/css/gtkGrey.PNG
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/css/macGrey.PNG b/examples/org.eclipse.e4.demo.simpleide/icons/css/macGrey.PNG
new file mode 100644
index 0000000..59075ad
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/css/macGrey.PNG
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/css/win7.PNG b/examples/org.eclipse.e4.demo.simpleide/icons/css/win7.PNG
new file mode 100644
index 0000000..e0f8910
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/css/win7.PNG
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/css/winXPBlue.PNG b/examples/org.eclipse.e4.demo.simpleide/icons/css/winXPBlue.PNG
new file mode 100644
index 0000000..57e94e5
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/css/winXPBlue.PNG
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/css/winXPOlive.PNG b/examples/org.eclipse.e4.demo.simpleide/icons/css/winXPOlive.PNG
new file mode 100644
index 0000000..c745ee1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/css/winXPOlive.PNG
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/disk.png b/examples/org.eclipse.e4.demo.simpleide/icons/disk.png
new file mode 100644
index 0000000..99d532e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/disk.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/disk_multiple.png b/examples/org.eclipse.e4.demo.simpleide/icons/disk_multiple.png
new file mode 100644
index 0000000..fc5a52f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/disk_multiple.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/newfile_wiz.gif b/examples/org.eclipse.e4.demo.simpleide/icons/newfile_wiz.gif
new file mode 100644
index 0000000..9d05088
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/newfile_wiz.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/newfolder_wiz.gif b/examples/org.eclipse.e4.demo.simpleide/icons/newfolder_wiz.gif
new file mode 100644
index 0000000..310eb18
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/newfolder_wiz.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/newprj_wiz.gif b/examples/org.eclipse.e4.demo.simpleide/icons/newprj_wiz.gif
new file mode 100644
index 0000000..fbbac0f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/newprj_wiz.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/wizard/newfolder_wiz.png b/examples/org.eclipse.e4.demo.simpleide/icons/wizard/newfolder_wiz.png
new file mode 100644
index 0000000..f4861b1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/wizard/newfolder_wiz.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/icons/wizard/newprj_wiz.png b/examples/org.eclipse.e4.demo.simpleide/icons/wizard/newprj_wiz.png
new file mode 100644
index 0000000..fdff016
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/icons/wizard/newprj_wiz.png
Binary files differ
diff --git a/examples/org.eclipse.e4.demo.simpleide/plugin.xml b/examples/org.eclipse.e4.demo.simpleide/plugin.xml
new file mode 100644
index 0000000..90933fd
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/plugin.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.e4.ui.css.swt.theme">
+ <theme
+ basestylesheeturi="css/e4_default.css"
+ id="org.eclipse.e4.demo.simpleide.theme"
+ label="Default Theme">
+ </theme>
+ <theme
+ basestylesheeturi="css/e4_default_gtk.css"
+ id="org.eclipse.e4.demo.simpleide.theme.gtk"
+ label="GTK Theme">
+ </theme>
+ <theme
+ basestylesheeturi="css/e4_default_mac.css"
+ id="org.eclipse.e4.demo.simpleide.theme.mac"
+ label="Mac Theme">
+ </theme>
+ <theme
+ basestylesheeturi="css/e4_default_win7.css"
+ id="org.eclipse.e4.demo.simpleide.theme.win7"
+ label="Win7 Theme">
+ </theme>
+ <theme
+ basestylesheeturi="css/e4_default_winxp_blu.css"
+ id="org.eclipse.e4.demo.simpleide.theme.winxp.blu"
+ label="WinXP Blue Theme">
+ </theme>
+ <theme
+ basestylesheeturi="css/e4_default_winxp_olv.css"
+ id="org.eclipse.e4.demo.simpleide.theme.winxp.olv"
+ label="WinXP Olive Theme">
+ </theme>
+ </extension>
+ <extension
+ id="product"
+ point="org.eclipse.core.runtime.products">
+ <product
+ application="org.eclipse.e4.ui.workbench.swt.E4Application"
+ name="SimpleIDE">
+ <property
+ name="appName"
+ value="SimpleIDE">
+ </property>
+ <property
+ name="applicationXMI"
+ value="org.eclipse.e4.demo.simpleide/Application.e4xmi">
+ </property>
+ <property
+ name="cssTheme"
+ value="org.eclipse.e4.demo.simpleide.theme">
+ </property>
+ <property
+ name="applicationCSSResources"
+ value="platform:/plugin/org.eclipse.e4.demo.simpleide/icons/css/">
+ </property>
+ </product>
+ </extension>
+ <extension
+ id="id1"
+ point="org.eclipse.e4.workbench.model">
+ <processor
+ beforefragment="true"
+ class="org.eclipse.e4.demo.simpleide.internal.ThemeMenuProcessor">
+ <element
+ id="simpleide.mainmenu">
+ </element>
+ </processor>
+ </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/ExitHandler.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/ExitHandler.java
new file mode 100644
index 0000000..eb05262
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/ExitHandler.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.handlers;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.workbench.IPresentationEngine;
+
+public class ExitHandler {
+ @Execute
+ public void exitWorkbench(IPresentationEngine engine) {
+ engine.stop();
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/Messages.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/Messages.java
new file mode 100644
index 0000000..345ef3c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/Messages.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.handlers;
+
+public interface Messages {
+ public String NewFolderDialogHandler_ParentFolder();
+
+ public String NewFolderDialogHandler_FolderName();
+
+ public String NewFolderDialogHandler_ShellTitle();
+
+ public String NewFolderDialogHandler_Title();
+
+ public String NewFolderDialogHandler_Message();
+
+ public String NewFolderDialogHandler_ErrorSelectAParentFolder();
+
+ public String NewFolderDialogHandler_ErrorEnterFolderName();
+
+ public String NewFolderDialogHandler_ErrorFolderCreation();
+
+ public String NewProjectDialogHandler_ShellTitle();
+
+ public String NewProjectDialogHandler_Title();
+
+ public String NewProjectDialogHandler_Message();
+
+ public String NewProjectDialogHandler_Name();
+
+ public String NewProjectDialogHandler_Type();
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/Messages.properties b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/Messages.properties
new file mode 100644
index 0000000..c1ba692
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/Messages.properties
@@ -0,0 +1,14 @@
+NewFolderDialogHandler_ParentFolder=Parent Folder
+NewFolderDialogHandler_FolderName=Folder name
+NewFolderDialogHandler_ShellTitle=New Folder
+NewFolderDialogHandler_Title=Folder
+NewFolderDialogHandler_Message=Create a new folder resource.
+NewFolderDialogHandler_ErrorSelectAParentFolder=Select a parent folder
+NewFolderDialogHandler_ErrorEnterFolderName=Enter a folder name
+
+NewProjectDialogHandler_ShellTitle=New Project
+NewProjectDialogHandler_Title=Project
+NewProjectDialogHandler_Message=Create a new project resource.
+NewProjectDialogHandler_Name=Name
+NewProjectDialogHandler_Type=Type
+NewFolderDialogHandler_ErrorFolderCreation=Failed to create folder
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewFolderDialogHandler.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewFolderDialogHandler.java
new file mode 100644
index 0000000..a14a261
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewFolderDialogHandler.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.handlers;
+
+import javax.inject.Named;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.demo.simpleide.services.INLSLookupFactoryService;
+import org.eclipse.e4.demo.simpleide.ui.ResourceViewerControl;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public class NewFolderDialogHandler {
+
+ @Execute
+ public void openNewTextFileDialog(
+ @Named(IServiceConstants.ACTIVE_SHELL) Shell parentShell,
+ @Optional @Named(IServiceConstants.SELECTION) final IResource resource,
+ final IWorkspace workspace, IProgressMonitor monitor,
+ final Logger logger, final INLSLookupFactoryService nlsFactory) {
+
+ TitleAreaDialog dialog = new TitleAreaDialog(parentShell) {
+ private ResourceViewerControl viewer;
+ private Text text;
+ private Messages messages = nlsFactory
+ .createNLSLookup(Messages.class);
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+
+ getShell()
+ .setText(messages.NewFolderDialogHandler_ShellTitle());
+ setTitle(messages.NewFolderDialogHandler_Title());
+ setMessage(messages.NewFolderDialogHandler_Message());
+
+ Composite comp = (Composite) super.createDialogArea(parent);
+ Composite container = new Composite(comp, SWT.NONE);
+ container.setLayoutData(new GridData(GridData.FILL_BOTH));
+ container.setLayout(new GridLayout(2, false));
+
+ Label label = new Label(container, SWT.NONE);
+ label.setLayoutData(new GridData(
+ GridData.VERTICAL_ALIGN_BEGINNING));
+ label.setText(messages.NewFolderDialogHandler_ParentFolder());
+
+ viewer = new ResourceViewerControl(container, SWT.NONE,
+ workspace, resource);
+ viewer.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ label = new Label(container, SWT.NONE);
+ label.setText(messages.NewFolderDialogHandler_FolderName());
+
+ text = new Text(container, SWT.BORDER);
+ text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ return comp;
+ }
+
+ @Override
+ protected void okPressed() {
+ IResource resource = viewer.getResource();
+ if (resource == null) {
+ setMessage(
+ messages.NewFolderDialogHandler_ErrorSelectAParentFolder(),
+ IMessageProvider.ERROR);
+ return;
+ }
+
+ if (text.getText().trim().length() == 0) {
+ setMessage(
+ messages.NewFolderDialogHandler_ErrorEnterFolderName(),
+ IMessageProvider.ERROR);
+ return;
+ }
+
+ IPath newFolderPath = resource.getFullPath().append(
+ text.getText());
+ IFolder folder = workspace.getRoot().getFolder(newFolderPath);
+ try {
+ folder.create(false, true, null);
+ super.okPressed();
+ } catch (CoreException e) {
+ logger.error(e);
+ setMessage(messages.NewFolderDialogHandler_ErrorFolderCreation(), IMessageProvider.ERROR);
+ }
+ }
+ };
+
+ dialog.open();
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewProjectDialogHandler.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewProjectDialogHandler.java
new file mode 100644
index 0000000..213f820
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewProjectDialogHandler.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.handlers;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+import javax.inject.Named;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.core.services.statusreporter.StatusReporter;
+import org.eclipse.e4.demo.simpleide.internal.ServiceRegistryComponent;
+import org.eclipse.e4.demo.simpleide.services.INLSLookupFactoryService;
+import org.eclipse.e4.demo.simpleide.services.IProjectService;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public class NewProjectDialogHandler {
+ private Map<IProjectService, Image> images = new HashMap<IProjectService, Image>();
+ private String projectName = ""; //$NON-NLS-1$
+ private IProjectService creator;
+
+ @Execute
+ public void openNewProjectDialog(
+ @Named(IServiceConstants.ACTIVE_SHELL) Shell parentShell,
+ IWorkspace workspace, IProgressMonitor monitor,
+ final ServiceRegistryComponent serviceRegistry,
+ StatusReporter reporter, Logger logger,
+ final INLSLookupFactoryService nlsFactory) {
+
+ TitleAreaDialog dialog = new TitleAreaDialog(parentShell) {
+ private Text projectName;
+ private TableViewer projectType;
+ private Messages messages = nlsFactory
+ .createNLSLookup(Messages.class);
+
+ @Override
+ protected int getShellStyle() {
+ return super.getShellStyle() | SWT.SHEET;
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite comp = (Composite) super.createDialogArea(parent);
+ getShell().setText(messages.NewProjectDialogHandler_ShellTitle());
+ setTitle(messages.NewProjectDialogHandler_Title());
+ setMessage(messages.NewProjectDialogHandler_Message());
+
+ final Image titleImage = new Image(parent.getDisplay(),
+ getClass().getClassLoader().getResourceAsStream(
+ "/icons/wizard/newprj_wiz.png"));
+
+ setTitleImage(titleImage);
+
+ final Image shellImg = new Image(parent.getDisplay(),
+ getClass().getClassLoader().getResourceAsStream(
+ "/icons/newprj_wiz.gif"));
+ getShell().setImage(shellImg);
+ getShell().addDisposeListener(new DisposeListener() {
+
+ public void widgetDisposed(DisposeEvent e) {
+ shellImg.dispose();
+ titleImage.dispose();
+ }
+ });
+
+ Composite container = new Composite(comp, SWT.NONE);
+ container.setLayoutData(new GridData(GridData.FILL_BOTH));
+ container.setLayout(new GridLayout(2, false));
+
+ Label l = new Label(container, SWT.NONE);
+ l.setText(messages.NewProjectDialogHandler_Name());
+
+ projectName = new Text(container, SWT.BORDER);
+ projectName
+ .setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ l = new Label(container, SWT.NONE);
+ l.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
+ l.setText(messages.NewProjectDialogHandler_Type());
+
+ projectType = new TableViewer(container);
+ projectType.setContentProvider(new ArrayContentProvider());
+ projectType.setLabelProvider(new LabelProvider() {
+ @Override
+ public String getText(Object element) {
+ IProjectService el = (IProjectService) element;
+ return el.getLabel();
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ IProjectService el = (IProjectService) element;
+ Image img = images.get(el);
+ if (img == null) {
+ URL url;
+ InputStream in = null;
+ try {
+ url = FileLocator.find(new URL(el.getIconURI()));
+ in = url.openStream();
+ img = new Image(getShell().getDisplay(), in);
+ images.put(el, img);
+ } catch (MalformedURLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+ return img;
+ }
+ });
+
+ Vector<IProjectService> creators = serviceRegistry
+ .getCreators();
+ projectType.setInput(creators);
+ if (creators.size() > 0) {
+ projectType.setSelection(new StructuredSelection(creators
+ .get(0)));
+ }
+ projectType.getControl().setLayoutData(
+ new GridData(GridData.FILL_BOTH));
+
+ getShell().addDisposeListener(new DisposeListener() {
+
+ public void widgetDisposed(DisposeEvent e) {
+ for (Image img : images.values()) {
+ img.dispose();
+ }
+ images.clear();
+ }
+ });
+
+ return comp;
+ }
+
+ @Override
+ protected void okPressed() {
+ if (projectType.getSelection().isEmpty()) {
+ setMessage("Please select a project type",
+ IMessageProvider.ERROR);
+ return;
+ }
+
+ if (projectName.getText().trim().length() == 0) {
+ setMessage("Please enter a projectname",
+ IMessageProvider.ERROR);
+ return;
+ }
+
+ NewProjectDialogHandler.this.creator = (IProjectService) ((IStructuredSelection) projectType
+ .getSelection()).getFirstElement();
+ NewProjectDialogHandler.this.projectName = projectName
+ .getText();
+
+ super.okPressed();
+ }
+ };
+
+ if (dialog.open() == IDialogConstants.OK_ID) {
+ creator.createProject(parentShell, workspace, reporter, logger,
+ monitor, projectName);
+ }
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewTextFileDialogHandler.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewTextFileDialogHandler.java
new file mode 100644
index 0000000..e456f24
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/NewTextFileDialogHandler.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.handlers;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import javax.inject.Named;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.core.di.annotations.Optional;
+import org.eclipse.e4.demo.simpleide.ui.ResourceViewerControl;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public class NewTextFileDialogHandler {
+ private IContainer parentContainer;
+ private String name;
+
+ @Execute
+ public void openNewTextFileDialog(
+ @Named(IServiceConstants.ACTIVE_SHELL) Shell parentShell,
+ @Optional @Named(IServiceConstants.SELECTION) final IResource resource,
+ final IWorkspace workspace,
+ IProgressMonitor monitor) {
+
+ TitleAreaDialog dialog = new TitleAreaDialog(parentShell) {
+ private ResourceViewerControl viewer;
+ private Text text;
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite comp = (Composite) super.createDialogArea(parent);
+ Composite container = new Composite(comp,SWT.NONE);
+ container.setLayoutData(new GridData(GridData.FILL_BOTH));
+ container.setLayout(new GridLayout(2,false));
+
+ Label label = new Label(container, SWT.NONE);
+ label.setText("Folder");
+
+ viewer = new ResourceViewerControl(container, SWT.NONE, workspace, resource);
+ viewer.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ label = new Label(container, SWT.NONE);
+ label.setText("File name");
+
+ text = new Text(container, SWT.BORDER);
+ text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ return comp;
+ }
+
+ @Override
+ protected void okPressed() {
+ IResource resource = viewer.getResource();
+ if( resource == null ) {
+ setMessage("Select a parent folder", IMessageProvider.ERROR);
+ return;
+ }
+
+ if( text.getText().trim().length() == 0 ) {
+ setMessage("Enter a folder name", IMessageProvider.ERROR);
+ return;
+ }
+
+ parentContainer = (IContainer) resource;
+ name = text.getText();
+ super.okPressed();
+ }
+ };
+
+ if( dialog.open() == IDialogConstants.OK_ID ) {
+ IPath newFilePath = parentContainer.getFullPath().append(name);
+ IFile file = workspace.getRoot().getFile(newFilePath);
+ ByteArrayInputStream out = new ByteArrayInputStream(new byte[0]);
+ try {
+ file.create(out, true, monitor);
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ try {
+ out.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SaveAllHandler.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SaveAllHandler.java
new file mode 100644
index 0000000..f272b42
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SaveAllHandler.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.handlers;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
+
+public class SaveAllHandler {
+ @Execute
+ public void saveAll(EPartService partService) {
+ partService.saveAll(false);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SaveHandler.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SaveHandler.java
new file mode 100644
index 0000000..0a41173
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SaveHandler.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.handlers;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
+
+public class SaveHandler {
+ @Execute
+ public void save(EPartService partService) {
+ MPart part = partService.getActivePart();
+ if( part != null && part.isDirty() ) {
+ partService.savePart(part, false);
+ }
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SwitchThemeHandler.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SwitchThemeHandler.java
new file mode 100644
index 0000000..d11d606
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/handlers/SwitchThemeHandler.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.handlers;
+
+import javax.inject.Named;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.css.swt.theme.IThemeEngine;
+
+public class SwitchThemeHandler {
+ private static final String THEME_BUNDLE = "org.eclipse.e4.ui.workbench.swt";
+ private static final String THEMEID_KEY = "themeid";
+
+
+ @Execute
+ public void switchTheme(@Named("simpleide.command.switchtheme.themeid") String themeId, IThemeEngine engine) {
+ engine.setTheme(themeId,true);
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/DefaultProjectService.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/DefaultProjectService.java
new file mode 100644
index 0000000..4da5c81
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/DefaultProjectService.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.core.services.statusreporter.StatusReporter;
+import org.eclipse.e4.demo.simpleide.services.IProjectService;
+import org.eclipse.swt.widgets.Shell;
+import org.osgi.framework.FrameworkUtil;
+
+public class DefaultProjectService implements IProjectService {
+
+ public void createProject(Shell shell, IWorkspace workspace, StatusReporter statusReporter, Logger looger,
+ IProgressMonitor monitor, String projectName) {
+ final IProject project = workspace.getRoot().getProject(projectName);
+ final IProjectDescription pd = workspace
+ .newProjectDescription(projectName);
+ try {
+ workspace.run(new IWorkspaceRunnable() {
+
+ public void run(IProgressMonitor monitor) throws CoreException {
+ if (!project.exists()) {
+ project.create(pd, monitor);
+ }
+ if (!project.isOpen()) {
+ project.open(monitor);
+ }
+ }
+
+ },monitor);
+ } catch (CoreException e) {
+ // TODO: handle exception
+ }
+ }
+
+ public String getIconURI() {
+ return "platform:/plugin/" + FrameworkUtil.getBundle(getClass()).getSymbolicName() + "/icons/newprj_wiz.gif";
+ }
+
+ public String getLabel() {
+ return "Project";
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/EclipseProjectImportService.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/EclipseProjectImportService.java
new file mode 100644
index 0000000..3aa2895
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/EclipseProjectImportService.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal;
+
+import org.eclipse.e4.core.contexts.ContextInjectionFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.demo.simpleide.internal.datatransfer.ExternalProjectImportWizard;
+import org.eclipse.e4.demo.simpleide.services.IImportResourceService;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.osgi.framework.FrameworkUtil;
+
+public class EclipseProjectImportService implements IImportResourceService {
+
+ public String getIconURI() {
+ return "platform:/plugin/" + FrameworkUtil.getBundle(getClass()).getSymbolicName() + "/icons/newprj_wiz.gif";
+ }
+
+ public String getLabel() {
+ return "Existing Projects Into Workspace";
+ }
+
+ public void importResource(Shell shell, IEclipseContext context) {
+ ExternalProjectImportWizard wz = ContextInjectionFactory.make(ExternalProjectImportWizard.class, context);
+ WizardDialog dialog = new WizardDialog(shell, wz);
+ dialog.open();
+ }
+
+ public String getCategoryName() {
+ return "General";
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ImageServiceFunction.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ImageServiceFunction.java
new file mode 100644
index 0000000..5f76507
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ImageServiceFunction.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal;
+
+import org.eclipse.e4.core.contexts.ContextFunction;
+import org.eclipse.e4.core.contexts.ContextInjectionFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.demo.simpleide.services.ImageService;
+
+public class ImageServiceFunction extends ContextFunction {
+
+ @Override
+ public Object compute(IEclipseContext context) {
+ return ContextInjectionFactory.make(ImageService.class, context);
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/NLSLookupFactoryServiceImpl.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/NLSLookupFactoryServiceImpl.java
new file mode 100644
index 0000000..b57ae1e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/NLSLookupFactoryServiceImpl.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import org.eclipse.e4.demo.simpleide.services.INLSLookupFactoryService;
+
+public class NLSLookupFactoryServiceImpl implements INLSLookupFactoryService {
+ static class Entry {
+ private Class<?> clazz;
+ private Locale locale;
+
+ Entry(Class<?> clazz, Locale locale) {
+ this.clazz = clazz;
+ this.locale = locale;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((clazz == null) ? 0 : clazz.hashCode());
+ result = prime * result
+ + ((locale == null) ? 0 : locale.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Entry other = (Entry) obj;
+ if (clazz == null) {
+ if (other.clazz != null)
+ return false;
+ } else if (!clazz.equals(other.clazz))
+ return false;
+ if (locale == null) {
+ if (other.locale != null)
+ return false;
+ } else if (!locale.equals(other.locale))
+ return false;
+ return true;
+ }
+ }
+
+ private Map<Entry, Object> CACHE = new ConcurrentHashMap<Entry, Object>();
+// private Map<String,List<ITranslationService>> translationServices = new ConcurrentHashMap<String, List<ITranslationService>>();
+
+ public void addTranslationService(ITranslationService translationService, Map<String, Object> properties) {
+ System.err.println("Added Service: " + translationService);
+ System.err.println("Properties: " + properties);
+ }
+
+ public void removeTranslationService(ITranslationService translationService, Map<String, Object> properties) {
+ System.err.println("Removed Service: " + translationService);
+ System.err.println("Properties: " + properties);
+ }
+
+ public String translate(String category, String key, Object... args) {
+ return translate(category, key, Locale.getDefault(), args);
+ }
+
+ public String translate(String category, String key, Locale locale, Object... args) {
+ throw new UnsupportedOperationException("OSGi Service based translation is not implemented yet!");
+ }
+
+ public <L> L createDynamicNLSLookup(Class<L> clazz) {
+ return createNLSLookup(clazz, null);
+ }
+
+ public <L> L createNLSLookup(Class<L> clazz) {
+ return createNLSLookup(clazz, Locale.getDefault());
+ }
+
+ public <L> L createNLSLookup(Class<L> clazz, Locale locale) {
+ if (clazz.getAnnotation(Cache.class) != null) {
+ return createFromCache(clazz, locale);
+ }
+ return create(clazz, locale);
+ }
+
+ @SuppressWarnings("unchecked")
+ private <L> L createFromCache(Class<L> clazz, Locale locale) {
+ Entry entry = new Entry(clazz, locale);
+ Object rv = CACHE.get(entry);
+ if (rv != null) {
+ L l = create(clazz, locale);
+ CACHE.put(entry, l);
+ return l;
+ } else {
+ return (L) rv;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private <L> L create(Class<L> clazz, Locale locale) {
+ OSGiService osgiService = clazz.getAnnotation(OSGiService.class);
+ if (osgiService != null) {
+ throw new UnsupportedOperationException("OSGi Service based translation is not implemented yet!");
+ } else {
+ return (L) Proxy.newProxyInstance(clazz.getClassLoader(),
+ new Class<?>[] { clazz }, new NLSFileInvocationHandler(
+ clazz, locale));
+ }
+ }
+
+// private static class NLSServiceInvocationHandler implements InvocationHandler {
+//
+// public Object invoke(Object proxy, Method method, Object[] args)
+// throws Throwable {
+// // TODO Auto-generated method stub
+// return null;
+// }
+//
+// }
+
+ private static class NLSFileInvocationHandler implements InvocationHandler {
+ private static final String EXTENSION = ".properties"; //$NON-NLS-1$
+
+ private Properties properties;
+
+ public NLSFileInvocationHandler(Class<?> clazz, Locale locale) {
+ properties = initProperties(clazz, locale);
+ }
+
+ private static Properties initProperties(Class<?> clazz, Locale locale) {
+ String plain = clazz.getName();
+ String language = plain + "_" + locale.getLanguage();
+ String country = language + "_" + locale.getCountry();
+ String variant = country + "_" + locale.getVariant();
+
+ ClassLoader loader = clazz.getClassLoader();
+ Properties properties = new Properties();
+
+ for (String aVariant : new String[] { plain, language, country,
+ variant }) {
+ String file = aVariant.replace('.', '/') + EXTENSION;
+ final InputStream input = loader == null ? ClassLoader
+ .getSystemResourceAsStream(file) : loader
+ .getResourceAsStream(file);
+ if (input == null) {
+ continue;
+ }
+
+ try {
+ properties.load(input);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ return properties;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ if (properties == null) {
+ return "Lookup is disposed";
+ } else {
+ Key tmp = method.getAnnotation(Key.class);
+ String key;
+ String value;
+ if (tmp == null) {
+ key = method.getName();
+ } else {
+ key = tmp.key();
+ }
+
+ value = properties.getProperty(key);
+ if (value != null) {
+ if (args != null && args.length > 0) {
+ return MessageFormat.format(value, args);
+ } else {
+ return value;
+ }
+ } else {
+ return "***NLS '" + key + "' UNKNOWN***";
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ServiceRegistryComponent.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ServiceRegistryComponent.java
new file mode 100644
index 0000000..99f6f2c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ServiceRegistryComponent.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal;
+
+import java.util.Vector;
+import org.eclipse.e4.demo.simpleide.services.IProjectService;
+
+public class ServiceRegistryComponent {
+ private Vector<IProjectService> creators = new Vector<IProjectService>();
+
+ public void addProjectService( IProjectService creator ) {
+ creators.add(creator);
+ }
+
+ public void removeProjectService(IProjectService creator) {
+ creators.remove(creator);
+ }
+
+ public Vector<IProjectService> getCreators() {
+ return creators;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ThemeMenuProcessor.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ThemeMenuProcessor.java
new file mode 100644
index 0000000..a1dd970
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/ThemeMenuProcessor.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal;
+
+import javax.inject.Named;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+
+import javax.inject.Inject;
+
+import java.util.List;
+import org.eclipse.e4.ui.css.swt.theme.ITheme;
+import org.eclipse.e4.ui.css.swt.theme.IThemeEngine;
+import org.eclipse.e4.ui.css.swt.theme.IThemeManager;
+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.e4.ui.model.application.ui.basic.MTrimmedWindow;
+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;
+import org.eclipse.swt.widgets.Display;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+
+public class ThemeMenuProcessor {
+
+ @Inject
+ @Named("simpleide.mainmenu")
+ private MMenu menu;
+
+ @Execute
+ public void process() {
+ if( menu == null ) {
+ return;
+ }
+
+ MTrimmedWindow window = (MTrimmedWindow) ((EObject) menu).eContainer();
+
+ //FIXME Remove once bug 314091 is resolved
+ Bundle bundle = FrameworkUtil.getBundle(getClass());
+ BundleContext context = bundle.getBundleContext();
+
+ ServiceReference reference = context.getServiceReference(IThemeManager.class.getName());
+ IThemeManager mgr = (IThemeManager) context.getService(reference);
+ IThemeEngine engine = mgr.getEngineForDisplay(Display.getCurrent());
+
+ List<ITheme> themes = engine.getThemes();
+ if (themes.size() > 0) {
+ MApplication application = (MApplication) ((EObject) window)
+ .eContainer();
+ MCommand switchThemeCommand = null;
+ for (MCommand cmd : application.getCommands()) {
+ if ("simpleide.command.switchtheme".equals(cmd.getElementId())) { //$NON-NLS-1$
+ switchThemeCommand = cmd;
+ break;
+ }
+ }
+
+ if (switchThemeCommand != null) {
+ MMenu themesMenu = MMenuFactory.INSTANCE.createMenu();
+ themesMenu.setLabel("Themes"); //$NON-NLS-1$
+
+ for (ITheme theme : themes) {
+ MHandledMenuItem item = MMenuFactory.INSTANCE
+ .createHandledMenuItem();
+ item.setLabel(theme.getLabel());
+ item.setCommand(switchThemeCommand);
+ MParameter parameter = MCommandsFactory.INSTANCE
+ .createParameter();
+ parameter.setName("simpleide.command.switchtheme.themeid"); //$NON-NLS-1$
+ parameter.setValue(theme.getId());
+ item.getParameters().add(parameter);
+ themesMenu.getChildren().add(item);
+ }
+
+ menu.getChildren().add(themesMenu);
+ }
+ }
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ArchiveFileManipulations.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ArchiveFileManipulations.java
new file mode 100644
index 0000000..9de8346
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ArchiveFileManipulations.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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 implementation
+ * Red Hat, Inc - Extracted methods from WizardArchiveFileResourceImportPage1
+ *******************************************************************************/
+
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.IOException;
+import java.util.zip.ZipFile;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @since 3.1
+ */
+public class ArchiveFileManipulations {
+
+ /**
+ * Determine whether the file with the given filename is in .tar.gz or .tar
+ * format.
+ *
+ * @param fileName
+ * file to test
+ * @return true if the file is in tar format
+ */
+ public static boolean isTarFile(String fileName, Messages messages) {
+ if (fileName.length() == 0) {
+ return false;
+ }
+
+ TarFile tarFile = null;
+ try {
+ tarFile = new TarFile(fileName,messages);
+ } catch (TarException tarException) {
+ return false;
+ } catch (IOException ioException) {
+ return false;
+ } finally {
+ if (tarFile != null) {
+ try {
+ tarFile.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Determine whether the file with the given filename is in .zip or .jar
+ * format.
+ *
+ * @param fileName
+ * file to test
+ * @return true if the file is in tar format
+ */
+ public static boolean isZipFile(String fileName) {
+ if (fileName.length() == 0) {
+ return false;
+ }
+
+ ZipFile zipFile = null;
+ try {
+ zipFile = new ZipFile(fileName);
+ } catch (IOException ioException) {
+ return false;
+ } finally {
+ if (zipFile != null) {
+ try {
+ zipFile.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Closes the given structure provider.
+ *
+ * @param structureProvider
+ * The structure provider to be closed, can be <code>null</code>
+ * @param shell
+ * The shell to display any possible Dialogs in
+ */
+ public static void closeStructureProvider(Messages messages, ILeveledImportStructureProvider structureProvider, Shell shell) {
+ if (structureProvider instanceof ZipLeveledStructureProvider) {
+ closeZipFile(messages, ((ZipLeveledStructureProvider) structureProvider).getZipFile(), shell);
+ }
+ if (structureProvider instanceof TarLeveledStructureProvider) {
+ closeTarFile(messages, ((TarLeveledStructureProvider) structureProvider).getTarFile(), shell);
+ }
+ }
+
+ /**
+ * Attempts to close the passed zip file, and answers a boolean indicating
+ * success.
+ *
+ * @param file
+ * The zip file to attempt to close
+ * @param shell
+ * The shell to display error dialogs in
+ * @return Returns true if the operation was successful
+ */
+ public static boolean closeZipFile(Messages messages, ZipFile file, Shell shell) {
+ try {
+ file.close();
+ } catch (IOException e) {
+ displayErrorDialog(
+ NLS.bind(messages.ZipImport_couldNotClose(), file.getName()),
+ shell);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Attempts to close the passed tar file, and answers a boolean indicating
+ * success.
+ *
+ * @param file
+ * The tar file to attempt to close
+ * @param shell
+ * The shell to display error dialogs in
+ * @return Returns true if the operation was successful
+ * @since 3.4
+ */
+ public static boolean closeTarFile(Messages messages, TarFile file, Shell shell) {
+ try {
+ file.close();
+ } catch (IOException e) {
+ displayErrorDialog(
+ NLS.bind(messages.ZipImport_couldNotClose(), file.getName()),
+ shell);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Display an error dialog with the specified message.
+ *
+ * @param message
+ * the error message
+ */
+ protected static void displayErrorDialog(String message, Shell shell) {
+ MessageDialog.open(MessageDialog.ERROR, shell, getErrorDialogTitle(), message, SWT.SHEET);
+ }
+
+ /**
+ * Get the title for an error dialog. Subclasses should override.
+ */
+ protected static String getErrorDialogTitle() {
+ return IDEWorkbenchMessages.WizardExportPage_internalErrorTitle;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ExternalProjectImportWizard.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ExternalProjectImportWizard.java
new file mode 100644
index 0000000..fe8fd54
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ExternalProjectImportWizard.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.e4.demo.simpleide.internal.datatransfer;
+
+import javax.inject.Inject;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.core.services.statusreporter.StatusReporter;
+import org.eclipse.e4.demo.simpleide.services.INLSLookupFactoryService;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+
+/**
+ * Standard workbench wizard for importing projects defined outside of the
+ * currently defined projects into Eclipse.
+ * <p>
+ * This class may be instantiated and used without further configuration; this
+ * class is not intended to be subclassed.
+ * </p>
+ * <p>
+ * Example:
+ *
+ * <pre>
+ * IWizard wizard = new ExternalProjectImportWizard();
+ * wizard.init(workbench, selection);
+ * WizardDialog dialog = new WizardDialog(shell, wizard);
+ * dialog.open();
+ * </pre>
+ *
+ * During the call to <code>open</code>, the wizard dialog is presented to the
+ * user. When the user hits Finish, a project is created with the location
+ * specified by the user.
+ * </p>
+ *
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+
+public class ExternalProjectImportWizard extends Wizard {
+ // private static final String EXTERNAL_PROJECT_SECTION = "ExternalProjectImportWizard";//$NON-NLS-1$
+ private WizardProjectsImportPage mainPage;
+ private IStructuredSelection currentSelection = null;
+ private String initialPath = null;
+
+ private IWorkspace workspace;
+ private StatusReporter statusReporter;
+ private Logger logger;
+ private Messages messsagesLookup;
+
+ /**
+ * Constructor for ExternalProjectImportWizard.
+ */
+ @Inject
+ public ExternalProjectImportWizard(IWorkspace workspace,
+ StatusReporter statusReporter, Logger logger,
+ INLSLookupFactoryService lookupService) {
+ this(workspace, statusReporter, logger, null, lookupService);
+ }
+
+ /**
+ * Constructor for ExternalProjectImportWizard.
+ *
+ * @param initialPath
+ * Default path for wizard to import
+ * @since 3.5
+ */
+ public ExternalProjectImportWizard(IWorkspace workspace,
+ StatusReporter statusReporter, Logger logger, String initialPath,
+ INLSLookupFactoryService lookupService) {
+ super();
+ this.messsagesLookup = lookupService.createNLSLookup(Messages.class);
+ this.workspace = workspace;
+ this.statusReporter = statusReporter;
+ this.logger = logger;
+ this.initialPath = initialPath;
+ setNeedsProgressMonitor(true);
+ // IDialogSettings workbenchSettings =
+ // IDEWorkbenchPlugin.getDefault().getDialogSettings();
+ //
+ // IDialogSettings wizardSettings = workbenchSettings
+ // .getSection(EXTERNAL_PROJECT_SECTION);
+ // if (wizardSettings == null) {
+ // wizardSettings = workbenchSettings
+ // .addNewSection(EXTERNAL_PROJECT_SECTION);
+ // }
+ // setDialogSettings(wizardSettings);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWizard.
+ */
+ public void addPages() {
+ super.addPages();
+ mainPage = new WizardProjectsImportPage(
+ "wizardExternalProjectsPage", initialPath, currentSelection, workspace, statusReporter, logger, messsagesLookup); //$NON-NLS-1$
+ addPage(mainPage);
+ }
+
+ // TODO SimpleIDE
+ // /* (non-Javadoc)
+ // * Method declared on IWorkbenchWizard.
+ // */
+ // public void init(IWorkbench workbench, IStructuredSelection
+ // currentSelection) {
+ // setWindowTitle(DataTransferMessages.DataTransfer_importTitle);
+ // setDefaultPageImageDescriptor(
+ // IDEWorkbenchPlugin.getIDEImageDescriptor("wizban/importproj_wiz.png")); //$NON-NLS-1$
+ // this.currentSelection = currentSelection;
+ // }
+
+ /*
+ * (non-Javadoc) Method declared on IWizard.
+ */
+ public boolean performCancel() {
+ mainPage.performCancel();
+ return true;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IWizard.
+ */
+ public boolean performFinish() {
+ return mainPage.createProjects();
+ }
+
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/FileSystemStructureProvider.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/FileSystemStructureProvider.java
new file mode 100644
index 0000000..1d263fe
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/FileSystemStructureProvider.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.e4.core.services.log.Logger;
+
+//import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+
+/**
+ * This class provides information regarding the structure and
+ * content of specified file system File objects.
+ */
+public class FileSystemStructureProvider implements IImportStructureProvider {
+
+ /**
+ * Holds a singleton instance of this class.
+ */
+// public final static FileSystemStructureProvider INSTANCE = new FileSystemStructureProvider();
+
+ private Logger logger;
+
+ /**
+ * Creates an instance of <code>FileSystemStructureProvider</code>.
+ */
+ FileSystemStructureProvider(Logger logger) {
+ super();
+ this.logger = logger;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IImportStructureProvider
+ */
+ public List<File> getChildren(Object element) {
+ File folder = (File) element;
+ String[] children = folder.list();
+ int childrenLength = children == null ? 0 : children.length;
+ List<File> result = new ArrayList<File>(childrenLength);
+
+ for (int i = 0; i < childrenLength; i++) {
+ result.add(new File(folder, children[i]));
+ }
+
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IImportStructureProvider
+ */
+ public InputStream getContents(Object element) {
+ try {
+ return new FileInputStream((File) element);
+ } catch (FileNotFoundException e) {
+ logger.error(e);
+// IDEWorkbenchPlugin.log(e.getLocalizedMessage(), e);
+ return null;
+ }
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IImportStructureProvider
+ */
+ public String getFullPath(Object element) {
+ return ((File) element).getPath();
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IImportStructureProvider
+ */
+ public String getLabel(Object element) {
+
+ //Get the name - if it is empty then return the path as it is a file root
+ File file = (File) element;
+ String name = file.getName();
+ if (name.length() == 0) {
+ return file.getPath();
+ }
+ return name;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IImportStructureProvider
+ */
+ public boolean isFolder(Object element) {
+ return ((File) element).isDirectory();
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/IDEWorkbenchMessages.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/IDEWorkbenchMessages.java
new file mode 100644
index 0000000..f30309d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/IDEWorkbenchMessages.java
@@ -0,0 +1,16 @@
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import org.eclipse.osgi.util.NLS;
+
+public class IDEWorkbenchMessages {
+ static {
+ NLS.initializeMessages(IDEWorkbenchMessages.class.getName(), IDEWorkbenchMessages.class);
+ }
+ public static String WizardDataTransfer_existsQuestion;
+ public static String WizardDataTransfer_overwriteNameAndPathQuestion;
+ public static String Question;
+ public static String WizardExportPage_internalErrorTitle;
+ public static String ContainerGenerator_pathOccupied;
+ public static String ContainerGenerator_progressMessage;
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/IImportStructureProvider.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/IImportStructureProvider.java
new file mode 100644
index 0000000..25d87da
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/IImportStructureProvider.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.InputStream;
+import java.util.List;
+
+/**
+ * Interface which can provide structure and content information
+ * for an element (for example, a file system element).
+ * Used by the import wizards to abstract the commonalities
+ * between importing from the file system and importing from an archive.
+ */
+public interface IImportStructureProvider {
+ /**
+ * Returns a collection with the children of the specified structured element.
+ *
+ * @param element the element for which to compute the children
+ * @return the list of child elements
+ */
+ public List<?> getChildren(Object element);
+
+ /**
+ * Returns the contents of the specified structured element, or
+ * <code>null</code> if there is a problem determining the element's
+ * contents.
+ * <p>
+ * <strong>Note:</strong>: The client is responsible for closing the stream when finished.</p>
+ *
+ * @param element a structured element
+ * @return the contents of the structured element, or <code>null</code>
+ */
+ InputStream getContents(Object element);
+
+ /**
+ * Returns the full path of the specified structured element.
+ *
+ * @param element a structured element
+ * @return the display label of the structured element
+ */
+ String getFullPath(Object element);
+
+ /**
+ * Returns the display label of the specified structured element.
+ *
+ * @param element a structured element
+ * @return the display label of the structured element
+ */
+ String getLabel(Object element);
+
+ /**
+ * Returns a boolean indicating whether the passed structured element represents
+ * a container element (as opposed to a leaf element).
+ *
+ * @return boolean
+ * @param element java.lang.Object
+ */
+ boolean isFolder(Object element);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ILeveledImportStructureProvider.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ILeveledImportStructureProvider.java
new file mode 100644
index 0000000..f374098
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ILeveledImportStructureProvider.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * Red Hat, Inc - setStrip(int), getStrip()
+ *******************************************************************************/
+
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+
+/**
+ * Interface which can provide structure and content information for an archive
+ * element. Used by the import wizards to abstract the commonalities between
+ * importing from the a zip file and importing from a tar file.
+ *
+ * @since 3.1
+ */
+public interface ILeveledImportStructureProvider extends IImportStructureProvider {
+ /**
+ * Returns the entry that this importer uses as the root sentinel.
+ *
+ * @return root entry of the archive file
+ */
+ public abstract Object getRoot();
+
+ /**
+ * Tells the provider to strip N number of directories from the path of any
+ * path or file name returned by the IImportStructureProvider (Default=0).
+ *
+ * @param level
+ * The number of directories to strip
+ */
+ public abstract void setStrip(int level);
+
+ /**
+ * Returns the number of directories that this IImportStructureProvider is
+ * stripping from the file name
+ *
+ * @return int Number of entries
+ */
+ public abstract int getStrip();
+
+ /**
+ * Close the archive file that was used to create this leveled structure provider.
+ *
+ * @return <code>true</code> if the archive was closed successfully
+ */
+ public boolean closeArchive();
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ImportOperation.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ImportOperation.java
new file mode 100644
index 0000000..0f5a772
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ImportOperation.java
@@ -0,0 +1,986 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 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
+ * Red Hat, Inc - changed TarFileStructureProvider to TarLeveledStructureProvider
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import org.eclipse.core.filesystem.URIUtil;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IPathVariableManager;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourceAttributes;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.e4.demo.simpleide.internal.datatransfer.actions.WorkspaceModifyOperation;
+import org.eclipse.e4.demo.simpleide.internal.datatransfer.dialogs.ContainerGenerator;
+import org.eclipse.e4.demo.simpleide.internal.datatransfer.dialogs.IOverwriteQuery;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Shell;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * An operation which does the actual work of copying objects from the local file
+ * system into the workspace.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ImportOperation extends WorkspaceModifyOperation {
+ private static final int POLICY_DEFAULT = 0;
+
+ private static final int POLICY_SKIP_CHILDREN = 1;
+
+ private static final int POLICY_FORCE_OVERWRITE = 2;
+
+ private Object source;
+
+ private IPath destinationPath;
+
+ private IContainer destinationContainer;
+
+ private List<?> selectedFiles;
+
+ private List<?> rejectedFiles;
+
+ private IImportStructureProvider provider;
+
+ private IProgressMonitor monitor;
+
+ protected IOverwriteQuery overwriteCallback;
+
+ private Shell context;
+
+ private List<IStatus> errorTable = new ArrayList<IStatus>();
+
+ private boolean createVirtualFolder = false;
+
+ private boolean createLinks = false;
+
+ private boolean createLinkFilesOnly = false;
+
+ private String relativeVariable = null;
+
+ private boolean createContainerStructure = true;
+
+ //The constants for the overwrite 3 state
+ private static final int OVERWRITE_NOT_SET = 0;
+
+ private static final int OVERWRITE_NONE = 1;
+
+ private static final int OVERWRITE_ALL = 2;
+
+ private int overwriteState = OVERWRITE_NOT_SET;
+
+ private static final String ABSOLUTE_PATH = "<Absolute Path>"; //$NON-NLS-1$
+
+ private IWorkspace workspace;
+
+ private Messages messages;
+
+ /**
+ * Creates a new operation that recursively imports the entire contents of the
+ * specified root file system object.
+ * <p>
+ * The <code>source</code> parameter represents the root file system object to
+ * import. All contents of this object are imported. Valid types for this parameter
+ * are determined by the supplied <code>IImportStructureProvider</code>.
+ * </p>
+ * <p>
+ * The <code>provider</code> parameter allows this operation to deal with the
+ * source object in an abstract way. This operation calls methods on the provider
+ * and the provider in turn calls specific methods on the source object.
+ * </p>
+ * <p>
+ * The default import behavior is to recreate the complete container structure
+ * for the contents of the root file system object in their destination.
+ * If <code>setCreateContainerStructure</code> is set to false then the container
+ * structure created is relative to the root file system object.
+ * </p>
+ *
+ * @param containerPath the full path of the destination container within the
+ * workspace
+ * @param source the root file system object to import
+ * @param provider the file system structure provider to use
+ * @param overwriteImplementor the overwrite strategy to use
+ */
+ public ImportOperation(IWorkspace workspace, IPath containerPath, Object source,
+ IImportStructureProvider provider,
+ IOverwriteQuery overwriteImplementor, Messages messages) {
+ super(workspace);
+ this.messages = messages;
+ this.workspace = workspace;
+ this.destinationPath = containerPath;
+ this.source = source;
+ this.provider = provider;
+ overwriteCallback = overwriteImplementor;
+ }
+
+ /**
+ * Creates a new operation that imports specific file system objects.
+ * In this usage context, the specified source file system object is used by the
+ * operation solely to determine the destination container structure of the file system
+ * objects being imported.
+ * <p>
+ * The <code>source</code> parameter represents the root file system object to
+ * import. Valid types for this parameter are determined by the supplied
+ * <code>IImportStructureProvider</code>. The contents of the source which
+ * are to be imported are specified in the <code>filesToImport</code>
+ * parameter.
+ * </p>
+ * <p>
+ * The <code>provider</code> parameter allows this operation to deal with the
+ * source object in an abstract way. This operation calls methods on the provider
+ * and the provider in turn calls specific methods on the source object.
+ * </p>
+ * <p>
+ * The <code>filesToImport</code> parameter specifies what contents of the root
+ * file system object are to be imported.
+ * </p>
+ * <p>
+ * The default import behavior is to recreate the complete container structure
+ * for the file system objects in their destination. If <code>setCreateContainerStructure</code>
+ * is set to <code>false</code>, then the container structure created for each of
+ * the file system objects is relative to the supplied root file system object.
+ * </p>
+ *
+ * @param containerPath the full path of the destination container within the
+ * workspace
+ * @param source the root file system object to import from
+ * @param provider the file system structure provider to use
+ * @param overwriteImplementor the overwrite strategy to use
+ * @param filesToImport the list of file system objects to be imported
+ * (element type: <code>Object</code>)
+ */
+ public ImportOperation(IWorkspace workspace, IPath containerPath, Object source,
+ IImportStructureProvider provider,
+ IOverwriteQuery overwriteImplementor, List<?> filesToImport, Messages messages) {
+ this(workspace, containerPath, source, provider, overwriteImplementor, messages);
+ setFilesToImport(filesToImport);
+ }
+
+ /**
+ * Creates a new operation that imports specific file system objects.
+ * <p>
+ * The <code>provider</code> parameter allows this operation to deal with the
+ * source object in an abstract way. This operation calls methods on the provider
+ * and the provider in turn calls specific methods on the source object.
+ * </p>
+ * <p>
+ * The <code>filesToImport</code> parameter specifies what file system objects
+ * are to be imported.
+ * </p>
+ * <p>
+ * The default import behavior is to recreate the complete container structure
+ * for the file system objects in their destination. If <code>setCreateContainerStructure</code>
+ * is set to <code>false</code>, then no container structure is created for each of
+ * the file system objects.
+ * </p>
+ *
+ * @param containerPath the full path of the destination container within the
+ * workspace
+ * @param provider the file system structure provider to use
+ * @param overwriteImplementor the overwrite strategy to use
+ * @param filesToImport the list of file system objects to be imported
+ * (element type: <code>Object</code>)
+ */
+ public ImportOperation(IWorkspace workspace, IPath containerPath,
+ IImportStructureProvider provider,
+ IOverwriteQuery overwriteImplementor, List<?> filesToImport, Messages messages) {
+ this(workspace, containerPath, null, provider, overwriteImplementor,messages);
+ setFilesToImport(filesToImport);
+ }
+
+ /**
+ * Prompts if existing resources should be overwritten. Recursively collects
+ * existing read-only files to overwrite and resources that should not be
+ * overwritten.
+ *
+ * @param sourceStart destination path to check for existing files
+ * @param sources file system objects that may exist in the destination
+ * @param noOverwrite files that were selected to be skipped (don't overwrite).
+ * object type IPath
+ * @param overwriteReadonly the collected existing read-only files to overwrite.
+ * object type IPath
+ * @param policy on of the POLICY constants defined in the
+ * class.
+ */
+ void collectExistingReadonlyFiles(IPath sourceStart, List<?> sources,
+ ArrayList<Object> noOverwrite, ArrayList<Object> overwriteReadonly, int policy) {
+ IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+ Iterator<?> sourceIter = sources.iterator();
+ IPath sourceRootPath = null;
+
+ if (this.source != null) {
+ sourceRootPath = new Path(provider.getFullPath(this.source));
+ }
+ while (sourceIter.hasNext()) {
+ Object nextSource = sourceIter.next();
+ IPath sourcePath = new Path(provider.getFullPath(nextSource));
+ IPath newDestinationPath;
+ IResource newDestination;
+
+ if (sourceRootPath == null) {
+ newDestinationPath = sourceStart.append(provider
+ .getLabel(nextSource));
+ } else {
+ int prefixLength = sourcePath
+ .matchingFirstSegments(sourceRootPath);
+ IPath relativeSourcePath = sourcePath
+ .removeFirstSegments(prefixLength);
+ newDestinationPath = this.destinationPath
+ .append(relativeSourcePath);
+ }
+ newDestination = workspaceRoot.findMember(newDestinationPath);
+ if (newDestination == null) {
+ continue;
+ }
+
+ IFolder folder = getFolder(newDestination);
+ if (folder != null) {
+ if (policy != POLICY_FORCE_OVERWRITE) {
+ if (this.overwriteState == OVERWRITE_NONE
+ || !queryOverwrite(newDestinationPath)) {
+ noOverwrite.add(folder);
+ continue;
+ }
+ }
+ if (provider.isFolder(nextSource)) {
+ collectExistingReadonlyFiles(newDestinationPath, provider
+ .getChildren(nextSource), noOverwrite,
+ overwriteReadonly, POLICY_FORCE_OVERWRITE);
+ }
+ } else {
+ IFile file = getFile(newDestination);
+
+ if (file != null) {
+ if (!queryOverwriteFile(file, policy)) {
+ noOverwrite.add(file.getFullPath());
+ } else if (file.isReadOnly()) {
+ overwriteReadonly.add(file);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates the folders that appear in the specified resource path.
+ * These folders are created relative to the destination container.
+ *
+ * @param path the relative path of the resource
+ * @return the container resource coresponding to the given path
+ * @exception CoreException if this method failed
+ */
+ IContainer createContainersFor(IPath path) throws CoreException {
+
+ IContainer currentFolder = destinationContainer;
+
+ int segmentCount = path.segmentCount();
+
+ //No containers to create
+ if (segmentCount == 0) {
+ return currentFolder;
+ }
+
+ //Needs to be handles differently at the root
+ if (currentFolder.getType() == IResource.ROOT) {
+ return createFromRoot(path);
+ }
+
+ for (int i = 0; i < segmentCount; i++) {
+ currentFolder = currentFolder.getFolder(new Path(path.segment(i)));
+ if (!currentFolder.exists()) {
+ if (createVirtualFolder)
+ ((IFolder) currentFolder).create(IResource.VIRTUAL, true,
+ null);
+ else if (createLinks)
+ ((IFolder) currentFolder).createLink(createRelativePath(
+ path, currentFolder), 0, null);
+ else
+ ((IFolder) currentFolder).create(false, true, null);
+ }
+ }
+
+ return currentFolder;
+ }
+
+ /**
+ * Creates the folders that appear in the specified resource path
+ * assuming that the destinationContainer begins at the root. Do not create projects.
+ *
+ * @param path the relative path of the resource
+ * @return the container resource coresponding to the given path
+ * @exception CoreException if this method failed
+ */
+ private IContainer createFromRoot(IPath path) throws CoreException {
+
+ int segmentCount = path.segmentCount();
+
+ //Assume the project exists
+ IContainer currentFolder = ((IWorkspaceRoot) destinationContainer)
+ .getProject(path.segment(0));
+
+ for (int i = 1; i < segmentCount; i++) {
+ currentFolder = currentFolder.getFolder(new Path(path.segment(i)));
+ if (!currentFolder.exists()) {
+ ((IFolder) currentFolder).create(false, true, null);
+ }
+ }
+
+ return currentFolder;
+ }
+
+ /**
+ * Deletes the given resource. If the resource fails to be deleted, adds a
+ * status object to the list to be returned by <code>getResult</code>.
+ *
+ * @param resource the resource
+ */
+ void deleteResource(IResource resource) {
+ try {
+ resource.delete(IResource.KEEP_HISTORY, null);
+ } catch (CoreException e) {
+ errorTable.add(e.getStatus());
+ }
+ }
+
+ /* (non-Javadoc)
+ * Method declared on WorkbenchModifyOperation.
+ * Imports the specified file system objects from the file system.
+ */
+ protected void execute(IProgressMonitor progressMonitor) {
+
+ monitor = progressMonitor;
+
+ try {
+ if (selectedFiles == null) {
+ //Set the amount to 1000 as we have no idea of how long this will take
+ monitor.beginTask(messages.ImportOperation_ImportTask(), 1000);
+ ContainerGenerator generator = new ContainerGenerator(workspace,
+ destinationPath);
+ monitor.worked(30);
+ validateFiles(Arrays.asList(new Object[] { source }));
+ monitor.worked(50);
+ destinationContainer = generator
+ .generateContainer(new SubProgressMonitor(monitor, 50));
+ importRecursivelyFrom(source, POLICY_DEFAULT);
+ //Be sure it finishes
+ monitor.worked(90);
+ } else {
+ // Choose twice the selected files size to take folders into account
+ int creationCount = selectedFiles.size();
+ monitor.beginTask(messages.ImportOperation_ImportTask(), creationCount + 100);
+ ContainerGenerator generator = new ContainerGenerator(workspace,
+ destinationPath);
+ monitor.worked(30);
+ validateFiles(selectedFiles);
+ monitor.worked(50);
+ destinationContainer = generator
+ .generateContainer(new SubProgressMonitor(monitor, 50));
+ importFileSystemObjects(selectedFiles);
+ monitor.done();
+ }
+ } catch (CoreException e) {
+ errorTable.add(e.getStatus());
+ } finally {
+ monitor.done();
+ }
+ }
+
+ /**
+ * Returns the container resource that the passed file system object should be
+ * imported into.
+ *
+ * @param fileSystemObject the file system object being imported
+ * @return the container resource that the passed file system object should be
+ * imported into
+ * @exception CoreException if this method failed
+ */
+ IContainer getDestinationContainerFor(Object fileSystemObject)
+ throws CoreException {
+ IPath pathname = new Path(provider.getFullPath(fileSystemObject));
+
+ if (createContainerStructure) {
+ return createContainersFor(pathname.removeLastSegments(1));
+ }
+ if (source == fileSystemObject) {
+ return null;
+ }
+ IPath sourcePath = new Path(provider.getFullPath(source));
+ IPath destContainerPath = pathname.removeLastSegments(1);
+ IPath relativePath = destContainerPath.removeFirstSegments(
+ sourcePath.segmentCount()).setDevice(null);
+ return createContainersFor(relativePath);
+
+ }
+
+ /**
+ * Returns the resource either casted to or adapted to an IFile.
+ *
+ * @param resource resource to cast/adapt
+ * @return the resource either casted to or adapted to an IFile.
+ * <code>null</code> if the resource does not adapt to IFile
+ */
+ IFile getFile(IResource resource) {
+ if (resource instanceof IFile) {
+ return (IFile) resource;
+ }
+ Object adapted = ((IAdaptable) resource).getAdapter(IFile.class);
+ if(adapted == null) {
+ return null;
+ }
+ return (IFile) adapted;
+
+ }
+
+ /**
+ * Returns the resource either casted to or adapted to an IFolder.
+ *
+ * @param resource resource to cast/adapt
+ * @return the resource either casted to or adapted to an IFolder.
+ * <code>null</code> if the resource does not adapt to IFolder
+ */
+ IFolder getFolder(IResource resource) {
+ if (resource instanceof IFolder) {
+ return (IFolder) resource;
+ }
+ Object adapted = ((IAdaptable) resource).getAdapter(IFolder.class);
+ if(adapted == null) {
+ return null;
+ }
+ return (IFolder) adapted;
+ }
+
+ /**
+ * Returns the rejected files based on the given multi status.
+ *
+ * @param multiStatus multi status to use to determine file rejection
+ * @param files source files
+ * @return list of rejected files as absolute paths. Object type IPath.
+ */
+ ArrayList<IPath> getRejectedFiles(IStatus multiStatus, IFile[] files) {
+ ArrayList<IPath> filteredFiles = new ArrayList<IPath>();
+
+ IStatus[] status = multiStatus.getChildren();
+ for (int i = 0; i < status.length; i++) {
+ if (status[i].isOK() == false) {
+ errorTable.add(status[i]);
+ filteredFiles.add(files[i].getFullPath());
+ }
+ }
+ return filteredFiles;
+ }
+
+ /**
+ * Returns the status of the import operation.
+ * If there were any errors, the result is a status object containing
+ * individual status objects for each error.
+ * If there were no errors, the result is a status object with error code <code>OK</code>.
+ *
+ * @return the status
+ */
+ public IStatus getStatus() {
+ IStatus[] errors = new IStatus[errorTable.size()];
+ errorTable.toArray(errors);
+ return new MultiStatus(getBundleName(), IStatus.OK, errors,
+ messages.ImportOperation_importProblems(),
+ null);
+ }
+
+ /**
+ * Imports the specified file system object into the workspace.
+ * If the import fails, adds a status object to the list to be returned by
+ * <code>getResult</code>.
+ *
+ * @param fileObject the file system object to be imported
+ * @param policy determines how the file object is imported
+ */
+ void importFile(Object fileObject, int policy) {
+ IContainer containerResource;
+ try {
+ containerResource = getDestinationContainerFor(fileObject);
+ } catch (CoreException e) {
+ IStatus coreStatus = e.getStatus();
+ String newMessage = NLS.bind(messages.ImportOperation_coreImportError(), fileObject, coreStatus.getMessage());
+ IStatus status = new Status(coreStatus.getSeverity(), coreStatus
+ .getPlugin(), coreStatus.getCode(), newMessage, null);
+ errorTable.add(status);
+ return;
+ }
+
+ String fileObjectPath = provider.getFullPath(fileObject);
+ monitor.subTask(fileObjectPath);
+ IFile targetResource = containerResource.getFile(new Path(provider
+ .getLabel(fileObject)));
+ monitor.worked(1);
+
+ if (rejectedFiles.contains(targetResource.getFullPath())) {
+ return;
+ }
+
+ // ensure that the source and target are not the same
+ IPath targetPath = targetResource.getLocation();
+ // Use Files for comparison to avoid platform specific case issues
+ if (targetPath != null
+ && (targetPath.toFile().equals(new File(fileObjectPath)))) {
+ errorTable.add(new Status(IStatus.ERROR, getBundleName(), 0,
+ NLS.bind(messages.ImportOperation_targetSameAsSourceError(), fileObjectPath), null));
+ return;
+ }
+
+ InputStream contentStream = provider.getContents(fileObject);
+ if (contentStream == null) {
+ errorTable
+ .add(new Status(
+ IStatus.ERROR,
+ getBundleName(),
+ 0,
+ NLS.bind(messages.ImportOperation_openStreamError(), fileObjectPath),
+ null));
+ return;
+ }
+
+ try {
+ if (targetResource.exists()) {
+ targetResource.setContents(contentStream,
+ IResource.KEEP_HISTORY, null);
+ } else {
+ if (createVirtualFolder || createLinks || createLinkFilesOnly)
+ targetResource.createLink(createRelativePath(
+ new Path(provider
+ .getFullPath(fileObject)), targetResource), 0, null);
+ else
+ targetResource.create(contentStream, false, null);
+ }
+ setResourceAttributes(targetResource, fileObject);
+
+ if (provider instanceof TarLeveledStructureProvider) {
+ try {
+ targetResource.setResourceAttributes(((TarLeveledStructureProvider) provider).getResourceAttributes(fileObject));
+ } catch (CoreException e) {
+ errorTable.add(e.getStatus());
+ }
+ }
+ } catch (CoreException e) {
+ errorTable.add(e.getStatus());
+ } finally {
+ try {
+ contentStream.close();
+ } catch (IOException e) {
+ errorTable
+ .add(new Status(
+ IStatus.ERROR,
+ getBundleName(),
+ 0,
+ NLS.bind(messages.ImportOperation_closeStreamError(), fileObjectPath),
+ e));
+ }
+ }
+ }
+
+ private String getBundleName() {
+ return FrameworkUtil.getBundle(getClass()).getSymbolicName();
+ }
+
+ /**
+ * Reuse the file attributes set in the import.
+ * @param targetResource
+ * @param fileObject
+ */
+ private void setResourceAttributes(IFile targetResource, Object fileObject) {
+
+ long timeStamp = 0;
+ if(fileObject instanceof File) {
+ try {
+ targetResource.setResourceAttributes(ResourceAttributes.fromFile((File) fileObject));
+ timeStamp = ((File)fileObject).lastModified();
+ } catch (CoreException e) {
+ errorTable.add(e.getStatus());
+ }
+ }else if (fileObject instanceof TarEntry) {
+ try {
+ targetResource.setResourceAttributes(((TarLeveledStructureProvider) provider).getResourceAttributes(fileObject));
+ timeStamp = ((TarEntry)fileObject).getTime()*1000; // TarEntry time is in secs. Convert to msecs
+ } catch (CoreException e) {
+ errorTable.add(e.getStatus());
+ }
+ }else if (fileObject instanceof ZipEntry) {
+ long zipTimeStamp = ((ZipEntry)fileObject).getTime();
+ if(zipTimeStamp != -1)
+ timeStamp = zipTimeStamp;
+ }
+
+ if(timeStamp!= 0) {
+ try {
+ targetResource.setLocalTimeStamp(timeStamp);
+ } catch (CoreException e) {
+ errorTable.add(e.getStatus());
+ }
+ }
+ }
+
+ /**
+ * Imports the specified file system objects into the workspace.
+ * If the import fails, adds a status object to the list to be returned by
+ * <code>getStatus</code>.
+ *
+ * @param filesToImport the list of file system objects to import
+ * (element type: <code>Object</code>)
+ * @throws CoreException
+ * @exception OperationCanceledException if canceled
+ */
+ void importFileSystemObjects(List<?> filesToImport) throws CoreException {
+ Iterator<?> filesEnum = filesToImport.iterator();
+ while (filesEnum.hasNext()) {
+ Object fileSystemObject = filesEnum.next();
+ if (source == null) {
+ // We just import what we are given into the destination
+ IPath sourcePath = new Path(provider
+ .getFullPath(fileSystemObject)).removeLastSegments(1);
+ if (provider.isFolder(fileSystemObject) && sourcePath.isEmpty()) {
+ // If we don't have a parent then we have selected the
+ // file systems root. Roots can't copied (at least not
+ // under windows).
+ errorTable.add(new Status(IStatus.INFO,
+ getBundleName(), 0, messages.ImportOperation_cannotCopy(),
+ null));
+ continue;
+ }
+ source = sourcePath.toFile();
+ }
+ importRecursivelyFrom(fileSystemObject, POLICY_DEFAULT);
+ }
+ }
+
+ /**
+ * Imports the specified file system container object into the workspace.
+ * If the import fails, adds a status object to the list to be returned by
+ * <code>getResult</code>.
+ *
+ * @param folderObject the file system container object to be imported
+ * @param policy determines how the folder object and children are imported
+ * @return the policy to use to import the folder's children
+ * @throws CoreException
+ */
+ int importFolder(Object folderObject, int policy) throws CoreException {
+ IContainer containerResource;
+ try {
+ containerResource = getDestinationContainerFor(folderObject);
+ } catch (CoreException e) {
+ errorTable.add(e.getStatus());
+ return policy;
+ }
+
+ if (containerResource == null) {
+ return policy;
+ }
+
+ monitor.subTask(provider.getFullPath(folderObject));
+ IWorkspace workspace = destinationContainer.getWorkspace();
+ IPath containerPath = containerResource.getFullPath();
+ IPath resourcePath = containerPath.append(provider
+ .getLabel(folderObject));
+
+ // Do not attempt the import if the resource path is unchanged. This may happen
+ // when importing from a zip file.
+ if (resourcePath.equals(containerPath)) {
+ return policy;
+ }
+
+ if (workspace.getRoot().exists(resourcePath)) {
+ if (rejectedFiles.contains(resourcePath)) {
+ return POLICY_SKIP_CHILDREN;
+ }
+
+ IFolder folder = workspace.getRoot().getFolder(resourcePath);
+ if (createVirtualFolder || createLinks || folder.isVirtual() || folder.isLinked()) {
+ folder.delete(true, null);
+ } else
+ return POLICY_FORCE_OVERWRITE;
+ }
+
+ try {
+ if (createVirtualFolder)
+ workspace.getRoot().getFolder(resourcePath).create(
+ IResource.VIRTUAL, true, null);
+ else if (createLinks) {
+ IFolder newFolder = workspace.getRoot().getFolder(resourcePath);
+ newFolder.createLink(
+ createRelativePath(new Path(provider.getFullPath(folderObject)), newFolder),
+ 0, null);
+ policy = POLICY_SKIP_CHILDREN;
+ } else
+ workspace.getRoot().getFolder(resourcePath).create(false, true, null);
+ } catch (CoreException e) {
+ errorTable.add(e.getStatus());
+ }
+
+ return policy;
+ }
+
+ /**
+ * Transform an absolute path URI to a relative path one (i.e. from
+ * "C:\foo\bar\file.txt" to "VAR\file.txt" granted that the relativeVariable
+ * is "VAR" and points to "C:\foo\bar\").
+ *
+ * @param location
+ * @param resource
+ * @return an URI that was made relative to a variable
+ */
+ private IPath createRelativePath(IPath location, IResource resource) {
+ if (relativeVariable == null)
+ return location;
+ if (relativeVariable.equals(ABSOLUTE_PATH))
+ return location;
+ IPathVariableManager pathVariableManager = resource.getPathVariableManager();
+ try {
+ return URIUtil.toPath(pathVariableManager.convertToRelative(URIUtil.toURI(location), true, relativeVariable));
+ } catch (CoreException e) {
+ return location;
+ }
+ }
+
+ /**
+ * Imports the specified file system object recursively into the workspace.
+ * If the import fails, adds a status object to the list to be returned by
+ * <code>getStatus</code>.
+ *
+ * @param fileSystemObject the file system object to be imported
+ * @param policy determines how the file system object and children are imported
+ * @throws CoreException
+ * @exception OperationCanceledException if canceled
+ */
+ void importRecursivelyFrom(Object fileSystemObject, int policy) throws CoreException {
+ if (monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+
+ if (!provider.isFolder(fileSystemObject)) {
+ importFile(fileSystemObject, policy);
+ return;
+ }
+
+ int childPolicy = importFolder(fileSystemObject, policy);
+ if (childPolicy != POLICY_SKIP_CHILDREN) {
+ Iterator<?> children = provider.getChildren(fileSystemObject)
+ .iterator();
+ while (children.hasNext()) {
+ importRecursivelyFrom(children.next(), childPolicy);
+ }
+ }
+ }
+
+ /**
+ * Queries the user whether the resource with the specified path should be
+ * overwritten by a file system object that is being imported.
+ *
+ * @param resourcePath the workspace path of the resource that needs to be overwritten
+ * @return <code>true</code> to overwrite, <code>false</code> to not overwrite
+ * @exception OperationCanceledException if canceled
+ */
+ boolean queryOverwrite(IPath resourcePath)
+ throws OperationCanceledException {
+ String overwriteAnswer = overwriteCallback.queryOverwrite(resourcePath
+ .makeRelative().toString());
+
+ if (overwriteAnswer.equals(IOverwriteQuery.CANCEL)) {
+ throw new OperationCanceledException(messages.ImportOperation_EmptyString());
+ }
+
+ if (overwriteAnswer.equals(IOverwriteQuery.NO)) {
+ return false;
+ }
+
+ if (overwriteAnswer.equals(IOverwriteQuery.NO_ALL)) {
+ this.overwriteState = OVERWRITE_NONE;
+ return false;
+ }
+
+ if (overwriteAnswer.equals(IOverwriteQuery.ALL)) {
+ this.overwriteState = OVERWRITE_ALL;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns whether the given file should be overwritten.
+ *
+ * @param targetFile the file to ask to overwrite
+ * @param policy determines if the user is queried for overwrite
+ * @return <code>true</code> if the file should be overwritten, and
+ * <code>false</code> if not.
+ */
+ boolean queryOverwriteFile(IFile targetFile, int policy) {
+ //If force overwrite is on don't bother
+ if (policy != POLICY_FORCE_OVERWRITE) {
+ if (this.overwriteState == OVERWRITE_NOT_SET
+ && !queryOverwrite(targetFile.getFullPath())) {
+ return false;
+ }
+ if (this.overwriteState == OVERWRITE_NONE) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Sets the context for use by the VCM provider to prompt the user
+ * for check-out of files.
+ *
+ * @param shell context for use by the VCM provider to prompt user
+ * for check-out. The user will not be prompted if set to <code>null</code>.
+ * @see IWorkspace#validateEdit(org.eclipse.core.resources.IFile[], java.lang.Object)
+ * @since 2.1
+ */
+ public void setContext(Shell shell) {
+ context = shell;
+ }
+
+ /**
+ * Sets whether the containment structures that are implied from the full paths
+ * of file system objects being imported should be duplicated in the workbench.
+ *
+ * @param value <code>true</code> if containers should be created, and
+ * <code>false</code> otherwise
+ */
+ public void setCreateContainerStructure(boolean value) {
+ createContainerStructure = value;
+ }
+
+ /**
+ * Sets the file system objects to import.
+ *
+ * @param filesToImport the list of file system objects to be imported
+ * (element type: <code>Object</code>)
+ */
+ public void setFilesToImport(List<?> filesToImport) {
+ this.selectedFiles = filesToImport;
+ }
+
+ /**
+ * Sets whether imported file system objects should automatically overwrite
+ * existing workbench resources when a conflict occurs.
+ *
+ * @param value <code>true</code> to automatically overwrite, and
+ * <code>false</code> otherwise
+ */
+ public void setOverwriteResources(boolean value) {
+ if (value) {
+ this.overwriteState = OVERWRITE_ALL;
+ }
+ }
+
+ /**
+ * Validates that the given source resources can be copied to the
+ * destination as decided by the VCM provider.
+ *
+ * @param existingFiles existing files to validate
+ * @return list of rejected files as absolute paths. Object type IPath.
+ */
+ ArrayList<IPath> validateEdit(List<IFile> existingFiles) {
+
+ if (existingFiles.size() > 0) {
+ IFile[] files = existingFiles
+ .toArray(new IFile[existingFiles.size()]);
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IStatus status = workspace.validateEdit(files, context);
+
+ //If there was a mix return the bad ones
+ if (status.isMultiStatus()) {
+ return getRejectedFiles(status, files);
+ }
+
+ if(!status.isOK()){
+ //If just a single status reject them all
+ errorTable.add(status);
+ ArrayList<IPath> filteredFiles = new ArrayList<IPath>();
+
+ for (int i = 0; i < files.length; i++) {
+ filteredFiles.add(files[i].getFullPath());
+ }
+ return filteredFiles;
+ }
+
+ }
+ return new ArrayList<IPath>();
+ }
+
+ /**
+ * Validates the given file system objects.
+ * The user is prompted to overwrite existing files.
+ * Existing read-only files are validated with the VCM provider.
+ *
+ * @param sourceFiles files to validate
+ */
+ @SuppressWarnings("unchecked")
+ void validateFiles(List<?> sourceFiles) {
+ ArrayList noOverwrite = new ArrayList();
+ ArrayList overwriteReadonly = new ArrayList();
+
+ collectExistingReadonlyFiles(destinationPath, sourceFiles, noOverwrite,
+ overwriteReadonly, POLICY_DEFAULT);
+ rejectedFiles = validateEdit(overwriteReadonly);
+ rejectedFiles.addAll(noOverwrite);
+ }
+
+ /**
+ * Set Whether groups and links will be created instead of files and folders
+ *
+ * @param virtualFolders
+ * @since 3.6
+ */
+ public void setVirtualFolders(boolean virtualFolders) {
+ createVirtualFolder = virtualFolders;
+ }
+
+ /**
+ * Set Whether links will be created instead of files and folders
+ *
+ * @param links
+ * @since 3.6
+ */
+ public void setCreateLinks(boolean links) {
+ createLinks = links;
+ }
+
+ /**
+ * Set a variable relative to which the links are created
+ *
+ * @param variable
+ * @since 3.6
+ */
+ public void setRelativeVariable(String variable) {
+ relativeVariable = variable;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/Messages.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/Messages.java
new file mode 100644
index 0000000..d159115
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/Messages.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+public interface Messages {
+ public String WizardProjectsImportPage_ProjectLabel();
+ public String WizardProjectsImportPage_ImportProjectsTitle();
+ public String WizardProjectsImportPage_ImportProjectsDescription();
+ public String WizardProjectsImportPage_CopyProjectsIntoWorkspace();
+ public String WizardProjectsImportPage_ProjectsListTitle();
+ public String WizardProjectsImportPage_RootSelectTitle();
+ public String WizardProjectsImportPage_ArchiveSelectTitle();
+ public String WizardProjectsImportPage_SearchingMessage();
+ public String WizardProjectsImportPage_ProcessingMessage();
+ public String WizardProjectsImportPage_ProjectsInWorkspace();
+ public String WizardProjectsImportPage_NoProjectsToImport();
+ public String WizardProjectsImportPage_CheckingMessage();
+ public String WizardProjectsImportPage_SelectDialogTitle();
+ public String WizardProjectsImportPage_SelectArchiveDialogTitle();
+ public String WizardProjectsImportPage_CreateProjectsTask();
+
+ public String WizardProjectsImportPage_SelectAll();
+ public String WizardProjectsImportPage_DeselectAll();
+ public String WizardProjectsImportPage_Refresh();
+ public String WizardProjectsImportPage_browse();
+
+ public String WizardExternalProjectImportPage_ErrorMessage();
+
+
+ public String ImportOperation_ImportTask();
+ public String ImportOperation_EmptyString();
+ public String ImportOperation_importProblems();
+ public String ImportOperation_coreImportError();
+ public String ImportOperation_targetSameAsSourceError();
+ public String ImportOperation_openStreamError();
+ public String ImportOperation_closeStreamError();
+ public String ImportOperation_cannotCopy();
+
+ public String ZipImport_badFormat();
+ public String ZipImport_couldNotRead();
+ public String ZipImport_couldNotClose();
+
+ public String TarImport_invalid_tar_format();
+ public String TarImport_badFormat();
+
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/Messages.properties b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/Messages.properties
new file mode 100644
index 0000000..375b498
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/Messages.properties
@@ -0,0 +1,37 @@
+WizardProjectsImportPage_RootSelectTitle=Select roo&t directory:
+WizardProjectsImportPage_ArchiveSelectTitle=Select &archive file:
+WizardProjectsImportPage_SelectArchiveDialogTitle=Select archive containing the projects to import
+WizardProjectsImportPage_ProjectsListTitle=&Projects:
+WizardProjectsImportPage_ProcessingMessage=Processing results
+WizardProjectsImportPage_SelectDialogTitle=Select root directory of the projects to import
+WizardProjectsImportPage_SearchingMessage=Searching for projects
+WizardProjectsImportPage_ImportProjectsTitle=Import Projects
+WizardProjectsImportPage_ProjectsInWorkspace=Some projects cannot be imported because they already exist in the workspace
+WizardProjectsImportPage_NoProjectsToImport=No projects are found to import
+WizardProjectsImportPage_CreateProjectsTask=Creating Projects
+WizardProjectsImportPage_ImportProjectsDescription=Select a directory to search for existing Eclipse projects.
+WizardProjectsImportPage_CheckingMessage= Checking: {0}
+WizardProjectsImportPage_CopyProjectsIntoWorkspace=&Copy projects into workspace
+WizardProjectsImportPage_ProjectLabel={0} ({1})
+WizardProjectsImportPage_SelectAll=&Select All
+WizardProjectsImportPage_DeselectAll=&Deselect All
+WizardProjectsImportPage_Refresh=R&efresh
+WizardProjectsImportPage_browse=B&rowse...
+
+WizardExternalProjectImportPage_ErrorMessage = Creation Problems
+
+ImportOperation_ImportTask=Importing:
+ImportOperation_EmptyString=
+ImportOperation_cannotCopy = Cannot copy root file system.
+ImportOperation_importProblems = Problems were encountered during import:
+ImportOperation_openStreamError = Error opening input stream for {0}
+ImportOperation_closeStreamError = Could not close input stream for {0}
+ImportOperation_coreImportError = Unable to import {0}. Reason: {1}
+ImportOperation_targetSameAsSourceError = Unable to import {0}. The file cannot be copied onto itself
+
+ZipImport_couldNotClose = Could not close file {0}
+ZipImport_badFormat = Source file is not a valid Zip file.
+ZipImport_couldNotRead = Source file could not be read.
+
+TarImport_badFormat = Source file is not a valid tar file.
+TarImport_invalid_tar_format = Not a valid tar format
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarEntry.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarEntry.java
new file mode 100644
index 0000000..5d0034e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarEntry.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 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.e4.demo.simpleide.internal.datatransfer;
+
+/**
+ * Representation of a file in a tar archive.
+ *
+ * @since 3.1
+ */
+public class TarEntry implements Cloneable
+{
+ private String name;
+ private long mode, time, size;
+ private int type;
+ int filepos;
+
+ /**
+ * Entry type for normal files.
+ */
+ public static final int FILE = '0';
+
+ /**
+ * Entry type for directories.
+ */
+ public static final int DIRECTORY = '5';
+
+ /**
+ * Create a new TarEntry for a file of the given name at the
+ * given position in the file.
+ *
+ * @param name filename
+ * @param pos position in the file in bytes
+ */
+ TarEntry(String name, int pos) {
+ this.name = name;
+ mode = 0644;
+ type = FILE;
+ filepos = pos;
+ time = System.currentTimeMillis() / 1000;
+ }
+
+ /**
+ * Create a new TarEntry for a file of the given name.
+ *
+ * @param name filename
+ */
+ public TarEntry(String name) {
+ this(name, -1);
+ }
+
+ /**
+ * Returns the type of this file, one of FILE, LINK, SYM_LINK,
+ * CHAR_DEVICE, BLOCK_DEVICE, DIRECTORY or FIFO.
+ *
+ * @return file type
+ */
+ public int getFileType() {
+ return type;
+ }
+
+ /**
+ * Returns the mode of the file in UNIX permissions format.
+ *
+ * @return file mode
+ */
+ public long getMode() {
+ return mode;
+ }
+
+ /**
+ * Returns the name of the file.
+ *
+ * @return filename
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the size of the file in bytes.
+ *
+ * @return filesize
+ */
+ public long getSize() {
+ return size;
+ }
+
+ /**
+ * Returns the modification time of the file in seconds since January
+ * 1st 1970.
+ *
+ * @return time
+ */
+ public long getTime() {
+ return time;
+ }
+
+ /**
+ * Sets the type of the file, one of FILE, LINK, SYMLINK, CHAR_DEVICE,
+ * BLOCK_DEVICE, or DIRECTORY.
+ *
+ * @param type
+ */
+ public void setFileType(int type) {
+ this.type = type;
+ }
+
+ /**
+ * Sets the mode of the file in UNIX permissions format.
+ *
+ * @param mode
+ */
+ public void setMode(long mode) {
+ this.mode = mode;
+ }
+
+ /**
+ * Sets the size of the file in bytes.
+ *
+ * @param size
+ */
+ public void setSize(long size) {
+ this.size = size;
+ }
+
+ /**
+ * Sets the modification time of the file in seconds since January
+ * 1st 1970.
+ *
+ * @param time
+ */
+ public void setTime(long time) {
+ this.time = time;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarException.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarException.java
new file mode 100644
index 0000000..c4ecc48
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarException.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 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.e4.demo.simpleide.internal.datatransfer;
+
+/**
+ * Exception generated upon encountering corrupted tar files.
+ */
+public class TarException extends Exception {
+ /**
+ * Generated serial version UID for this class.
+ */
+ private static final long serialVersionUID = 2886671254518853528L;
+
+ /**
+ * Constructs a TarException without a detail string.
+ */
+ public TarException() {
+ super();
+ }
+
+ /**
+ * Constructs a TarException with the specified detail string.
+ *
+ * @param s the detail string
+ */
+ public TarException(String s) {
+ super(s);
+ }
+
+ /**
+ * Constructs a TarException with the specified detail string.
+ *
+ * @param s the detail string
+ * @param cause the cause
+ */
+ public TarException(String s, Throwable cause) {
+ super(s, cause);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarFile.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarFile.java
new file mode 100644
index 0000000..bfc342b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarFile.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 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
+ * Remy Chi Jian Suen <remy.suen@gmail.com> - Bug 243347 TarFile should not throw NPE in finalize()
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.zip.GZIPInputStream;
+
+
+/**
+ * Reads a .tar or .tar.gz archive file, providing an index enumeration
+ * and allows for accessing an InputStream for arbitrary files in the
+ * archive.
+ *
+ * @since 3.1
+ */
+public class TarFile {
+ private File file;
+ private TarInputStream entryEnumerationStream;
+ private TarEntry curEntry;
+ private TarInputStream entryStream;
+
+ private InputStream internalEntryStream;
+ private Messages messages;
+
+ /**
+ * Create a new TarFile for the given file.
+ *
+ * @param file
+ * @throws TarException
+ * @throws IOException
+ */
+ public TarFile(File file, Messages messages) throws TarException, IOException {
+ this.file = file;
+ this.messages = messages;
+
+ InputStream in = new FileInputStream(file);
+ // First, check if it's a GZIPInputStream.
+ try {
+ in = new GZIPInputStream(in);
+ } catch(IOException e) {
+ //If it is not compressed we close
+ //the old one and recreate
+ in.close();
+ in = new FileInputStream(file);
+ }
+ try {
+ entryEnumerationStream = new TarInputStream(in, messages);
+ } catch (TarException ex) {
+ in.close();
+ throw ex;
+ }
+ curEntry = entryEnumerationStream.getNextEntry();
+ }
+
+ /**
+ * Close the tar file input stream.
+ *
+ * @throws IOException if the file cannot be successfully closed
+ */
+ public void close() throws IOException {
+ if (entryEnumerationStream != null)
+ entryEnumerationStream.close();
+ if (internalEntryStream != null)
+ internalEntryStream.close();
+ }
+
+ /**
+ * Create a new TarFile for the given path name.
+ *
+ * @param filename
+ * @throws TarException
+ * @throws IOException
+ */
+ public TarFile(String filename, Messages messages) throws TarException, IOException {
+ this(new File(filename),messages);
+ }
+
+ /**
+ * Returns an enumeration cataloguing the tar archive.
+ *
+ * @return enumeration of all files in the archive
+ */
+ public Enumeration<TarEntry> entries() {
+ return new Enumeration<TarEntry>() {
+ public boolean hasMoreElements() {
+ return (curEntry != null);
+ }
+
+ public TarEntry nextElement() {
+ TarEntry oldEntry = curEntry;
+ try {
+ curEntry = entryEnumerationStream.getNextEntry();
+ } catch(TarException e) {
+ curEntry = null;
+ } catch(IOException e) {
+ curEntry = null;
+ }
+ return oldEntry;
+ }
+ };
+ }
+
+ /**
+ * Returns a new InputStream for the given file in the tar archive.
+ *
+ * @param entry
+ * @return an input stream for the given file
+ * @throws TarException
+ * @throws IOException
+ */
+ public InputStream getInputStream(TarEntry entry) throws TarException, IOException {
+ if(entryStream == null || !entryStream.skipToEntry(entry)) {
+ if (internalEntryStream != null) {
+ internalEntryStream.close();
+ }
+ internalEntryStream = new FileInputStream(file);
+ // First, check if it's a GZIPInputStream.
+ try {
+ internalEntryStream = new GZIPInputStream(internalEntryStream);
+ } catch(IOException e) {
+ //If it is not compressed we close
+ //the old one and recreate
+ internalEntryStream.close();
+ internalEntryStream = new FileInputStream(file);
+ }
+ entryStream = new TarInputStream(internalEntryStream, entry, messages) {
+ public void close() {
+ // Ignore close() since we want to reuse the stream.
+ }
+ };
+ }
+ return entryStream;
+ }
+
+ /**
+ * Returns the path name of the file this archive represents.
+ *
+ * @return path
+ */
+ public String getName() {
+ return file.getPath();
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.zip.ZipFile#finalize()
+ *
+ */
+ protected void finalize() throws Throwable {
+ close();
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarInputStream.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarInputStream.java
new file mode 100644
index 0000000..c770520
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarInputStream.java
@@ -0,0 +1,346 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 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.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Input stream for reading files in ustar format (tar) compatible
+ * with the specification in IEEE Std 1003.1-2001. Also supports
+ * long filenames encoded using the GNU @LongLink extension.
+ *
+ * @since 3.1
+ */
+public class TarInputStream extends FilterInputStream
+{
+ private int nextEntry = 0;
+ private int nextEOF = 0;
+ private int filepos = 0;
+ private int bytesread = 0;
+ private TarEntry firstEntry = null;
+ private String longLinkName = null;
+ private Messages messages;
+
+ /**
+ * Creates a new tar input stream on the given input stream.
+ *
+ * @param in input stream
+ * @throws TarException
+ * @throws IOException
+ */
+ public TarInputStream(InputStream in, Messages messages) throws TarException, IOException {
+ super(in);
+ this.messages = messages;
+ // Read in the first TarEntry to make sure
+ // the input is a valid tar file stream.
+ firstEntry = getNextEntry();
+ }
+
+ /**
+ * Create a new tar input stream, skipping ahead to the given entry
+ * in the file.
+ *
+ * @param in input stream
+ * @param entry skips to this entry in the file
+ * @throws TarException
+ * @throws IOException
+ */
+ TarInputStream(InputStream in, TarEntry entry, Messages messages) throws TarException, IOException {
+ super(in);
+ this.messages = messages;
+ skipToEntry(entry);
+ }
+
+ /**
+ * The checksum of a tar file header is simply the sum of the bytes in
+ * the header.
+ *
+ * @param header
+ * @return checksum
+ */
+ private long headerChecksum(byte[] header) {
+ long sum = 0;
+ for(int i = 0; i < 512; i++) {
+ sum += header[i] & 0xff;
+ }
+ return sum;
+ }
+
+ /**
+ * Skips ahead to the position of the given entry in the file.
+ *
+ * @param entry
+ * @returns false if the entry has already been passed
+ * @throws TarException
+ * @throws IOException
+ */
+ boolean skipToEntry(TarEntry entry) throws TarException, IOException {
+ int bytestoskip = entry.filepos - bytesread;
+ if(bytestoskip < 0) {
+ return false;
+ }
+ while(bytestoskip > 0) {
+ long ret = in.skip(bytestoskip);
+ if(ret < 0) {
+ throw new IOException("early end of stream"); //$NON-NLS-1$
+ }
+ bytestoskip -= ret;
+ bytesread += ret;
+ }
+ filepos = entry.filepos;
+ nextEntry = 0;
+ nextEOF = 0;
+ // Read next header to seek to file data.
+ getNextEntry();
+ return true;
+ }
+
+ /**
+ * Returns true if the header checksum is correct.
+ *
+ * @param header
+ * @return true if this header has a valid checksum
+ */
+ private boolean isValidTarHeader(byte[] header) {
+ long fileChecksum, calculatedChecksum;
+ int pos, i;
+
+ pos = 148;
+ StringBuffer checksumString = new StringBuffer();
+ for(i = 0; i < 8; i++) {
+ if(header[pos + i] == ' ') {
+ continue;
+ }
+ if(header[pos + i] == 0 || !Character.isDigit((char) header[pos + i])) {
+ break;
+ }
+ checksumString.append((char) header[pos + i]);
+ }
+ if(checksumString.length() == 0) {
+ return false;
+ }
+ if(checksumString.charAt(0) != '0') {
+ checksumString.insert(0, '0');
+ }
+ try {
+ fileChecksum = Long.decode(checksumString.toString()).longValue();
+ } catch(NumberFormatException exception) {
+ //This is not valid if it cannot be parsed
+ return false;
+ }
+
+ // Blank out the checksum.
+ for(i = 0; i < 8; i++) {
+ header[pos + i] = ' ';
+ }
+ calculatedChecksum = headerChecksum(header);
+
+ return (fileChecksum == calculatedChecksum);
+ }
+
+ /**
+ * Returns the next entry in the tar file. Does not handle
+ * GNU @LongLink extensions.
+ *
+ * @return the next entry in the tar file
+ * @throws TarException
+ * @throws IOException
+ */
+ TarEntry getNextEntryInternal() throws TarException, IOException {
+ byte[] header = new byte[512];
+ int pos = 0;
+ int i;
+
+ if(firstEntry != null) {
+ TarEntry entryReturn = firstEntry;
+ firstEntry = null;
+ return entryReturn;
+ }
+
+ while(nextEntry > 0) {
+ long ret = in.skip(nextEntry);
+ if(ret < 0) {
+ throw new IOException("early end of stream"); //$NON-NLS-1$
+ }
+ nextEntry -= ret;
+ bytesread += ret;
+ }
+
+ int bytestoread = 512;
+ while(bytestoread > 0) {
+ int ret = super.read(header, 512 - bytestoread, bytestoread);
+ if( ret < 0 ) {
+ throw new IOException("early end of stream"); //$NON-NLS-1$
+ }
+ bytestoread -= ret;
+ bytesread += ret;
+ }
+
+ // If we have a header of all zeros, this marks the end of the file.
+ if(headerChecksum(header) == 0) {
+ // We are at the end of the file.
+ if(filepos > 0) {
+ return null;
+ }
+
+ // Invalid stream.
+ throw new TarException("not in tar format"); //$NON-NLS-1$
+ }
+
+ // Validate checksum.
+ if(!isValidTarHeader(header)) {
+ throw new TarException("not in tar format"); //$NON-NLS-1$
+ }
+
+ while (pos < 100 && header[pos] != 0) {
+ pos++;
+ }
+ String name = new String(header, 0, pos, "UTF8"); //$NON-NLS-1$
+ // Prepend the prefix here.
+ pos = 345;
+ if(header[pos] != 0) {
+ while (pos < 500 && header[pos] != 0) {
+ pos++;
+ }
+ String prefix = new String(header, 345, pos - 345, "UTF8"); //$NON-NLS-1$
+ name = prefix + "/" + name; //$NON-NLS-1$
+ }
+
+ TarEntry entry;
+ if(longLinkName != null) {
+ entry = new TarEntry(longLinkName, filepos);
+ longLinkName = null;
+ } else {
+ entry = new TarEntry(name, filepos);
+ }
+ if(header[156] != 0) {
+ entry.setFileType(header[156]);
+ }
+
+ pos = 100;
+ StringBuffer mode = new StringBuffer();
+ for(i = 0; i < 8; i++) {
+ if(header[pos + i] == 0) {
+ break;
+ }
+ if(header[pos + i] == ' ') {
+ continue;
+ }
+ mode.append((char) header[pos + i]);
+ }
+ if(mode.length() > 0 && mode.charAt(0) != '0') {
+ mode.insert(0, '0');
+ }
+ try {
+ long fileMode = Long.decode(mode.toString()).longValue();
+ entry.setMode(fileMode);
+ } catch(NumberFormatException nfe) {
+ throw new TarException(messages.TarImport_invalid_tar_format(), nfe);
+ }
+
+ pos = 100 + 24;
+ StringBuffer size = new StringBuffer();
+ for(i = 0; i < 12; i++) {
+ if(header[pos + i] == 0) {
+ break;
+ }
+ if(header[pos + i] == ' ') {
+ continue;
+ }
+ size.append((char) header[pos + i]);
+ }
+ if(size.charAt(0) != '0') {
+ size.insert(0, '0');
+ }
+ int fileSize;
+ try {
+ fileSize = Integer.decode(size.toString()).intValue();
+ } catch(NumberFormatException nfe) {
+ throw new TarException(messages.TarImport_invalid_tar_format(), nfe);
+ }
+
+ entry.setSize(fileSize);
+ nextEOF = fileSize;
+ if(fileSize % 512 > 0) {
+ nextEntry = fileSize + (512 - (fileSize % 512));
+ } else {
+ nextEntry = fileSize;
+ }
+ filepos += (nextEntry + 512);
+ return entry;
+ }
+
+ /**
+ * Moves ahead to the next file in the tar archive and returns
+ * a TarEntry object describing it.
+ *
+ * @return the next entry in the tar file
+ * @throws TarException
+ * @throws IOException
+ */
+ public TarEntry getNextEntry() throws TarException, IOException {
+ TarEntry entry = getNextEntryInternal();
+
+ if(entry != null && entry.getName().equals("././@LongLink")) { //$NON-NLS-1$
+ // This is a GNU extension for doing long filenames.
+ // We get a file called ././@LongLink which just contains
+ // the real pathname.
+ byte[] longNameData = new byte[(int) entry.getSize()];
+ int bytesread = 0;
+ while (bytesread < longNameData.length) {
+ int cur = read(longNameData, bytesread, longNameData.length - bytesread);
+ if (cur < 0) {
+ throw new IOException("early end of stream"); //$NON-NLS-1$
+ }
+ bytesread += cur;
+ }
+
+ int pos = 0;
+ while (pos < longNameData.length && longNameData[pos] != 0) {
+ pos++;
+ }
+ longLinkName = new String(longNameData, 0, pos, "UTF8"); //$NON-NLS-1$
+ return getNextEntryInternal();
+ }
+ return entry;
+ }
+
+ /* (non-Javadoc)
+ * @see java.io.FilterInputStream#read(byte[], int, int)
+ */
+ public int read(byte[] b, int off, int len) throws IOException {
+ if(nextEOF == 0) {
+ return -1;
+ }
+ if(len > nextEOF) {
+ len = nextEOF;
+ }
+ int size = super.read(b, off, len);
+ nextEntry -= size;
+ nextEOF -= size;
+ bytesread += size;
+ return size;
+ }
+
+ /* (non-Javadoc)
+ * @see java.io.FilterInputStream#read()
+ */
+ public int read() throws IOException {
+ byte[] data = new byte[1];
+ int size = read(data, 0, 1);
+ if (size < 0) {
+ return size;
+ }
+ return data[0];
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarLeveledStructureProvider.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarLeveledStructureProvider.java
new file mode 100644
index 0000000..44e9eb3
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/TarLeveledStructureProvider.java
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * Red Hat, Inc - Was TarFileStructureProvider, performed changes from
+ * IImportStructureProvider to ILeveledImportStructureProvider
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.eclipse.core.resources.ResourceAttributes;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.e4.core.services.log.Logger;
+
+/**
+ * This class provides information regarding the context structure and content
+ * of specified tar file entry objects.
+ *
+ * @since 3.1
+ */
+public class TarLeveledStructureProvider implements
+ ILeveledImportStructureProvider {
+ private TarFile tarFile;
+
+ private TarEntry root = new TarEntry("/");//$NON-NLS-1$
+
+ private Map<TarEntry,List<TarEntry>> children;
+
+ private Map<IPath,TarEntry> directoryEntryCache = new HashMap<IPath,TarEntry>();
+
+ private int stripLevel;
+
+ private Logger logger;
+
+ private Messages messages;
+
+ /**
+ * Creates a <code>TarFileStructureProvider</code>, which will operate on
+ * the passed tar file.
+ *
+ * @param sourceFile
+ * the source TarFile
+ */
+ public TarLeveledStructureProvider(TarFile sourceFile, Logger logger, Messages messages) {
+ super();
+ this.messages = messages;
+ this.logger = logger;
+ tarFile = sourceFile;
+ root.setFileType(TarEntry.DIRECTORY);
+ }
+
+ /**
+ * Creates a new container tar entry with the specified name, iff it has
+ * not already been created. If the parent of the given element does not
+ * already exist it will be recursively created as well.
+ * @param pathname The path representing the container
+ * @return The element represented by this pathname (it may have already existed)
+ */
+ protected TarEntry createContainer(IPath pathname) {
+ TarEntry existingEntry = (TarEntry) directoryEntryCache.get(pathname);
+ if (existingEntry != null) {
+ return existingEntry;
+ }
+
+ TarEntry parent;
+ if (pathname.segmentCount() == 1) {
+ parent = root;
+ } else {
+ parent = createContainer(pathname.removeLastSegments(1));
+ }
+ TarEntry newEntry = new TarEntry(pathname.toString());
+ newEntry.setFileType(TarEntry.DIRECTORY);
+ directoryEntryCache.put(pathname, newEntry);
+ List<TarEntry> childList = new ArrayList<TarEntry>();
+ children.put(newEntry, childList);
+
+ List<TarEntry> parentChildList = children.get(parent);
+ parentChildList.add(newEntry);
+ return newEntry;
+ }
+
+ /**
+ * Creates a new tar file entry with the specified name.
+ */
+ protected void createFile(TarEntry entry) {
+ IPath pathname = new Path(entry.getName());
+ TarEntry parent;
+ if (pathname.segmentCount() == 1) {
+ parent = root;
+ } else {
+ parent = (TarEntry) directoryEntryCache.get(pathname
+ .removeLastSegments(1));
+ }
+
+ List<TarEntry> childList = children.get(parent);
+ childList.add(entry);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IImportStructureProvider
+ */
+ public List<TarEntry> getChildren(Object element) {
+ if (children == null) {
+ initialize();
+ }
+
+ return children.get(element);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IImportStructureProvider
+ */
+ public InputStream getContents(Object element) {
+ try {
+ return tarFile.getInputStream((TarEntry) element);
+ } catch (TarException e) {
+ logger.error(e);
+// IDEWorkbenchPlugin.log(e.getLocalizedMessage(), e);
+ return null;
+ } catch (IOException e) {
+ logger.error(e);
+// IDEWorkbenchPlugin.log(e.getLocalizedMessage(), e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the resource attributes for this file.
+ *
+ * @param element
+ * @return the attributes of the file
+ */
+ public ResourceAttributes getResourceAttributes(Object element) {
+ ResourceAttributes attributes = new ResourceAttributes();
+ TarEntry entry = (TarEntry) element;
+ attributes.setExecutable((entry.getMode() & 0100) != 0);
+ attributes.setReadOnly((entry.getMode() & 0200) == 0);
+ return attributes;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IImportStructureProvider
+ */
+ public String getFullPath(Object element) {
+ return stripPath(((TarEntry) element).getName());
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IImportStructureProvider
+ */
+ public String getLabel(Object element) {
+ if (element.equals(root)) {
+ return ((TarEntry) element).getName();
+ }
+
+ return stripPath(new Path(((TarEntry) element).getName()).lastSegment());
+ }
+
+ /**
+ * Returns the entry that this importer uses as the root sentinel.
+ *
+ * @return TarEntry entry
+ */
+ public Object getRoot() {
+ return root;
+ }
+
+ /**
+ * Returns the tar file that this provider provides structure for.
+ *
+ * @return TarFile file
+ */
+ public TarFile getTarFile() {
+ return tarFile;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.internal.wizards.datatransfer.ILeveledImportStructureProvider#closeArchive()
+ */
+ public boolean closeArchive(){
+ try {
+ getTarFile().close();
+ } catch (IOException e) {
+ logger.error(e, messages.ZipImport_couldNotClose()
+ + getTarFile().getName());
+// IDEWorkbenchPlugin.log(DataTransferMessages.ZipImport_couldNotClose
+// + getTarFile().getName(), e);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Initializes this object's children table based on the contents of the
+ * specified source file.
+ */
+ protected void initialize() {
+ children = new HashMap<TarEntry,List<TarEntry>>(1000);
+
+ children.put(root, new ArrayList<TarEntry>());
+ Enumeration<TarEntry> entries = tarFile.entries();
+ while (entries.hasMoreElements()) {
+ TarEntry entry = (TarEntry) entries.nextElement();
+ IPath path = new Path(entry.getName()).addTrailingSeparator();
+
+ if (entry.getFileType() == TarEntry.DIRECTORY) {
+ createContainer(path);
+ } else
+ {
+ // Ensure the container structure for all levels above this is initialized
+ // Once we hit a higher-level container that's already added we need go no further
+ int pathSegmentCount = path.segmentCount();
+ if (pathSegmentCount > 1) {
+ createContainer(path.uptoSegment(pathSegmentCount - 1));
+ }
+ createFile(entry);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IImportStructureProvider
+ */
+ public boolean isFolder(Object element) {
+ return (((TarEntry) element).getFileType() == TarEntry.DIRECTORY);
+ }
+
+ /*
+ * Strip the leading directories from the path
+ */
+ private String stripPath(String path) {
+ String pathOrig = new String(path);
+ for (int i = 0; i < stripLevel; i++) {
+ int firstSep = path.indexOf('/');
+ // If the first character was a seperator we must strip to the next
+ // seperator as well
+ if (firstSep == 0) {
+ path = path.substring(1);
+ firstSep = path.indexOf('/');
+ }
+ // No seperator wasw present so we're in a higher directory right
+ // now
+ if (firstSep == -1) {
+ return pathOrig;
+ }
+ path = path.substring(firstSep);
+ }
+ return path;
+ }
+
+ public void setStrip(int level) {
+ stripLevel = level;
+ }
+
+ public int getStrip() {
+ return stripLevel;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/WizardProjectsImportPage.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/WizardProjectsImportPage.java
new file mode 100644
index 0000000..c49772e
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/WizardProjectsImportPage.java
@@ -0,0 +1,1647 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * Red Hat, Inc - extensive changes to allow importing of Archive Files
+ * Philippe Ombredanne (pombredanne@nexb.com)
+ * - Bug 101180 [Import/Export] Import Existing Project into Workspace default widget is back button , should be text field
+ * Martin Oberhuber (martin.oberhuber@windriver.com)
+ * - Bug 187318[Wizards] "Import Existing Project" loops forever with cyclic symbolic links
+ * Remy Chi Jian Suen (remy.suen@gmail.com)
+ * - Bug 210568 [Import/Export] [Import/Export] - Refresh button does not update list of projects
+ *******************************************************************************/
+
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.core.services.statusreporter.StatusReporter;
+import org.eclipse.e4.demo.simpleide.internal.datatransfer.actions.WorkspaceModifyOperation;
+import org.eclipse.e4.demo.simpleide.internal.datatransfer.dialogs.IOverwriteQuery;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.PixelConverter;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.IColorProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * The WizardProjectsImportPage is the page that allows the user to import
+ * projects from a particular location.
+ */
+public class WizardProjectsImportPage extends WizardPage implements
+ IOverwriteQuery {
+
+ /**
+ * The name of the folder containing metadata information for the workspace.
+ */
+ public static final String METADATA_FOLDER = ".metadata"; //$NON-NLS-1$
+
+ /**
+ * The import structure provider.
+ *
+ * @since 3.4
+ */
+ private ILeveledImportStructureProvider structureProvider;
+
+ /**
+ * @since 3.5
+ *
+ */
+ private final class ProjectLabelProvider extends LabelProvider implements
+ IColorProvider {
+
+ public String getText(Object element) {
+ return ((ProjectRecord) element).getProjectLabel();
+ }
+
+ public Color getBackground(Object element) {
+ return null;
+ }
+
+ public Color getForeground(Object element) {
+ ProjectRecord projectRecord = (ProjectRecord) element;
+ if (projectRecord.hasConflicts)
+ return getShell().getDisplay().getSystemColor(SWT.COLOR_GRAY);
+ return null;
+ }
+ }
+
+ /**
+ * Class declared public only for test suite.
+ *
+ */
+ public class ProjectRecord {
+ File projectSystemFile;
+
+ Object projectArchiveFile;
+
+ String projectName;
+
+ Object parent;
+
+ int level;
+
+ boolean hasConflicts;
+
+ IProjectDescription description;
+
+ /**
+ * Create a record for a project based on the info in the file.
+ *
+ * @param file
+ */
+ ProjectRecord(File file) {
+ projectSystemFile = file;
+ setProjectName();
+ }
+
+ /**
+ * @param file
+ * The Object representing the .project file
+ * @param parent
+ * The parent folder of the .project file
+ * @param level
+ * The number of levels deep in the provider the file is
+ */
+ ProjectRecord(Object file, Object parent, int level) {
+ this.projectArchiveFile = file;
+ this.parent = parent;
+ this.level = level;
+ setProjectName();
+ }
+
+ /**
+ * Set the name of the project based on the projectFile.
+ */
+ private void setProjectName() {
+ try {
+ if (projectArchiveFile != null) {
+ InputStream stream = structureProvider
+ .getContents(projectArchiveFile);
+
+ // If we can get a description pull the name from there
+ if (stream == null) {
+ if (projectArchiveFile instanceof ZipEntry) {
+ IPath path = new Path(
+ ((ZipEntry) projectArchiveFile).getName());
+ projectName = path.segment(path.segmentCount() - 2);
+ } else if (projectArchiveFile instanceof TarEntry) {
+ IPath path = new Path(
+ ((TarEntry) projectArchiveFile).getName());
+ projectName = path.segment(path.segmentCount() - 2);
+ }
+ } else {
+ description = workspace.loadProjectDescription(stream);
+ stream.close();
+ projectName = description.getName();
+ }
+
+ }
+
+ // If we don't have the project name try again
+ if (projectName == null) {
+ IPath path = new Path(projectSystemFile.getPath());
+ // if the file is in the default location, use the directory
+ // name as the project name
+ if (isDefaultLocation(path)) {
+ projectName = path.segment(path.segmentCount() - 2);
+ description = workspace
+ .newProjectDescription(projectName);
+ } else {
+ description = workspace.loadProjectDescription(path);
+ projectName = description.getName();
+ }
+
+ }
+ } catch (CoreException e) {
+ // no good couldn't get the name
+ } catch (IOException e) {
+ // no good couldn't get the name
+ }
+ }
+
+ /**
+ * Returns whether the given project description file path is in the
+ * default location for a project
+ *
+ * @param path
+ * The path to examine
+ * @return Whether the given path is the default location for a project
+ */
+ private boolean isDefaultLocation(IPath path) {
+ // The project description file must at least be within the project,
+ // which is within the workspace location
+ if (path.segmentCount() < 2)
+ return false;
+ return path.removeLastSegments(2).toFile()
+ .equals(Platform.getLocation().toFile());
+ }
+
+ /**
+ * Get the name of the project
+ *
+ * @return String
+ */
+ public String getProjectName() {
+ return projectName;
+ }
+
+ /**
+ * Gets the label to be used when rendering this project record in the
+ * UI.
+ *
+ * @return String the label
+ * @since 3.4
+ */
+ public String getProjectLabel() {
+ if (description == null)
+ return projectName;
+
+ String path = projectSystemFile == null ? structureProvider
+ .getLabel(parent) : projectSystemFile.getParent();
+
+ return NLS.bind(
+ messsagesLookup.WizardProjectsImportPage_ProjectLabel(),
+ projectName, path);
+ }
+
+ /**
+ * @return Returns the hasConflicts.
+ */
+ public boolean hasConflicts() {
+ return hasConflicts;
+ }
+ }
+
+ // dialog store id constants
+ private final static String STORE_COPY_PROJECT_ID = "WizardProjectsImportPage.STORE_COPY_PROJECT_ID"; //$NON-NLS-1$
+
+ private final static String STORE_ARCHIVE_SELECTED = "WizardProjectsImportPage.STORE_ARCHIVE_SELECTED"; //$NON-NLS-1$
+
+ private Text directoryPathField;
+
+ private CheckboxTreeViewer projectsList;
+
+ private Button copyCheckbox;
+
+ private boolean copyFiles = false;
+
+ private ProjectRecord[] selectedProjects = new ProjectRecord[0];
+
+ // Keep track of the directory that we browsed to last time
+ // the wizard was invoked.
+ private static String previouslyBrowsedDirectory = ""; //$NON-NLS-1$
+
+ // Keep track of the archive that we browsed to last time
+ // the wizard was invoked.
+ private static String previouslyBrowsedArchive = ""; //$NON-NLS-1$
+
+ private Button projectFromDirectoryRadio;
+
+ private Button projectFromArchiveRadio;
+
+ private Text archivePathField;
+
+ private Button browseDirectoriesButton;
+
+ private Button browseArchivesButton;
+
+ private IProject[] wsProjects;
+
+ // constant from WizardArchiveFileResourceImportPage1
+ private static final String[] FILE_IMPORT_MASK = {
+ "*.jar;*.zip;*.tar;*.tar.gz;*.tgz", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+ // The initial path to set
+ private String initialPath;
+
+ // The last selected path to minimize searches
+ private String lastPath;
+ // The last time that the file or folder at the selected path was modified
+ // to mimize searches
+ private long lastModified;
+
+ // TODO SimpleIDE
+ // private WorkingSetGroup workingSetGroup;
+
+ // private IStructuredSelection currentSelection;
+
+ private IWorkspace workspace;
+
+ private Logger logger;
+
+ private StatusReporter statusReporter;
+
+ private Messages messsagesLookup;
+
+ /**
+ * Creates a new project creation wizard page.
+ *
+ */
+ public WizardProjectsImportPage(IWorkspace workspace,
+ StatusReporter statusReporter, Logger logger,
+ Messages messsagesLookup) {
+ this(
+ "wizardExternalProjectsPage", null, null, workspace, statusReporter, logger, messsagesLookup); //$NON-NLS-1$
+ }
+
+ /**
+ * Create a new instance of the receiver.
+ *
+ * @param pageName
+ */
+ public WizardProjectsImportPage(String pageName, IWorkspace workspace,
+ StatusReporter statusReporter, Logger logger,
+ Messages messsagesLookup) {
+ this(pageName, null, null, workspace, statusReporter, logger,
+ messsagesLookup);
+ }
+
+ /**
+ * More (many more) parameters.
+ *
+ * @param pageName
+ * @param initialPath
+ * @param currentSelection
+ * @since 3.5
+ */
+ public WizardProjectsImportPage(String pageName, String initialPath,
+ IStructuredSelection currentSelection, IWorkspace workspace,
+ StatusReporter statusReporter, Logger logger,
+ Messages messsagesLookup) {
+ super(pageName);
+ this.messsagesLookup = messsagesLookup;
+ this.logger = logger;
+ this.statusReporter = statusReporter;
+ this.workspace = workspace;
+ this.initialPath = initialPath;
+ // this.currentSelection = currentSelection;
+ setPageComplete(false);
+ setTitle(messsagesLookup.WizardProjectsImportPage_ImportProjectsTitle());
+ setDescription(messsagesLookup
+ .WizardProjectsImportPage_ImportProjectsDescription());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets
+ * .Composite)
+ */
+ public void createControl(Composite parent) {
+
+ initializeDialogUnits(parent);
+
+ Composite workArea = new Composite(parent, SWT.NONE);
+ setControl(workArea);
+
+ workArea.setLayout(new GridLayout());
+ workArea.setLayoutData(new GridData(GridData.FILL_BOTH
+ | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));
+
+ createProjectsRoot(workArea);
+ createProjectsList(workArea);
+ createOptionsArea(workArea);
+ // TODO SimpleIDE createWorkingSetGroup(workArea);
+ restoreWidgetValues();
+ Dialog.applyDialogFont(workArea);
+
+ }
+
+ // TODO SimpleIDE
+ // /**
+ // * @param workArea
+ // */
+ // private void createWorkingSetGroup(Composite workArea) {
+ // String[] workingSetIds = new String[] {"org.eclipse.ui.resourceWorkingSetPage", //$NON-NLS-1$
+ // "org.eclipse.jdt.ui.JavaWorkingSetPage"}; //$NON-NLS-1$
+ // workingSetGroup = new WorkingSetGroup(workArea, currentSelection,
+ // workingSetIds);
+ // }
+
+ /**
+ * Create the area with the extra options.
+ *
+ * @param workArea
+ */
+ private void createOptionsArea(Composite workArea) {
+ Composite optionsGroup = new Composite(workArea, SWT.NONE);
+ optionsGroup.setLayout(new GridLayout());
+ optionsGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ copyCheckbox = new Button(optionsGroup, SWT.CHECK);
+ copyCheckbox.setText(messsagesLookup
+ .WizardProjectsImportPage_CopyProjectsIntoWorkspace());
+ copyCheckbox.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ copyCheckbox.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ copyFiles = copyCheckbox.getSelection();
+ }
+ });
+ }
+
+ /**
+ * Create the checkbox list for the found projects.
+ *
+ * @param workArea
+ */
+ private void createProjectsList(Composite workArea) {
+
+ Label title = new Label(workArea, SWT.NONE);
+ title.setText(messsagesLookup
+ .WizardProjectsImportPage_ProjectsListTitle());
+
+ Composite listComposite = new Composite(workArea, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ layout.marginWidth = 0;
+ layout.makeColumnsEqualWidth = false;
+ listComposite.setLayout(layout);
+
+ listComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
+ | GridData.GRAB_VERTICAL | GridData.FILL_BOTH));
+
+ projectsList = new CheckboxTreeViewer(listComposite, SWT.BORDER);
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
+ gridData.widthHint = new PixelConverter(projectsList.getControl())
+ .convertWidthInCharsToPixels(25);
+ gridData.heightHint = new PixelConverter(projectsList.getControl())
+ .convertHeightInCharsToPixels(10);
+ projectsList.getControl().setLayoutData(gridData);
+ projectsList.setContentProvider(new ITreeContentProvider() {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java
+ * .lang.Object)
+ */
+ public Object[] getChildren(Object parentElement) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.viewers.IStructuredContentProvider#getElements
+ * (java.lang.Object)
+ */
+ public Object[] getElements(Object inputElement) {
+ return getProjectRecords();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java
+ * .lang.Object)
+ */
+ public boolean hasChildren(Object element) {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.viewers.ITreeContentProvider#getParent(java
+ * .lang.Object)
+ */
+ public Object getParent(Object element) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse
+ * .jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ public void inputChanged(Viewer viewer, Object oldInput,
+ Object newInput) {
+ }
+
+ });
+
+ projectsList.setLabelProvider(new ProjectLabelProvider());
+
+ projectsList.addCheckStateListener(new ICheckStateListener() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged
+ * (org.eclipse.jface.viewers.CheckStateChangedEvent)
+ */
+ public void checkStateChanged(CheckStateChangedEvent event) {
+ ProjectRecord element = (ProjectRecord) event.getElement();
+ if (element.hasConflicts) {
+ projectsList.setChecked(element, false);
+ }
+ setPageComplete(projectsList.getCheckedElements().length > 0);
+ }
+ });
+
+ projectsList.setInput(this);
+ projectsList.setComparator(new ViewerComparator());
+ createSelectionButtons(listComposite);
+ }
+
+ /**
+ * Create the selection buttons in the listComposite.
+ *
+ * @param listComposite
+ */
+ private void createSelectionButtons(Composite listComposite) {
+ Composite buttonsComposite = new Composite(listComposite, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ buttonsComposite.setLayout(layout);
+
+ buttonsComposite.setLayoutData(new GridData(
+ GridData.VERTICAL_ALIGN_BEGINNING));
+
+ Button selectAll = new Button(buttonsComposite, SWT.PUSH);
+ selectAll.setText(messsagesLookup.WizardProjectsImportPage_SelectAll());
+ selectAll.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ for (int i = 0; i < selectedProjects.length; i++) {
+ if (selectedProjects[i].hasConflicts)
+ projectsList.setChecked(selectedProjects[i], false);
+ else
+ projectsList.setChecked(selectedProjects[i], true);
+ }
+ setPageComplete(projectsList.getCheckedElements().length > 0);
+ }
+ });
+ Dialog.applyDialogFont(selectAll);
+ setButtonLayoutData(selectAll);
+
+ Button deselectAll = new Button(buttonsComposite, SWT.PUSH);
+ deselectAll.setText(messsagesLookup
+ .WizardProjectsImportPage_DeselectAll());
+ deselectAll.addSelectionListener(new SelectionAdapter() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse
+ * .swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+
+ projectsList.setCheckedElements(new Object[0]);
+ setPageComplete(false);
+ }
+ });
+ Dialog.applyDialogFont(deselectAll);
+ setButtonLayoutData(deselectAll);
+
+ Button refresh = new Button(buttonsComposite, SWT.PUSH);
+ refresh.setText(messsagesLookup.WizardProjectsImportPage_Refresh());
+ refresh.addSelectionListener(new SelectionAdapter() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse
+ * .swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ if (projectFromDirectoryRadio.getSelection()) {
+ updateProjectsList(directoryPathField.getText().trim());
+ } else {
+ updateProjectsList(archivePathField.getText().trim());
+ }
+ }
+ });
+ Dialog.applyDialogFont(refresh);
+ setButtonLayoutData(refresh);
+ }
+
+ /**
+ * Create the area where you select the root directory for the projects.
+ *
+ * @param workArea
+ * Composite
+ */
+ private void createProjectsRoot(Composite workArea) {
+
+ // project specification group
+ Composite projectGroup = new Composite(workArea, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 3;
+ layout.makeColumnsEqualWidth = false;
+ layout.marginWidth = 0;
+ projectGroup.setLayout(layout);
+ projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ // new project from directory radio button
+ projectFromDirectoryRadio = new Button(projectGroup, SWT.RADIO);
+ projectFromDirectoryRadio.setText(messsagesLookup
+ .WizardProjectsImportPage_RootSelectTitle());
+
+ // project location entry field
+ this.directoryPathField = new Text(projectGroup, SWT.BORDER);
+
+ GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true,
+ false);
+ directoryPathData.widthHint = new PixelConverter(directoryPathField)
+ .convertWidthInCharsToPixels(25);
+ directoryPathField.setLayoutData(directoryPathData);
+
+ // browse button
+ browseDirectoriesButton = new Button(projectGroup, SWT.PUSH);
+ browseDirectoriesButton.setText(messsagesLookup
+ .WizardProjectsImportPage_browse());
+ setButtonLayoutData(browseDirectoriesButton);
+
+ // new project from archive radio button
+ projectFromArchiveRadio = new Button(projectGroup, SWT.RADIO);
+ projectFromArchiveRadio.setText(messsagesLookup
+ .WizardProjectsImportPage_ArchiveSelectTitle());
+
+ // project location entry field
+ archivePathField = new Text(projectGroup, SWT.BORDER);
+
+ GridData archivePathData = new GridData(SWT.FILL, SWT.NONE, true, false);
+ archivePathData.widthHint = new PixelConverter(archivePathField)
+ .convertWidthInCharsToPixels(25);
+ archivePathField.setLayoutData(archivePathData); // browse button
+ browseArchivesButton = new Button(projectGroup, SWT.PUSH);
+ browseArchivesButton.setText(messsagesLookup
+ .WizardProjectsImportPage_browse());
+ setButtonLayoutData(browseArchivesButton);
+
+ projectFromDirectoryRadio.setSelection(true);
+ archivePathField.setEnabled(false);
+ browseArchivesButton.setEnabled(false);
+
+ browseDirectoriesButton.addSelectionListener(new SelectionAdapter() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.swt.events.SelectionAdapter#widgetS
+ * elected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ handleLocationDirectoryButtonPressed();
+ }
+
+ });
+
+ browseArchivesButton.addSelectionListener(new SelectionAdapter() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse
+ * .swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ handleLocationArchiveButtonPressed();
+ }
+
+ });
+
+ directoryPathField.addTraverseListener(new TraverseListener() {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.swt.events.TraverseListener#keyTraversed(org.eclipse
+ * .swt.events.TraverseEvent)
+ */
+ public void keyTraversed(TraverseEvent e) {
+ if (e.detail == SWT.TRAVERSE_RETURN) {
+ e.doit = false;
+ updateProjectsList(directoryPathField.getText().trim());
+ }
+ }
+
+ });
+
+ directoryPathField.addFocusListener(new FocusAdapter() {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt
+ * .events.FocusEvent)
+ */
+ public void focusLost(org.eclipse.swt.events.FocusEvent e) {
+ updateProjectsList(directoryPathField.getText().trim());
+ }
+
+ });
+
+ archivePathField.addTraverseListener(new TraverseListener() {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.swt.events.TraverseListener#keyTraversed(org.eclipse
+ * .swt.events.TraverseEvent)
+ */
+ public void keyTraversed(TraverseEvent e) {
+ if (e.detail == SWT.TRAVERSE_RETURN) {
+ e.doit = false;
+ updateProjectsList(archivePathField.getText().trim());
+ }
+ }
+
+ });
+
+ archivePathField.addFocusListener(new FocusAdapter() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt
+ * .events.FocusEvent)
+ */
+ public void focusLost(org.eclipse.swt.events.FocusEvent e) {
+ updateProjectsList(archivePathField.getText().trim());
+ }
+ });
+
+ projectFromDirectoryRadio.addSelectionListener(new SelectionAdapter() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse
+ * .swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ directoryRadioSelected();
+ }
+ });
+
+ projectFromArchiveRadio.addSelectionListener(new SelectionAdapter() {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse
+ * .swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ archiveRadioSelected();
+ }
+ });
+ }
+
+ private void archiveRadioSelected() {
+ if (projectFromArchiveRadio.getSelection()) {
+ directoryPathField.setEnabled(false);
+ browseDirectoriesButton.setEnabled(false);
+ archivePathField.setEnabled(true);
+ browseArchivesButton.setEnabled(true);
+ updateProjectsList(archivePathField.getText());
+ archivePathField.setFocus();
+ copyCheckbox.setSelection(true);
+ copyCheckbox.setEnabled(false);
+ }
+ }
+
+ private void directoryRadioSelected() {
+ if (projectFromDirectoryRadio.getSelection()) {
+ directoryPathField.setEnabled(true);
+ browseDirectoriesButton.setEnabled(true);
+ archivePathField.setEnabled(false);
+ browseArchivesButton.setEnabled(false);
+ updateProjectsList(directoryPathField.getText());
+ directoryPathField.setFocus();
+ copyCheckbox.setEnabled(true);
+ copyCheckbox.setSelection(copyFiles);
+ }
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IDialogPage. Set the focus on path
+ * fields when page becomes visible.
+ */
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+ if (visible && this.projectFromDirectoryRadio.getSelection()) {
+ this.directoryPathField.setFocus();
+ }
+ if (visible && this.projectFromArchiveRadio.getSelection()) {
+ this.archivePathField.setFocus();
+ }
+ }
+
+ /**
+ * Update the list of projects based on path. Method declared public only
+ * for test suite.
+ *
+ * @param path
+ */
+ public void updateProjectsList(final String path) {
+ // on an empty path empty selectedProjects
+ if (path == null || path.length() == 0) {
+ setMessage(messsagesLookup
+ .WizardProjectsImportPage_ImportProjectsDescription());
+ selectedProjects = new ProjectRecord[0];
+ projectsList.refresh(true);
+ projectsList.setCheckedElements(selectedProjects);
+ setPageComplete(projectsList.getCheckedElements().length > 0);
+ lastPath = path;
+ return;
+ }
+
+ final File directory = new File(path);
+ long modified = directory.lastModified();
+ if (path.equals(lastPath) && lastModified == modified) {
+ // since the file/folder was not modified and the path did not
+ // change, no refreshing is required
+ return;
+ }
+
+ lastPath = path;
+ lastModified = modified;
+
+ // We can't access the radio button from the inner class so get the
+ // status beforehand
+ final boolean dirSelected = this.projectFromDirectoryRadio
+ .getSelection();
+ try {
+ getContainer().run(true, true, new IRunnableWithProgress() {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.jface.operation.IRunnableWithProgress#run(org
+ * .eclipse.core.runtime.IProgressMonitor)
+ */
+ public void run(IProgressMonitor monitor) {
+
+ monitor.beginTask(messsagesLookup
+ .WizardProjectsImportPage_SearchingMessage(), 100);
+ selectedProjects = new ProjectRecord[0];
+ Collection<Object> files = new ArrayList<Object>();
+ monitor.worked(10);
+ if (!dirSelected
+ && ArchiveFileManipulations.isTarFile(path,messsagesLookup)) {
+ TarFile sourceTarFile = getSpecifiedTarSourceFile(path);
+ if (sourceTarFile == null) {
+ return;
+ }
+
+ structureProvider = new TarLeveledStructureProvider(
+ sourceTarFile, logger, messsagesLookup);
+ Object child = structureProvider.getRoot();
+
+ if (!collectProjectFilesFromProvider(files, child, 0,
+ monitor)) {
+ return;
+ }
+ Iterator<Object> filesIterator = files.iterator();
+ selectedProjects = new ProjectRecord[files.size()];
+ int index = 0;
+ monitor.worked(50);
+ monitor.subTask(messsagesLookup
+ .WizardProjectsImportPage_ProcessingMessage());
+ while (filesIterator.hasNext()) {
+ selectedProjects[index++] = (ProjectRecord) filesIterator
+ .next();
+ }
+ } else if (!dirSelected
+ && ArchiveFileManipulations.isZipFile(path)) {
+ ZipFile sourceFile = getSpecifiedZipSourceFile(path);
+ if (sourceFile == null) {
+ return;
+ }
+ structureProvider = new ZipLeveledStructureProvider(
+ sourceFile, logger);
+ Object child = structureProvider.getRoot();
+
+ if (!collectProjectFilesFromProvider(files, child, 0,
+ monitor)) {
+ return;
+ }
+ Iterator<Object> filesIterator = files.iterator();
+ selectedProjects = new ProjectRecord[files.size()];
+ int index = 0;
+ monitor.worked(50);
+ monitor.subTask(messsagesLookup
+ .WizardProjectsImportPage_ProcessingMessage());
+ while (filesIterator.hasNext()) {
+ selectedProjects[index++] = (ProjectRecord) filesIterator
+ .next();
+ }
+ }
+
+ else if (dirSelected && directory.isDirectory()) {
+
+ if (!collectProjectFilesFromDirectory(files, directory,
+ null, monitor)) {
+ return;
+ }
+ Iterator<Object> filesIterator = files.iterator();
+ selectedProjects = new ProjectRecord[files.size()];
+ int index = 0;
+ monitor.worked(50);
+ monitor.subTask(messsagesLookup
+ .WizardProjectsImportPage_ProcessingMessage());
+ while (filesIterator.hasNext()) {
+ File file = (File) filesIterator.next();
+ selectedProjects[index] = new ProjectRecord(file);
+ index++;
+ }
+ } else {
+ monitor.worked(60);
+ }
+ monitor.done();
+ }
+
+ });
+ } catch (InvocationTargetException e) {
+ logger.error(e);
+ // IDEWorkbenchPlugin.log(e.getMessage(), e);
+ } catch (InterruptedException e) {
+ // Nothing to do if the user interrupts.
+ }
+
+ projectsList.refresh(true);
+ ProjectRecord[] projects = getProjectRecords();
+ boolean displayWarning = false;
+ for (int i = 0; i < projects.length; i++) {
+ if (projects[i].hasConflicts) {
+ displayWarning = true;
+ projectsList.setGrayed(projects[i], true);
+ } else {
+ projectsList.setChecked(projects[i], true);
+ }
+ }
+
+ if (displayWarning) {
+ setMessage(
+ messsagesLookup
+ .WizardProjectsImportPage_ProjectsInWorkspace(),
+ WARNING);
+ } else {
+ setMessage(messsagesLookup
+ .WizardProjectsImportPage_ImportProjectsDescription());
+ }
+ setPageComplete(projectsList.getCheckedElements().length > 0);
+ if (selectedProjects.length == 0) {
+ setMessage(
+ messsagesLookup
+ .WizardProjectsImportPage_NoProjectsToImport(),
+ WARNING);
+ }
+ }
+
+ /**
+ * Answer a handle to the zip file currently specified as being the source.
+ * Return null if this file does not exist or is not of valid format.
+ */
+ private ZipFile getSpecifiedZipSourceFile(String fileName) {
+ if (fileName.length() == 0) {
+ return null;
+ }
+
+ try {
+ return new ZipFile(fileName);
+ } catch (ZipException e) {
+ displayErrorDialog(messsagesLookup.ZipImport_badFormat());
+ } catch (IOException e) {
+ displayErrorDialog(messsagesLookup.ZipImport_couldNotRead());
+ }
+
+ archivePathField.setFocus();
+ return null;
+ }
+
+ /**
+ * Answer a handle to the zip file currently specified as being the source.
+ * Return null if this file does not exist or is not of valid format.
+ */
+ private TarFile getSpecifiedTarSourceFile(String fileName) {
+ if (fileName.length() == 0) {
+ return null;
+ }
+
+ try {
+ return new TarFile(fileName,messsagesLookup);
+ } catch (TarException e) {
+ displayErrorDialog(messsagesLookup.TarImport_badFormat());
+ } catch (IOException e) {
+ displayErrorDialog(messsagesLookup.ZipImport_couldNotRead());
+ }
+
+ archivePathField.setFocus();
+ return null;
+ }
+
+ /**
+ * Display an error dialog with the specified message.
+ *
+ * @param message
+ * the error message
+ */
+ protected void displayErrorDialog(String message) {
+ MessageDialog.open(MessageDialog.ERROR, getContainer().getShell(),
+ getErrorDialogTitle(), message, SWT.SHEET);
+ }
+
+ /**
+ * Get the title for an error dialog. Subclasses should override.
+ */
+ protected String getErrorDialogTitle() {
+ return IDEWorkbenchMessages.WizardExportPage_internalErrorTitle;
+ }
+
+ /**
+ * Collect the list of .project files that are under directory into files.
+ *
+ * @param files
+ * @param directory
+ * @param directoriesVisited
+ * Set of canonical paths of directories, used as recursion guard
+ * @param monitor
+ * The monitor to report to
+ * @return boolean <code>true</code> if the operation was completed.
+ */
+ private boolean collectProjectFilesFromDirectory(Collection<Object> files,
+ File directory, Set<String> directoriesVisited,
+ IProgressMonitor monitor) {
+
+ if (monitor.isCanceled()) {
+ return false;
+ }
+ monitor.subTask(NLS.bind(
+ messsagesLookup.WizardProjectsImportPage_CheckingMessage(),
+ directory.getPath()));
+ File[] contents = directory.listFiles();
+ if (contents == null)
+ return false;
+
+ // Initialize recursion guard for recursive symbolic links
+ if (directoriesVisited == null) {
+ directoriesVisited = new HashSet<String>();
+ try {
+ directoriesVisited.add(directory.getCanonicalPath());
+ } catch (IOException exception) {
+ statusReporter.report(
+ new Status(IStatus.ERROR, FrameworkUtil.getBundle(
+ getClass()).getSymbolicName(), exception
+ .getLocalizedMessage(), exception),
+ StatusReporter.ERROR);
+ // StatusManager.getManager().handle(
+ // StatusUtil.newStatus(IStatus.ERROR, exception
+ // .getLocalizedMessage(), exception));
+ }
+ }
+
+ // first look for project description files
+ final String dotProject = IProjectDescription.DESCRIPTION_FILE_NAME;
+ for (int i = 0; i < contents.length; i++) {
+ File file = contents[i];
+ if (file.isFile() && file.getName().equals(dotProject)) {
+ files.add(file);
+ // don't search sub-directories since we can't have nested
+ // projects
+ return true;
+ }
+ }
+ // no project description found, so recurse into sub-directories
+ for (int i = 0; i < contents.length; i++) {
+ if (contents[i].isDirectory()) {
+ if (!contents[i].getName().equals(METADATA_FOLDER)) {
+ try {
+ String canonicalPath = contents[i].getCanonicalPath();
+ if (!directoriesVisited.add(canonicalPath)) {
+ // already been here --> do not recurse
+ continue;
+ }
+ } catch (IOException exception) {
+ statusReporter.report(
+ new Status(IStatus.ERROR, FrameworkUtil
+ .getBundle(getClass())
+ .getSymbolicName(), exception
+ .getLocalizedMessage(), exception),
+ StatusReporter.ERROR);
+ //
+ // StatusManager.getManager().handle(
+ // StatusUtil.newStatus(IStatus.ERROR, exception
+ // .getLocalizedMessage(), exception));
+
+ }
+ collectProjectFilesFromDirectory(files, contents[i],
+ directoriesVisited, monitor);
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Collect the list of .project files that are under directory into files.
+ *
+ * @param files
+ * @param monitor
+ * The monitor to report to
+ * @return boolean <code>true</code> if the operation was completed.
+ */
+ private boolean collectProjectFilesFromProvider(Collection<Object> files,
+ Object entry, int level, IProgressMonitor monitor) {
+
+ if (monitor.isCanceled()) {
+ return false;
+ }
+ monitor.subTask(NLS.bind(
+ messsagesLookup.WizardProjectsImportPage_CheckingMessage(),
+ structureProvider.getLabel(entry)));
+ List<?> children = structureProvider.getChildren(entry);
+ if (children == null) {
+ children = new ArrayList<Object>(1);
+ }
+ Iterator<?> childrenEnum = children.iterator();
+ while (childrenEnum.hasNext()) {
+ Object child = childrenEnum.next();
+ if (structureProvider.isFolder(child)) {
+ collectProjectFilesFromProvider(files, child, level + 1,
+ monitor);
+ }
+ String elementLabel = structureProvider.getLabel(child);
+ if (elementLabel.equals(IProjectDescription.DESCRIPTION_FILE_NAME)) {
+ files.add(new ProjectRecord(child, entry, level));
+ }
+ }
+ return true;
+ }
+
+ /**
+ * The browse button has been selected. Select the location.
+ */
+ protected void handleLocationDirectoryButtonPressed() {
+
+ DirectoryDialog dialog = new DirectoryDialog(
+ directoryPathField.getShell(), SWT.SHEET);
+ dialog.setMessage(messsagesLookup
+ .WizardProjectsImportPage_SelectDialogTitle());
+
+ String dirName = directoryPathField.getText().trim();
+ if (dirName.length() == 0) {
+ dirName = previouslyBrowsedDirectory;
+ }
+
+ if (dirName.length() == 0) {
+ dialog.setFilterPath(workspace.getRoot().getLocation().toOSString());
+ } else {
+ File path = new File(dirName);
+ if (path.exists()) {
+ dialog.setFilterPath(new Path(dirName).toOSString());
+ }
+ }
+
+ String selectedDirectory = dialog.open();
+ if (selectedDirectory != null) {
+ previouslyBrowsedDirectory = selectedDirectory;
+ directoryPathField.setText(previouslyBrowsedDirectory);
+ updateProjectsList(selectedDirectory);
+ }
+
+ }
+
+ /**
+ * The browse button has been selected. Select the location.
+ */
+ protected void handleLocationArchiveButtonPressed() {
+
+ FileDialog dialog = new FileDialog(archivePathField.getShell(),
+ SWT.SHEET);
+ dialog.setFilterExtensions(FILE_IMPORT_MASK);
+ dialog.setText(messsagesLookup
+ .WizardProjectsImportPage_SelectArchiveDialogTitle());
+
+ String fileName = archivePathField.getText().trim();
+ if (fileName.length() == 0) {
+ fileName = previouslyBrowsedArchive;
+ }
+
+ if (fileName.length() == 0) {
+ dialog.setFilterPath(workspace.getRoot().getLocation().toOSString());
+ } else {
+ File path = new File(fileName).getParentFile();
+ if (path != null && path.exists()) {
+ dialog.setFilterPath(path.toString());
+ }
+ }
+
+ String selectedArchive = dialog.open();
+ if (selectedArchive != null) {
+ previouslyBrowsedArchive = selectedArchive;
+ archivePathField.setText(previouslyBrowsedArchive);
+ updateProjectsList(selectedArchive);
+ }
+
+ }
+
+ /**
+ * Create the selected projects
+ *
+ * @return boolean <code>true</code> if all project creations were
+ * successful.
+ */
+ public boolean createProjects() {
+ saveWidgetValues();
+
+ final Object[] selected = projectsList.getCheckedElements();
+ createdProjects = new ArrayList<IProject>();
+ WorkspaceModifyOperation op = new WorkspaceModifyOperation(workspace) {
+
+ protected void execute(IProgressMonitor monitor)
+ throws InvocationTargetException, InterruptedException {
+ try {
+ monitor.beginTask("", selected.length); //$NON-NLS-1$
+ if (monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ for (int i = 0; i < selected.length; i++) {
+ createExistingProject((ProjectRecord) selected[i],
+ new SubProgressMonitor(monitor, 1));
+ }
+ } finally {
+ monitor.done();
+ }
+ }
+ };
+ // run the new project creation operation
+ try {
+ getContainer().run(true, true, op);
+ } catch (InterruptedException e) {
+ return false;
+ } catch (InvocationTargetException e) {
+ // one of the steps resulted in a core exception
+ Throwable t = e.getTargetException();
+ String message = messsagesLookup
+ .WizardExternalProjectImportPage_ErrorMessage();
+ IStatus status;
+ if (t instanceof CoreException) {
+ status = ((CoreException) t).getStatus();
+ } else {
+ status = new Status(IStatus.ERROR, FrameworkUtil.getBundle(
+ getClass()).getSymbolicName(), 1, message, t);
+ }
+ ErrorDialog.openError(getShell(), message, null, status);
+ return false;
+ }
+ ArchiveFileManipulations.closeStructureProvider(messsagesLookup,
+ structureProvider, getShell());
+
+ // Adds the projects to the working sets
+ // TODO SimpleIDE addToWorkingSets();
+
+ return true;
+ }
+
+ List<IProject> createdProjects;
+
+ // TODO SimpleIDE
+ // private void addToWorkingSets() {
+ //
+ // IWorkingSet[] selectedWorkingSets =
+ // workingSetGroup.getSelectedWorkingSets();
+ // if(selectedWorkingSets == null || selectedWorkingSets.length == 0)
+ // return; // no Working set is selected
+ // IWorkingSetManager workingSetManager =
+ // PlatformUI.getWorkbench().getWorkingSetManager();
+ // for (Iterator i = createdProjects.iterator(); i.hasNext();) {
+ // IProject project = (IProject) i.next();
+ // workingSetManager.addToWorkingSets(project, selectedWorkingSets);
+ // }
+ // }
+
+ /**
+ * Performs clean-up if the user cancels the wizard without doing anything
+ */
+ public void performCancel() {
+ ArchiveFileManipulations.closeStructureProvider(messsagesLookup,
+ structureProvider, getShell());
+ }
+
+ /**
+ * Create the project described in record. If it is successful return true.
+ *
+ * @param record
+ * @return boolean <code>true</code> if successful
+ * @throws InterruptedException
+ */
+ private boolean createExistingProject(final ProjectRecord record,
+ IProgressMonitor monitor) throws InvocationTargetException,
+ InterruptedException {
+ String projectName = record.getProjectName();
+ // final IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ final IProject project = workspace.getRoot().getProject(projectName);
+ createdProjects.add(project);
+ if (record.description == null) {
+ // error case
+ record.description = workspace.newProjectDescription(projectName);
+ IPath locationPath = new Path(
+ record.projectSystemFile.getAbsolutePath());
+
+ // If it is under the root use the default location
+ if (Platform.getLocation().isPrefixOf(locationPath)) {
+ record.description.setLocation(null);
+ } else {
+ record.description.setLocation(locationPath);
+ }
+ } else {
+ record.description.setName(projectName);
+ }
+ if (record.projectArchiveFile != null) {
+ // import from archive
+ List<?> fileSystemObjects = structureProvider
+ .getChildren(record.parent);
+ structureProvider.setStrip(record.level);
+ ImportOperation operation = new ImportOperation(workspace,
+ project.getFullPath(), structureProvider.getRoot(),
+ structureProvider, this, fileSystemObjects, messsagesLookup);
+ operation.setContext(getShell());
+ operation.run(monitor);
+ return true;
+ }
+ // import from file system
+ File importSource = null;
+ if (copyFiles) {
+ // import project from location copying files - use default project
+ // location for this workspace
+ URI locationURI = record.description.getLocationURI();
+ // if location is null, project already exists in this location or
+ // some error condition occured.
+ if (locationURI != null) {
+ importSource = new File(locationURI);
+ IProjectDescription desc = workspace
+ .newProjectDescription(projectName);
+ desc.setBuildSpec(record.description.getBuildSpec());
+ desc.setComment(record.description.getComment());
+ desc.setDynamicReferences(record.description
+ .getDynamicReferences());
+ desc.setNatureIds(record.description.getNatureIds());
+ desc.setReferencedProjects(record.description
+ .getReferencedProjects());
+ record.description = desc;
+ }
+ }
+
+ try {
+ monitor.beginTask(messsagesLookup
+ .WizardProjectsImportPage_CreateProjectsTask(), 100);
+ project.create(record.description, new SubProgressMonitor(monitor,
+ 30));
+ project.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(
+ monitor, 70));
+ } catch (CoreException e) {
+ throw new InvocationTargetException(e);
+ } finally {
+ monitor.done();
+ }
+
+ // import operation to import project files if copy checkbox is selected
+ if (copyFiles && importSource != null) {
+ FileSystemStructureProvider pv = new FileSystemStructureProvider(
+ logger);
+ List<File> filesToImport = pv.getChildren(importSource);
+ ImportOperation operation = new ImportOperation(workspace,
+ project.getFullPath(), importSource, pv, this,
+ filesToImport, messsagesLookup);
+ operation.setContext(getShell());
+ operation.setOverwriteResources(true); // need to overwrite
+ // .project, .classpath
+ // files
+ operation.setCreateContainerStructure(false);
+ operation.run(monitor);
+ }
+
+ return true;
+ }
+
+ /**
+ * The <code>WizardDataTransfer</code> implementation of this
+ * <code>IOverwriteQuery</code> method asks the user whether the existing
+ * resource at the given path should be overwritten.
+ *
+ * @param pathString
+ * @return the user's reply: one of <code>"YES"</code>, <code>"NO"</code>,
+ * <code>"ALL"</code>, or <code>"CANCEL"</code>
+ */
+ public String queryOverwrite(String pathString) {
+
+ Path path = new Path(pathString);
+
+ String messageString;
+ // Break the message up if there is a file name and a directory
+ // and there are at least 2 segments.
+ if (path.getFileExtension() == null || path.segmentCount() < 2) {
+ messageString = NLS.bind(
+ IDEWorkbenchMessages.WizardDataTransfer_existsQuestion,
+ pathString);
+ } else {
+ messageString = NLS
+ .bind(IDEWorkbenchMessages.WizardDataTransfer_overwriteNameAndPathQuestion,
+ path.lastSegment(), path.removeLastSegments(1)
+ .toOSString());
+ }
+
+ final MessageDialog dialog = new MessageDialog(getContainer()
+ .getShell(), IDEWorkbenchMessages.Question, null,
+ messageString, MessageDialog.QUESTION, new String[] {
+ IDialogConstants.YES_LABEL,
+ IDialogConstants.YES_TO_ALL_LABEL,
+ IDialogConstants.NO_LABEL,
+ IDialogConstants.NO_TO_ALL_LABEL,
+ IDialogConstants.CANCEL_LABEL }, 0) {
+ protected int getShellStyle() {
+ return super.getShellStyle() | SWT.SHEET;
+ }
+ };
+ String[] response = new String[] { YES, ALL, NO, NO_ALL, CANCEL };
+ // run in syncExec because callback is from an operation,
+ // which is probably not running in the UI thread.
+ getControl().getDisplay().syncExec(new Runnable() {
+ public void run() {
+ dialog.open();
+ }
+ });
+ return dialog.getReturnCode() < 0 ? CANCEL : response[dialog
+ .getReturnCode()];
+ }
+
+ /**
+ * Method used for test suite.
+ *
+ * @return Button the Import from Directory RadioButton
+ */
+ public Button getProjectFromDirectoryRadio() {
+ return projectFromDirectoryRadio;
+ }
+
+ /**
+ * Method used for test suite.
+ *
+ * @return CheckboxTreeViewer the viewer containing all the projects found
+ */
+ public CheckboxTreeViewer getProjectsList() {
+ return projectsList;
+ }
+
+ /**
+ * Retrieve all the projects in the current workspace.
+ *
+ * @return IProject[] array of IProject in the current workspace
+ */
+ private IProject[] getProjectsInWorkspace() {
+ if (wsProjects == null) {
+ wsProjects = workspace.getRoot().getProjects();
+ }
+ return wsProjects;
+ }
+
+ /**
+ * Get the array of project records that can be imported from the source
+ * workspace or archive, selected by the user. If a project with the same
+ * name exists in both the source workspace and the current workspace, then
+ * the hasConflicts flag would be set on that project record.
+ *
+ * Method declared public for test suite.
+ *
+ * @return ProjectRecord[] array of projects that can be imported into the
+ * workspace
+ */
+ public ProjectRecord[] getProjectRecords() {
+ List<ProjectRecord> projectRecords = new ArrayList<ProjectRecord>();
+ for (int i = 0; i < selectedProjects.length; i++) {
+ if (isProjectInWorkspace(selectedProjects[i].getProjectName())) {
+ selectedProjects[i].hasConflicts = true;
+ }
+ projectRecords.add(selectedProjects[i]);
+ }
+ return (ProjectRecord[]) projectRecords
+ .toArray(new ProjectRecord[projectRecords.size()]);
+ }
+
+ /**
+ * Determine if the project with the given name is in the current workspace.
+ *
+ * @param projectName
+ * String the project name to check
+ * @return boolean true if the project with the given name is in this
+ * workspace
+ */
+ private boolean isProjectInWorkspace(String projectName) {
+ if (projectName == null) {
+ return false;
+ }
+ IProject[] workspaceProjects = getProjectsInWorkspace();
+ for (int i = 0; i < workspaceProjects.length; i++) {
+ if (projectName.equals(workspaceProjects[i].getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Use the dialog store to restore widget values to the values that they
+ * held last time this wizard was used to completion, or alternatively, if
+ * an initial path is specified, use it to select values.
+ *
+ * Method declared public only for use of tests.
+ */
+ public void restoreWidgetValues() {
+
+ // First, check to see if we have resore settings, and
+ // take care of the checkbox
+ IDialogSettings settings = getDialogSettings();
+ if (settings != null) {
+ // checkbox
+ copyFiles = settings.getBoolean(STORE_COPY_PROJECT_ID);
+ copyCheckbox.setSelection(copyFiles);
+ }
+
+ // Second, check to see if we don't have an initial path,
+ // and if we do have restore settings. If so, set the
+ // radio selection properly to restore settings
+
+ if (initialPath == null && settings != null) {
+ // radio selection
+ boolean archiveSelected = settings
+ .getBoolean(STORE_ARCHIVE_SELECTED);
+ projectFromDirectoryRadio.setSelection(!archiveSelected);
+ projectFromArchiveRadio.setSelection(archiveSelected);
+ if (archiveSelected) {
+ archiveRadioSelected();
+ } else {
+ directoryRadioSelected();
+ }
+ }
+ // Third, if we do have an initial path, set the proper
+ // path and radio buttons to the initial value. Move
+ // cursor to the end of the path so user can see the
+ // most relevant part (directory / archive name)
+ else if (initialPath != null) {
+ boolean dir = new File(initialPath).isDirectory();
+
+ projectFromDirectoryRadio.setSelection(dir);
+ projectFromArchiveRadio.setSelection(!dir);
+
+ if (dir) {
+ directoryPathField.setText(initialPath);
+ directoryPathField.setSelection(initialPath.length());
+ directoryRadioSelected();
+ } else {
+ archivePathField.setText(initialPath);
+ archivePathField.setSelection(initialPath.length());
+ archiveRadioSelected();
+ }
+ }
+ }
+
+ /**
+ * Since Finish was pressed, write widget values to the dialog store so that
+ * they will persist into the next invocation of this wizard page.
+ *
+ * Method declared public only for use of tests.
+ */
+ public void saveWidgetValues() {
+ IDialogSettings settings = getDialogSettings();
+ if (settings != null) {
+ settings.put(STORE_COPY_PROJECT_ID, copyCheckbox.getSelection());
+
+ settings.put(STORE_ARCHIVE_SELECTED,
+ projectFromArchiveRadio.getSelection());
+ }
+ }
+
+ /**
+ * Method used for test suite.
+ *
+ * @return Button copy checkbox
+ */
+ public Button getCopyCheckbox() {
+ return copyCheckbox;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ZipLeveledStructureProvider.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ZipLeveledStructureProvider.java
new file mode 100644
index 0000000..21a0706
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/ZipLeveledStructureProvider.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * Red Hat, Inc - Was ZipFileStructureProvider, performed changes from
+ * IImportStructureProvider to ILeveledImportStructureProvider
+ *******************************************************************************/
+package org.eclipse.e4.demo.simpleide.internal.datatransfer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.e4.core.services.log.Logger;
+
+/**
+ * This class provides information regarding the context structure and content
+ * of specified zip file entry objects.
+ *
+ * @since 3.1
+ */
+public class ZipLeveledStructureProvider implements
+ ILeveledImportStructureProvider {
+ private ZipFile zipFile;
+
+ private ZipEntry root = new ZipEntry("/");//$NON-NLS-1$
+
+ private Map<ZipEntry,List<ZipEntry>> children;
+
+ private Map<IPath,ZipEntry> directoryEntryCache = new HashMap<IPath,ZipEntry>();
+
+ private int stripLevel;
+
+ private Logger logger;
+
+ /**
+ * Creates a <code>ZipFileStructureProvider</code>, which will operate on
+ * the passed zip file.
+ *
+ * @param sourceFile
+ * The source file to create the ZipLeveledStructureProvider
+ * around
+ */
+ public ZipLeveledStructureProvider(ZipFile sourceFile, Logger logger) {
+ super();
+ this.logger = logger;
+ zipFile = sourceFile;
+ stripLevel = 0;
+ }
+
+ /**
+ * Creates a new container zip entry with the specified name, iff it has
+ * not already been created. If the parent of the given element does not
+ * already exist it will be recursively created as well.
+ * @param pathname The path representing the container
+ * @return The element represented by this pathname (it may have already existed)
+ */
+ protected ZipEntry createContainer(IPath pathname) {
+ ZipEntry existingEntry = (ZipEntry) directoryEntryCache.get(pathname);
+ if (existingEntry != null) {
+ return existingEntry;
+ }
+
+ ZipEntry parent;
+ if (pathname.segmentCount() == 1) {
+ parent = root;
+ } else {
+ parent = createContainer(pathname.removeLastSegments(1));
+ }
+ ZipEntry newEntry = new ZipEntry(pathname.toString());
+ directoryEntryCache.put(pathname, newEntry);
+ List<ZipEntry> childList = new ArrayList<ZipEntry>();
+ children.put(newEntry, childList);
+
+ List<ZipEntry> parentChildList = children.get(parent);
+ parentChildList.add(newEntry);
+ return newEntry;
+ }
+
+ /**
+ * Creates a new file zip entry with the specified name.
+ */
+ protected void createFile(ZipEntry entry) {
+ IPath pathname = new Path(entry.getName());
+ ZipEntry parent;
+ if (pathname.segmentCount() == 1) {
+ parent = root;
+ } else {
+ parent = (ZipEntry) directoryEntryCache.get(pathname
+ .removeLastSegments(1));
+ }
+
+ List<ZipEntry> childList = children.get(parent);
+ childList.add(entry);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IImportStructureProvider
+ */
+ public List<ZipEntry> getChildren(Object element) {
+ if (children == null) {
+ initialize();
+ }
+
+ return children.get(element);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IImportStructureProvider
+ */
+ public InputStream getContents(Object element) {
+ try {
+ return zipFile.getInputStream((ZipEntry) element);
+ } catch (IOException e) {
+ logger.error(e);
+// IDEWorkbenchPlugin.log(e.getLocalizedMessage(), e);
+ return null;
+ }
+ }
+
+ /*
+ * Strip the leading directories from the path
+ */
+ private String stripPath(String path) {
+ String pathOrig = new String(path);
+ for (int i = 0; i < stripLevel; i++) {
+ int firstSep = path.indexOf('/');
+ // If the first character was a seperator we must strip to the next
+ // seperator as well
+ if (firstSep == 0) {
+ path = path.substring(1);
+ firstSep = path.indexOf('/');
+ }
+ // No seperator wasw present so we're in a higher directory right
+ // now
+ if (firstSep == -1) {
+ return pathOrig;
+ }
+ path = path.substring(firstSep);
+ }
+ return path;
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IImportStructureProvider
+ */
+ public String getFullPath(Object element) {
+ return stripPath(((ZipEntry) element).getName());
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IImportStructureProvider
+ */
+ public String getLabel(Object element) {
+ if (element.equals(root)) {
+ return ((ZipEntry) element).getName();
+ }
+
+ return stripPath(new Path(((ZipEntry) element).getName()).lastSegment());
+ }
+
+ /**
+ * Returns the entry that this importer uses as the root sentinel.
+ *
+ * @return java.util.zip.ZipEntry
+ */
+ public Object getRoot() {
+ return root;
+ }
+
+ /**
+ * Returns the zip file that this provider provides structure for.
+ *
+ * @return The zip file
+ */
+ public ZipFile getZipFile() {
+ return zipFile;
+ }
+
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.internal.wizards.datatransfer.ILeveledImportStructureProvider#closeArchive()
+ */
+ public boolean closeArchive(){
+ try {
+ getZipFile().close();
+ } catch (IOException e) {
+ logger.error(e);
+// IDEWorkbenchPlugin.log(DataTransferMessages.ZipImport_couldNotClose
+// + getZipFile().getName(), e);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Initializes this object's children table based on the contents of the
+ * specified source file.
+ */
+ protected void initialize() {
+ children = new HashMap<ZipEntry,List<ZipEntry>>(1000);
+
+ children.put(root, new ArrayList<ZipEntry>());
+ Enumeration<?> entries = zipFile.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry entry = (ZipEntry) entries.nextElement();
+ IPath path = new Path(entry.getName()).addTrailingSeparator();
+
+ if (entry.isDirectory()) {
+ createContainer(path);
+ } else
+ {
+ // Ensure the container structure for all levels above this is initialized
+ // Once we hit a higher-level container that's already added we need go no further
+ int pathSegmentCount = path.segmentCount();
+ if (pathSegmentCount > 1) {
+ createContainer(path.uptoSegment(pathSegmentCount - 1));
+ }
+ createFile(entry);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc) Method declared on IImportStructureProvider
+ */
+ public boolean isFolder(Object element) {
+ return ((ZipEntry) element).isDirectory();
+ }
+
+ public void setStrip(int level) {
+ stripLevel = level;
+ }
+
+ public int getStrip() {
+ return stripLevel;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/actions/WorkspaceModifyOperation.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/actions/WorkspaceModifyOperation.java
new file mode 100644
index 0000000..9dbc19c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/actions/WorkspaceModifyOperation.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.e4.demo.simpleide.internal.datatransfer.actions;
+
+import java.lang.reflect.InvocationTargetException;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.operation.IThreadListener;
+
+//import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+
+/**
+ * An operation which potentially makes changes to the workspace. All resource
+ * modification should be performed using this operation. The primary
+ * consequence of using this operation is that events which typically occur as a
+ * result of workspace changes (such as the firing of resource deltas,
+ * performance of autobuilds, etc.) are generally deferred until the outermost operation
+ * has successfully completed. The platform may still decide to broadcast
+ * periodic resource change notifications during the scope of the operation
+ * if the operation runs for a long time or another thread modifies the workspace
+ * concurrently.
+ * <p>
+ * If a scheduling rule is provided, the operation will obtain that scheduling
+ * rule for the duration of its <code>execute</code> method. If no scheduling
+ * rule is provided, the operation will obtain a scheduling rule that locks
+ * the entire workspace for the duration of the operation.
+ * </p>
+ * <p>
+ * Subclasses must implement <code>execute</code> to do the work of the
+ * operation.
+ * </p>
+ * @see ISchedulingRule
+ * @see org.eclipse.core.resources.IWorkspace#run(IWorkspaceRunnable, IProgressMonitor)
+ * */
+public abstract class WorkspaceModifyOperation implements IRunnableWithProgress, IThreadListener {
+ private ISchedulingRule rule;
+ private IWorkspace workspace;
+
+ /**
+ * Creates a new operation.
+ */
+ protected WorkspaceModifyOperation(IWorkspace workspace) {
+ this(workspace, workspace.getRoot());
+ }
+
+ /**
+ * Creates a new operation that will run using the provided
+ * scheduling rule.
+ * @param rule The ISchedulingRule to use or <code>null</code>.
+ * @since 3.0
+ */
+ protected WorkspaceModifyOperation(IWorkspace workspace, ISchedulingRule rule) {
+ this.workspace = workspace;
+ this.rule = rule;
+ }
+
+ /**
+ * Performs the steps that are to be treated as a single logical workspace
+ * change.
+ * <p>
+ * Subclasses must implement this method.
+ * </p>
+ *
+ * @param monitor the progress monitor to use to display progress and field
+ * user requests to cancel
+ * @exception CoreException if the operation fails due to a CoreException
+ * @exception InvocationTargetException if the operation fails due to an exception other than CoreException
+ * @exception InterruptedException if the operation detects a request to cancel,
+ * using <code>IProgressMonitor.isCanceled()</code>, it should exit by throwing
+ * <code>InterruptedException</code>. It is also possible to throw
+ * <code>OperationCanceledException</code>, which gets mapped to <code>InterruptedException</code>
+ * by the <code>run</code> method.
+ */
+ protected abstract void execute(IProgressMonitor monitor)
+ throws CoreException, InvocationTargetException,
+ InterruptedException;
+
+ /**
+ * The <code>WorkspaceModifyOperation</code> implementation of this
+ * <code>IRunnableWithProgress</code> method initiates a batch of changes by
+ * invoking the <code>execute</code> method as a workspace runnable
+ * (<code>IWorkspaceRunnable</code>).
+ */
+ public synchronized final void run(IProgressMonitor monitor)
+ throws InvocationTargetException, InterruptedException {
+ final InvocationTargetException[] iteHolder = new InvocationTargetException[1];
+ try {
+ IWorkspaceRunnable workspaceRunnable = new IWorkspaceRunnable() {
+ public void run(IProgressMonitor pm) throws CoreException {
+ try {
+ execute(pm);
+ } catch (InvocationTargetException e) {
+ // Pass it outside the workspace runnable
+ iteHolder[0] = e;
+ } catch (InterruptedException e) {
+ // Re-throw as OperationCanceledException, which will be
+ // caught and re-thrown as InterruptedException below.
+ throw new OperationCanceledException(e.getMessage());
+ }
+ // CoreException and OperationCanceledException are propagated
+ }
+ };
+ workspace.run(workspaceRunnable,
+ rule, IResource.NONE, monitor);
+ } catch (CoreException e) {
+ throw new InvocationTargetException(e);
+ } catch (OperationCanceledException e) {
+ throw new InterruptedException(e.getMessage());
+ }
+ // Re-throw the InvocationTargetException, if any occurred
+ if (iteHolder[0] != null) {
+ throw iteHolder[0];
+ }
+ }
+ /* (non-Javadoc)
+ * @see IThreadListener#threadChange(Thread);
+ * @since 3.2
+ */
+ public void threadChange(Thread thread) {
+ //we must make sure we aren't transferring control away from a thread that
+ //already owns a scheduling rule because this is deadlock prone (bug 105491)
+ if (rule == null) {
+ return;
+ }
+ Job currentJob = Job.getJobManager().currentJob();
+ if (currentJob == null) {
+ return;
+ }
+ ISchedulingRule currentRule = currentJob.getRule();
+ if (currentRule == null) {
+ return;
+ }
+ throw new IllegalStateException("Cannot fork a thread from a thread owning a rule"); //$NON-NLS-1$
+ }
+
+ /**
+ * The scheduling rule. Should not be modified.
+ * @return the scheduling rule, or <code>null</code>.
+ * @since 3.4
+ */
+ public ISchedulingRule getRule() {
+ return rule;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/dialogs/ContainerGenerator.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/dialogs/ContainerGenerator.java
new file mode 100644
index 0000000..bd3319d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/dialogs/ContainerGenerator.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.e4.demo.simpleide.internal.datatransfer.dialogs;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.e4.demo.simpleide.internal.datatransfer.IDEWorkbenchMessages;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * For creating folder resources that currently do not exist,
+ * along a given workspace path.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * <p>
+ * Example usage:
+ * <pre>
+ * ContainerGenerator gen = new ContainerGenerator(new Path("/A/B"));
+ * IContainer res = null;
+ * try {
+ * res = gen.getContainer(monitor); // creates project A and folder B if required
+ * } catch (CoreException e) {
+ * // handle failure
+ * } catch (OperationCanceledException e) {
+ * // handle cancelation
+ * }
+ * </pre>
+ * </p>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ContainerGenerator {
+ private IPath containerFullPath;
+
+ private IContainer container;
+
+ private IWorkspace workspace;
+
+ /**
+ * Creates a generator for the container resource (folder or project) at the
+ * given workspace path. Assumes the path has already been validated.
+ * <p>
+ * Call <code>getContainer</code> to create any missing resources along the
+ * path.
+ * </p>
+ *
+ * @param containerPath the workspace path of the container
+ */
+ public ContainerGenerator(IWorkspace workspace, IPath containerPath) {
+ super();
+ this.workspace = workspace;
+ this.containerFullPath = containerPath;
+ }
+
+ /**
+ * Creates a folder resource for the given folder handle.
+ *
+ * @param folderHandle the handle to create a folder resource
+ * @param monitor the progress monitor to show visual progress
+ * @return the folder handle (<code>folderHandle</code>)
+ * @exception CoreException if the operation fails
+ * @exception OperationCanceledException if the operation is canceled
+ */
+ private IFolder createFolder(IFolder folderHandle, IProgressMonitor monitor)
+ throws CoreException {
+ folderHandle.create(false, true, monitor);
+
+ if (monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+
+ return folderHandle;
+ }
+
+ /**
+ * Creates a folder resource handle for the folder with the given name.
+ * This method does not create the folder resource; this is the responsibility
+ * of <code>createFolder</code>.
+ *
+ * @param container the resource container
+ * @param folderName the name of the folder
+ * @return the new folder resource handle
+ */
+ private IFolder createFolderHandle(IContainer container, String folderName) {
+ return container.getFolder(new Path(folderName));
+ }
+
+ /**
+ * Creates a project resource for the given project handle.
+ *
+ * @param projectHandle the handle to create a project resource
+ * @param monitor the progress monitor to show visual progress
+ * @return the project handle (<code>projectHandle</code>)
+ * @exception CoreException if the operation fails
+ * @exception OperationCanceledException if the operation is canceled
+ */
+ private IProject createProject(IProject projectHandle,
+ IProgressMonitor monitor) throws CoreException {
+ try {
+ monitor.beginTask("", 2000);//$NON-NLS-1$
+
+ projectHandle.create(new SubProgressMonitor(monitor, 1000));
+ if (monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+
+ projectHandle.open(new SubProgressMonitor(monitor, 1000));
+ if (monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ } finally {
+ monitor.done();
+ }
+
+ return projectHandle;
+ }
+
+ /**
+ * Creates a project resource handle for the project with the given name.
+ * This method does not create the project resource; this is the responsibility
+ * of <code>createProject</code>.
+ *
+ * @param root the workspace root resource
+ * @param projectName the name of the project
+ * @return the new project resource handle
+ */
+ private IProject createProjectHandle(IWorkspaceRoot root, String projectName) {
+ return root.getProject(projectName);
+ }
+
+ /**
+ * Ensures that this generator's container resource exists. Creates any missing
+ * resource containers along the path; does nothing if the container resource
+ * already exists.
+ * <p>
+ * Note: This method should be called within a workspace modify operation since
+ * it may create resources.
+ * </p>
+ *
+ * @param monitor a progress monitor
+ * @return the container resource
+ * @exception CoreException if the operation fails
+ * @exception OperationCanceledException if the operation is canceled
+ */
+ public IContainer generateContainer(IProgressMonitor monitor)
+ throws CoreException {
+ workspace.run(new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ monitor
+ .beginTask(
+ IDEWorkbenchMessages.ContainerGenerator_progressMessage, 1000 * containerFullPath.segmentCount());
+ if (container != null) {
+ return;
+ }
+
+ // Does the container exist already?
+ IWorkspaceRoot root = getWorkspaceRoot();
+ container = (IContainer) root.findMember(containerFullPath);
+ if (container != null) {
+ return;
+ }
+
+ // Create the container for the given path
+ container = root;
+ for (int i = 0; i < containerFullPath.segmentCount(); i++) {
+ String currentSegment = containerFullPath.segment(i);
+ IResource resource = container.findMember(currentSegment);
+ if (resource != null) {
+ if (resource.getType() == IResource.FILE) {
+ String msg = NLS.bind(IDEWorkbenchMessages.ContainerGenerator_pathOccupied, resource.getFullPath().makeRelative());
+ throw new CoreException(new Status(IStatus.ERROR, FrameworkUtil.getBundle(getClass()).getSymbolicName(), 1, msg, null));
+ }
+ container = (IContainer) resource;
+ monitor.worked(1000);
+ } else {
+ if (i == 0) {
+ IProject projectHandle = createProjectHandle(root,
+ currentSegment);
+ container = createProject(projectHandle,
+ new SubProgressMonitor(monitor, 1000));
+ } else {
+ IFolder folderHandle = createFolderHandle(
+ container, currentSegment);
+ container = createFolder(folderHandle,
+ new SubProgressMonitor(monitor, 1000));
+ }
+ }
+ }
+ }
+ }, null, IResource.NONE, monitor);
+ return container;
+ }
+
+ /**
+ * Returns the workspace root resource handle.
+ *
+ * @return the workspace root resource handle
+ */
+ private IWorkspaceRoot getWorkspaceRoot() {
+ return workspace.getRoot();
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/dialogs/IOverwriteQuery.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/dialogs/IOverwriteQuery.java
new file mode 100644
index 0000000..7c72b77
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/internal/datatransfer/dialogs/IOverwriteQuery.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demo.simpleide.internal.datatransfer.dialogs;
+
+/**
+ * Implementors of this interface answer one of the prescribed return codes
+ * when asked whether to overwrite a certain path string (which could
+ * represent a resource path, a file system path, etc).
+ */
+public interface IOverwriteQuery {
+ /**
+ * Return code indicating the operation should be canceled.
+ */
+ public static final String CANCEL = "CANCEL"; //$NON-NLS-1$
+
+ /**
+ * Return code indicating the entity should not be overwritten,
+ * but operation should not be canceled.
+ */
+ public static final String NO = "NO"; //$NON-NLS-1$
+
+ /**
+ * Return code indicating the entity should be overwritten.
+ */
+ public static final String YES = "YES"; //$NON-NLS-1$
+
+ /**
+ * Return code indicating the entity should be overwritten,
+ * and all subsequent entities should be overwritten without prompting.
+ */
+ public static final String ALL = "ALL"; //$NON-NLS-1$
+
+ /**
+ * Return code indicating the entity should not be overwritten,
+ * and all subsequent entities should not be overwritten without prompting.
+ */
+ public static final String NO_ALL = "NOALL"; //$NON-NLS-1$
+
+ /**
+ * Returns one of the return code constants declared on this interface,
+ * indicating whether the entity represented by the passed String should be overwritten.
+ * <p>
+ * This method may be called from a non-UI thread, in which case this method must run the query
+ * in a sync exec in the UI thread, if it needs to query the user.
+ * </p>
+ * @param pathString the path representing the entity to be overwritten
+ * @return one of the return code constants declared on this interface
+ */
+ String queryOverwrite(String pathString);
+}
diff --git a/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/ui/ResourceViewerControl.java b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/ui/ResourceViewerControl.java
new file mode 100644
index 0000000..c0c455c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.simpleide/src/org/eclipse/e4/demo/simpleide/ui/ResourceViewerControl.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * 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 <tom.schindl@bestsolution.at> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.demo.simpleide.ui;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+
+public class ResourceViewerControl extends Composite {
+ private TreeViewer viewer;
+
+ public ResourceViewerControl(Composite parent, int style, IWorkspace workspace, IResource resource) {
+ super(parent, style);
+ setLayout(new FillLayout());
+
+ viewer = new TreeViewer(this);
+ viewer.setContentProvider(new ResourceContentProviderImpl());
+ viewer.setLabelProvider(new LabelProvider() {
+ public String getText(Object element) {
+ if (element instanceof IResource)
+ return ((IResource) element).getName();
+ return element == null ? "" : element.toString();
+ }
+ });
+ viewer.setSorter(new ViewerSorter());
+ viewer.setInput(workspace.getRoot());
+
+ if( resource != null ) {
+ IContainer resContainer;
+ if( resource instanceof IContainer ) {
+ resContainer = (IContainer) resource;
+ } else {
+ resContainer = resource.getParent();
+ }
+
+ if( resContainer != null ) {
+ List<IContainer> path = new ArrayList<IContainer>();
+ path.add(resContainer);
+ while( (resContainer = resContainer.getParent()) != null ) {
+ path.add(resContainer);
+ }
+ Collections.reverse(path);
+ path.remove(0);
+ viewer.setSelection(new TreeSelection(new TreePath(path.toArray())));
+ }
+ }
+ }
+
+ public IResource getResource() {
+ if( viewer.getSelection().isEmpty() ) {
+ return null;
+ } else {
+ IStructuredSelection s = (IStructuredSelection) viewer.getSelection();
+ return (IResource) s.getFirstElement();
+ }
+ }
+
+ private static class ResourceContentProviderImpl implements ITreeContentProvider {
+
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+
+ public void dispose() {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ final IContainer resource = (IContainer) parentElement;
+ final List<IResource> children = new ArrayList<IResource>();
+ try {
+ for( IResource res : resource.members() ) {
+ if( res instanceof IContainer ) {
+ children.add(res);
+ }
+ }
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return children.toArray();
+ }
+
+ public Object getParent(Object element) {
+ IContainer resource = (IContainer) element;
+ return resource.getParent();
+ }
+
+ public boolean hasChildren(Object element) {
+ return getChildren(element).length > 0;
+ }
+
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/.classpath b/examples/org.eclipse.e4.demo.tools.simpleide/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/.project b/examples/org.eclipse.e4.demo.tools.simpleide/.project
new file mode 100644
index 0000000..f721119
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.tools.simpleide</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.tools.simpleide/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..9ef8794
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sat May 15 11:15:26 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.demo.tools.simpleide/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..360454f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,6 @@
+#Wed Jun 02 15:50:17 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.tools.simpleide/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..5e524dd
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/META-INF/MANIFEST.MF
@@ -0,0 +1,21 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Simpleide
+Bundle-SymbolicName: org.eclipse.e4.demo.tools.simpleide;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.tools.emf.ui;bundle-version="0.9.0",
+ org.eclipse.swt;bundle-version="3.6.0",
+ javax.inject;bundle-version="1.0.0",
+ org.eclipse.emf.ecore;bundle-version="2.6.0",
+ org.eclipse.emf.databinding;bundle-version="1.2.0",
+ org.eclipse.core.databinding.property;bundle-version="1.3.0",
+ org.eclipse.emf.databinding.edit;bundle-version="1.2.0",
+ org.eclipse.jface.databinding;bundle-version="1.4.0",
+ org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.e4.core.di;bundle-version="0.9.0",
+ org.eclipse.e4.demo.simpleide.model;bundle-version="1.0.0",
+ org.eclipse.e4.tools.services;bundle-version="0.11.0"
+Import-Package: org.eclipse.core.databinding.observable.list,
+ org.eclipse.core.resources,
+ org.eclipse.emf.edit.domain
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/build.properties b/examples/org.eclipse.e4.demo.tools.simpleide/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/plugin.xml b/examples/org.eclipse.e4.demo.tools.simpleide/plugin.xml
new file mode 100644
index 0000000..9426186
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/plugin.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.e4.tools.emf.ui.editors">
+ <editor
+ descriptorClass="org.eclipse.e4.demo.tools.simpleide.SimpleIDEApplicationEditorDesc">
+ </editor>
+ <virtualeditor
+ class="org.eclipse.e4.demo.tools.simpleide.VEditorPartDescriptorEditor"
+ id="org.eclipse.e4.demo.tools.simpleide.SimpleIDEApplicationEditor.EDITOR_DESCRIPTORS">
+ </virtualeditor>
+ <editor
+ descriptorClass="org.eclipse.e4.demo.tools.simpleide.EditorPartDescriptorEditorDesc">
+ </editor>
+ <editorfeature
+ class="org.eclipse.e4.demo.tools.simpleide.EditorFeature">
+ </editorfeature>
+ </extension>
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorFeature.java b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorFeature.java
new file mode 100644
index 0000000..f8e5cad
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorFeature.java
@@ -0,0 +1,23 @@
+package org.eclipse.e4.demo.tools.simpleide;
+
+import java.util.Collections;
+import java.util.List;
+import org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl;
+import org.eclipse.e4.tools.emf.ui.common.IEditorFeature;
+import org.eclipse.e4.ui.model.fragment.impl.FragmentPackageImpl;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+public class EditorFeature implements IEditorFeature {
+
+ public List<FeatureClass> getFeatureClasses(EClass eClass,
+ EStructuralFeature feature) {
+ if( eClass == FragmentPackageImpl.Literals.MODEL_FRAGMENT ) {
+ if( feature == FragmentPackageImpl.Literals.MODEL_FRAGMENT__ELEMENTS ) {
+ return Collections.singletonList(new FeatureClass(SimpleidePackageImpl.Literals.EDITOR_PART_DESCRIPTOR.getName(), SimpleidePackageImpl.Literals.EDITOR_PART_DESCRIPTOR));
+ }
+ }
+ return Collections.emptyList();
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorPartDescriptorEditor.java b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorPartDescriptorEditor.java
new file mode 100644
index 0000000..786955f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorPartDescriptorEditor.java
@@ -0,0 +1,174 @@
+package org.eclipse.e4.demo.tools.simpleide;
+
+import org.eclipse.e4.core.di.annotations.Optional;
+
+import org.eclipse.e4.tools.emf.ui.internal.Messages;
+
+import javax.inject.Inject;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl;
+import org.eclipse.e4.tools.emf.ui.common.component.AbstractComponentEditor;
+import org.eclipse.e4.tools.emf.ui.internal.ResourceProvider;
+import org.eclipse.e4.tools.emf.ui.internal.common.component.ControlFactory;
+import org.eclipse.e4.tools.emf.ui.internal.common.component.dialogs.ContributionClassDialog;
+import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor;
+import org.eclipse.e4.ui.model.application.descriptor.basic.impl.BasicPackageImpl;
+import org.eclipse.e4.ui.model.application.impl.ApplicationPackageImpl;
+import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl;
+import org.eclipse.emf.databinding.EMFDataBindingContext;
+import org.eclipse.emf.databinding.edit.EMFEditProperties;
+import org.eclipse.jface.databinding.swt.IWidgetValueProperty;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class EditorPartDescriptorEditor extends AbstractComponentEditor {
+ private Composite composite;
+ private EMFDataBindingContext context;
+
+ @Inject
+ @Optional
+ private IProject project;
+
+ @Inject
+ public EditorPartDescriptorEditor() {
+ super();
+ }
+
+ @Override
+ public Image getImage(Object element, Display display) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getLabel(Object element) {
+ return "Editor Descriptor";
+ }
+
+ @Override
+ public String getDetailLabel(Object element) {
+ MEditorPartDescriptor desc = (MEditorPartDescriptor) element;
+ return desc.getLabel();
+ }
+
+ @Override
+ public String getDescription(Object element) {
+ return "Editor Descriptor Bla Bla Bla Bla Bla";
+ }
+
+ @Override
+ public Composite doGetEditor(Composite parent, Object object) {
+ if( composite == null ) {
+ context = new EMFDataBindingContext();
+ composite = createForm(parent,context, getMaster());
+ }
+ getMaster().setValue(object);
+ return composite;
+ }
+
+ protected Composite createForm(Composite parent, EMFDataBindingContext context, IObservableValue master) {
+ parent = new Composite(parent,SWT.NONE);
+ parent.setLayout(new GridLayout(3, false));
+
+ IWidgetValueProperty textProp = WidgetProperties.text(SWT.Modify);
+
+ // ------------------------------------------------------------
+ {
+ Label l = new Label(parent, SWT.NONE);
+ l.setText("Id");
+
+ Text t = new Text(parent, SWT.BORDER);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan=2;
+ t.setLayoutData(gd);
+ context.bindValue(textProp.observeDelayed(200,t), EMFEditProperties.value(getEditingDomain(), ApplicationPackageImpl.Literals.APPLICATION_ELEMENT__ELEMENT_ID).observeDetail(master));
+ }
+
+ // ------------------------------------------------------------
+ {
+ Label l = new Label(parent, SWT.NONE);
+ l.setText("Label");
+
+ Text t = new Text(parent, SWT.BORDER);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan=2;
+ t.setLayoutData(gd);
+ context.bindValue(textProp.observeDelayed(200,t), EMFEditProperties.value(getEditingDomain(), UiPackageImpl.Literals.UI_LABEL__LABEL).observeDetail(master));
+ }
+
+ // ------------------------------------------------------------
+ {
+ Label l = new Label(parent, SWT.NONE);
+ l.setText("Tooltip");
+
+ Text t = new Text(parent, SWT.BORDER);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan=2;
+ t.setLayoutData(gd);
+ context.bindValue(textProp.observeDelayed(200,t), EMFEditProperties.value(getEditingDomain(), UiPackageImpl.Literals.UI_LABEL__TOOLTIP).observeDetail(master));
+ }
+
+ // ------------------------------------------------------------
+ {
+ Label l = new Label(parent, SWT.NONE);
+ l.setText("Icon URI");
+
+ Text t = new Text(parent, SWT.BORDER);
+ t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ context.bindValue(textProp.observeDelayed(200,t), EMFEditProperties.value(getEditingDomain(), UiPackageImpl.Literals.UI_LABEL__ICON_URI).observeDetail(master));
+
+ Button b = new Button(parent, SWT.PUSH|SWT.FLAT);
+ b.setImage(createImage(ResourceProvider.IMG_Obj16_zoom));
+ b.setText("Find");
+ }
+
+ // ------------------------------------------------------------
+ {
+ Label l = new Label(parent, SWT.NONE);
+ l.setText("Class URI");
+
+ Text t = new Text(parent, SWT.BORDER);
+ t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ context.bindValue(textProp.observeDelayed(200,t), EMFEditProperties.value(getEditingDomain(), SimpleidePackageImpl.Literals.EDITOR_PART_DESCRIPTOR__CONTRIBUTION_URI).observeDetail(master));
+
+ final Button b = new Button(parent, SWT.PUSH|SWT.FLAT);
+ b.setImage(createImage(ResourceProvider.IMG_Obj16_zoom));
+ b.setText("Find");
+ b.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ ContributionClassDialog dialog = new ContributionClassDialog(b.getShell(),project,getEditingDomain(),(MPartDescriptor) getMaster().getValue(), BasicPackageImpl.Literals.PART_DESCRIPTOR__CONTRIBUTION_URI, Messages);
+ dialog.open();
+ }
+ });
+ }
+
+
+ // ------------------------------------------------------------
+ {
+ ControlFactory.createStringListWidget(parent, Messages, this, "File extensions", SimpleidePackageImpl.Literals.EDITOR_PART_DESCRIPTOR__FILEEXTENSIONS, 10);
+ }
+
+ return parent;
+ }
+
+ @Override
+ public IObservableList getChildList(Object element) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorPartDescriptorEditorDesc.java b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorPartDescriptorEditorDesc.java
new file mode 100644
index 0000000..c9e719f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/EditorPartDescriptorEditorDesc.java
@@ -0,0 +1,17 @@
+package org.eclipse.e4.demo.tools.simpleide;
+
+import org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl;
+import org.eclipse.e4.tools.emf.ui.common.IEditorDescriptor;
+import org.eclipse.emf.ecore.EClass;
+
+public class EditorPartDescriptorEditorDesc implements IEditorDescriptor {
+
+ public EClass getEClass() {
+ return SimpleidePackageImpl.Literals.EDITOR_PART_DESCRIPTOR;
+ }
+
+ public Class<?> getEditorClass() {
+ return EditorPartDescriptorEditor.class;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/SimpleIDEApplicationEditor.java b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/SimpleIDEApplicationEditor.java
new file mode 100644
index 0000000..d95be15
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/SimpleIDEApplicationEditor.java
@@ -0,0 +1,45 @@
+package org.eclipse.e4.demo.tools.simpleide;
+
+import org.eclipse.e4.tools.services.IResourcePool;
+
+import org.eclipse.e4.tools.emf.ui.internal.common.ModelEditor;
+
+import javax.inject.Inject;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.property.list.IListProperty;
+import org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl;
+import org.eclipse.e4.tools.emf.ui.common.IModelResource;
+import org.eclipse.e4.tools.emf.ui.internal.common.VirtualEntry;
+import org.eclipse.e4.tools.emf.ui.internal.common.component.ApplicationEditor;
+import org.eclipse.emf.databinding.EMFProperties;
+
+@SuppressWarnings({ "restriction"})
+public class SimpleIDEApplicationEditor extends ApplicationEditor {
+ private static final String EDITOR_DESCRIPTORS_ID = SimpleIDEApplicationEditor.class.getName() + ".EDITOR_DESCRIPTORS";
+ private IListProperty EDITOR_DESCRIPTORS = EMFProperties.list(SimpleidePackageImpl.Literals.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS);
+
+
+ @Inject
+ public SimpleIDEApplicationEditor() {
+ super();
+ }
+
+ @Override
+ public String getLabel(Object element) {
+ return "SimpleIDE Application";
+ }
+
+ @Override
+ public IObservableList getChildList(Object element) {
+ IObservableList list = super.getChildList(element);
+ VirtualEntry<Object> v = new VirtualEntry<Object>(EDITOR_DESCRIPTORS_ID,EDITOR_DESCRIPTORS,element,"Editor Part Descriptors") {
+
+ @Override
+ protected boolean accepted(Object o) {
+ return true;
+ }
+ };
+ list.add(v);
+ return list;
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/SimpleIDEApplicationEditorDesc.java b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/SimpleIDEApplicationEditorDesc.java
new file mode 100644
index 0000000..e1f2b1c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/SimpleIDEApplicationEditorDesc.java
@@ -0,0 +1,17 @@
+package org.eclipse.e4.demo.tools.simpleide;
+
+import org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl;
+import org.eclipse.e4.tools.emf.ui.common.IEditorDescriptor;
+import org.eclipse.emf.ecore.EClass;
+
+public class SimpleIDEApplicationEditorDesc implements IEditorDescriptor {
+
+ public EClass getEClass() {
+ return SimpleidePackageImpl.Literals.SIMPLE_IDE_APPLICATION;
+ }
+
+ public Class<?> getEditorClass() {
+ return SimpleIDEApplicationEditor.class;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/VEditorPartDescriptorEditor.java b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/VEditorPartDescriptorEditor.java
new file mode 100644
index 0000000..05302b9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide/src/org/eclipse/e4/demo/tools/simpleide/VEditorPartDescriptorEditor.java
@@ -0,0 +1,223 @@
+package org.eclipse.e4.demo.tools.simpleide;
+
+import org.eclipse.e4.tools.services.IResourcePool;
+
+import org.eclipse.e4.tools.emf.ui.internal.ResourceProvider;
+
+import org.eclipse.e4.tools.emf.ui.internal.common.ModelEditor;
+
+import java.util.List;
+import javax.inject.Inject;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.value.WritableValue;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MEditorPartDescriptor;
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleideFactory;
+import org.eclipse.e4.demo.simpleide.model.simpleide.impl.SimpleidePackageImpl;
+import org.eclipse.e4.tools.emf.ui.common.IModelResource;
+import org.eclipse.e4.tools.emf.ui.common.component.AbstractComponentEditor;
+import org.eclipse.e4.tools.emf.ui.internal.ObservableColumnLabelProvider;
+import org.eclipse.e4.tools.emf.ui.internal.common.VirtualEntry;
+import org.eclipse.e4.ui.model.application.commands.MHandler;
+import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptorContainer;
+import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.databinding.EMFDataBindingContext;
+import org.eclipse.emf.databinding.edit.EMFEditProperties;
+import org.eclipse.emf.databinding.edit.IEMFEditValueProperty;
+import org.eclipse.emf.edit.command.AddCommand;
+import org.eclipse.emf.edit.command.MoveCommand;
+import org.eclipse.emf.edit.command.RemoveCommand;
+import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+
+public class VEditorPartDescriptorEditor extends AbstractComponentEditor {
+ private Composite composite;
+ private EMFDataBindingContext context;
+ private TableViewer viewer;
+
+ @Inject
+ public VEditorPartDescriptorEditor() {
+ super();
+ }
+
+ @Override
+ public Image getImage(Object element, Display display) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getLabel(Object element) {
+ return "Editor Part Descriptors";
+ }
+
+ @Override
+ public String getDetailLabel(Object element) {
+ return null;
+ }
+
+ @Override
+ public String getDescription(Object element) {
+ return "Editor Part Descriptors Bla Bla Bla Bla";
+ }
+
+ @Override
+ public Composite doGetEditor(Composite parent, Object object) {
+ if( composite == null ) {
+ context = new EMFDataBindingContext();
+ composite = createForm(parent,context, getMaster());
+ }
+ VirtualEntry<?> o = (VirtualEntry<?>)object;
+ viewer.setInput(o.getList());
+ getMaster().setValue(o.getOriginalParent());
+ return composite;
+ }
+
+ private Composite createForm(Composite parent, EMFDataBindingContext context,
+ WritableValue master) {
+ parent = new Composite(parent,SWT.NONE);
+ parent.setLayout(new GridLayout(3, false));
+
+ {
+ Label l = new Label(parent, SWT.NONE);
+ l.setText("Descriptors");
+ l.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
+
+ viewer = new TableViewer(parent);
+ ObservableListContentProvider cp = new ObservableListContentProvider();
+ viewer.setContentProvider(cp);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.heightHint = 300;
+ viewer.getControl().setLayoutData(gd);
+ viewer.getTable().setHeaderVisible(true);
+
+ {
+ IEMFEditValueProperty prop = EMFEditProperties.value(getEditingDomain(), UiPackageImpl.Literals.UI_LABEL__LABEL);
+
+ TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
+ column.getColumn().setText("Name");
+ column.getColumn().setWidth(200);
+ column.setLabelProvider(new ObservableColumnLabelProvider<MHandler>(prop.observeDetail(cp.getKnownElements())));
+ }
+
+ Composite buttonComp = new Composite(parent, SWT.NONE);
+ buttonComp.setLayoutData(new GridData(GridData.FILL,GridData.END,false,false));
+ GridLayout gl = new GridLayout();
+ gl.marginLeft=0;
+ gl.marginRight=0;
+ gl.marginWidth=0;
+ gl.marginHeight=0;
+ buttonComp.setLayout(gl);
+
+ Button b = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
+ b.setText("Up");
+ b.setImage(createImage(ResourceProvider.IMG_Obj16_arrow_up));
+ b.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
+ b.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if( ! viewer.getSelection().isEmpty() ) {
+ IStructuredSelection s = (IStructuredSelection)viewer.getSelection();
+ if( s.size() == 1 ) {
+ Object obj = s.getFirstElement();
+ MPartDescriptorContainer container = (MPartDescriptorContainer) getMaster().getValue();
+ int idx = container.getDescriptors().indexOf(obj) - 1;
+ if( idx >= 0 ) {
+ Command cmd = MoveCommand.create(getEditingDomain(), getMaster().getValue(), SimpleidePackageImpl.Literals.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS, obj, idx);
+
+ if( cmd.canExecute() ) {
+ getEditingDomain().getCommandStack().execute(cmd);
+ viewer.setSelection(new StructuredSelection(obj));
+ }
+ }
+
+ }
+ }
+ }
+ });
+
+ b = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
+ b.setText("Down");
+ b.setImage(createImage(ResourceProvider.IMG_Obj16_arrow_down));
+ b.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
+ b.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if( ! viewer.getSelection().isEmpty() ) {
+ IStructuredSelection s = (IStructuredSelection)viewer.getSelection();
+ if( s.size() == 1 ) {
+ Object obj = s.getFirstElement();
+ MPartDescriptorContainer container = (MPartDescriptorContainer) getMaster().getValue();
+ int idx = container.getDescriptors().indexOf(obj) + 1;
+ if( idx < container.getDescriptors().size() ) {
+ Command cmd = MoveCommand.create(getEditingDomain(), getMaster().getValue(), SimpleidePackageImpl.Literals.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS, obj, idx);
+
+ if( cmd.canExecute() ) {
+ getEditingDomain().getCommandStack().execute(cmd);
+ viewer.setSelection(new StructuredSelection(obj));
+ }
+ }
+
+ }
+ }
+ }
+ });
+
+ b = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
+ b.setText("Add ...");
+ b.setImage(createImage(ResourceProvider.IMG_Obj16_table_add));
+ b.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
+ b.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ MEditorPartDescriptor obj = MSimpleideFactory.INSTANCE.createEditorPartDescriptor();
+ Command cmd = AddCommand.create(getEditingDomain(), getMaster().getValue(), SimpleidePackageImpl.Literals.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS, obj);
+
+ if( cmd.canExecute() ) {
+ getEditingDomain().getCommandStack().execute(cmd);
+//TODO Need to abstract this editor.setSelection(command);
+ }
+ }
+ });
+
+ b = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
+ b.setText("Remove");
+ b.setImage(createImage(ResourceProvider.IMG_Obj16_table_delete));
+ b.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
+ b.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if( ! viewer.getSelection().isEmpty() ) {
+ List<?> commands = ((IStructuredSelection)viewer.getSelection()).toList();
+ Command cmd = RemoveCommand.create(getEditingDomain(), getMaster().getValue(), SimpleidePackageImpl.Literals.SIMPLE_IDE_APPLICATION__EDITOR_PART_DESCRIPTORS, commands);
+ if( cmd.canExecute() ) {
+ getEditingDomain().getCommandStack().execute(cmd);
+ }
+ }
+ }
+ });
+ }
+
+ return parent;
+ }
+
+ @Override
+ public IObservableList getChildList(Object element) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide3x/.classpath b/examples/org.eclipse.e4.demo.tools.simpleide3x/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide3x/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide3x/.project b/examples/org.eclipse.e4.demo.tools.simpleide3x/.project
new file mode 100644
index 0000000..3d69bf1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide3x/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.tools.simpleide3x</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide3x/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.tools.simpleide3x/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..5699a5c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide3x/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Sat May 15 13:45:29 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide3x/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.tools.simpleide3x/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e5cb063
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide3x/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Simpleide3x
+Bundle-SymbolicName: org.eclipse.e4.demo.tools.simpleide3x;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.e4.tools.emf.editor3x;bundle-version="0.9.0",
+ org.eclipse.emf.ecore;bundle-version="2.6.0",
+ org.eclipse.ui;bundle-version="3.6.0",
+ org.eclipse.e4.demo.simpleide.model;bundle-version="1.0.0",
+ org.eclipse.e4.tools;bundle-version="0.9.0"
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide3x/build.properties b/examples/org.eclipse.e4.demo.tools.simpleide3x/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide3x/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide3x/plugin.xml b/examples/org.eclipse.e4.demo.tools.simpleide3x/plugin.xml
new file mode 100644
index 0000000..aeea30c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide3x/plugin.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.ui.newWizards">
+ <wizard
+ canFinishEarly="false"
+ category="org.eclipse.e4.tools/org.eclipse.e4.tools.model"
+ class="org.eclipse.e4.demo.tools.simpleide3x.SimpleIDEModelWizard"
+ hasPages="true"
+ id="org.eclipse.e4.demo.tools.simpleide3x.wizard1"
+ name="New Simple IDE Model">
+ </wizard>
+ </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.tools.simpleide3x/src/org/eclipse/e4/demo/tools/simpleide3x/SimpleIDEModelWizard.java b/examples/org.eclipse.e4.demo.tools.simpleide3x/src/org/eclipse/e4/demo/tools/simpleide3x/SimpleIDEModelWizard.java
new file mode 100644
index 0000000..fbe4d11
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.tools.simpleide3x/src/org/eclipse/e4/demo/tools/simpleide3x/SimpleIDEModelWizard.java
@@ -0,0 +1,27 @@
+package org.eclipse.e4.demo.tools.simpleide3x;
+
+import org.eclipse.e4.demo.simpleide.model.simpleide.MSimpleideFactory;
+import org.eclipse.e4.internal.tools.wizards.model.BaseApplicationModelWizard;
+import org.eclipse.e4.internal.tools.wizards.model.NewModelFilePage;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.viewers.ISelection;
+
+public class SimpleIDEModelWizard extends BaseApplicationModelWizard {
+
+ @Override
+ public String getDefaultFileName() {
+ return "Application.e4xmi";
+ }
+
+ @Override
+ protected EObject createInitialModel() {
+ return (EObject) MSimpleideFactory.INSTANCE.createSimpleIDEApplication();
+ }
+
+ @Override
+ protected NewModelFilePage createWizardPage(ISelection selection) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/.classpath b/examples/org.eclipse.e4.demo.views/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.demo.views/.project b/examples/org.eclipse.e4.demo.views/.project
new file mode 100644
index 0000000..4891d5b
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.demo.views</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.demo.views/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.demo.views/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..2aa81ad
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Fri Nov 28 13:21:46 EST 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/examples/org.eclipse.e4.demo.views/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.demo.views/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e767e96
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: LegacyViews Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.demo.views;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-Activator: org.eclipse.e4.demio.views.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.ui.ide;bundle-version="3.5.0",
+ org.eclipse.core.expressions;bundle-version="3.4.100"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Import-Package: org.eclipse.core.resources
+Bundle-Vendor: Eclipse.org
diff --git a/examples/org.eclipse.e4.demo.views/build.properties b/examples/org.eclipse.e4.demo.views/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml
diff --git a/examples/org.eclipse.e4.demo.views/plugin.xml b/examples/org.eclipse.e4.demo.views/plugin.xml
new file mode 100644
index 0000000..bd39fe2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/plugin.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+ <extension
+ point="org.eclipse.ui.views">
+ <view
+ class="org.eclipse.e4.demio.views.nav.ResourceNavigator"
+ id="LegacyViews.ResourceView"
+ name="ResourceNav"
+ restorable="true">
+ </view>
+ </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/Activator.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/Activator.java
new file mode 100644
index 0000000..d2f266c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/Activator.java
@@ -0,0 +1,51 @@
+package org.eclipse.e4.demio.views;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "LegacyViews";
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ *
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/CollapseAllAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/CollapseAllAction.java
new file mode 100644
index 0000000..833f1ad
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/CollapseAllAction.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * Sebastian Davids <sdavids@gmx.de> - Collapse all action (25826)
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.CollapseAllHandler;
+
+/**
+ * Collapse all project nodes.
+ */
+public class CollapseAllAction extends ResourceNavigatorAction {
+
+ /**
+ * Creates the action.
+ *
+ * @param navigator the resource navigator
+ * @param label the label for the action
+ */
+ public CollapseAllAction(IResourceNavigator navigator, String label) {
+ super(navigator, label);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+ INavigatorHelpContextIds.COLLAPSE_ALL_ACTION);
+ setEnabled(true);
+ setActionDefinitionId(CollapseAllHandler.COMMAND_ID);
+ }
+
+ /*
+ * Implementation of method defined on <code>IAction</code>.
+ */
+ public void run() {
+ getNavigator().getViewer().collapseAll();
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/CopyAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/CopyAction.java
new file mode 100644
index 0000000..8e799fb
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/CopyAction.java
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demio.views.nav;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.SelectionListenerAction;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.part.ResourceTransfer;
+
+/**
+ * Standard action for copying the currently selected resources to the clipboard.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ *
+ * @since 2.0
+ */
+/*package*/class CopyAction extends SelectionListenerAction {
+
+ /**
+ * The id of this action.
+ */
+ public static final String ID = PlatformUI.PLUGIN_ID + ".CopyAction"; //$NON-NLS-1$
+
+ /**
+ * The shell in which to show any dialogs.
+ */
+ private Shell shell;
+
+ /**
+ * System clipboard
+ */
+ private Clipboard clipboard;
+
+ /**
+ * Associated paste action. May be <code>null</code>
+ */
+ private PasteAction pasteAction;
+
+ /**
+ * Creates a new action.
+ *
+ * @param shell the shell for any dialogs
+ * @param clipboard a platform clipboard
+ */
+ public CopyAction(Shell shell, Clipboard clipboard) {
+ super(ResourceNavigatorMessages.CopyAction_title);
+ Assert.isNotNull(shell);
+ Assert.isNotNull(clipboard);
+ this.shell = shell;
+ this.clipboard = clipboard;
+ setToolTipText(ResourceNavigatorMessages.CopyAction_toolTip);
+ setId(CopyAction.ID);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+ INavigatorHelpContextIds.COPY_ACTION);
+ }
+
+ /**
+ * Creates a new action.
+ *
+ * @param shell the shell for any dialogs
+ * @param clipboard a platform clipboard
+ * @param pasteAction a paste action
+ *
+ * @since 2.0
+ */
+ public CopyAction(Shell shell, Clipboard clipboard, PasteAction pasteAction) {
+ this(shell, clipboard);
+ this.pasteAction = pasteAction;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ public void run() {
+ /**
+ * The <code>CopyAction</code> implementation of this method defined
+ * on <code>IAction</code> copies the selected resources to the
+ * clipboard.
+ */
+ List selectedResources = getSelectedResources();
+ IResource[] resources = (IResource[]) selectedResources
+ .toArray(new IResource[selectedResources.size()]);
+
+ // Get the file names and a string representation
+ final int length = resources.length;
+ int actualLength = 0;
+ String[] fileNames = new String[length];
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < length; i++) {
+ IPath location = resources[i].getLocation();
+ // location may be null. See bug 29491.
+ if (location != null) {
+ fileNames[actualLength++] = location.toOSString();
+ }
+ if (i > 0) {
+ buf.append("\n"); //$NON-NLS-1$
+ }
+ buf.append(resources[i].getName());
+ }
+ // was one or more of the locations null?
+ if (actualLength < length) {
+ String[] tempFileNames = fileNames;
+ fileNames = new String[actualLength];
+ for (int i = 0; i < actualLength; i++) {
+ fileNames[i] = tempFileNames[i];
+ }
+ }
+ setClipboard(resources, fileNames, buf.toString());
+
+ // update the enablement of the paste action
+ // workaround since the clipboard does not suppot callbacks
+ if (pasteAction != null && pasteAction.getStructuredSelection() != null) {
+ pasteAction.selectionChanged(pasteAction.getStructuredSelection());
+ }
+ }
+
+ /**
+ * Set the clipboard contents. Prompt to retry if clipboard is busy.
+ *
+ * @param resources the resources to copy to the clipboard
+ * @param fileNames file names of the resources to copy to the clipboard
+ * @param names string representation of all names
+ */
+ private void setClipboard(IResource[] resources, String[] fileNames,
+ String names) {
+ try {
+ // set the clipboard contents
+ if (fileNames.length > 0) {
+ clipboard.setContents(new Object[] { resources, fileNames,
+ names },
+ new Transfer[] { ResourceTransfer.getInstance(),
+ FileTransfer.getInstance(),
+ TextTransfer.getInstance() });
+ } else {
+ clipboard.setContents(new Object[] { resources, names },
+ new Transfer[] { ResourceTransfer.getInstance(),
+ TextTransfer.getInstance() });
+ }
+ } catch (SWTError e) {
+ if (e.code != DND.ERROR_CANNOT_SET_CLIPBOARD) {
+ throw e;
+ }
+ if (MessageDialog
+ .openQuestion(
+ shell,
+ ResourceNavigatorMessages.CopyToClipboardProblemDialog_title, ResourceNavigatorMessages.CopyToClipboardProblemDialog_message)) {
+ setClipboard(resources, fileNames, names);
+ }
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.actions.BaseSelectionListenerAction#updateSelection(org.eclipse.jface.viewers.IStructuredSelection)
+ */
+ protected boolean updateSelection(IStructuredSelection selection) {
+
+ /**
+ * The <code>CopyAction</code> implementation of this
+ * <code>SelectionListenerAction</code> method enables this action if
+ * one or more resources of compatible types are selected.
+ */
+
+ if (!super.updateSelection(selection)) {
+ return false;
+ }
+
+ if (getSelectedNonResources().size() > 0) {
+ return false;
+ }
+
+ List selectedResources = getSelectedResources();
+ if (selectedResources.size() == 0) {
+ return false;
+ }
+
+ boolean projSelected = selectionIsOfType(IResource.PROJECT);
+ boolean fileFoldersSelected = selectionIsOfType(IResource.FILE
+ | IResource.FOLDER);
+ if (!projSelected && !fileFoldersSelected) {
+ return false;
+ }
+
+ // selection must be homogeneous
+ if (projSelected && fileFoldersSelected) {
+ return false;
+ }
+
+ // must have a common parent
+ IContainer firstParent = ((IResource) selectedResources.get(0))
+ .getParent();
+ if (firstParent == null) {
+ return false;
+ }
+
+ Iterator resourcesEnum = selectedResources.iterator();
+ while (resourcesEnum.hasNext()) {
+ IResource currentResource = (IResource) resourcesEnum.next();
+ if (!currentResource.getParent().equals(firstParent)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+}
+
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/FilterSelectionAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/FilterSelectionAction.java
new file mode 100644
index 0000000..505903a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/FilterSelectionAction.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.e4.demio.views.nav;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.window.Window;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.ListSelectionDialog;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+
+/**
+ * The FilterSelectionAction opens the filters dialog.
+ */
+public class FilterSelectionAction extends ResourceNavigatorAction {
+ private static final String FILTER_TOOL_TIP = ResourceNavigatorMessages.FilterSelection_toolTip;
+
+ private static final String FILTER_SELECTION_MESSAGE = ResourceNavigatorMessages.FilterSelection_message;
+
+ private static final String FILTER_TITLE_MESSAGE = ResourceNavigatorMessages.FilterSelection_title;
+
+ /**
+ * Creates the action.
+ *
+ * @param navigator the resource navigator
+ * @param label the label for the action
+ */
+ public FilterSelectionAction(IResourceNavigator navigator, String label) {
+ super(navigator, label);
+ setToolTipText(FILTER_TOOL_TIP);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+ INavigatorHelpContextIds.FILTER_SELECTION_ACTION);
+ setEnabled(true);
+ }
+
+ /*
+ * Implementation of method defined on <code>IAction</code>.
+ */
+ public void run() {
+ IResourceNavigator navigator = getNavigator();
+ ResourcePatternFilter filter = navigator.getPatternFilter();
+ FiltersContentProvider contentProvider = new FiltersContentProvider(
+ filter);
+
+ ListSelectionDialog dialog = new ListSelectionDialog(getShell(),
+ getViewer(), contentProvider, new LabelProvider(),
+ FILTER_SELECTION_MESSAGE);
+
+ dialog.setTitle(FILTER_TITLE_MESSAGE);
+ dialog.setInitialSelections(contentProvider.getInitialSelections());
+ dialog.open();
+ if (dialog.getReturnCode() == Window.OK) {
+ Object[] results = dialog.getResult();
+ String[] selectedPatterns = new String[results.length];
+ System.arraycopy(results, 0, selectedPatterns, 0, results.length);
+ filter.setPatterns(selectedPatterns);
+ navigator.setFiltersPreference(selectedPatterns);
+ Viewer viewer = getViewer();
+ viewer.getControl().setRedraw(false);
+ viewer.refresh();
+ viewer.getControl().setRedraw(true);
+ }
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/FiltersContentProvider.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/FiltersContentProvider.java
new file mode 100644
index 0000000..36804e4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/FiltersContentProvider.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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.e4.demio.views.nav;
+
+import java.util.ArrayList;
+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.Platform;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+
+/**
+ * The FiltersContentProvider provides the elements for use by the list dialog
+ * for selecting the patterns to apply.
+ */
+/* package */class FiltersContentProvider implements
+ IStructuredContentProvider {
+
+ private static List definedFilters;
+
+ private static List defaultFilters;
+
+ private ResourcePatternFilter resourceFilter;
+
+ /**
+ * Create a FiltersContentProvider using the selections from the supplied
+ * resource filter.
+ *
+ * @param filter the resource pattern filter
+ */
+ public FiltersContentProvider(ResourcePatternFilter filter) {
+ this.resourceFilter = filter;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IContentProvider.
+ */
+ public void dispose() {
+ }
+
+ /**
+ * Returns the filters which are enabled by default.
+ *
+ * @return a list of strings
+ */
+ public static List getDefaultFilters() {
+ if (defaultFilters == null) {
+ readFilters();
+ }
+ return defaultFilters;
+ }
+
+ /**
+ * Returns the filters currently defined for the navigator.
+ *
+ * @return a list of strings
+ */
+ public static List getDefinedFilters() {
+ if (definedFilters == null) {
+ readFilters();
+ }
+ return definedFilters;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IStructuredContentProvider.
+ */
+ public Object[] getElements(Object inputElement) {
+ return getDefinedFilters().toArray();
+ }
+
+ /**
+ * Return the initially selected elements.
+ *
+ * @return an array with the initial selections
+ */
+ public String[] getInitialSelections() {
+ return this.resourceFilter.getPatterns();
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IContentProvider.
+ */
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ /**
+ * Reads the filters currently defined for the workbench.
+ */
+ private static void readFilters() {
+ definedFilters = new ArrayList();
+ defaultFilters = new ArrayList();
+ IExtensionPoint extension = Platform.getExtensionRegistry()
+ .getExtensionPoint(IDEWorkbenchPlugin.IDE_WORKBENCH + '.'
+ + ResourcePatternFilter.FILTERS_TAG);
+ if (extension != null) {
+ IExtension[] extensions = extension.getExtensions();
+ for (int i = 0; i < extensions.length; i++) {
+ IConfigurationElement[] configElements = extensions[i]
+ .getConfigurationElements();
+ for (int j = 0; j < configElements.length; j++) {
+ String pattern = configElements[j].getAttribute("pattern");//$NON-NLS-1$
+ if (pattern != null) {
+ definedFilters.add(pattern);
+ }
+ String selected = configElements[j]
+ .getAttribute("selected");//$NON-NLS-1$
+ if (selected != null && selected.equalsIgnoreCase("true")) { //$NON-NLS-1$
+ defaultFilters.add(pattern);
+ }
+ }
+
+ }
+ }
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoActionGroup.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoActionGroup.java
new file mode 100644
index 0000000..b07e4c2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoActionGroup.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.views.framelist.BackAction;
+import org.eclipse.ui.views.framelist.ForwardAction;
+import org.eclipse.ui.views.framelist.FrameList;
+import org.eclipse.ui.views.framelist.GoIntoAction;
+import org.eclipse.ui.views.framelist.UpAction;
+
+/**
+ * This is the action group for the goto actions.
+ */
+public class GotoActionGroup extends ResourceNavigatorActionGroup {
+
+ private BackAction backAction;
+
+ private ForwardAction forwardAction;
+
+ private GoIntoAction goIntoAction;
+
+ private UpAction upAction;
+
+ private GotoResourceAction goToResourceAction;
+
+ public GotoActionGroup(IResourceNavigator navigator) {
+ super(navigator);
+ }
+
+ public void fillContextMenu(IMenuManager menu) {
+ IStructuredSelection selection = (IStructuredSelection) getContext()
+ .getSelection();
+ if (selection.size() == 1) {
+ if (ResourceSelectionUtil.allResourcesAreOfType(selection,
+ IResource.FOLDER)) {
+ menu.add(goIntoAction);
+ } else {
+ IStructuredSelection resourceSelection = ResourceSelectionUtil
+ .allResources(selection, IResource.PROJECT);
+ if (resourceSelection != null && !resourceSelection.isEmpty()) {
+ IProject project = (IProject) resourceSelection
+ .getFirstElement();
+ if (project.isOpen()) {
+ menu.add(goIntoAction);
+ }
+ }
+ }
+ }
+ }
+
+ public void fillActionBars(IActionBars actionBars) {
+ actionBars.setGlobalActionHandler(IWorkbenchActionConstants.GO_INTO,
+ goIntoAction);
+ actionBars.setGlobalActionHandler(ActionFactory.BACK.getId(),
+ backAction);
+ actionBars.setGlobalActionHandler(ActionFactory.FORWARD.getId(),
+ forwardAction);
+ actionBars.setGlobalActionHandler(IWorkbenchActionConstants.UP,
+ upAction);
+ actionBars.setGlobalActionHandler(
+ IWorkbenchActionConstants.GO_TO_RESOURCE, goToResourceAction);
+
+ IToolBarManager toolBar = actionBars.getToolBarManager();
+ toolBar.add(backAction);
+ toolBar.add(forwardAction);
+ toolBar.add(upAction);
+ }
+
+ protected void makeActions() {
+ FrameList frameList = navigator.getFrameList();
+ goIntoAction = new GoIntoAction(frameList);
+ backAction = new BackAction(frameList);
+ forwardAction = new ForwardAction(frameList);
+ upAction = new UpAction(frameList);
+ goToResourceAction = new GotoResourceAction(navigator,
+ ResourceNavigatorMessages.GoToResource_label);
+ }
+
+ public void updateActionBars() {
+ ActionContext context = getContext();
+ boolean enable = false;
+
+ // Fix for bug 26126. Resource change listener could call
+ // updateActionBars without a context being set.
+ // This should never happen because resource navigator sets
+ // context immediately after this group is created.
+ if (context != null) {
+ IStructuredSelection selection = (IStructuredSelection) context
+ .getSelection();
+
+ if (selection.size() == 1) {
+ Object object = selection.getFirstElement();
+ if (object instanceof IProject) {
+ enable = ((IProject) object).isOpen();
+ } else if (object instanceof IFolder) {
+ enable = true;
+ }
+ }
+ }
+ goIntoAction.setEnabled(enable);
+ // the rest of the actions update by listening to frame list changes
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoResourceAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoResourceAction.java
new file mode 100644
index 0000000..5c3dd90
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoResourceAction.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Implements the go to resource action. Opens a dialog and set
+ * the navigator selection with the resource selected by
+ * the user.
+ */
+public class GotoResourceAction extends ResourceNavigatorAction {
+ /**
+ * Creates a new instance of the class.
+ *
+ * @param navigator the navigator
+ * @param label the label
+ * @since 2.0
+ */
+ public GotoResourceAction(IResourceNavigator navigator, String label) {
+ super(navigator, label);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+ INavigatorHelpContextIds.GOTO_RESOURCE_ACTION);
+ }
+
+ /**
+ * Collect all resources in the workbench open a dialog asking
+ * the user to select a resource and change the selection in
+ * the navigator.
+ */
+ public void run() {
+ IContainer container = (IContainer) getViewer().getInput();
+ GotoResourceDialog dialog = new GotoResourceDialog(getShell(),
+ container, IResource.FILE | IResource.FOLDER
+ | IResource.PROJECT);
+ dialog.open();
+ Object[] result = dialog.getResult();
+ if (result == null || result.length == 0
+ || result[0] instanceof IResource == false) {
+ return;
+ }
+
+ IResource selection = (IResource) result[0];
+ getViewer().setSelection(new StructuredSelection(selection), true);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoResourceDialog.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoResourceDialog.java
new file mode 100644
index 0000000..8dac66f
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/GotoResourceDialog.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.FilteredResourcesSelectionDialog;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+
+/**
+ * Shows a list of resources to the user with a text entry field for a string
+ * pattern used to filter the list of resources.
+ *
+ */
+/* package */class GotoResourceDialog extends FilteredResourcesSelectionDialog {
+
+ /**
+ * Creates a new instance of the class.
+ */
+ protected GotoResourceDialog(Shell parentShell, IContainer container,
+ int typesMask) {
+ super(parentShell, false, container, typesMask);
+ setTitle(ResourceNavigatorMessages.Goto_title);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(parentShell,
+ INavigatorHelpContextIds.GOTO_RESOURCE_DIALOG);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/INavigatorHelpContextIds.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/INavigatorHelpContextIds.java
new file mode 100644
index 0000000..c89fbfb
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/INavigatorHelpContextIds.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * Sebastian Davids <sdavids@gmx.de> - Collapse all action (25826)
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Help context ids for the resource navigator view.
+ * <p>
+ * This interface contains constants only; it is not intended to be implemented
+ * or extended.
+ * </p>
+ *
+ */
+/*package*/interface INavigatorHelpContextIds {
+ public static final String PREFIX = PlatformUI.PLUGIN_ID + "."; //$NON-NLS-1$
+
+ // Actions
+ public static final String FILTER_SELECTION_ACTION = PREFIX
+ + "filter_selection_action_context"; //$NON-NLS-1$
+
+ public static final String GOTO_RESOURCE_ACTION = PREFIX
+ + "goto_resource_action_context"; //$NON-NLS-1$
+
+ public static final String RESOURCE_NAVIGATOR_MOVE_ACTION = PREFIX
+ + "resource_navigator_move_action_context"; //$NON-NLS-1$
+
+ public static final String RESOURCE_NAVIGATOR_RENAME_ACTION = PREFIX
+ + "resource_navigator_rename_action_context"; //$NON-NLS-1$
+
+ public static final String SHOW_IN_NAVIGATOR_ACTION = PREFIX
+ + "show_in_navigator_action_context"; //$NON-NLS-1$
+
+ public static final String SORT_VIEW_ACTION = PREFIX
+ + "sort_view_action_context"; //$NON-NLS-1$
+
+ public static final String COPY_ACTION = PREFIX
+ + "resource_navigator_copy_action_context"; //$NON-NLS-1$
+
+ public static final String PASTE_ACTION = PREFIX
+ + "resource_navigator_paste_action_context"; //$NON-NLS-1$
+
+ public static final String COLLAPSE_ALL_ACTION = PREFIX
+ + "collapse_all_action_context"; //$NON-NLS-1$
+
+ // Dialogs
+ public static final String GOTO_RESOURCE_DIALOG = PREFIX
+ + "goto_resource_dialog_context"; //$NON-NLS-1$
+
+ // Views
+ public static final String RESOURCE_VIEW = PREFIX + "resource_view_context"; //$NON-NLS-1$
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/IResourceNavigator.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/IResourceNavigator.java
new file mode 100644
index 0000000..81adb44
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/IResourceNavigator.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.e4.demio.views.nav;
+
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.views.framelist.FrameList;
+
+/**
+ * This interface defines the API for the resource navigator.
+ * The action groups should restrict themselves to using this API.
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * Subclass <code>org.eclipse.ui.views.ResourceNavigator</code>
+ * instead.
+ * </p>
+ *
+ * @since 2.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IResourceNavigator extends IViewPart {
+
+ /**
+ * Returns the pattern filter.
+ *
+ * @return the pattern filter
+ */
+ ResourcePatternFilter getPatternFilter();
+
+ /**
+ * Returns the active working set, or <code>null<code> if none.
+ *
+ * @return the active working set, or <code>null<code> if none
+ * @since 2.0
+ */
+ IWorkingSet getWorkingSet();
+
+ /**
+ * Returns the current sorter.
+ * @return the resource navigator's sorter
+ *
+ * @deprecated as of 3.3, use {@link IResourceNavigator#getComparator()} instead
+ */
+ ResourceSorter getSorter();
+
+ /**
+ * Sets the current sorter.
+ * @param sorter the sorter to use
+ *
+ * @deprecated as of 3.3, use {@link IResourceNavigator#setComparator(ResourceComparator)} instead
+ */
+ void setSorter(ResourceSorter sorter);
+
+ /**
+ * Returns the current comparator.
+ *
+ * @return the resource navigator's comparator
+ * @since 3.3
+ */
+ ResourceComparator getComparator();
+
+ /**
+ * Sets the current comparator.
+ *
+ * @param comparator the comparator to use
+ * @since 3.3
+ */
+ void setComparator(ResourceComparator comparator);
+
+ /**
+ * Sets the values of the filter preference to be the
+ * strings in preference values.
+ * @param patterns filter patterns to use on contents of the resource navigator
+ */
+ void setFiltersPreference(String[] patterns);
+
+ /**
+ * Returns the viewer which shows the resource tree.
+ * @return the resource navigator's tree viewer
+ */
+ TreeViewer getViewer();
+
+ /**
+ * Returns the frame list for this navigator.
+ * @return the list of frames maintained by the resource navigator
+ */
+ FrameList getFrameList();
+
+ /**
+ * Returns whether this navigator's selection automatically tracks the active editor.
+ *
+ * @return <code>true</code> if linking is enabled, <code>false</code> if not
+ * @since 2.1
+ */
+ boolean isLinkingEnabled();
+
+ /**
+ * Sets the working set for this view, or <code>null</code> to clear it.
+ *
+ * @param workingSet the working set, or <code>null</code> to clear it
+ * @since 2.0
+ */
+ void setWorkingSet(IWorkingSet workingSet);
+
+ /**
+ * Sets whether this navigator's selection automatically tracks the active editor.
+ *
+ * @param enabled <code>true</code> to enable, <code>false</code> to disable
+ * @since 2.1
+ */
+ void setLinkingEnabled(boolean enabled);
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/LocalSelectionTransfer.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/LocalSelectionTransfer.java
new file mode 100644
index 0000000..5336090
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/LocalSelectionTransfer.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.e4.demio.views.nav;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.dnd.TransferData;
+
+/**
+ * A LocalSelectionTransfer may be used for drag and drop operations within the
+ * same instance of Eclipse. The selection is made available directly for use in
+ * the DropTargetListener. dropAccept method. The DropTargetEvent passed to
+ * dropAccept does not contain the drop data. The selection may be used for
+ * validation purposes so that the drop can be aborted if appropriate. This
+ * class is not intended to be subclassed.
+ *
+ * @since 2.1
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class LocalSelectionTransfer extends
+ org.eclipse.jface.util.LocalSelectionTransfer {
+
+ private static final LocalSelectionTransfer INSTANCE = new LocalSelectionTransfer();
+
+ /**
+ * The get/set methods delegate to JFace's LocalSelectionTransfer to allow
+ * data to be exchanged freely whether the client uses this
+ * LocalSelectionTransfer or JFace's LocalSelectionTransfer. Protected
+ * methods such as getTypeIds() are handled via inheritance, not delegation
+ * due to visibility constraints.
+ */
+ private org.eclipse.jface.util.LocalSelectionTransfer jfaceTransfer = org.eclipse.jface.util.LocalSelectionTransfer
+ .getTransfer();
+
+ /**
+ * Only the singleton instance of this class may be used.
+ */
+ private LocalSelectionTransfer() {
+ }
+
+ /**
+ * Returns the singleton.
+ *
+ * @return the singleton
+ */
+ public static LocalSelectionTransfer getInstance() {
+ return INSTANCE;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.util.LocalSelectionTransfer#getSelection()
+ */
+ public ISelection getSelection() {
+ return jfaceTransfer.getSelection();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.util.LocalSelectionTransfer#getSelectionSetTime()
+ */
+ public long getSelectionSetTime() {
+ return jfaceTransfer.getSelectionSetTime();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.util.LocalSelectionTransfer#setSelection(org.eclipse.jface.viewers.ISelection)
+ */
+ public void setSelection(ISelection s) {
+ jfaceTransfer.setSelection(s);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.util.LocalSelectionTransfer#setSelectionSetTime(long)
+ */
+ public void setSelectionSetTime(long time) {
+ jfaceTransfer.setSelectionSetTime(time);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.util.LocalSelectionTransfer#javaToNative(java.lang.Object, org.eclipse.swt.dnd.TransferData)
+ */
+ public void javaToNative(Object object, TransferData transferData) {
+ jfaceTransfer.javaToNative(object, transferData);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.util.LocalSelectionTransfer#nativeToJava(org.eclipse.swt.dnd.TransferData)
+ */
+ public Object nativeToJava(TransferData transferData) {
+ return jfaceTransfer.nativeToJava(transferData);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/MainActionGroup.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/MainActionGroup.java
new file mode 100644
index 0000000..ced7aeb
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/MainActionGroup.java
@@ -0,0 +1,365 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * Sebastian Davids <sdavids@gmx.de> - Collapse all action (25826)
+ * Sebastian Davids <sdavids@gmx.de> - Images for menu items (27481)
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import java.util.List;
+
+import org.eclipse.core.commands.operations.IUndoContext;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.window.IShellProvider;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.AddBookmarkAction;
+import org.eclipse.ui.actions.AddTaskAction;
+import org.eclipse.ui.actions.ExportResourcesAction;
+import org.eclipse.ui.actions.ImportResourcesAction;
+import org.eclipse.ui.actions.NewWizardMenu;
+import org.eclipse.ui.actions.WorkingSetFilterActionGroup;
+import org.eclipse.ui.dialogs.PropertyDialogAction;
+import org.eclipse.ui.ide.IDEActionFactory;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.operations.UndoRedoActionGroup;
+
+/**
+ * The main action group for the navigator.
+ * This contains a few actions and several subgroups.
+ */
+public class MainActionGroup extends ResourceNavigatorActionGroup {
+
+ protected AddBookmarkAction addBookmarkAction;
+
+ protected AddTaskAction addTaskAction;
+
+ protected PropertyDialogAction propertyDialogAction;
+
+ protected ImportResourcesAction importAction;
+
+ protected ExportResourcesAction exportAction;
+
+ protected CollapseAllAction collapseAllAction;
+
+ protected ToggleLinkingAction toggleLinkingAction;
+
+ protected GotoActionGroup gotoGroup;
+
+ protected OpenActionGroup openGroup;
+
+ protected RefactorActionGroup refactorGroup;
+
+ protected WorkingSetFilterActionGroup workingSetGroup;
+
+ protected SortAndFilterActionGroup sortAndFilterGroup;
+
+ protected UndoRedoActionGroup undoRedoGroup;
+
+ protected WorkspaceActionGroup workspaceGroup;
+
+ private IResourceChangeListener resourceChangeListener;
+
+ private NewWizardMenu newWizardMenu;
+
+ /**
+ * Constructs the main action group.
+ *
+ * @param navigator the navigator view
+ */
+ public MainActionGroup(IResourceNavigator navigator) {
+ super(navigator);
+ resourceChangeListener = new IResourceChangeListener() {
+ public void resourceChanged(IResourceChangeEvent event) {
+ handleResourceChanged(event);
+ }
+ };
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(
+ resourceChangeListener, IResourceChangeEvent.POST_CHANGE);
+ makeSubGroups();
+ }
+
+ /**
+ * Handles a resource changed event by updating the enablement
+ * if one of the selected projects is opened or closed.
+ */
+ protected void handleResourceChanged(IResourceChangeEvent event) {
+ ActionContext context = getContext();
+ if (context == null) {
+ return;
+ }
+
+ final IStructuredSelection selection = (IStructuredSelection) context
+ .getSelection();
+ if (ResourceSelectionUtil.allResourcesAreOfType(selection,
+ IResource.PROJECT) == false) {
+ return;
+ }
+ List sel = selection.toList();
+ IResourceDelta delta = event.getDelta();
+ if (delta == null) {
+ return;
+ }
+ IResourceDelta[] projDeltas = delta
+ .getAffectedChildren(IResourceDelta.CHANGED);
+ for (int i = 0; i < projDeltas.length; ++i) {
+ IResourceDelta projDelta = projDeltas[i];
+ //changing the project open state or description will effect open/close/build action enablement
+ if ((projDelta.getFlags() & (IResourceDelta.OPEN | IResourceDelta.DESCRIPTION)) != 0) {
+ if (sel.contains(projDelta.getResource())) {
+ getNavigator().getSite().getShell().getDisplay().syncExec(
+ new Runnable() {
+ public void run() {
+ addTaskAction.selectionChanged(selection);
+ gotoGroup.updateActionBars();
+ refactorGroup.updateActionBars();
+ workspaceGroup.updateActionBars();
+ }
+ });
+ }
+ }
+ }
+ }
+
+ /**
+ * Makes the actions contained directly in this action group.
+ */
+ protected void makeActions() {
+ IShellProvider provider = navigator.getSite();
+
+ newWizardMenu = new NewWizardMenu(navigator.getSite().getWorkbenchWindow());
+ addBookmarkAction = new AddBookmarkAction(provider, true);
+ addTaskAction = new AddTaskAction(provider);
+ propertyDialogAction = new PropertyDialogAction(provider, navigator
+ .getViewer());
+
+ importAction = new ImportResourcesAction(navigator.getSite()
+ .getWorkbenchWindow());
+ importAction
+ .setDisabledImageDescriptor(getImageDescriptor("dtool16/import_wiz.gif")); //$NON-NLS-1$
+ importAction
+ .setImageDescriptor(getImageDescriptor("etool16/import_wiz.gif")); //$NON-NLS-1$
+
+ exportAction = new ExportResourcesAction(navigator.getSite()
+ .getWorkbenchWindow());
+ exportAction
+ .setDisabledImageDescriptor(getImageDescriptor("dtool16/export_wiz.gif")); //$NON-NLS-1$
+ exportAction
+ .setImageDescriptor(getImageDescriptor("etool16/export_wiz.gif")); //$NON-NLS-1$
+
+
+ collapseAllAction = new CollapseAllAction(navigator,
+ ResourceNavigatorMessages.CollapseAllAction_title);
+ collapseAllAction.setToolTipText(ResourceNavigatorMessages.CollapseAllAction_toolTip);
+ collapseAllAction
+ .setImageDescriptor(getImageDescriptor("elcl16/collapseall.gif")); //$NON-NLS-1$
+
+ toggleLinkingAction = new ToggleLinkingAction(navigator,
+ ResourceNavigatorMessages.ToggleLinkingAction_text);
+ toggleLinkingAction.setToolTipText(ResourceNavigatorMessages.ToggleLinkingAction_toolTip);
+ toggleLinkingAction
+ .setImageDescriptor(getImageDescriptor("elcl16/synced.gif"));//$NON-NLS-1$
+ }
+
+ /**
+ * Makes the sub action groups.
+ */
+ protected void makeSubGroups() {
+ gotoGroup = new GotoActionGroup(navigator);
+ openGroup = new OpenActionGroup(navigator);
+ refactorGroup = new RefactorActionGroup(navigator);
+ IPropertyChangeListener workingSetUpdater = new IPropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ String property = event.getProperty();
+
+ if (WorkingSetFilterActionGroup.CHANGE_WORKING_SET
+ .equals(property)) {
+ IResourceNavigator navigator = getNavigator();
+ Object newValue = event.getNewValue();
+
+ if (newValue instanceof IWorkingSet) {
+ navigator.setWorkingSet((IWorkingSet) newValue);
+ } else if (newValue == null) {
+ navigator.setWorkingSet(null);
+ }
+ }
+ }
+ };
+ TreeViewer treeView = navigator.getViewer();
+ Shell shell = treeView.getControl().getShell();
+ workingSetGroup = new WorkingSetFilterActionGroup(shell,
+ workingSetUpdater);
+ workingSetGroup.setWorkingSet(navigator.getWorkingSet());
+ sortAndFilterGroup = new SortAndFilterActionGroup(navigator);
+ workspaceGroup = new WorkspaceActionGroup(navigator);
+ IUndoContext workspaceContext= (IUndoContext)ResourcesPlugin.getWorkspace().getAdapter(IUndoContext.class);
+ undoRedoGroup= new UndoRedoActionGroup(getNavigator().getSite(), workspaceContext, true);
+
+ }
+
+ /**
+ * Extends the superclass implementation to set the context in the subgroups.
+ */
+ public void setContext(ActionContext context) {
+ super.setContext(context);
+ gotoGroup.setContext(context);
+ openGroup.setContext(context);
+ refactorGroup.setContext(context);
+ sortAndFilterGroup.setContext(context);
+ workspaceGroup.setContext(context);
+ undoRedoGroup.setContext(context);
+ }
+
+ /**
+ * Fills the context menu with the actions contained in this group
+ * and its subgroups.
+ *
+ * @param menu the context menu
+ */
+ public void fillContextMenu(IMenuManager menu) {
+ IStructuredSelection selection = (IStructuredSelection) getContext()
+ .getSelection();
+
+ MenuManager newMenu = new MenuManager(ResourceNavigatorMessages.ResourceNavigator_new);
+ menu.add(newMenu);
+ newMenu.add(newWizardMenu);
+
+ gotoGroup.fillContextMenu(menu);
+ openGroup.fillContextMenu(menu);
+ menu.add(new Separator());
+
+ refactorGroup.fillContextMenu(menu);
+ menu.add(new Separator());
+
+ menu.add(importAction);
+ menu.add(exportAction);
+ importAction.selectionChanged(selection);
+ exportAction.selectionChanged(selection);
+ menu.add(new Separator());
+
+ workspaceGroup.fillContextMenu(menu);
+
+ menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ menu
+ .add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS
+ + "-end")); //$NON-NLS-1$
+ menu.add(new Separator());
+
+ if (selection.size() == 1) {
+ propertyDialogAction.selectionChanged(selection);
+ menu.add(propertyDialogAction);
+ }
+ }
+
+ /**
+ * Adds the actions in this group and its subgroups to the action bars.
+ */
+ public void fillActionBars(IActionBars actionBars) {
+ actionBars.setGlobalActionHandler(ActionFactory.PROPERTIES.getId(),
+ propertyDialogAction);
+ actionBars.setGlobalActionHandler(IDEActionFactory.BOOKMARK.getId(),
+ addBookmarkAction);
+ actionBars.setGlobalActionHandler(IDEActionFactory.ADD_TASK.getId(),
+ addTaskAction);
+
+ gotoGroup.fillActionBars(actionBars);
+ openGroup.fillActionBars(actionBars);
+ refactorGroup.fillActionBars(actionBars);
+ workingSetGroup.fillActionBars(actionBars);
+ sortAndFilterGroup.fillActionBars(actionBars);
+ workspaceGroup.fillActionBars(actionBars);
+ undoRedoGroup.fillActionBars(actionBars);
+
+ IMenuManager menu = actionBars.getMenuManager();
+ menu.add(toggleLinkingAction);
+
+ IToolBarManager toolBar = actionBars.getToolBarManager();
+ toolBar.add(new Separator());
+ toolBar.add(collapseAllAction);
+ toolBar.add(toggleLinkingAction);
+ }
+
+ /**
+ * Updates the actions which were added to the action bars,
+ * delegating to the subgroups as necessary.
+ */
+ public void updateActionBars() {
+ IStructuredSelection selection = (IStructuredSelection) getContext()
+ .getSelection();
+ propertyDialogAction.setEnabled(selection.size() == 1);
+ addBookmarkAction.selectionChanged(selection);
+ addTaskAction.selectionChanged(selection);
+
+ gotoGroup.updateActionBars();
+ openGroup.updateActionBars();
+ refactorGroup.updateActionBars();
+ workingSetGroup.updateActionBars();
+ sortAndFilterGroup.updateActionBars();
+ workspaceGroup.updateActionBars();
+ undoRedoGroup.updateActionBars();
+ }
+
+ /**
+ * Runs the default action (open file) by delegating the open group.
+ */
+ public void runDefaultAction(IStructuredSelection selection) {
+ openGroup.runDefaultAction(selection);
+ }
+
+ /**
+ * Handles a key pressed event by invoking the appropriate action,
+ * delegating to the subgroups as necessary.
+ */
+ public void handleKeyPressed(KeyEvent event) {
+ refactorGroup.handleKeyPressed(event);
+ workspaceGroup.handleKeyPressed(event);
+ }
+
+ /**
+ * Extends the superclass implementation to dispose the
+ * actions in this group and its subgroups.
+ */
+ public void dispose() {
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(
+ resourceChangeListener);
+
+ newWizardMenu.dispose();
+ collapseAllAction.dispose();
+ importAction.dispose();
+ exportAction.dispose();
+ propertyDialogAction.dispose();
+ toggleLinkingAction.dispose();
+
+ gotoGroup.dispose();
+ openGroup.dispose();
+ refactorGroup.dispose();
+ sortAndFilterGroup.dispose();
+ workingSetGroup.dispose();
+ workspaceGroup.dispose();
+ undoRedoGroup.dispose();
+ super.dispose();
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorDragAdapter.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorDragAdapter.java
new file mode 100644
index 0000000..cb1d2c2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorDragAdapter.java
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.e4.demio.views.nav;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DragSource;
+import org.eclipse.swt.dnd.DragSourceAdapter;
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.DragSourceListener;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.actions.ReadOnlyStateChecker;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.part.ResourceTransfer;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+/**
+ * Implements drag behaviour when items are dragged out of the
+ * resource navigator.
+ *
+ * @since 2.0
+ */
+public class NavigatorDragAdapter extends DragSourceAdapter {
+ private static final String CHECK_MOVE_TITLE = ResourceNavigatorMessages.DragAdapter_title;
+
+ private static final String CHECK_DELETE_MESSAGE = ResourceNavigatorMessages.DragAdapter_checkDeleteMessage;
+
+ ISelectionProvider selectionProvider;
+
+ private TransferData lastDataType;
+
+ /**
+ * Constructs a new drag adapter.
+ * @param provider The selection provider
+ */
+ public NavigatorDragAdapter(ISelectionProvider provider) {
+ selectionProvider = provider;
+ }
+
+ /**
+ * This implementation of {@link DragSourceListener#dragFinished(DragSourceEvent)}
+ * responds to a drag that has moved resources outside the Navigator by deleting
+ * the corresponding source resource.
+ */
+ public void dragFinished(DragSourceEvent event) {
+ LocalSelectionTransfer.getInstance().setSelection(null);
+
+ if (event.doit == false) {
+ return;
+ }
+
+ final int typeMask = IResource.FOLDER | IResource.FILE;
+ if (event.detail == DND.DROP_MOVE) {
+ //never delete resources when dragging outside Eclipse.
+ //workaround for bug 30543.
+ if (lastDataType != null
+ && FileTransfer.getInstance().isSupportedType(lastDataType)) {
+ return;
+ }
+
+ IResource[] resources = getSelectedResources(typeMask);
+ DragSource dragSource = (DragSource) event.widget;
+ Control control = dragSource.getControl();
+ Shell shell = control.getShell();
+ ReadOnlyStateChecker checker;
+
+ if (resources == null || resources.length == 0) {
+ return;
+ }
+
+ checker = new ReadOnlyStateChecker(shell, CHECK_MOVE_TITLE,
+ CHECK_DELETE_MESSAGE);
+ resources = checker.checkReadOnlyResources(resources);
+ //delete the old elements
+ for (int i = 0; i < resources.length; i++) {
+ try {
+ resources[i].delete(IResource.KEEP_HISTORY
+ | IResource.FORCE, null);
+ } catch (CoreException e) {
+ StatusManager.getManager().handle(e, IDEWorkbenchPlugin.IDE_WORKBENCH);
+ }
+ }
+ } else if (event.detail == DND.DROP_TARGET_MOVE) {
+ IResource[] resources = getSelectedResources(typeMask);
+
+ // file moved for us by OS, no need to delete the resources, just
+ // update the view
+ if (resources == null) {
+ return;
+ }
+ for (int i = 0; i < resources.length; i++) {
+ try {
+ resources[i].refreshLocal(IResource.DEPTH_INFINITE, null);
+ } catch (CoreException e) {
+ StatusManager.getManager().handle(e, IDEWorkbenchPlugin.IDE_WORKBENCH);
+ }
+ }
+ }
+ }
+
+ /**
+ * This implementation of {@link DragSourceListener#dragSetData(DragSourceEvent)}
+ * sets the drag event data based on the current selection in the Navigator.
+ */
+ public void dragSetData(DragSourceEvent event) {
+ final int typeMask = IResource.FILE | IResource.FOLDER;
+ IResource[] resources = getSelectedResources(typeMask);
+
+ if (resources == null || resources.length == 0) {
+ return;
+ }
+
+ lastDataType = event.dataType;
+ //use local selection transfer if possible
+ if (LocalSelectionTransfer.getInstance()
+ .isSupportedType(event.dataType)) {
+ event.data = LocalSelectionTransfer.getInstance().getSelection();
+ return;
+ }
+ //use resource transfer if possible
+ if (ResourceTransfer.getInstance().isSupportedType(event.dataType)) {
+ event.data = resources;
+ return;
+ }
+ //resort to a file transfer
+ if (!FileTransfer.getInstance().isSupportedType(event.dataType)) {
+ return;
+ }
+
+ // Get the path of each file and set as the drag data
+ final int length = resources.length;
+ int actualLength = 0;
+ String[] fileNames = new String[length];
+ for (int i = 0; i < length; i++) {
+ IPath location = resources[i].getLocation();
+ // location may be null. See bug 29491.
+ if (location != null) {
+ fileNames[actualLength++] = location.toOSString();
+ }
+ }
+ if (actualLength == 0) {
+ return;
+ }
+ // was one or more of the locations null?
+ if (actualLength < length) {
+ String[] tempFileNames = fileNames;
+ fileNames = new String[actualLength];
+ for (int i = 0; i < actualLength; i++) {
+ fileNames[i] = tempFileNames[i];
+ }
+ }
+ event.data = fileNames;
+ }
+
+ /**
+ * This implementation of {@link DragSourceListener#dragStart(DragSourceEvent)}
+ * allows the drag to start if the current Navigator selection contains resources
+ * that can be dragged.
+ */
+ public void dragStart(DragSourceEvent event) {
+ lastDataType = null;
+ // Workaround for 1GEUS9V
+ DragSource dragSource = (DragSource) event.widget;
+ Control control = dragSource.getControl();
+ if (control != control.getDisplay().getFocusControl()) {
+ event.doit = false;
+ return;
+ }
+
+ IStructuredSelection selection = (IStructuredSelection) selectionProvider
+ .getSelection();
+ for (Iterator i = selection.iterator(); i.hasNext();) {
+ Object next = i.next();
+ if (!(next instanceof IFile || next instanceof IFolder)) {
+ event.doit = false;
+ return;
+ }
+ }
+ if (selection.isEmpty()) {
+ event.doit = false;
+ return;
+ }
+ LocalSelectionTransfer.getInstance().setSelection(selection);
+ event.doit = true;
+ }
+
+ private IResource[] getSelectedResources(int resourceTypes) {
+ List resources = new ArrayList();
+ IResource[] result = new IResource[0];
+
+ ISelection selection = selectionProvider.getSelection();
+ if (!(selection instanceof IStructuredSelection) || selection.isEmpty()) {
+ return null;
+ }
+ IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+
+ // loop through list and look for matching items
+ Iterator itr = structuredSelection.iterator();
+ while (itr.hasNext()) {
+ Object obj = itr.next();
+ if (obj instanceof IResource) {
+ IResource res = (IResource) obj;
+ if ((res.getType() & resourceTypes) == res.getType()) {
+ resources.add(res);
+ }
+ }
+ }
+ result = new IResource[resources.size()];
+ resources.toArray(result);
+ return result;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorDropAdapter.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorDropAdapter.java
new file mode 100644
index 0000000..3c38ee0
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorDropAdapter.java
@@ -0,0 +1,422 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demio.views.nav;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.CopyFilesAndFoldersOperation;
+import org.eclipse.ui.actions.MoveFilesAndFoldersOperation;
+import org.eclipse.ui.actions.ReadOnlyStateChecker;
+import org.eclipse.ui.dialogs.IOverwriteQuery;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.part.PluginDropAdapter;
+import org.eclipse.ui.part.ResourceTransfer;
+
+/**
+ * Implements drop behaviour for drag and drop operations
+ * that land on the resource navigator.
+ *
+ * @since 2.0
+ */
+public class NavigatorDropAdapter extends PluginDropAdapter implements
+ IOverwriteQuery {
+
+ /**
+ * A flag indicating that overwrites should always occur.
+ */
+ private boolean alwaysOverwrite = false;
+
+ /**
+ * The last valid operation.
+ */
+ private int lastValidOperation = DND.DROP_NONE;
+
+ /**
+ * Constructs a new drop adapter.
+ *
+ * @param viewer the navigator's viewer
+ */
+ public NavigatorDropAdapter(StructuredViewer viewer) {
+ super(viewer);
+ }
+
+ /*
+ * @see org.eclipse.swt.dnd.DropTargetListener#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
+ */
+ public void dragEnter(DropTargetEvent event) {
+ if (FileTransfer.getInstance().isSupportedType(event.currentDataType)
+ && event.detail == DND.DROP_DEFAULT) {
+ // default to copy when dragging from outside Eclipse. Fixes bug 16308.
+ event.detail = DND.DROP_COPY;
+ }
+ super.dragEnter(event);
+ }
+
+ /**
+ * Returns an error status with the given info.
+ */
+ private IStatus error(String message) {
+ return error(message, null);
+ }
+
+ /**
+ * Returns an error status with the given info.
+ */
+ private IStatus error(String message, Throwable exception) {
+ return new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, message,
+ exception);
+ }
+
+ /**
+ * Returns the actual target of the drop, given the resource
+ * under the mouse. If the mouse target is a file, then the drop actually
+ * occurs in its parent. If the drop location is before or after the
+ * mouse target and feedback is enabled, the target is also the parent.
+ */
+ private IContainer getActualTarget(IResource mouseTarget) {
+ /* if cursor is before or after mouseTarget, set target to parent */
+ if (getFeedbackEnabled()) {
+ if (getCurrentLocation() == LOCATION_BEFORE
+ || getCurrentLocation() == LOCATION_AFTER) {
+ return mouseTarget.getParent();
+ }
+ }
+ /* if cursor is on a file, return the parent */
+ if (mouseTarget.getType() == IResource.FILE) {
+ return mouseTarget.getParent();
+ }
+ /* otherwise the mouseTarget is the real target */
+ return (IContainer) mouseTarget;
+ }
+
+ /**
+ * Returns the display
+ */
+ private Display getDisplay() {
+ return getViewer().getControl().getDisplay();
+ }
+
+ /**
+ * Returns the resource selection from the LocalSelectionTransfer.
+ *
+ * @return the resource selection from the LocalSelectionTransfer
+ */
+ private IResource[] getSelectedResources() {
+ ArrayList selectedResources = new ArrayList();
+
+ ISelection selection = LocalSelectionTransfer.getInstance()
+ .getSelection();
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection ssel = (IStructuredSelection) selection;
+ for (Iterator i = ssel.iterator(); i.hasNext();) {
+ Object o = i.next();
+ if (o instanceof IResource) {
+ selectedResources.add(o);
+ }
+ else if (o instanceof IAdaptable) {
+ IAdaptable a = (IAdaptable) o;
+ IResource r = (IResource) a.getAdapter(IResource.class);
+ if (r != null) {
+ selectedResources.add(r);
+ }
+ }
+ }
+ }
+ return (IResource[]) selectedResources.toArray(new IResource[selectedResources.size()]);
+ }
+
+ /**
+ * Returns the shell
+ */
+ private Shell getShell() {
+ return getViewer().getControl().getShell();
+ }
+
+ /**
+ * Returns an error status with the given info.
+ */
+ private IStatus info(String message) {
+ return new Status(IStatus.INFO, PlatformUI.PLUGIN_ID, 0, message, null);
+ }
+
+ /**
+ * Adds the given status to the list of problems. Discards
+ * OK statuses. If the status is a multi-status, only its children
+ * are added.
+ */
+ private void mergeStatus(MultiStatus status, IStatus toMerge) {
+ if (!toMerge.isOK()) {
+ status.merge(toMerge);
+ }
+ }
+
+ /**
+ * Returns an status indicating success.
+ */
+ private IStatus ok() {
+ return new Status(IStatus.OK, PlatformUI.PLUGIN_ID, 0,
+ ResourceNavigatorMessages.DropAdapter_ok, null);
+ }
+
+ /**
+ * Opens an error dialog if necessary. Takes care of
+ * complex rules necessary for making the error dialog look nice.
+ */
+ private void openError(IStatus status) {
+ if (status == null) {
+ return;
+ }
+
+ String genericTitle = ResourceNavigatorMessages.DropAdapter_title;
+ int codes = IStatus.ERROR | IStatus.WARNING;
+
+ //simple case: one error, not a multistatus
+ if (!status.isMultiStatus()) {
+ ErrorDialog
+ .openError(getShell(), genericTitle, null, status, codes);
+ return;
+ }
+
+ //one error, single child of multistatus
+ IStatus[] children = status.getChildren();
+ if (children.length == 1) {
+ ErrorDialog.openError(getShell(), status.getMessage(), null,
+ children[0], codes);
+ return;
+ }
+ //several problems
+ ErrorDialog.openError(getShell(), genericTitle, null, status, codes);
+ }
+
+ /**
+ * Perform the drop.
+ * @see org.eclipse.swt.dnd.DropTargetListener#drop(org.eclipse.swt.dnd.DropTargetEvent)
+ */
+ public boolean performDrop(final Object data) {
+ alwaysOverwrite = false;
+ if (getCurrentTarget() == null || data == null) {
+ return false;
+ }
+ boolean result = false;
+ IStatus status = null;
+ IResource[] resources = null;
+ TransferData currentTransfer = getCurrentTransfer();
+ if (LocalSelectionTransfer.getInstance().isSupportedType(
+ currentTransfer)) {
+ resources = getSelectedResources();
+ } else if (ResourceTransfer.getInstance().isSupportedType(
+ currentTransfer)) {
+ resources = (IResource[]) data;
+ } else if (FileTransfer.getInstance().isSupportedType(currentTransfer)) {
+ status = performFileDrop(data);
+ result = status.isOK();
+ } else {
+ result = NavigatorDropAdapter.super.performDrop(data);
+ }
+ if (resources != null && resources.length > 0) {
+ if (getCurrentOperation() == DND.DROP_COPY) {
+ status = performResourceCopy(getShell(), resources);
+ } else {
+ status = performResourceMove(resources);
+ }
+ }
+ openError(status);
+ return result;
+ }
+
+ /**
+ * Performs a drop using the FileTransfer transfer type.
+ */
+ private IStatus performFileDrop(Object data) {
+ MultiStatus problems = new MultiStatus(PlatformUI.PLUGIN_ID, 0,
+ ResourceNavigatorMessages.DropAdapter_problemImporting, null);
+ mergeStatus(problems, validateTarget(getCurrentTarget(),
+ getCurrentTransfer()));
+
+ final IContainer target = getActualTarget((IResource) getCurrentTarget());
+ final String[] names = (String[]) data;
+ // Run the import operation asynchronously.
+ // Otherwise the drag source (e.g., Windows Explorer) will be blocked
+ // while the operation executes. Fixes bug 16478.
+ Display.getCurrent().asyncExec(new Runnable() {
+ public void run() {
+ getShell().forceActive();
+ CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(
+ getShell());
+ operation.copyFiles(names, target);
+ }
+ });
+ return problems;
+ }
+
+ /**
+ * Performs a resource copy
+ */
+ private IStatus performResourceCopy(Shell shell, IResource[] sources) {
+ MultiStatus problems = new MultiStatus(PlatformUI.PLUGIN_ID, 1,
+ ResourceNavigatorMessages.DropAdapter_problemsMoving, null);
+ mergeStatus(problems, validateTarget(getCurrentTarget(),
+ getCurrentTransfer()));
+
+ IContainer target = getActualTarget((IResource) getCurrentTarget());
+ CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(
+ shell);
+ operation.copyResources(sources, target);
+
+ return problems;
+ }
+
+ /**
+ * Performs a resource move
+ */
+ private IStatus performResourceMove(IResource[] sources) {
+ MultiStatus problems = new MultiStatus(PlatformUI.PLUGIN_ID, 1,
+ ResourceNavigatorMessages.DropAdapter_problemsMoving, null);
+ mergeStatus(problems, validateTarget(getCurrentTarget(),
+ getCurrentTransfer()));
+
+ IContainer target = getActualTarget((IResource) getCurrentTarget());
+ ReadOnlyStateChecker checker = new ReadOnlyStateChecker(
+ getShell(),
+ ResourceNavigatorMessages.MoveResourceAction_title,
+ ResourceNavigatorMessages.MoveResourceAction_checkMoveMessage);
+ sources = checker.checkReadOnlyResources(sources);
+ MoveFilesAndFoldersOperation operation = new MoveFilesAndFoldersOperation(
+ getShell());
+ operation.copyResources(sources, target);
+
+ return problems;
+ }
+
+ /*
+ * @see org.eclipse.ui.dialogs.IOverwriteQuery#queryOverwrite(java.lang.String)
+ */
+ public String queryOverwrite(String pathString) {
+ if (alwaysOverwrite) {
+ return ALL;
+ }
+
+ final String returnCode[] = { CANCEL };
+ final String msg = NLS.bind(ResourceNavigatorMessages.DropAdapter_overwriteQuery, pathString);
+ final String[] options = { IDialogConstants.YES_LABEL,
+ IDialogConstants.YES_TO_ALL_LABEL, IDialogConstants.NO_LABEL,
+ IDialogConstants.CANCEL_LABEL };
+ getDisplay().syncExec(new Runnable() {
+ public void run() {
+ MessageDialog dialog = new MessageDialog(
+ getShell(),
+ ResourceNavigatorMessages.DropAdapter_question, null, msg, MessageDialog.QUESTION, options, 0);
+ dialog.open();
+ int returnVal = dialog.getReturnCode();
+ String[] returnCodes = { YES, ALL, NO, CANCEL };
+ returnCode[0] = returnVal < 0 ? CANCEL : returnCodes[returnVal];
+ }
+ });
+ if (returnCode[0] == ALL) {
+ alwaysOverwrite = true;
+ }
+ return returnCode[0];
+ }
+
+ /**
+ * This method is used to notify the action that some aspect of
+ * the drop operation has changed.
+ */
+ public boolean validateDrop(Object target, int dragOperation,
+ TransferData transferType) {
+
+ if (dragOperation != DND.DROP_NONE) {
+ lastValidOperation = dragOperation;
+ }
+ if (FileTransfer.getInstance().isSupportedType(transferType)
+ && lastValidOperation != DND.DROP_COPY) {
+ // only allow copying when dragging from outside Eclipse
+ return false;
+ }
+ if (super.validateDrop(target, dragOperation, transferType)) {
+ return true;
+ }
+ return validateTarget(target, transferType).isOK();
+ }
+
+ /**
+ * Ensures that the drop target meets certain criteria
+ */
+ private IStatus validateTarget(Object target, TransferData transferType) {
+ if (!(target instanceof IResource)) {
+ return info(ResourceNavigatorMessages.DropAdapter_targetMustBeResource);
+ }
+ IResource resource = (IResource) target;
+ if (!resource.isAccessible()) {
+ return error(ResourceNavigatorMessages.DropAdapter_canNotDropIntoClosedProject);
+ }
+ IContainer destination = getActualTarget(resource);
+ if (destination.getType() == IResource.ROOT) {
+ return error(ResourceNavigatorMessages.DropAdapter_resourcesCanNotBeSiblings);
+ }
+ String message = null;
+ // drag within Eclipse?
+ if (LocalSelectionTransfer.getInstance().isSupportedType(transferType)) {
+ IResource[] selectedResources = getSelectedResources();
+
+ if (selectedResources.length == 0) {
+ message = ResourceNavigatorMessages.DropAdapter_dropOperationErrorOther;
+ } else {
+ CopyFilesAndFoldersOperation operation;
+ if (lastValidOperation == DND.DROP_COPY) {
+ operation = new CopyFilesAndFoldersOperation(getShell());
+ } else {
+ operation = new MoveFilesAndFoldersOperation(getShell());
+ }
+ message = operation.validateDestination(destination,
+ selectedResources);
+ }
+ } // file import?
+ else if (FileTransfer.getInstance().isSupportedType(transferType)) {
+ String[] sourceNames = (String[]) FileTransfer.getInstance()
+ .nativeToJava(transferType);
+ if (sourceNames == null) {
+ // source names will be null on Linux. Use empty names to do destination validation.
+ // Fixes bug 29778
+ sourceNames = new String[0];
+ }
+ CopyFilesAndFoldersOperation copyOperation = new CopyFilesAndFoldersOperation(
+ getShell());
+ message = copyOperation.validateImportDestination(destination,
+ sourceNames);
+ }
+ if (message != null) {
+ return error(message);
+ }
+ return ok();
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorFrameSource.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorFrameSource.java
new file mode 100644
index 0000000..6ba7965
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/NavigatorFrameSource.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.views.framelist.TreeFrame;
+import org.eclipse.ui.views.framelist.TreeViewerFrameSource;
+
+/**
+ * Frame source for the resource navigator.
+ */
+public class NavigatorFrameSource extends TreeViewerFrameSource {
+
+ private ResourceNavigator navigator;
+
+ /**
+ * Constructs a new frame source for the specified resource navigator.
+ *
+ * @param navigator the resource navigator
+ */
+ public NavigatorFrameSource(ResourceNavigator navigator) {
+ super(navigator.getTreeViewer());
+ this.navigator = navigator;
+ }
+
+ /**
+ * Returns a new frame. This implementation extends the super implementation
+ * by setting the frame's tool tip text to show the full path for the input
+ * element.
+ */
+ protected TreeFrame createFrame(Object input) {
+ TreeFrame frame = super.createFrame(input);
+ frame.setName(navigator.getFrameName(input));
+ frame.setToolTipText(navigator.getFrameToolTipText(input));
+ return frame;
+ }
+
+ /**
+ * Also updates the navigator's title.
+ */
+ protected void frameChanged(TreeFrame frame) {
+ IResource resource = (IResource) frame.getInput();
+ IProject project = resource.getProject();
+
+ if (project != null && project.isOpen() == false) {
+ MessageDialog
+ .openInformation(
+ navigator.getViewSite().getShell(),
+ ResourceNavigatorMessages.NavigatorFrameSource_closedProject_title,
+ NLS.bind(ResourceNavigatorMessages.NavigatorFrameSource_closedProject_message, project.getName()));
+ navigator.getFrameList().back();
+ } else {
+ super.frameChanged(frame);
+ navigator.updateTitle();
+ }
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/OpenActionGroup.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/OpenActionGroup.java
new file mode 100644
index 0000000..78a9a29
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/OpenActionGroup.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.IStructuredSelection;
+
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.OpenFileAction;
+import org.eclipse.ui.actions.OpenInNewWindowAction;
+import org.eclipse.ui.actions.OpenWithMenu;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+
+/**
+ * This is the action group for the open actions.
+ */
+public class OpenActionGroup extends ResourceNavigatorActionGroup {
+
+ private OpenFileAction openFileAction;
+
+ /**
+ * The id for the Open With submenu.
+ */
+ public static final String OPEN_WITH_ID = PlatformUI.PLUGIN_ID
+ + ".OpenWithSubMenu"; //$NON-NLS-1$
+
+ /**
+ * Creates a new action group for open actions.
+ *
+ * @param navigator the resource navigator
+ */
+ public OpenActionGroup(IResourceNavigator navigator) {
+ super(navigator);
+ }
+
+ protected void makeActions() {
+ openFileAction = new OpenFileAction(navigator.getSite().getPage());
+ }
+
+ public void fillContextMenu(IMenuManager menu) {
+ IStructuredSelection selection = (IStructuredSelection) getContext()
+ .getSelection();
+
+ boolean anyResourceSelected = !selection.isEmpty()
+ && ResourceSelectionUtil.allResourcesAreOfType(selection,
+ IResource.PROJECT | IResource.FOLDER | IResource.FILE);
+ boolean onlyFilesSelected = !selection.isEmpty()
+ && ResourceSelectionUtil.allResourcesAreOfType(selection,
+ IResource.FILE);
+
+ if (onlyFilesSelected) {
+ openFileAction.selectionChanged(selection);
+ menu.add(openFileAction);
+ fillOpenWithMenu(menu, selection);
+ }
+
+ if (anyResourceSelected) {
+ addNewWindowAction(menu, selection);
+ }
+ }
+
+ /**
+ * Adds the OpenWith submenu to the context menu.
+ *
+ * @param menu the context menu
+ * @param selection the current selection
+ */
+ private void fillOpenWithMenu(IMenuManager menu,
+ IStructuredSelection selection) {
+
+ // Only supported if exactly one file is selected.
+ if (selection.size() != 1) {
+ return;
+ }
+ Object element = selection.getFirstElement();
+ if (!(element instanceof IFile)) {
+ return;
+ }
+
+ MenuManager submenu = new MenuManager(ResourceNavigatorMessages.ResourceNavigator_openWith, OPEN_WITH_ID);
+ submenu.add(new OpenWithMenu(navigator.getSite().getPage(),
+ (IFile) element));
+ menu.add(submenu);
+ }
+
+ /**
+ * Adds the Open in New Window action to the context menu.
+ *
+ * @param menu the context menu
+ * @param selection the current selection
+ */
+ private void addNewWindowAction(IMenuManager menu,
+ IStructuredSelection selection) {
+
+ // Only supported if exactly one container (i.e open project or folder) is selected.
+ if (selection.size() != 1) {
+ return;
+ }
+ Object element = selection.getFirstElement();
+ if (!(element instanceof IContainer)) {
+ return;
+ }
+ if (element instanceof IProject && !(((IProject) element).isOpen())) {
+ return;
+ }
+
+ menu.add(new OpenInNewWindowAction(navigator.getSite()
+ .getWorkbenchWindow(), (IContainer) element));
+ }
+
+ /**
+ * Runs the default action (open file).
+ */
+ public void runDefaultAction(IStructuredSelection selection) {
+ Object element = selection.getFirstElement();
+ if (element instanceof IFile) {
+ openFileAction.selectionChanged(selection);
+ openFileAction.run();
+ }
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/PasteAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/PasteAction.java
new file mode 100644
index 0000000..a304877
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/PasteAction.java
@@ -0,0 +1,264 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demio.views.nav;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.CopyFilesAndFoldersOperation;
+import org.eclipse.ui.actions.CopyProjectOperation;
+import org.eclipse.ui.actions.SelectionListenerAction;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.part.ResourceTransfer;
+
+/**
+ * Standard action for pasting resources on the clipboard to the selected resource's location.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ *
+ * @since 2.0
+ */
+/*package*/class PasteAction extends SelectionListenerAction {
+
+ /**
+ * The id of this action.
+ */
+ public static final String ID = PlatformUI.PLUGIN_ID + ".PasteAction";//$NON-NLS-1$
+
+ /**
+ * The shell in which to show any dialogs.
+ */
+ private Shell shell;
+
+ /**
+ * System clipboard
+ */
+ private Clipboard clipboard;
+
+ /**
+ * Creates a new action.
+ *
+ * @param shell the shell for any dialogs
+ * @param clipboard the clipboard
+ */
+ public PasteAction(Shell shell, Clipboard clipboard) {
+ super(ResourceNavigatorMessages.PasteAction_title);
+ Assert.isNotNull(shell);
+ Assert.isNotNull(clipboard);
+ this.shell = shell;
+ this.clipboard = clipboard;
+ setToolTipText(ResourceNavigatorMessages.PasteAction_toolTip);
+ setId(PasteAction.ID);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+ INavigatorHelpContextIds.PASTE_ACTION);
+ }
+
+ /**
+ * Returns the actual target of the paste action. Returns null
+ * if no valid target is selected.
+ *
+ * @return the actual target of the paste action
+ */
+ private IResource getTarget() {
+ List selectedResources = getSelectedResources();
+
+ for (int i = 0; i < selectedResources.size(); i++) {
+ IResource resource = (IResource) selectedResources.get(i);
+
+ if (resource instanceof IProject && !((IProject) resource).isOpen()) {
+ return null;
+ }
+ if (resource.getType() == IResource.FILE) {
+ resource = resource.getParent();
+ }
+ if (resource != null) {
+ return resource;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns whether any of the given resources are linked resources.
+ *
+ * @param resources resource to check for linked type. may be null
+ * @return true=one or more resources are linked. false=none of the
+ * resources are linked
+ */
+ private boolean isLinked(IResource[] resources) {
+ for (int i = 0; i < resources.length; i++) {
+ if (resources[i].isLinked()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Implementation of method defined on <code>IAction</code>.
+ */
+ public void run() {
+ // try a resource transfer
+ ResourceTransfer resTransfer = ResourceTransfer.getInstance();
+ IResource[] resourceData = (IResource[]) clipboard
+ .getContents(resTransfer);
+
+ if (resourceData != null && resourceData.length > 0) {
+ if (resourceData[0].getType() == IResource.PROJECT) {
+ // enablement checks for all projects
+ for (int i = 0; i < resourceData.length; i++) {
+ CopyProjectOperation operation = new CopyProjectOperation(
+ this.shell);
+ operation.copyProject((IProject) resourceData[i]);
+ }
+ } else {
+ // enablement should ensure that we always have access to a container
+ IContainer container = getContainer();
+
+ CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(
+ this.shell);
+ operation.copyResources(resourceData, container);
+ }
+ return;
+ }
+
+ // try a file transfer
+ FileTransfer fileTransfer = FileTransfer.getInstance();
+ String[] fileData = (String[]) clipboard.getContents(fileTransfer);
+
+ if (fileData != null) {
+ // enablement should ensure that we always have access to a container
+ IContainer container = getContainer();
+
+ CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(
+ this.shell);
+ operation.copyFiles(fileData, container);
+ }
+ }
+
+ /**
+ * Returns the container to hold the pasted resources.
+ */
+ private IContainer getContainer() {
+ List selection = getSelectedResources();
+ if (selection.get(0) instanceof IFile) {
+ return ((IFile) selection.get(0)).getParent();
+ } else {
+ return (IContainer) selection.get(0);
+ }
+ }
+
+ /**
+ * The <code>PasteAction</code> implementation of this
+ * <code>SelectionListenerAction</code> method enables this action if
+ * a resource compatible with what is on the clipboard is selected.
+ *
+ * -Clipboard must have IResource or java.io.File
+ * -Projects can always be pasted if they are open
+ * -Workspace folder may not be copied into itself
+ * -Files and folders may be pasted to a single selected folder in open
+ * project or multiple selected files in the same folder
+ */
+ protected boolean updateSelection(IStructuredSelection selection) {
+ if (!super.updateSelection(selection)) {
+ return false;
+ }
+
+ final IResource[][] clipboardData = new IResource[1][];
+ shell.getDisplay().syncExec(new Runnable() {
+ public void run() {
+ // clipboard must have resources or files
+ ResourceTransfer resTransfer = ResourceTransfer.getInstance();
+ clipboardData[0] = (IResource[]) clipboard
+ .getContents(resTransfer);
+ }
+ });
+ IResource[] resourceData = clipboardData[0];
+ boolean isProjectRes = resourceData != null && resourceData.length > 0
+ && resourceData[0].getType() == IResource.PROJECT;
+
+ if (isProjectRes) {
+ for (int i = 0; i < resourceData.length; i++) {
+ // make sure all resource data are open projects
+ // can paste open projects regardless of selection
+ if (resourceData[i].getType() != IResource.PROJECT
+ || ((IProject) resourceData[i]).isOpen() == false) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ if (getSelectedNonResources().size() > 0) {
+ return false;
+ }
+
+ IResource targetResource = getTarget();
+ // targetResource is null if no valid target is selected (e.g., open project)
+ // or selection is empty
+ if (targetResource == null) {
+ return false;
+ }
+
+ // can paste files and folders to a single selection (file, folder,
+ // open project) or multiple file selection with the same parent
+ List selectedResources = getSelectedResources();
+ if (selectedResources.size() > 1) {
+ for (int i = 0; i < selectedResources.size(); i++) {
+ IResource resource = (IResource) selectedResources.get(i);
+ if (resource.getType() != IResource.FILE) {
+ return false;
+ }
+ if (!targetResource.equals(resource.getParent())) {
+ return false;
+ }
+ }
+ }
+ if (resourceData != null) {
+ // linked resources can only be pasted into projects
+ if (isLinked(resourceData)
+ && targetResource.getType() != IResource.PROJECT
+ && targetResource.getType() != IResource.FOLDER) {
+ return false;
+ }
+
+ if (targetResource.getType() == IResource.FOLDER) {
+ // don't try to copy folder to self
+ for (int i = 0; i < resourceData.length; i++) {
+ if (targetResource.equals(resourceData[i])) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ TransferData[] transfers = clipboard.getAvailableTypes();
+ FileTransfer fileTransfer = FileTransfer.getInstance();
+ for (int i = 0; i < transfers.length; i++) {
+ if (fileTransfer.isSupportedType(transfers[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/RefactorActionGroup.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/RefactorActionGroup.java
new file mode 100644
index 0000000..ea59952
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/RefactorActionGroup.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * Sebastian Davids <sdavids@gmx.de> - Images for menu items (27481)
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.window.IShellProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.DeleteResourceAction;
+import org.eclipse.ui.actions.TextActionHandler;
+
+/**
+ * This is the action group for refactor actions,
+ * including global action handlers for copy, paste and delete.
+ *
+ * @since 2.0
+ */
+public class RefactorActionGroup extends ResourceNavigatorActionGroup {
+
+ private Clipboard clipboard;
+
+ private CopyAction copyAction;
+
+ private DeleteResourceAction deleteAction;
+
+ private PasteAction pasteAction;
+
+ private ResourceNavigatorRenameAction renameAction;
+
+ private ResourceNavigatorMoveAction moveAction;
+
+ private TextActionHandler textActionHandler;
+
+ public RefactorActionGroup(IResourceNavigator navigator) {
+ super(navigator);
+ }
+
+ public void dispose() {
+ if (clipboard != null) {
+ clipboard.dispose();
+ clipboard = null;
+ }
+ super.dispose();
+ }
+
+ public void fillContextMenu(IMenuManager menu) {
+ IStructuredSelection selection = (IStructuredSelection) getContext()
+ .getSelection();
+
+ boolean anyResourceSelected = !selection.isEmpty()
+ && ResourceSelectionUtil.allResourcesAreOfType(selection,
+ IResource.PROJECT | IResource.FOLDER | IResource.FILE);
+
+ copyAction.selectionChanged(selection);
+ menu.add(copyAction);
+ pasteAction.selectionChanged(selection);
+ menu.add(pasteAction);
+
+ if (anyResourceSelected) {
+ deleteAction.selectionChanged(selection);
+ menu.add(deleteAction);
+ moveAction.selectionChanged(selection);
+ menu.add(moveAction);
+ renameAction.selectionChanged(selection);
+ menu.add(renameAction);
+ }
+ }
+
+ public void fillActionBars(IActionBars actionBars) {
+ textActionHandler = new TextActionHandler(actionBars); // hooks handlers
+ textActionHandler.setCopyAction(copyAction);
+ textActionHandler.setPasteAction(pasteAction);
+ textActionHandler.setDeleteAction(deleteAction);
+ renameAction.setTextActionHandler(textActionHandler);
+
+ actionBars.setGlobalActionHandler(ActionFactory.MOVE.getId(),
+ moveAction);
+ actionBars.setGlobalActionHandler(ActionFactory.RENAME.getId(),
+ renameAction);
+ }
+
+ /**
+ * Handles a key pressed event by invoking the appropriate action.
+ */
+ public void handleKeyPressed(KeyEvent event) {
+ if (event.character == SWT.DEL && event.stateMask == 0) {
+ if (deleteAction.isEnabled()) {
+ deleteAction.run();
+ }
+
+ // Swallow the event.
+ event.doit = false;
+
+ } else if (event.keyCode == SWT.F2 && event.stateMask == 0) {
+ if (renameAction.isEnabled()) {
+ renameAction.run();
+ }
+
+ // Swallow the event.
+ event.doit = false;
+ }
+ }
+
+ protected void makeActions() {
+ TreeViewer treeViewer = navigator.getViewer();
+ IShellProvider provider = navigator.getSite();
+ clipboard = new Clipboard(provider.getShell().getDisplay());
+
+ pasteAction = new PasteAction(provider.getShell(), clipboard);
+ ISharedImages images = PlatformUI.getWorkbench().getSharedImages();
+ pasteAction.setDisabledImageDescriptor(images
+ .getImageDescriptor(ISharedImages.IMG_TOOL_PASTE_DISABLED));
+ pasteAction.setImageDescriptor(images
+ .getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
+
+ copyAction = new CopyAction(provider.getShell(), clipboard, pasteAction);
+ copyAction.setDisabledImageDescriptor(images
+ .getImageDescriptor(ISharedImages.IMG_TOOL_COPY_DISABLED));
+ copyAction.setImageDescriptor(images
+ .getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
+
+ moveAction = new ResourceNavigatorMoveAction(provider.getShell(), treeViewer);
+ renameAction = new ResourceNavigatorRenameAction(provider.getShell(), treeViewer);
+
+ deleteAction = new DeleteResourceAction(provider);
+ deleteAction.setDisabledImageDescriptor(images
+ .getImageDescriptor(ISharedImages.IMG_TOOL_DELETE_DISABLED));
+ deleteAction.setImageDescriptor(images
+ .getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));
+ }
+
+ public void updateActionBars() {
+ IStructuredSelection selection = (IStructuredSelection) getContext()
+ .getSelection();
+
+ copyAction.selectionChanged(selection);
+ pasteAction.selectionChanged(selection);
+ deleteAction.selectionChanged(selection);
+ moveAction.selectionChanged(selection);
+ renameAction.selectionChanged(selection);
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceComparator.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceComparator.java
new file mode 100644
index 0000000..dd91b00
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceComparator.java
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+
+/**
+ * Comparator for viewers that display items of type <code>IResource</code>.
+ * The sorter supports two sort criteria:
+ * <p>
+ * <code>NAME</code>: Folders are given order precedence, followed by files.
+ * Within these two groups resources are ordered by name. All name comparisons
+ * are case-insensitive.
+ * </p>
+ * <p>
+ * <code>TYPE</code>: Folders are given order precedence, followed by files.
+ * Within these two groups resources are ordered by extension. All extension
+ * comparisons are case-insensitive.
+ * </p>
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ *
+ * @since 3.3
+ */
+public class ResourceComparator extends ViewerComparator {
+
+ /**
+ * Constructor argument value that indicates to sort items by name.
+ */
+ public final static int NAME = 1;
+
+ /**
+ * Constructor argument value that indicates to sort items by extension.
+ */
+ public final static int TYPE = 2;
+
+ private int criteria;
+
+ /**
+ * Creates a resource sorter that will use the given sort criteria.
+ *
+ * @param criteria the sort criterion to use: one of <code>NAME</code> or
+ * <code>TYPE</code>
+ */
+ public ResourceComparator(int criteria) {
+ super();
+ this.criteria = criteria;
+ }
+
+ /**
+ * Returns an integer value representing the relative sort priority of the
+ * given element based on its class.
+ * <p>
+ * <ul>
+ * <li>resources (<code>IResource</code>) - 2</li>
+ * <li>project references (<code>ProjectReference</code>) - 1</li>
+ * <li>everything else - 0</li>
+ * </ul>
+ * </p>
+ *
+ * @param element the element
+ * @return the sort priority (larger numbers means more important)
+ */
+ protected int classComparison(Object element) {
+ if (element instanceof IResource) {
+ return 2;
+ }
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on ViewerComparator.
+ */
+ public int compare(Viewer viewer, Object o1, Object o2) {
+ //have to deal with non-resources in navigator
+ //if one or both objects are not resources, returned a comparison
+ //based on class.
+ if (!(o1 instanceof IResource && o2 instanceof IResource)) {
+ return compareClass(o1, o2);
+ }
+ IResource r1 = (IResource) o1;
+ IResource r2 = (IResource) o2;
+
+ if (r1 instanceof IContainer && r2 instanceof IContainer) {
+ return compareNames(r1, r2);
+ } else if (r1 instanceof IContainer) {
+ return -1;
+ } else if (r2 instanceof IContainer) {
+ return 1;
+ } else if (criteria == NAME) {
+ return compareNames(r1, r2);
+ } else if (criteria == TYPE) {
+ return compareTypes(r1, r2);
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Returns a number reflecting the collation order of the given elements
+ * based on their class.
+ *
+ * @param element1 the first element to be ordered
+ * @param element2 the second element to be ordered
+ * @return a negative number if the first element is less than the
+ * second element; the value <code>0</code> if the first element is
+ * equal to the second element; and a positive number if the first
+ * element is greater than the second element
+ */
+ protected int compareClass(Object element1, Object element2) {
+ return classComparison(element1) - classComparison(element2);
+ }
+
+ /**
+ * Returns a number reflecting the collation order of the given resources
+ * based on their resource names.
+ *
+ * @param resource1 the first resource element to be ordered
+ * @param resource2 the second resource element to be ordered
+ * @return a negative number if the first element is less than the
+ * second element; the value <code>0</code> if the first element is
+ * equal to the second element; and a positive number if the first
+ * element is greater than the second element
+ */
+ protected int compareNames(IResource resource1, IResource resource2) {
+ return getComparator().compare(resource1.getName(), resource2.getName());
+ }
+
+ /**
+ * Returns a number reflecting the collation order of the given resources
+ * based on their respective file extensions. Resources with the same file
+ * extension will be collated based on their names.
+ *
+ * @param resource1 the first resource element to be ordered
+ * @param resource2 the second resource element to be ordered
+ * @return a negative number if the first element is less than the
+ * second element; the value <code>0</code> if the first element is
+ * equal to the second element; and a positive number if the first
+ * element is greater than the second element
+ */
+ protected int compareTypes(IResource resource1, IResource resource2) {
+ String ext1 = getExtensionFor(resource1);
+ String ext2 = getExtensionFor(resource2);
+
+ // Compare extensions. If they're different then return a value that
+ // indicates correct extension ordering. If they're the same then
+ // return a value that indicates the correct NAME ordering.
+ int result = getComparator().compare(ext1, ext2);
+
+ if (result != 0) {
+ return result;
+ }
+
+ return compareNames(resource1, resource2);
+ }
+
+ /**
+ * Returns the sort criteria of this sorter.
+ *
+ * @return the sort criterion: one of <code>NAME</code> or <code>TYPE</code>
+ */
+ public int getCriteria() {
+ return criteria;
+ }
+
+ /**
+ * Returns the extension portion of the given resource.
+ *
+ * @param resource the resource
+ * @return the file extension, possibily the empty string
+ */
+ private String getExtensionFor(IResource resource) {
+ String ext = resource.getFileExtension();
+ return ext == null ? "" : ext; //$NON-NLS-1$
+ }
+
+ /**
+ * Sets the sort criteria of this sorter.
+ *
+ * @param criteria the sort criterion:
+ * one of <code>ResourceSorter.NAME</code> or
+ * <code>ResourceSorter.TYPE</code>
+ */
+ public void setCriteria(int criteria) {
+ this.criteria = criteria;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigator.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigator.java
new file mode 100644
index 0000000..5c043c4
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigator.java
@@ -0,0 +1,1580 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * Benjamin Muskalla - bug 105041
+ * Remy Chi Jian Suen - bug 144102
+ *******************************************************************************/
+
+package org.eclipse.e4.demio.views.nav;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.osgi.util.NLS;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.commands.ActionHandler;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.util.Util;
+import org.eclipse.jface.viewers.DecoratingLabelProvider;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.OpenEvent;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.jface.viewers.ViewerSorter;
+
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPreferenceConstants;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.OpenAndLinkWithEditorHelper;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ResourceWorkingSetFilter;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.OpenFileAction;
+import org.eclipse.ui.actions.OpenResourceAction;
+import org.eclipse.ui.handlers.CollapseAllHandler;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.ide.ResourceUtil;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.model.WorkbenchContentProvider;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.part.ISetSelectionTarget;
+import org.eclipse.ui.part.IShowInSource;
+import org.eclipse.ui.part.IShowInTarget;
+import org.eclipse.ui.part.PluginTransfer;
+import org.eclipse.ui.part.ResourceTransfer;
+import org.eclipse.ui.part.ShowInContext;
+import org.eclipse.ui.part.ViewPart;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.ui.views.framelist.FrameList;
+import org.eclipse.ui.views.framelist.TreeFrame;
+
+/**
+ * Implements the Resource Navigator view.
+ */
+public class ResourceNavigator extends ViewPart implements ISetSelectionTarget,
+ IResourceNavigator {
+
+ private TreeViewer viewer;
+
+ private IDialogSettings settings;
+
+ private IMemento memento;
+
+ private FrameList frameList;
+
+ private ResourceNavigatorActionGroup actionGroup;
+
+ private ResourcePatternFilter patternFilter = new ResourcePatternFilter();
+
+ private ResourceWorkingSetFilter workingSetFilter = new ResourceWorkingSetFilter();
+
+ private boolean linkingEnabled;
+
+ private boolean dragDetected;
+
+ private Listener dragDetectListener;
+ /**
+ * Remembered working set.
+ */
+ private IWorkingSet workingSet;
+
+ /**
+ * Marks whether the working set we're using is currently empty. In this
+ * event we're effectively not using a working set.
+ */
+ private boolean emptyWorkingSet = false;
+
+ /**
+ * Settings constant for section name (value <code>ResourceNavigator</code>).
+ */
+ private static final String STORE_SECTION = "ResourceNavigator"; //$NON-NLS-1$
+
+ /**
+ * Settings constant for sort order (value <code>ResourceViewer.STORE_SORT_TYPE</code>).
+ */
+ private static final String STORE_SORT_TYPE = "ResourceViewer.STORE_SORT_TYPE"; //$NON-NLS-1$
+
+ /**
+ * Settings constant for working set (value <code>ResourceWorkingSetFilter.STORE_WORKING_SET</code>).
+ */
+ private static final String STORE_WORKING_SET = "ResourceWorkingSetFilter.STORE_WORKING_SET"; //$NON-NLS-1$
+
+ /**
+ * @deprecated No longer used but preserved to avoid an api change.
+ */
+ public static final String NAVIGATOR_VIEW_HELP_ID = INavigatorHelpContextIds.RESOURCE_VIEW;
+
+ /**
+ * True iff we've already scheduled an asynchronous call to linkToEditor
+ */
+ private boolean linkScheduled = false;
+
+ // Persistance tags.
+ private static final String TAG_SORTER = "sorter"; //$NON-NLS-1$
+
+ private static final String TAG_FILTERS = "filters"; //$NON-NLS-1$
+
+ private static final String TAG_FILTER = "filter"; //$NON-NLS-1$
+
+ private static final String TAG_SELECTION = "selection"; //$NON-NLS-1$
+
+ private static final String TAG_EXPANDED = "expanded"; //$NON-NLS-1$
+
+ private static final String TAG_ELEMENT = "element"; //$NON-NLS-1$
+
+ private static final String TAG_IS_ENABLED = "isEnabled"; //$NON-NLS-1$
+
+ private static final String TAG_PATH = "path"; //$NON-NLS-1$
+
+ private static final String TAG_CURRENT_FRAME = "currentFrame"; //$NON-NLS-1$
+
+ private IPartListener partListener = new IPartListener() {
+ public void partActivated(IWorkbenchPart part) {
+ if (part instanceof IEditorPart) {
+ editorActivated((IEditorPart) part);
+ }
+ }
+
+ public void partBroughtToTop(IWorkbenchPart part) {
+ if (part instanceof IEditorPart) {
+ editorActivated((IEditorPart) part);
+ }
+ }
+
+ public void partClosed(IWorkbenchPart part) {
+ }
+
+ public void partDeactivated(IWorkbenchPart part) {
+ }
+
+ public void partOpened(IWorkbenchPart part) {
+ }
+ };
+
+ private IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ String property = event.getProperty();
+ Object newValue = event.getNewValue();
+ Object oldValue = event.getOldValue();
+
+ if (IWorkingSetManager.CHANGE_WORKING_SET_REMOVE.equals(property)
+ && oldValue == workingSet) {
+ setWorkingSet(null);
+ } else if (IWorkingSetManager.CHANGE_WORKING_SET_NAME_CHANGE
+ .equals(property)
+ && newValue == workingSet) {
+ updateTitle();
+ } else if (IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE
+ .equals(property)
+ && newValue == workingSet) {
+ if (workingSet.isAggregateWorkingSet() && workingSet.isEmpty()) {
+ // act as if the working set has been made null
+ if (!emptyWorkingSet) {
+ emptyWorkingSet = true;
+ workingSetFilter.setWorkingSet(null);
+ }
+ } else {
+ // we've gone from empty to non-empty on our set.
+ // Restore it.
+ if (emptyWorkingSet) {
+ emptyWorkingSet = false;
+ workingSetFilter.setWorkingSet(workingSet);
+ }
+ }
+ getViewer().refresh();
+ }
+ }
+ };
+
+ private CollapseAllHandler collapseAllHandler;
+
+ /**
+ * Helper to open and activate editors.
+ *
+ * @since 3.5
+ */
+ private OpenAndLinkWithEditorHelper openAndLinkWithEditorHelper;
+
+
+ /**
+ * Constructs a new resource navigator view.
+ */
+ public ResourceNavigator() {
+ IDialogSettings viewsSettings = getPlugin().getDialogSettings();
+
+ settings = viewsSettings.getSection(STORE_SECTION);
+ if (settings == null) {
+ settings = viewsSettings.addNewSection(STORE_SECTION);
+ }
+
+ initLinkingEnabled();
+ }
+
+ /**
+ * Converts the given selection into a form usable by the viewer,
+ * where the elements are resources.
+ */
+ private StructuredSelection convertSelection(ISelection selection) {
+ ArrayList list = new ArrayList();
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection ssel = (IStructuredSelection) selection;
+ for (Iterator i = ssel.iterator(); i.hasNext();) {
+ Object o = i.next();
+ IResource resource = null;
+ if (o instanceof IResource) {
+ resource = (IResource) o;
+ } else {
+ if (o instanceof IAdaptable) {
+ resource = (IResource) ((IAdaptable) o)
+ .getAdapter(IResource.class);
+ }
+ }
+ if (resource != null) {
+ list.add(resource);
+ }
+ }
+ }
+ return new StructuredSelection(list);
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IWorkbenchPart.
+ */
+ public void createPartControl(Composite parent) {
+ TreeViewer viewer = createViewer(parent);
+ this.viewer = viewer;
+
+ if (memento != null) {
+ restoreFilters();
+ restoreLinkingEnabled();
+ }
+ frameList = createFrameList();
+ initDragAndDrop();
+ updateTitle();
+
+// initContextMenu();
+
+ initResourceComparator();
+ initWorkingSetFilter();
+
+ // make sure input is set after sorters and filters,
+ // to avoid unnecessary refreshes
+ viewer.setInput(getInitialInput());
+
+// // make actions after setting input, because some actions
+// // look at the viewer for enablement (e.g. the Up action)
+// makeActions();
+//
+// // Fill the action bars and update the global action handlers'
+// // enabled state to match the current selection.
+// getActionGroup().fillActionBars(getViewSite().getActionBars());
+// updateActionBars((IStructuredSelection) viewer.getSelection());
+//
+// getSite().setSelectionProvider(viewer);
+// getSite().getPage().addPartListener(partListener);
+// IWorkingSetManager workingSetManager = getPlugin().getWorkbench()
+// .getWorkingSetManager();
+// workingSetManager.addPropertyChangeListener(propertyChangeListener);
+//
+// if (memento != null) {
+// restoreState(memento);
+// }
+// memento = null;
+//
+// // Set help for the view
+// getSite().getWorkbenchWindow().getWorkbench().getHelpSystem().setHelp(
+// viewer.getControl(), getHelpContextId());
+ }
+
+ /**
+ * Returns the help context id to use for this view.
+ *
+ * @since 2.0
+ */
+ protected String getHelpContextId() {
+ return INavigatorHelpContextIds.RESOURCE_VIEW;
+ }
+
+ /**
+ * Initializes and registers the context menu.
+ *
+ * @since 2.0
+ */
+ protected void initContextMenu() {
+ MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ public void menuAboutToShow(IMenuManager manager) {
+ ResourceNavigator.this.fillContextMenu(manager);
+ }
+ });
+ TreeViewer viewer = getTreeViewer();
+ Menu menu = menuMgr.createContextMenu(viewer.getTree());
+ viewer.getTree().setMenu(menu);
+ getSite().registerContextMenu(menuMgr, viewer);
+ }
+
+ /**
+ * Creates the viewer.
+ *
+ * @param parent the parent composite
+ * @since 2.0
+ */
+ protected TreeViewer createViewer(Composite parent) {
+ TreeViewer viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL
+ | SWT.V_SCROLL);
+ viewer.setUseHashlookup(true);
+ initContentProvider(viewer);
+ initLabelProvider(viewer);
+ initFilters(viewer);
+ initListeners(viewer);
+
+ return viewer;
+ }
+
+ /**
+ * Sets the content provider for the viewer.
+ *
+ * @param viewer the viewer
+ * @since 2.0
+ */
+ protected void initContentProvider(TreeViewer viewer) {
+ viewer.setContentProvider(new WorkbenchContentProvider());
+ }
+
+ /**
+ * Sets the label provider for the viewer.
+ *
+ * @param viewer the viewer
+ * @since 2.0
+ */
+ protected void initLabelProvider(TreeViewer viewer) {
+ viewer.setLabelProvider(new DecoratingLabelProvider(
+ new WorkbenchLabelProvider(), getPlugin().getWorkbench()
+ .getDecoratorManager().getLabelDecorator()));
+ }
+
+ /**
+ * Adds the filters to the viewer.
+ *
+ * @param viewer the viewer
+ * @since 2.0
+ */
+ protected void initFilters(TreeViewer viewer) {
+ viewer.addFilter(patternFilter);
+ viewer.addFilter(workingSetFilter);
+ }
+
+ /**
+ * Initializes the linking enabled setting from the preference store.
+ */
+ private void initLinkingEnabled() {
+ // Try the dialog settings first, which remember the last choice.
+ String setting = settings
+ .get(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR);
+ if (setting != null) {
+ linkingEnabled = setting.equals("true"); //$NON-NLS-1$
+ return;
+ }
+ // If not in the dialog settings, check the preference store for the default setting.
+ // Use the UI plugin's preference store since this is a public preference.
+ linkingEnabled = PlatformUI.getPreferenceStore().getBoolean(
+ IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR);
+ }
+
+ /**
+ * Adds the listeners to the viewer.
+ *
+ * @param viewer the viewer
+ * @since 2.0
+ */
+ protected void initListeners(final TreeViewer viewer) {
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ handleSelectionChanged(event);
+ }
+ });
+ viewer.addDoubleClickListener(new IDoubleClickListener() {
+ public void doubleClick(DoubleClickEvent event) {
+ handleDoubleClick(event);
+ }
+ });
+
+ openAndLinkWithEditorHelper = new OpenAndLinkWithEditorHelper(viewer) {
+ protected void activate(ISelection selection) {
+ Object selectedElement = getSingleElement(selection);
+ if (selectedElement instanceof IFile) {
+ IEditorInput input = new FileEditorInput((IFile)selectedElement);
+ final IWorkbenchPage page = getSite().getPage();
+ IEditorPart editor = page.findEditor(input);
+ if (editor != null) {
+ page.activate(editor);
+ }
+ }
+
+ }
+
+ protected void linkToEditor(ISelection selection) {
+ if (!linkScheduled) {
+ // Ensure that if another selection change arrives while we're waiting for the *syncExec,
+ // we only do this work once.
+ linkScheduled = true;
+ getSite().getShell().getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ // There's no telling what might have changed since the syncExec was scheduled.
+ // Check to make sure that the widgets haven't been disposed.
+ linkScheduled = false;
+
+ if (viewer == null || viewer.getControl() == null || viewer.getControl().isDisposed()) {
+ return;
+ }
+
+ if (dragDetected == false) {
+ // only synchronize with editor when the selection is not the result
+ // of a drag. Fixes bug 22274.
+ ResourceNavigator.this.linkToEditor(viewer.getSelection());
+ }
+ }
+ });
+ }
+ }
+
+ protected void open(ISelection selection, boolean activate) {
+ handleOpen(selection);
+ }
+
+ };
+
+
+ viewer.getControl().addKeyListener(new KeyListener() {
+ public void keyPressed(KeyEvent event) {
+ handleKeyPressed(event);
+ }
+
+ public void keyReleased(KeyEvent event) {
+ handleKeyReleased(event);
+ }
+ });
+
+ openAndLinkWithEditorHelper.setLinkWithEditor(linkingEnabled);
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IWorkbenchPart.
+ */
+ public void dispose() {
+ getSite().getPage().removePartListener(partListener);
+
+ IWorkingSetManager workingSetManager = getPlugin().getWorkbench()
+ .getWorkingSetManager();
+ workingSetManager.removePropertyChangeListener(propertyChangeListener);
+
+ if (collapseAllHandler != null) {
+ collapseAllHandler.dispose();
+ }
+
+ if (getActionGroup() != null) {
+ getActionGroup().dispose();
+ }
+ Control control = viewer.getControl();
+ if (dragDetectListener != null && control != null
+ && control.isDisposed() == false) {
+ control.removeListener(SWT.DragDetect, dragDetectListener);
+ }
+
+ super.dispose();
+ }
+
+ /**
+ * An editor has been activated. Sets the selection in this navigator
+ * to be the editor's input, if linking is enabled.
+ *
+ * @param editor the active editor
+ * @since 2.0
+ */
+ protected void editorActivated(IEditorPart editor) {
+ if (!isLinkingEnabled()) {
+ return;
+ }
+
+ IFile file = ResourceUtil.getFile(editor.getEditorInput());
+ if (file != null) {
+ ISelection newSelection = new StructuredSelection(file);
+ if (getTreeViewer().getSelection().equals(newSelection)) {
+ getTreeViewer().getTree().showSelection();
+ } else {
+ getTreeViewer().setSelection(newSelection, true);
+ }
+ }
+ }
+
+ /**
+ * Called when the context menu is about to open.
+ * Delegates to the action group using the viewer's selection as the action context.
+ * @since 2.0
+ */
+ protected void fillContextMenu(IMenuManager menu) {
+ IStructuredSelection selection = (IStructuredSelection) getViewer()
+ .getSelection();
+ getActionGroup().setContext(new ActionContext(selection));
+ getActionGroup().fillContextMenu(menu);
+ }
+
+ /*
+ * @see IResourceNavigatorPart
+ * @since 2.0
+ */
+ public FrameList getFrameList() {
+ return frameList;
+ }
+
+ /**
+ * Returns the initial input for the viewer.
+ * Tries to convert the page input to a resource, either directly or via IAdaptable.
+ * If the resource is a container, it uses that.
+ * If the resource is a file, it uses its parent folder.
+ * If a resource could not be obtained, it uses the workspace root.
+ *
+ * @since 2.0
+ */
+ protected IAdaptable getInitialInput() {
+ IAdaptable input = getSite().getPage().getInput();
+ if (input != null) {
+ IResource resource = null;
+ if (input instanceof IResource) {
+ resource = (IResource) input;
+ } else {
+ resource = (IResource) input.getAdapter(IResource.class);
+ }
+ if (resource != null) {
+ switch (resource.getType()) {
+ case IResource.FILE:
+ return resource.getParent();
+ case IResource.FOLDER:
+ case IResource.PROJECT:
+ case IResource.ROOT:
+ return resource;
+ default:
+ // Unknown resource type. Fall through.
+ break;
+ }
+ }
+ }
+ return ResourcesPlugin.getWorkspace().getRoot();
+ }
+
+ /**
+ * Returns the pattern filter for this view.
+ *
+ * @return the pattern filter
+ * @since 2.0
+ */
+ public ResourcePatternFilter getPatternFilter() {
+ return this.patternFilter;
+ }
+
+ /**
+ * Returns the working set for this view.
+ *
+ * @return the working set
+ * @since 2.0
+ */
+ public IWorkingSet getWorkingSet() {
+ return workingSetFilter.getWorkingSet();
+ }
+
+ /**
+ * Returns the navigator's plugin.
+ * @return the UI plugin for this bundle
+ */
+ public AbstractUIPlugin getPlugin() {
+ return IDEWorkbenchPlugin.getDefault();
+ }
+
+ /**
+ * Return the sorter. If a comparator was set using
+ * {@link #setComparator(ResourceComparator)}, this method will return
+ * <code>null</code>.
+ *
+ * @since 2.0
+ * @deprecated as of 3.3, use {@link ResourceNavigator#getComparator()}
+ */
+ public ResourceSorter getSorter() {
+ ViewerSorter sorter = getTreeViewer().getSorter();
+ if (sorter instanceof ResourceSorter) {
+ return (ResourceSorter) sorter;
+ }
+ return null;
+ }
+
+ /**
+ * Returns the comparator. If a sorter was set using
+ * {@link #setSorter(ResourceSorter)}, this method will return
+ * <code>null</code>.
+ *
+ * @return the <code>ResourceComparator</code>
+ * @since 3.3
+ */
+
+ public ResourceComparator getComparator(){
+ ViewerComparator comparator = getTreeViewer().getComparator();
+ if (comparator instanceof ResourceComparator) {
+ return (ResourceComparator) comparator;
+ }
+ return null;
+ }
+ /**
+ * Returns the resource viewer which shows the resource hierarchy.
+ * @since 2.0
+ */
+ public TreeViewer getViewer() {
+ return viewer;
+ }
+
+ /**
+ * Returns the tree viewer which shows the resource hierarchy.
+ * @return the tree viewer
+ * @since 2.0
+ */
+ public TreeViewer getTreeViewer() {
+ return viewer;
+ }
+
+ /**
+ * Returns the shell to use for opening dialogs.
+ * Used in this class, and in the actions.
+ *
+ * @return the shell
+ * @deprecated use getViewSite().getShell()
+ */
+ public Shell getShell() {
+ return getViewSite().getShell();
+ }
+
+ /**
+ * Returns the message to show in the status line.
+ *
+ * @param selection the current selection
+ * @return the status line message
+ * @since 2.0
+ */
+ protected String getStatusLineMessage(IStructuredSelection selection) {
+ if (selection.size() == 1) {
+ Object o = selection.getFirstElement();
+ if (o instanceof IResource) {
+ return ((IResource) o).getFullPath().makeRelative().toString();
+ }
+ return ResourceNavigatorMessages.ResourceNavigator_oneItemSelected;
+ }
+ if (selection.size() > 1) {
+ return NLS.bind(ResourceNavigatorMessages.ResourceNavigator_statusLine, String.valueOf(selection.size()));
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the name for the given element.
+ * Used as the name for the current frame.
+ */
+ String getFrameName(Object element) {
+ if (element instanceof IResource) {
+ return ((IResource) element).getName();
+ }
+ String text = ((ILabelProvider) getTreeViewer().getLabelProvider())
+ .getText(element);
+ if(text == null) {
+ return "";//$NON-NLS-1$
+ }
+ return text;
+ }
+
+ /**
+ * Returns the tool tip text for the given element.
+ * Used as the tool tip text for the current frame, and for the view title tooltip.
+ */
+ String getFrameToolTipText(Object element) {
+ if (element instanceof IResource) {
+ IPath path = ((IResource) element).getFullPath();
+ if (path.isRoot()) {
+ return ResourceNavigatorMessages.ResourceManager_toolTip;
+ }
+ return path.makeRelative().toString();
+ }
+
+ String text = ((ILabelProvider) getTreeViewer().getLabelProvider())
+ .getText(element);
+ if(text == null) {
+ return "";//$NON-NLS-1$
+ }
+ return text;
+ }
+
+ /**
+ * Handles an open event from the viewer. Opens an editor on the selected file.
+ *
+ * @param event the open event
+ * @since 2.0
+ * @deprecated As of 3.5, replaced by {@link #handleOpen(ISelection)}
+ */
+ protected void handleOpen(OpenEvent event) {
+ handleOpen(event.getSelection());
+ }
+
+ /**
+ * Handles an open event from the viewer. Opens an editor on the selected file.
+ *
+ * @param selection the selection
+ * @since 3.5
+ */
+ protected void handleOpen(ISelection selection) {
+ if (selection instanceof IStructuredSelection) {
+ OpenFileAction ofa = new OpenFileAction(getSite().getPage());
+ ofa.selectionChanged((IStructuredSelection) selection);
+ ofa.run();
+ //getActionGroup().runDefaultAction((IStructuredSelection)selection);
+ }
+ }
+
+ /**
+ * Handles a double-click event from the viewer.
+ * Expands or collapses a folder when double-clicked.
+ *
+ * @param event the double-click event
+ * @since 2.0
+ */
+ protected void handleDoubleClick(DoubleClickEvent event) {
+ IStructuredSelection selection = (IStructuredSelection) event
+ .getSelection();
+ Object element = selection.getFirstElement();
+
+ // 1GBZIA0: ITPUI:WIN2000 - Double-clicking in navigator should expand/collapse containers
+ TreeViewer viewer = getTreeViewer();
+ if (viewer.isExpandable(element)) {
+ viewer.setExpandedState(element, !viewer.getExpandedState(element));
+ } else if (selection.size() == 1 && (element instanceof IResource)
+ && ((IResource) element).getType() == IResource.PROJECT) {
+ OpenResourceAction ora = new OpenResourceAction(getSite());
+ ora.selectionChanged((IStructuredSelection) viewer.getSelection());
+ if (ora.isEnabled()) {
+ ora.run();
+ }
+ }
+
+ }
+
+ /**
+ * Handles a selection changed event from the viewer.
+ * Updates the status line and the action bars, and links to editor (if option enabled).
+ *
+ * @param event the selection event
+ * @since 2.0
+ */
+ protected void handleSelectionChanged(SelectionChangedEvent event) {
+ final IStructuredSelection sel = (IStructuredSelection) event
+ .getSelection();
+ updateStatusLine(sel);
+ updateActionBars(sel);
+ dragDetected = false;
+ }
+
+ /**
+ * Handles a key press event from the viewer.
+ * Delegates to the action group.
+ *
+ * @param event the key event
+ * @since 2.0
+ */
+ protected void handleKeyPressed(KeyEvent event) {
+ getActionGroup().handleKeyPressed(event);
+ }
+
+ /**
+ * Handles a key release in the viewer. Does nothing by default.
+ *
+ * @param event the key event
+ * @since 2.0
+ */
+ protected void handleKeyReleased(KeyEvent event) {
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IViewPart.
+ */
+ public void init(IViewSite site, IMemento memento) throws PartInitException {
+ super.init(site, memento);
+ this.memento = memento;
+ }
+
+ /**
+ * Adds drag and drop support to the navigator.
+ *
+ * @since 2.0
+ */
+ protected void initDragAndDrop() {
+ int ops = DND.DROP_COPY | DND.DROP_MOVE;
+ Transfer[] transfers = new Transfer[] {
+ LocalSelectionTransfer.getInstance(),
+ ResourceTransfer.getInstance(), FileTransfer.getInstance(),
+ PluginTransfer.getInstance() };
+ TreeViewer viewer = getTreeViewer();
+ viewer.addDragSupport(ops, transfers, new NavigatorDragAdapter(viewer));
+ NavigatorDropAdapter adapter = new NavigatorDropAdapter(viewer);
+ adapter.setFeedbackEnabled(false);
+ viewer.addDropSupport(ops | DND.DROP_DEFAULT, transfers, adapter);
+ dragDetectListener = new Listener() {
+ public void handleEvent(Event event) {
+ dragDetected = true;
+ }
+ };
+ viewer.getControl().addListener(SWT.DragDetect, dragDetectListener);
+ }
+
+ /**
+ * Creates the frame source and frame list, and connects them.
+ *
+ * @since 2.0
+ */
+ protected FrameList createFrameList() {
+ NavigatorFrameSource frameSource = new NavigatorFrameSource(this);
+ FrameList frameList = new FrameList(frameSource);
+ frameSource.connectTo(frameList);
+ return frameList;
+ }
+
+ /**
+ * Initializes the sorter.
+ *
+ * @deprecated as of 3.3, use {@link ResourceNavigator#initResourceComparator()} instead
+ */
+ protected void initResourceSorter() {
+ int sortType = ResourceSorter.NAME;
+ try {
+ int sortInt = 0;
+ if (memento != null) {
+ String sortStr = memento.getString(TAG_SORTER);
+ if (sortStr != null) {
+ sortInt = new Integer(sortStr).intValue();
+ }
+ } else {
+ sortInt = settings.getInt(STORE_SORT_TYPE);
+ }
+ if (sortInt == ResourceSorter.NAME
+ || sortInt == ResourceSorter.TYPE) {
+ sortType = sortInt;
+ }
+ } catch (NumberFormatException e) {
+ }
+ setSorter(new ResourceSorter(sortType));
+ }
+
+ /**
+ * Initializes the comparator.
+ * @since 3.3
+ */
+ protected void initResourceComparator(){
+ int sortType = ResourceComparator.NAME;
+ try {
+ int sortInt = 0;
+ if (memento != null) {
+ String sortStr = memento.getString(TAG_SORTER);
+ if (sortStr != null) {
+ sortInt = new Integer(sortStr).intValue();
+ }
+ } else {
+ sortInt = settings.getInt(STORE_SORT_TYPE);
+ }
+ if (sortInt == ResourceComparator.NAME
+ || sortInt == ResourceComparator.TYPE) {
+ sortType = sortInt;
+ }
+ } catch (NumberFormatException e) {
+ }
+ setComparator(new ResourceComparator(sortType));
+ }
+
+ /**
+ * Restores the working set filter from the persistence store.
+ */
+ protected void initWorkingSetFilter() {
+ String workingSetName = settings.get(STORE_WORKING_SET);
+
+ IWorkingSet workingSet = null;
+
+ if (workingSetName != null && workingSetName.equals("") == false) { //$NON-NLS-1$
+ IWorkingSetManager workingSetManager = getPlugin().getWorkbench()
+ .getWorkingSetManager();
+ workingSet = workingSetManager.getWorkingSet(workingSetName);
+ } else if (PlatformUI
+ .getPreferenceStore()
+ .getBoolean(
+ IWorkbenchPreferenceConstants.USE_WINDOW_WORKING_SET_BY_DEFAULT)) {
+ // use the window set by default if the global preference is set
+ workingSet = getSite().getPage().getAggregateWorkingSet();
+ }
+
+ if (workingSet != null) {
+ // Only initialize filter. Don't set working set into viewer.
+ // Working set is set via WorkingSetFilterActionGroup
+ // during action creation.
+ workingSetFilter.setWorkingSet(workingSet);
+ internalSetWorkingSet(workingSet);
+ }
+ }
+
+ /**
+ * Returns whether the navigator selection automatically tracks the active
+ * editor.
+ *
+ * @return <code>true</code> if linking is enabled, <code>false</code>
+ * if not
+ * @since 2.0 (this was protected in 2.0, but was made public in 2.1)
+ */
+ public boolean isLinkingEnabled() {
+ return linkingEnabled;
+ }
+
+ /**
+ * Brings the corresponding editor to top if the selected resource is open.
+ *
+ * @since 2.0
+ * @deprecated As of 3.5, replaced by {@link #linkToEditor(ISelection)}
+ */
+ protected void linkToEditor(IStructuredSelection selection) {
+ linkToEditor((ISelection)selection);
+ }
+
+ /**
+ * Brings the corresponding editor to top if the selected resource is open.
+ *
+ * @since 3.5
+ */
+ protected void linkToEditor(ISelection selection) {
+
+ if (this != this.getSite().getPage().getActivePart())
+ return;
+
+ Object obj = getSingleElement(selection);
+ if (obj instanceof IFile) {
+ IFile file = (IFile) obj;
+ IWorkbenchPage page = getSite().getPage();
+ IEditorPart editor = ResourceUtil.findEditor(page, file);
+ if (editor != null) {
+ page.bringToTop(editor);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Creates the action group, which encapsulates all actions for the view.
+ */
+ protected void makeActions() {
+ MainActionGroup group = new MainActionGroup(this);
+ setActionGroup(group);
+
+ IHandlerService service = (IHandlerService) getSite().getService(IHandlerService.class);
+ service.activateHandler("org.eclipse.ui.navigate.linkWithEditor", //$NON-NLS-1$
+ new ActionHandler(group.toggleLinkingAction));
+ collapseAllHandler = new CollapseAllHandler(viewer);
+ service.activateHandler(CollapseAllHandler.COMMAND_ID,
+ collapseAllHandler);
+ }
+
+ /**
+ * Restores the saved filter settings.
+ */
+ private void restoreFilters() {
+ IMemento filtersMem = memento.getChild(TAG_FILTERS);
+
+ if (filtersMem != null) { //filters have been defined
+ IMemento children[] = filtersMem.getChildren(TAG_FILTER);
+
+ // check if first element has new tag defined, indicates new version
+ if (children.length > 0
+ && children[0].getString(TAG_IS_ENABLED) != null) {
+ ArrayList selectedFilters = new ArrayList();
+ ArrayList unSelectedFilters = new ArrayList();
+ for (int i = 0; i < children.length; i++) {
+ if (children[i].getString(TAG_IS_ENABLED).equals(
+ String.valueOf(true))) {
+ selectedFilters.add(children[i].getString(TAG_ELEMENT));
+ } else {
+ //enabled == false
+ unSelectedFilters.add(children[i]
+ .getString(TAG_ELEMENT));
+ }
+ }
+
+ /* merge filters from Memento with selected = true filters from plugins
+ * ensure there are no duplicates & don't override user preferences */
+ List pluginFilters = FiltersContentProvider.getDefaultFilters();
+ for (Iterator iter = pluginFilters.iterator(); iter.hasNext();) {
+ String element = (String) iter.next();
+ if (!selectedFilters.contains(element)
+ && !unSelectedFilters.contains(element)) {
+ selectedFilters.add(element);
+ }
+ }
+
+ //Convert to an array of Strings
+ String[] patternArray = new String[selectedFilters.size()];
+ selectedFilters.toArray(patternArray);
+ getPatternFilter().setPatterns(patternArray);
+
+ } else { //filters defined, old version: ignore filters from plugins
+ String filters[] = new String[children.length];
+ for (int i = 0; i < children.length; i++) {
+ filters[i] = children[i].getString(TAG_ELEMENT);
+ }
+ getPatternFilter().setPatterns(filters);
+ }
+ } else { //no filters defined, old version: ignore filters from plugins
+ getPatternFilter().setPatterns(new String[0]);
+ }
+ }
+
+ /**
+ * Restores the state of the receiver to the state described in the specified memento.
+ *
+ * @param memento the memento
+ * @since 2.0
+ */
+ protected void restoreState(IMemento memento) {
+ TreeViewer viewer = getTreeViewer();
+ IMemento frameMemento = memento.getChild(TAG_CURRENT_FRAME);
+
+ if (frameMemento != null) {
+ TreeFrame frame = new TreeFrame(viewer);
+ frame.restoreState(frameMemento);
+ frame.setName(getFrameName(frame.getInput()));
+ frame.setToolTipText(getFrameToolTipText(frame.getInput()));
+ viewer.setSelection(new StructuredSelection(frame.getInput()));
+ frameList.gotoFrame(frame);
+ } else {
+ IContainer container = ResourcesPlugin.getWorkspace().getRoot();
+ IMemento childMem = memento.getChild(TAG_EXPANDED);
+ if (childMem != null) {
+ ArrayList elements = new ArrayList();
+ IMemento[] elementMem = childMem.getChildren(TAG_ELEMENT);
+ for (int i = 0; i < elementMem.length; i++) {
+ Object element = container.findMember(elementMem[i]
+ .getString(TAG_PATH));
+ if (element != null) {
+ elements.add(element);
+ }
+ }
+ viewer.setExpandedElements(elements.toArray());
+ }
+ childMem = memento.getChild(TAG_SELECTION);
+ if (childMem != null) {
+ ArrayList list = new ArrayList();
+ IMemento[] elementMem = childMem.getChildren(TAG_ELEMENT);
+ for (int i = 0; i < elementMem.length; i++) {
+ Object element = container.findMember(elementMem[i]
+ .getString(TAG_PATH));
+ if (element != null) {
+ list.add(element);
+ }
+ }
+ viewer.setSelection(new StructuredSelection(list));
+ }
+ }
+ }
+
+ /**
+ * Restores the linking enabled state.
+ */
+ private void restoreLinkingEnabled() {
+ Integer val = memento
+ .getInteger(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR);
+ if (val != null) {
+ linkingEnabled = val.intValue() != 0;
+ }
+ }
+
+ /**
+ * @see ViewPart#saveState
+ */
+ public void saveState(IMemento memento) {
+ TreeViewer viewer = getTreeViewer();
+ if (viewer == null) {
+ if (this.memento != null) {
+ memento.putMemento(this.memento);
+ }
+ return;
+ }
+
+ //save sorter
+ if (getComparator() != null) {
+ memento.putInteger(TAG_SORTER, getComparator().getCriteria());
+ } else if (getSorter() != null) {
+ memento.putInteger(TAG_SORTER, getSorter().getCriteria());
+ }
+
+ //save filters
+ String filters[] = getPatternFilter().getPatterns();
+ List selectedFilters = Arrays.asList(filters);
+ List allFilters = FiltersContentProvider.getDefinedFilters();
+ IMemento filtersMem = memento.createChild(TAG_FILTERS);
+ for (Iterator iter = allFilters.iterator(); iter.hasNext();) {
+ String element = (String) iter.next();
+ IMemento child = filtersMem.createChild(TAG_FILTER);
+ child.putString(TAG_ELEMENT, element);
+ child.putString(TAG_IS_ENABLED, String.valueOf(selectedFilters
+ .contains(element)));
+ }
+
+ if (frameList.getCurrentIndex() > 0) {
+ //save frame, it's not the "home"/workspace frame
+ TreeFrame currentFrame = (TreeFrame) frameList.getCurrentFrame();
+ IMemento frameMemento = memento.createChild(TAG_CURRENT_FRAME);
+ currentFrame.saveState(frameMemento);
+ } else {
+ //save visible expanded elements
+ Object expandedElements[] = viewer.getVisibleExpandedElements();
+ if (expandedElements.length > 0) {
+ IMemento expandedMem = memento.createChild(TAG_EXPANDED);
+ for (int i = 0; i < expandedElements.length; i++) {
+ if (expandedElements[i] instanceof IResource) {
+ IMemento elementMem = expandedMem
+ .createChild(TAG_ELEMENT);
+ elementMem.putString(TAG_PATH,
+ ((IResource) expandedElements[i]).getFullPath()
+ .toString());
+ }
+ }
+ }
+ //save selection
+ Object elements[] = ((IStructuredSelection) viewer.getSelection())
+ .toArray();
+ if (elements.length > 0) {
+ IMemento selectionMem = memento.createChild(TAG_SELECTION);
+ for (int i = 0; i < elements.length; i++) {
+ if (elements[i] instanceof IResource) {
+ IMemento elementMem = selectionMem
+ .createChild(TAG_ELEMENT);
+ elementMem.putString(TAG_PATH,
+ ((IResource) elements[i]).getFullPath()
+ .toString());
+ }
+ }
+ }
+ }
+
+ saveLinkingEnabled(memento);
+ }
+
+ /**
+ * Saves the linking enabled state.
+ */
+ private void saveLinkingEnabled(IMemento memento) {
+ memento.putInteger(
+ IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR,
+ linkingEnabled ? 1 : 0);
+ }
+
+ /**
+ * Selects and reveals the specified elements.
+ */
+ public void selectReveal(ISelection selection) {
+ StructuredSelection ssel = convertSelection(selection);
+ if (!ssel.isEmpty()) {
+ getViewer().getControl().setRedraw(false);
+ getViewer().setSelection(ssel, true);
+ getViewer().getControl().setRedraw(true);
+ }
+ }
+
+ /**
+ * Saves the filters defined as strings in <code>patterns</code>
+ * in the preference store.
+ */
+ public void setFiltersPreference(String[] patterns) {
+
+ StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < patterns.length; i++) {
+ if (i != 0) {
+ sb.append(ResourcePatternFilter.COMMA_SEPARATOR);
+ }
+ sb.append(patterns[i]);
+ }
+
+ getPlugin().getPreferenceStore().setValue(
+ ResourcePatternFilter.FILTERS_TAG, sb.toString());
+
+ // remove value in old workbench preference store location
+ IPreferenceStore preferenceStore = IDEWorkbenchPlugin.getDefault()
+ .getPreferenceStore();
+ String storedPatterns = preferenceStore
+ .getString(ResourcePatternFilter.FILTERS_TAG);
+ if (storedPatterns.length() > 0) {
+ preferenceStore.setValue(ResourcePatternFilter.FILTERS_TAG, ""); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * @see IWorkbenchPart#setFocus()
+ */
+ public void setFocus() {
+ getTreeViewer().getTree().setFocus();
+ }
+
+ /**
+ * Note: For experimental use only.
+ * Sets the decorator for the navigator.
+ * <p>
+ * As of 2.0, this method no longer has any effect.
+ * </p>
+ *
+ * @param decorator a label decorator or <code>null</code> for no decorations.
+ * @deprecated use the decorators extension point instead; see IWorkbench.getDecoratorManager()
+ */
+ public void setLabelDecorator(ILabelDecorator decorator) {
+ // do nothing
+ }
+
+ /**
+ * @see IResourceNavigator#setLinkingEnabled(boolean)
+ * @since 2.1
+ */
+ public void setLinkingEnabled(boolean enabled) {
+ this.linkingEnabled = enabled;
+
+ // remember the last setting in the dialog settings
+ settings.put(IWorkbenchPreferenceConstants.LINK_NAVIGATOR_TO_EDITOR,
+ enabled);
+
+ // if turning linking on, update the selection to correspond to the active editor
+ if (enabled) {
+ IEditorPart editor = getSite().getPage().getActiveEditor();
+ if (editor != null) {
+ editorActivated(editor);
+ }
+ }
+ openAndLinkWithEditorHelper.setLinkWithEditor(enabled);
+ }
+
+ /**
+ * Sets the resource sorter.
+ *
+ * @param sorter the resource sorter
+ * @since 2.0
+ * @deprecated as of 3.3, use {@link ResourceNavigator#setComparator(ResourceComparator)}
+ */
+ public void setSorter(ResourceSorter sorter) {
+ TreeViewer viewer = getTreeViewer();
+ ViewerSorter viewerSorter = viewer.getSorter();
+
+ viewer.getControl().setRedraw(false);
+ if (viewerSorter == sorter) {
+ viewer.refresh();
+ } else {
+ viewer.setSorter(sorter);
+ }
+ viewer.getControl().setRedraw(true);
+ settings.put(STORE_SORT_TYPE, sorter.getCriteria());
+
+ // update the sort actions' checked state
+ updateActionBars((IStructuredSelection) viewer.getSelection());
+ }
+
+ /**
+ * Sets the resource comparator
+ *
+ * @param comparator the resource comparator
+ * @since 3.3
+ */
+ public void setComparator(ResourceComparator comparator){
+ TreeViewer viewer = getTreeViewer();
+ ViewerComparator viewerComparator = viewer.getComparator();
+
+ viewer.getControl().setRedraw(false);
+ if (viewerComparator == comparator) {
+ viewer.refresh();
+ } else {
+ viewer.setComparator(comparator);
+ }
+ viewer.getControl().setRedraw(true);
+ settings.put(STORE_SORT_TYPE, comparator.getCriteria());
+
+ // update the sort actions' checked state
+ updateActionBars((IStructuredSelection) viewer.getSelection());
+ }
+
+ /*
+ * @see org.eclipse.ui.views.navigator.IResourceNavigatorPart#setWorkingSet(IWorkingSet)
+ * @since 2.0
+ */
+ public void setWorkingSet(IWorkingSet workingSet) {
+ TreeViewer treeViewer = getTreeViewer();
+ Object[] expanded = treeViewer.getExpandedElements();
+ ISelection selection = treeViewer.getSelection();
+
+ boolean refreshNeeded = internalSetWorkingSet(workingSet);
+
+ workingSetFilter.setWorkingSet(emptyWorkingSet ? null : workingSet);
+ if (workingSet != null) {
+ settings.put(STORE_WORKING_SET, workingSet.getName());
+ } else {
+ settings.put(STORE_WORKING_SET, ""); //$NON-NLS-1$
+ }
+ updateTitle();
+ if(refreshNeeded) {
+ treeViewer.refresh();
+ }
+ treeViewer.setExpandedElements(expanded);
+ if (selection.isEmpty() == false
+ && selection instanceof IStructuredSelection) {
+ IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+ treeViewer.reveal(structuredSelection.getFirstElement());
+ }
+ }
+
+ /**
+ * Set the internal working set fields specific to the navigator.
+ *
+ * @param workingSet
+ * the new working set
+ * @since 3.2
+ */
+ private boolean internalSetWorkingSet(IWorkingSet workingSet) {
+ boolean refreshNeeded = !Util.equals(this.workingSet, workingSet);
+ this.workingSet = workingSet;
+ emptyWorkingSet = workingSet != null && workingSet.isAggregateWorkingSet()
+ && workingSet.isEmpty();
+ return refreshNeeded;
+ }
+
+ /**
+ * Updates the action bar actions.
+ *
+ * @param selection the current selection
+ * @since 2.0
+ */
+ protected void updateActionBars(IStructuredSelection selection) {
+ ResourceNavigatorActionGroup group = getActionGroup();
+ if (group != null) {
+ group.setContext(new ActionContext(selection));
+ group.updateActionBars();
+ }
+ }
+
+ /**
+ * Updates the message shown in the status line.
+ *
+ * @param selection the current selection
+ */
+ protected void updateStatusLine(IStructuredSelection selection) {
+ String msg = getStatusLineMessage(selection);
+ //getViewSite().getActionBars().getStatusLineManager().setMessage(msg);
+ }
+
+ /**
+ * Updates the title text and title tool tip.
+ * Called whenever the input of the viewer changes.
+ * Called whenever the input of the viewer changes.
+ *
+ * @since 2.0
+ */
+ public void updateTitle() {
+ Object input = getViewer().getInput();
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IWorkingSet workingSet = workingSetFilter.getWorkingSet();
+
+ if (input == null || input.equals(workspace)
+ || input.equals(workspace.getRoot())) {
+ setContentDescription(""); //$NON-NLS-1$
+ if (workingSet != null) {
+ setTitleToolTip(NLS.bind(ResourceNavigatorMessages.ResourceNavigator_workingSetToolTip, workingSet.getLabel()));
+ } else {
+ setTitleToolTip(""); //$NON-NLS-1$
+ }
+ } else {
+ ILabelProvider labelProvider = (ILabelProvider) getTreeViewer()
+ .getLabelProvider();
+ String inputToolTip = getFrameToolTipText(input);
+ String text = labelProvider.getText(input);
+ if(text != null) {
+ setContentDescription(text);
+ }
+ if (workingSet != null) {
+ setTitleToolTip(NLS.bind(ResourceNavigatorMessages.ResourceNavigator_workingSetInputToolTip, inputToolTip, workingSet.getLabel()));
+ } else {
+ setTitleToolTip(inputToolTip);
+ }
+ }
+ }
+
+ /**
+ * Returns the action group.
+ *
+ * @return the action group
+ */
+ protected ResourceNavigatorActionGroup getActionGroup() {
+ return actionGroup;
+ }
+
+ /**
+ * Sets the action group.
+ *
+ * @param actionGroup the action group
+ */
+ protected void setActionGroup(ResourceNavigatorActionGroup actionGroup) {
+ this.actionGroup = actionGroup;
+ }
+
+ /*
+ * @see IWorkbenchPart#getAdapter(Class)
+ */
+ public Object getAdapter(Class adapter) {
+ if (adapter == IShowInSource.class) {
+ return getShowInSource();
+ }
+ if (adapter == IShowInTarget.class) {
+ return getShowInTarget();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the <code>IShowInSource</code> for this view.
+ */
+ protected IShowInSource getShowInSource() {
+ return new IShowInSource() {
+ public ShowInContext getShowInContext() {
+ return new ShowInContext(getViewer().getInput(), getViewer()
+ .getSelection());
+ }
+ };
+ }
+
+ /**
+ * Returns the <code>IShowInTarget</code> for this view.
+ */
+ protected IShowInTarget getShowInTarget() {
+ return new IShowInTarget() {
+ public boolean show(ShowInContext context) {
+ ArrayList toSelect = new ArrayList();
+ ISelection sel = context.getSelection();
+ if (sel instanceof IStructuredSelection) {
+ IStructuredSelection ssel = (IStructuredSelection) sel;
+ for (Iterator i = ssel.iterator(); i.hasNext();) {
+ Object o = i.next();
+ if (o instanceof IResource) {
+ toSelect.add(o);
+ } else if (o instanceof IMarker) {
+ IResource r = ((IMarker) o).getResource();
+ if (r.getType() != IResource.ROOT) {
+ toSelect.add(r);
+ }
+ } else if (o instanceof IAdaptable) {
+ IAdaptable adaptable = (IAdaptable) o;
+ o = adaptable.getAdapter(IResource.class);
+ if (o instanceof IResource) {
+ toSelect.add(o);
+ } else {
+ o = adaptable.getAdapter(IMarker.class);
+ if (o instanceof IMarker) {
+ IResource r = ((IMarker) o).getResource();
+ if (r.getType() != IResource.ROOT) {
+ toSelect.add(r);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (toSelect.isEmpty()) {
+ Object input = context.getInput();
+ if (input instanceof IAdaptable) {
+ IAdaptable adaptable = (IAdaptable) input;
+ Object o = adaptable.getAdapter(IResource.class);
+ if (o instanceof IResource) {
+ toSelect.add(o);
+ }
+ }
+ }
+ if (!toSelect.isEmpty()) {
+ selectReveal(new StructuredSelection(toSelect));
+ return true;
+ }
+ return false;
+ }
+ };
+ }
+
+ /**
+ * Returns the selected element if the selection consists of a single element only.
+ *
+ * @param s the selection
+ * @return the selected first element or null
+ * @since 3.5
+ */
+ protected static final Object getSingleElement(ISelection s) {
+ if (!(s instanceof IStructuredSelection))
+ return null;
+
+ IStructuredSelection selection = (IStructuredSelection)s;
+ if (selection.size() != 1)
+ return null;
+
+ return selection.getFirstElement();
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorAction.java
new file mode 100644
index 0000000..7cb7482
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorAction.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demio.views.nav;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.SelectionProviderAction;
+
+/**
+ * Superclass of all actions provided by the resource navigator.
+ */
+public abstract class ResourceNavigatorAction extends SelectionProviderAction {
+
+ private IResourceNavigator navigator;
+
+ /**
+ * Creates a new instance of the class.
+ */
+ public ResourceNavigatorAction(IResourceNavigator navigator, String label) {
+ super(navigator.getViewer(), label);
+ this.navigator = navigator;
+ }
+
+ /**
+ * Returns the resource navigator for which this action was created.
+ */
+ public IResourceNavigator getNavigator() {
+ return navigator;
+ }
+
+ /**
+ * Returns the resource viewer
+ */
+ protected Viewer getViewer() {
+ return getNavigator().getViewer();
+ }
+
+ /**
+ * Returns the shell to use within actions.
+ */
+ protected Shell getShell() {
+ return getNavigator().getSite().getShell();
+ }
+
+ /**
+ * Returns the workbench.
+ */
+ protected IWorkbench getWorkbench() {
+ return PlatformUI.getWorkbench();
+ }
+
+ /**
+ * Returns the workbench window.
+ */
+ protected IWorkbenchWindow getWorkbenchWindow() {
+ return getNavigator().getSite().getWorkbenchWindow();
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorActionGroup.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorActionGroup.java
new file mode 100644
index 0000000..7412e98
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorActionGroup.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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
+ * Sebastian Davids <sdavids@gmx.de> - Images for menu items (27481)
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+
+/**
+ * This is the action group for all the resource navigator actions.
+ * It delegates to several subgroups for most of the actions.
+ *
+ * @see GotoActionGroup
+ * @see OpenActionGroup
+ * @see RefactorActionGroup
+ * @see SortAndFilterActionGroup
+ * @see WorkspaceActionGroup
+ *
+ * @since 2.0
+ */
+public abstract class ResourceNavigatorActionGroup extends ActionGroup {
+
+ /**
+ * The resource navigator.
+ */
+ protected IResourceNavigator navigator;
+
+ /**
+ * Constructs a new navigator action group and creates its actions.
+ *
+ * @param navigator the resource navigator
+ */
+ public ResourceNavigatorActionGroup(IResourceNavigator navigator) {
+ this.navigator = navigator;
+ makeActions();
+ }
+
+ /**
+ * Returns the image descriptor with the given relative path.
+ */
+ protected ImageDescriptor getImageDescriptor(String relativePath) {
+ return IDEWorkbenchPlugin.getIDEImageDescriptor(relativePath);
+
+ }
+
+ /**
+ * Returns the resource navigator.
+ */
+ public IResourceNavigator getNavigator() {
+ return navigator;
+ }
+
+ /**
+ * Handles a key pressed event by invoking the appropriate action.
+ * Does nothing by default.
+ */
+ public void handleKeyPressed(KeyEvent event) {
+ }
+
+ /**
+ * Makes the actions contained in this action group.
+ */
+ protected abstract void makeActions();
+
+ /**
+ * Runs the default action in the group.
+ * Does nothing by default.
+ *
+ * @param selection the current selection
+ */
+ public void runDefaultAction(IStructuredSelection selection) {
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorMessages.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorMessages.java
new file mode 100644
index 0000000..56bb2cc
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorMessages.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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.e4.demio.views.nav;
+
+
+/**
+ * Utility class which helps managing messages
+ * @since 2.0
+ * @deprecated These messages are not API and should not be referenced
+ * outside of this plug-in.
+ */
+public class ResourceNavigatorMessages {
+
+ private ResourceNavigatorMessages() {
+ // prevent instantiation of class
+ }
+
+ /**
+ * Returns the formatted message for the given key in
+ * the resource bundle.
+ *
+ * @param key the resource name
+ * @param args the message arguments
+ * @return the string
+ */
+ public static String format(String key, Object[] args) {
+ return key;
+ }
+
+ /**
+ * Returns the resource object with the given key in
+ * the resource bundle. If there isn't any value under
+ * the given key, the key is returned.
+ *
+ * @param key the resource name
+ * @return the string
+ */
+ public static String getString(String key) {
+ return key;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorMoveAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorMoveAction.java
new file mode 100644
index 0000000..381b29a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorMoveAction.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demio.views.nav;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.MoveProjectAction;
+import org.eclipse.ui.actions.MoveResourceAction;
+
+/**
+ * The ResourceNavigatorMoveAction is a resource move that aso updates the navigator
+ * to show the result of the move.
+ * It also delegates to MoveProjectAction as needed.
+ *
+ * @since 2.0
+ */
+public class ResourceNavigatorMoveAction extends MoveResourceAction {
+ private StructuredViewer viewer;
+
+ private MoveProjectAction moveProjectAction;
+
+ /**
+ * Create a ResourceNavigatorMoveAction and use the supplied viewer to update the UI.
+ * @param shell Shell
+ * @param structureViewer StructuredViewer
+ */
+ public ResourceNavigatorMoveAction(Shell shell,
+ StructuredViewer structureViewer) {
+ super(shell);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+ INavigatorHelpContextIds.RESOURCE_NAVIGATOR_MOVE_ACTION);
+ this.viewer = structureViewer;
+ this.moveProjectAction = new MoveProjectAction(shell);
+ }
+
+ /* (non-Javadoc)
+ * Method declared on IAction.
+ */
+ public void run() {
+ if (moveProjectAction.isEnabled()) {
+ moveProjectAction.run();
+ return;
+ }
+
+ super.run();
+ List destinations = getDestinations();
+ if (destinations != null && destinations.isEmpty() == false) {
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ List resources = new ArrayList();
+ Iterator iterator = destinations.iterator();
+
+ while (iterator.hasNext()) {
+ IResource newResource = root
+ .findMember((IPath) iterator.next());
+ if (newResource != null) {
+ resources.add(newResource);
+ }
+ }
+
+ this.viewer.setSelection(new StructuredSelection(resources), true);
+ }
+
+ }
+
+ protected boolean updateSelection(IStructuredSelection selection) {
+ moveProjectAction.selectionChanged(selection);
+ return super.updateSelection(selection)
+ || moveProjectAction.isEnabled();
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorRenameAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorRenameAction.java
new file mode 100644
index 0000000..c9f9ff9
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceNavigatorRenameAction.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.RenameResourceAction;
+
+/**
+ * The ResourceNavigatorRenameAction is the rename action used by the
+ * ResourceNavigator that also allows updating after rename.
+ * @since 2.0
+ */
+public class ResourceNavigatorRenameAction extends RenameResourceAction {
+ private TreeViewer viewer;
+
+ /**
+ * Create a ResourceNavigatorRenameAction and use the tree of the supplied viewer
+ * for editing.
+ * @param shell Shell
+ * @param treeViewer TreeViewer
+ */
+ public ResourceNavigatorRenameAction(Shell shell, TreeViewer treeViewer) {
+ super(shell, treeViewer.getTree());
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+ INavigatorHelpContextIds.RESOURCE_NAVIGATOR_RENAME_ACTION);
+ this.viewer = treeViewer;
+ }
+
+ /* (non-Javadoc)
+ * Run the action to completion using the supplied path.
+ */
+ protected void runWithNewPath(IPath path, IResource resource) {
+ IWorkspaceRoot root = resource.getProject().getWorkspace().getRoot();
+ super.runWithNewPath(path, resource);
+ if (this.viewer != null) {
+ IResource newResource = root.findMember(path);
+ if (newResource != null) {
+ this.viewer.setSelection(new StructuredSelection(newResource),
+ true);
+ }
+ }
+ }
+
+ /**
+ * Handle the key release
+ */
+ public void handleKeyReleased(KeyEvent event) {
+ if (event.keyCode == SWT.F2 && event.stateMask == 0 && isEnabled()) {
+ run();
+ }
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourcePatternFilter.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourcePatternFilter.java
new file mode 100644
index 0000000..5baa8be
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourcePatternFilter.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demio.views.nav;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+import org.eclipse.ui.internal.util.PrefUtil;
+
+/**
+ * Filter used to determine whether resources are to be shown or not.
+ *
+ * @since 2.0
+ */
+public class ResourcePatternFilter extends ViewerFilter {
+ private String[] patterns;
+
+ private StringMatcher[] matchers;
+
+ static final String COMMA_SEPARATOR = ",";//$NON-NLS-1$
+
+ static final String FILTERS_TAG = "resourceFilters";//$NON-NLS-1$
+
+ /**
+ * Creates a new resource pattern filter.
+ */
+ public ResourcePatternFilter() {
+ super();
+ }
+
+ /**
+ * Return the currently configured StringMatchers. If there aren't any look
+ * them up.
+ */
+ private StringMatcher[] getMatchers() {
+
+ if (this.matchers == null) {
+ initializeFromPreferences();
+ }
+
+ return this.matchers;
+ }
+
+ /**
+ * Gets the patterns for the receiver. Returns the cached values if there
+ * are any - if not look it up.
+ */
+ public String[] getPatterns() {
+
+ if (this.patterns == null) {
+ initializeFromPreferences();
+ }
+
+ return this.patterns;
+
+ }
+
+ /**
+ * Initializes the filters from the preference store.
+ */
+ private void initializeFromPreferences() {
+ // get the filters that were saved by ResourceNavigator.setFiltersPreference
+ IPreferenceStore viewsPrefs = IDEWorkbenchPlugin.getDefault()
+ .getPreferenceStore();
+ String storedPatterns = viewsPrefs.getString(FILTERS_TAG);
+
+ if (storedPatterns.length() == 0) {
+ // try to migrate patterns from old workbench preference store location
+ IPreferenceStore workbenchPrefs = PrefUtil.getInternalPreferenceStore();
+ storedPatterns = workbenchPrefs.getString(FILTERS_TAG);
+ if (storedPatterns.length() > 0) {
+ viewsPrefs.setValue(FILTERS_TAG, storedPatterns);
+ workbenchPrefs.setValue(FILTERS_TAG, ""); //$NON-NLS-1$
+ }
+ }
+
+ if (storedPatterns.length() == 0) {
+ // revert to all filter extensions with selected == "true"
+ // if there are no filters in the preference store
+ List defaultFilters = FiltersContentProvider.getDefaultFilters();
+ String[] patterns = new String[defaultFilters.size()];
+ defaultFilters.toArray(patterns);
+ setPatterns(patterns);
+ return;
+ }
+
+ //Get the strings separated by a comma and filter them from the currently
+ //defined ones
+ List definedFilters = FiltersContentProvider.getDefinedFilters();
+ StringTokenizer entries = new StringTokenizer(storedPatterns,
+ COMMA_SEPARATOR);
+ List patterns = new ArrayList();
+
+ while (entries.hasMoreElements()) {
+ String nextToken = entries.nextToken();
+ if (definedFilters.indexOf(nextToken) > -1) {
+ patterns.add(nextToken);
+ }
+ }
+
+ //Convert to an array of Strings
+ String[] patternArray = new String[patterns.size()];
+ patterns.toArray(patternArray);
+ setPatterns(patternArray);
+
+ }
+
+ /* (non-Javadoc)
+ * Method declared on ViewerFilter.
+ */
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ IResource resource = null;
+ if (element instanceof IResource) {
+ resource = (IResource) element;
+ } else if (element instanceof IAdaptable) {
+ IAdaptable adaptable = (IAdaptable) element;
+ resource = (IResource) adaptable.getAdapter(IResource.class);
+ }
+ if (resource != null) {
+ String name = resource.getName();
+ StringMatcher[] testMatchers = getMatchers();
+ for (int i = 0; i < testMatchers.length; i++) {
+ if (testMatchers[i].match(name)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return true;
+ }
+
+ /**
+ * Sets the patterns to filter out for the receiver.
+ */
+ public void setPatterns(String[] newPatterns) {
+
+ this.patterns = newPatterns;
+ this.matchers = new StringMatcher[newPatterns.length];
+ for (int i = 0; i < newPatterns.length; i++) {
+ //Reset the matchers to prevent constructor overhead
+ matchers[i] = new StringMatcher(newPatterns[i], true, false);
+ }
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceSelectionUtil.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceSelectionUtil.java
new file mode 100644
index 0000000..9fa7a0d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceSelectionUtil.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.e4.demio.views.nav;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+
+/**
+ * Provides utilities for checking the validity of selections.
+ * <p>
+ * This class provides static methods only; it is not intended to be instantiated
+ * or subclassed.
+ * @since 2.0
+ * </p>
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ResourceSelectionUtil {
+ /* (non-Javadoc)
+ * Private constructor to block instantiation.
+ */
+ private ResourceSelectionUtil() {
+ }
+
+ /**
+ * Returns whether the types of the resources in the given selection are among
+ * the specified resource types.
+ *
+ * @param selection the selection
+ * @param resourceMask resource mask formed by bitwise OR of resource type
+ * constants (defined on <code>IResource</code>)
+ * @return <code>true</code> if all selected elements are resources of the right
+ * type, and <code>false</code> if at least one element is either a resource
+ * of some other type or a non-resource
+ * @see IResource#getType()
+ */
+ public static boolean allResourcesAreOfType(IStructuredSelection selection,
+ int resourceMask) {
+ Iterator resources = selection.iterator();
+ while (resources.hasNext()) {
+ Object next = resources.next();
+ if (!(next instanceof IResource)) {
+ return false;
+ }
+ if (!resourceIsType((IResource) next, resourceMask)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns the selection adapted to IResource. Returns null
+ * if any of the entries are not adaptable.
+ *
+ * @param selection the selection
+ * @param resourceMask resource mask formed by bitwise OR of resource type
+ * constants (defined on <code>IResource</code>)
+ * @return IStructuredSelection or null if any of the entries are not adaptable.
+ * @see IResource#getType()
+ */
+ public static IStructuredSelection allResources(
+ IStructuredSelection selection, int resourceMask) {
+ Iterator adaptables = selection.iterator();
+ List result = new ArrayList();
+ while (adaptables.hasNext()) {
+ Object next = adaptables.next();
+ if (next instanceof IAdaptable) {
+ Object resource = ((IAdaptable) next)
+ .getAdapter(IResource.class);
+ if (resource == null) {
+ return null;
+ } else if (resourceIsType((IResource) resource, resourceMask)) {
+ result.add(resource);
+ }
+ } else {
+ return null;
+ }
+ }
+ return new StructuredSelection(result);
+
+ }
+
+ /**
+ * Returns whether the type of the given resource is among the specified
+ * resource types.
+ *
+ * @param resource the resource
+ * @param resourceMask resource mask formed by bitwise OR of resource type
+ * constants (defined on <code>IResource</code>)
+ * @return <code>true</code> if the resources has a matching type, and
+ * <code>false</code> otherwise
+ * @see IResource#getType()
+ */
+ public static boolean resourceIsType(IResource resource, int resourceMask) {
+ return (resource.getType() & resourceMask) != 0;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceSorter.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceSorter.java
new file mode 100644
index 0000000..aad368c
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ResourceSorter.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.e4.demio.views.nav;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+
+/**
+ * Sorter for viewers that display items of type <code>IResource</code>.
+ * The sorter supports two sort criteria:
+ * <p>
+ * <code>NAME</code>: Folders are given order precedence, followed by files.
+ * Within these two groups resources are ordered by name. All name comparisons
+ * are case-insensitive.
+ * </p>
+ * <p>
+ * <code>TYPE</code>: Folders are given order precedence, followed by files.
+ * Within these two groups resources are ordered by extension. All extension
+ * comparisons are case-insensitive.
+ * </p>
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ *
+ * @deprecated as of 3.3, use {@link ResourceComparator} instead
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ResourceSorter extends ViewerSorter {
+
+ /**
+ * Constructor argument value that indicates to sort items by name.
+ */
+ public final static int NAME = 1;
+
+ /**
+ * Constructor argument value that indicates to sort items by extension.
+ */
+ public final static int TYPE = 2;
+
+ private int criteria;
+
+ /**
+ * Creates a resource sorter that will use the given sort criteria.
+ *
+ * @param criteria the sort criterion to use: one of <code>NAME</code> or
+ * <code>TYPE</code>
+ */
+ public ResourceSorter(int criteria) {
+ super();
+ this.criteria = criteria;
+ }
+
+ /**
+ * Returns an integer value representing the relative sort priority of the
+ * given element based on its class.
+ * <p>
+ * <ul>
+ * <li>resources (<code>IResource</code>) - 2</li>
+ * <li>project references (<code>ProjectReference</code>) - 1</li>
+ * <li>everything else - 0</li>
+ * </ul>
+ * </p>
+ *
+ * @param element the element
+ * @return the sort priority (larger numbers means more important)
+ */
+ protected int classComparison(Object element) {
+ if (element instanceof IResource) {
+ return 2;
+ }
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * Method declared on ViewerSorter.
+ */
+ public int compare(Viewer viewer, Object o1, Object o2) {
+ //have to deal with non-resources in navigator
+ //if one or both objects are not resources, returned a comparison
+ //based on class.
+ if (!(o1 instanceof IResource && o2 instanceof IResource)) {
+ return compareClass(o1, o2);
+ }
+ IResource r1 = (IResource) o1;
+ IResource r2 = (IResource) o2;
+
+ if (r1 instanceof IContainer && r2 instanceof IContainer) {
+ return compareNames(r1, r2);
+ } else if (r1 instanceof IContainer) {
+ return -1;
+ } else if (r2 instanceof IContainer) {
+ return 1;
+ } else if (criteria == NAME) {
+ return compareNames(r1, r2);
+ } else if (criteria == TYPE) {
+ return compareTypes(r1, r2);
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Returns a number reflecting the collation order of the given elements
+ * based on their class.
+ *
+ * @param element1 the first element to be ordered
+ * @param element2 the second element to be ordered
+ * @return a negative number if the first element is less than the
+ * second element; the value <code>0</code> if the first element is
+ * equal to the second element; and a positive number if the first
+ * element is greater than the second element
+ */
+ protected int compareClass(Object element1, Object element2) {
+ return classComparison(element1) - classComparison(element2);
+ }
+
+ /**
+ * Returns a number reflecting the collation order of the given resources
+ * based on their resource names.
+ *
+ * @param resource1 the first resource element to be ordered
+ * @param resource2 the second resource element to be ordered
+ * @return a negative number if the first element is less than the
+ * second element; the value <code>0</code> if the first element is
+ * equal to the second element; and a positive number if the first
+ * element is greater than the second element
+ */
+ protected int compareNames(IResource resource1, IResource resource2) {
+ return collator.compare(resource1.getName(), resource2.getName());
+ }
+
+ /**
+ * Returns a number reflecting the collation order of the given resources
+ * based on their respective file extensions. Resources with the same file
+ * extension will be collated based on their names.
+ *
+ * @param resource1 the first resource element to be ordered
+ * @param resource2 the second resource element to be ordered
+ * @return a negative number if the first element is less than the
+ * second element; the value <code>0</code> if the first element is
+ * equal to the second element; and a positive number if the first
+ * element is greater than the second element
+ */
+ protected int compareTypes(IResource resource1, IResource resource2) {
+ String ext1 = getExtensionFor(resource1);
+ String ext2 = getExtensionFor(resource2);
+
+ // Compare extensions. If they're different then return a value that
+ // indicates correct extension ordering. If they're the same then
+ // return a value that indicates the correct NAME ordering.
+ int result = collator.compare(ext1, ext2);
+
+ if (result != 0) {
+ return result;
+ }
+
+ return compareNames(resource1, resource2);
+ }
+
+ /**
+ * Returns the sort criteria of this sorter.
+ *
+ * @return the sort criterion: one of <code>NAME</code> or <code>TYPE</code>
+ */
+ public int getCriteria() {
+ return criteria;
+ }
+
+ /**
+ * Returns the extension portion of the given resource.
+ *
+ * @param resource the resource
+ * @return the file extension, possibily the empty string
+ */
+ private String getExtensionFor(IResource resource) {
+ String ext = resource.getFileExtension();
+ return ext == null ? "" : ext; //$NON-NLS-1$
+ }
+
+ /**
+ * Sets the sort criteria of this sorter.
+ *
+ * @param criteria the sort criterion:
+ * one of <code>ResourceSorter.NAME</code> or
+ * <code>ResourceSorter.TYPE</code>
+ */
+ public void setCriteria(int criteria) {
+ this.criteria = criteria;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ShowInNavigatorAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ShowInNavigatorAction.java
new file mode 100644
index 0000000..0ed009a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ShowInNavigatorAction.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demio.views.nav;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.actions.SelectionProviderAction;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+import org.eclipse.ui.part.ISetSelectionTarget;
+
+/**
+ * An action which shows the current selection in the Navigator view.
+ * For each element in the selection, if it is an <code>IResource</code>
+ * it uses it directly, otherwise if it is an <code>IMarker</code> it uses the marker's resource,
+ * otherwise if it is an <code>IAdaptable</code>, it tries to get the <code>IResource.class</code> adapter.
+ */
+public class ShowInNavigatorAction extends SelectionProviderAction {
+ private IWorkbenchPage page;
+
+ /**
+ * Create a new instance of this class.
+ *
+ * @param page the page
+ * @param viewer the viewer
+ */
+ public ShowInNavigatorAction(IWorkbenchPage page, ISelectionProvider viewer) {
+ super(viewer, ResourceNavigatorMessages.ShowInNavigator_text);
+ Assert.isNotNull(page);
+ this.page = page;
+ setDescription(ResourceNavigatorMessages.ShowInNavigator_toolTip);
+ page.getWorkbenchWindow().getWorkbench().getHelpSystem().setHelp(this,
+ INavigatorHelpContextIds.SHOW_IN_NAVIGATOR_ACTION);
+ }
+
+ /**
+ * Returns the resources in the given selection.
+ *
+ * @return a list of <code>IResource</code>
+ */
+ List getResources(IStructuredSelection selection) {
+ List v = new ArrayList();
+ for (Iterator i = selection.iterator(); i.hasNext();) {
+ Object o = i.next();
+ if (o instanceof IResource) {
+ v.add(o);
+ } else if (o instanceof IMarker) {
+ IResource resource = ((IMarker) o).getResource();
+ v.add(resource);
+ } else if (o instanceof IAdaptable) {
+ IResource resource = (IResource) ((IAdaptable) o)
+ .getAdapter(IResource.class);
+ if (resource != null) {
+ v.add(resource);
+ }
+ }
+ }
+ return v;
+ }
+
+ /*
+ * (non-Javadoc)
+ * Method declared on IAction.
+ */
+ /**
+ * Shows the Navigator view and sets its selection to the resources
+ * selected in this action's selection provider.
+ */
+ public void run() {
+ List v = getResources(getStructuredSelection());
+ if (v.isEmpty()) {
+ return;
+ }
+ try {
+ IViewPart view = page.showView(IPageLayout.ID_RES_NAV);
+ if (view instanceof ISetSelectionTarget) {
+ ISelection selection = new StructuredSelection(v);
+ ((ISetSelectionTarget) view).selectReveal(selection);
+ }
+ } catch (PartInitException e) {
+ ErrorDialog.openError(page.getWorkbenchWindow().getShell(),
+ ResourceNavigatorMessages.ShowInNavigator_errorMessage,
+ e.getMessage(), e.getStatus());
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * Method declared on SelectionProviderAction.
+ */
+ public void selectionChanged(IStructuredSelection selection) {
+ setEnabled(!getResources(selection).isEmpty());
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/SortAndFilterActionGroup.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/SortAndFilterActionGroup.java
new file mode 100644
index 0000000..38e4cec
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/SortAndFilterActionGroup.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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
+ * Sebastian Davids <sdavids@gmx.de> - Images for menu items (27481)
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+
+/**
+ * This is the action group for the sort and filter actions.
+ */
+public class SortAndFilterActionGroup extends ResourceNavigatorActionGroup {
+
+ private SortViewAction sortByTypeAction;
+
+ private SortViewAction sortByNameAction;
+
+ private FilterSelectionAction filterAction;
+
+ /**
+ * Constructor.
+ *
+ * @param navigator
+ */
+ public SortAndFilterActionGroup(IResourceNavigator navigator) {
+ super(navigator);
+ }
+
+ protected void makeActions() {
+ sortByNameAction = new SortViewAction(navigator, false);
+ sortByTypeAction = new SortViewAction(navigator, true);
+
+ filterAction = new FilterSelectionAction(navigator,
+ ResourceNavigatorMessages.ResourceNavigator_filterText);
+ filterAction
+ .setDisabledImageDescriptor(getImageDescriptor("dlcl16/filter_ps.gif"));//$NON-NLS-1$
+ filterAction
+ .setImageDescriptor(getImageDescriptor("elcl16/filter_ps.gif"));//$NON-NLS-1$
+ }
+
+ public void fillActionBars(IActionBars actionBars) {
+ IMenuManager menu = actionBars.getMenuManager();
+ IMenuManager submenu = new MenuManager(ResourceNavigatorMessages.ResourceNavigator_sort);
+ menu.add(submenu);
+ submenu.add(sortByNameAction);
+ submenu.add(sortByTypeAction);
+ menu.add(filterAction);
+ }
+
+ public void updateActionBars() {
+ int criteria = navigator.getComparator().getCriteria();
+ sortByNameAction.setChecked(criteria == ResourceComparator.NAME);
+ sortByTypeAction.setChecked(criteria == ResourceComparator.TYPE);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/SortViewAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/SortViewAction.java
new file mode 100644
index 0000000..c2da71a
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/SortViewAction.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demio.views.nav;
+
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
+
+/**
+ * Implementation of the view sorting actions.
+ * @since 2.0
+ */
+public class SortViewAction extends ResourceNavigatorAction {
+ private int sortCriteria;
+
+ /**
+ * Creates the action.
+ *
+ * @param navigator the resource navigator
+ * @param sortByType <code>true</code> for sort by type, <code>false</code> for sort by name
+ */
+ public SortViewAction(IResourceNavigator navigator, boolean sortByType) {
+ super(
+ navigator,
+ sortByType ? ResourceNavigatorMessages.SortView_byType : ResourceNavigatorMessages.SortView_byName);
+ if (sortByType) {
+ setToolTipText(ResourceNavigatorMessages.SortView_toolTipByType);
+ } else {
+ setToolTipText(ResourceNavigatorMessages.SortView_toolTipByName);
+ }
+ setEnabled(true);
+ sortCriteria = sortByType ? ResourceComparator.TYPE : ResourceComparator.NAME;
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
+ INavigatorHelpContextIds.SORT_VIEW_ACTION);
+ }
+
+ public void run() {
+ IResourceNavigator navigator = getNavigator();
+ ResourceComparator comparator = navigator.getComparator();
+
+ if (comparator == null) {
+ navigator.setComparator(new ResourceComparator(sortCriteria));
+ } else {
+ comparator.setCriteria(sortCriteria);
+ navigator.setComparator(comparator);
+ }
+
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/StringMatcher.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/StringMatcher.java
new file mode 100644
index 0000000..f9acac2
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/StringMatcher.java
@@ -0,0 +1,449 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.e4.demio.views.nav;
+
+import java.util.Vector;
+
+/**
+ * A string pattern matcher, suppporting ?*? and ??? wildcards.
+ */
+/* package */class StringMatcher {
+ protected String fPattern;
+
+ protected int fLength; // pattern length
+
+ protected boolean fIgnoreWildCards;
+
+ protected boolean fIgnoreCase;
+
+ protected boolean fHasLeadingStar;
+
+ protected boolean fHasTrailingStar;
+
+ protected String fSegments[]; //the given pattern is split into * separated segments
+
+ /* boundary value beyond which we don't need to search in the text */
+ protected int fBound = 0;
+
+ protected static final char fSingleWildCard = '\u0000';
+
+ public static class Position {
+ int start; //inclusive
+
+ int end; //exclusive
+
+ public Position(int start, int end) {
+ this.start = start;
+ this.end = end;
+ }
+
+ public int getStart() {
+ return start;
+ }
+
+ public int getEnd() {
+ return end;
+ }
+ }
+
+ /**
+ * StringMatcher constructor takes in a String object that is a simple
+ * pattern which may contain '*' for 0 and many characters and
+ * '?' for exactly one character.
+ *
+ * Literal '*' and '?' characters must be escaped in the pattern
+ * e.g., "\*" means literal "*", etc.
+ *
+ * Escaping any other character (including the escape character itself),
+ * just results in that character in the pattern.
+ * e.g., "\a" means "a" and "\\" means "\"
+ *
+ * If invoking the StringMatcher with string literals in Java, don't forget
+ * escape characters are represented by "\\".
+ *
+ * @param pattern the pattern to match text against
+ * @param ignoreCase if true, case is ignored
+ * @param ignoreWildCards if true, wild cards and their escape sequences are ignored
+ * (everything is taken literally).
+ */
+ public StringMatcher(String pattern, boolean ignoreCase,
+ boolean ignoreWildCards) {
+ if (pattern == null) {
+ throw new IllegalArgumentException();
+ }
+ fIgnoreCase = ignoreCase;
+ fIgnoreWildCards = ignoreWildCards;
+ fPattern = pattern;
+ fLength = pattern.length();
+
+ if (fIgnoreWildCards) {
+ parseNoWildCards();
+ } else {
+ parseWildCards();
+ }
+ }
+
+ /**
+ * Find the first occurrence of the pattern between <code>start</code)(inclusive)
+ * and <code>end</code>(exclusive).
+ * @param <code>text</code>, the String object to search in
+ * @param <code>start</code>, the starting index of the search range, inclusive
+ * @param <code>end</code>, the ending index of the search range, exclusive
+ * @return an <code>StringMatcher.Position</code> object that keeps the starting
+ * (inclusive) and ending positions (exclusive) of the first occurrence of the
+ * pattern in the specified range of the text; return null if not found or subtext
+ * is empty (start==end). A pair of zeros is returned if pattern is empty string
+ * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc"
+ * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned
+ */
+ public StringMatcher.Position find(String text, int start, int end) {
+ if (text == null) {
+ throw new IllegalArgumentException();
+ }
+
+ int tlen = text.length();
+ if (start < 0) {
+ start = 0;
+ }
+ if (end > tlen) {
+ end = tlen;
+ }
+ if (end < 0 || start >= end) {
+ return null;
+ }
+ if (fLength == 0) {
+ return new Position(start, start);
+ }
+ if (fIgnoreWildCards) {
+ int x = posIn(text, start, end);
+ if (x < 0) {
+ return null;
+ }
+ return new Position(x, x + fLength);
+ }
+
+ int segCount = fSegments.length;
+ if (segCount == 0) {
+ return new Position(start, end);
+ }
+
+ int curPos = start;
+ int matchStart = -1;
+ int i;
+ for (i = 0; i < segCount && curPos < end; ++i) {
+ String current = fSegments[i];
+ int nextMatch = regExpPosIn(text, curPos, end, current);
+ if (nextMatch < 0) {
+ return null;
+ }
+ if (i == 0) {
+ matchStart = nextMatch;
+ }
+ curPos = nextMatch + current.length();
+ }
+ if (i < segCount) {
+ return null;
+ }
+ return new Position(matchStart, curPos);
+ }
+
+ /**
+ * match the given <code>text</code> with the pattern
+ * @return true if matched eitherwise false
+ * @param <code>text</code>, a String object
+ */
+ public boolean match(String text) {
+ return match(text, 0, text.length());
+ }
+
+ /**
+ * Given the starting (inclusive) and the ending (exclusive) poisitions in the
+ * <code>text</code>, determine if the given substring matches with aPattern
+ * @return true if the specified portion of the text matches the pattern
+ * @param String <code>text</code>, a String object that contains the substring to match
+ * @param int <code>start<code> marks the starting position (inclusive) of the substring
+ * @param int <code>end<code> marks the ending index (exclusive) of the substring
+ */
+ public boolean match(String text, int start, int end) {
+ if (null == text) {
+ throw new IllegalArgumentException();
+ }
+
+ if (start > end) {
+ return false;
+ }
+
+ if (fIgnoreWildCards) {
+ return (end - start == fLength)
+ && fPattern.regionMatches(fIgnoreCase, 0, text, start,
+ fLength);
+ }
+ int segCount = fSegments.length;
+ if (segCount == 0 && (fHasLeadingStar || fHasTrailingStar)) {
+ return true;
+ }
+ if (start == end) {
+ return fLength == 0;
+ }
+ if (fLength == 0) {
+ return start == end;
+ }
+
+ int tlen = text.length();
+ if (start < 0) {
+ start = 0;
+ }
+ if (end > tlen) {
+ end = tlen;
+ }
+
+ int tCurPos = start;
+ int bound = end - fBound;
+ if (bound < 0) {
+ return false;
+ }
+ int i = 0;
+ String current = fSegments[i];
+ int segLength = current.length();
+
+ /* process first segment */
+ if (!fHasLeadingStar) {
+ if (!regExpRegionMatches(text, start, current, 0, segLength)) {
+ return false;
+ } else {
+ ++i;
+ tCurPos = tCurPos + segLength;
+ }
+ }
+ if ((fSegments.length == 1) && (!fHasLeadingStar)
+ && (!fHasTrailingStar)) {
+ // only one segment to match, no wildcards specified
+ return tCurPos == end;
+ }
+ /* process middle segments */
+ for (; i < segCount && tCurPos <= bound; ++i) {
+ current = fSegments[i];
+ int currentMatch;
+ int k = current.indexOf(fSingleWildCard);
+ if (k < 0) {
+ currentMatch = textPosIn(text, tCurPos, end, current);
+ if (currentMatch < 0) {
+ return false;
+ }
+ } else {
+ currentMatch = regExpPosIn(text, tCurPos, end, current);
+ if (currentMatch < 0) {
+ return false;
+ }
+ }
+ tCurPos = currentMatch + current.length();
+ }
+
+ /* process final segment */
+ if (!fHasTrailingStar && tCurPos != end) {
+ int clen = current.length();
+ return regExpRegionMatches(text, end - clen, current, 0, clen);
+ }
+ return i == segCount;
+ }
+
+ /**
+ * This method parses the given pattern into segments seperated by wildcard '*' characters.
+ * Since wildcards are not being used in this case, the pattern consists of a single segment.
+ */
+ private void parseNoWildCards() {
+ fSegments = new String[1];
+ fSegments[0] = fPattern;
+ fBound = fLength;
+ }
+
+ /**
+ * Parses the given pattern into segments seperated by wildcard '*' characters.
+ * @param p, a String object that is a simple regular expression with '*' and/or '?'
+ */
+ private void parseWildCards() {
+ if (fPattern.startsWith("*")) { //$NON-NLS-1$
+ fHasLeadingStar = true;
+ }
+ if (fPattern.endsWith("*")) {//$NON-NLS-1$
+ /* make sure it's not an escaped wildcard */
+ if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') {
+ fHasTrailingStar = true;
+ }
+ }
+
+ Vector temp = new Vector();
+
+ int pos = 0;
+ StringBuffer buf = new StringBuffer();
+ while (pos < fLength) {
+ char c = fPattern.charAt(pos++);
+ switch (c) {
+ case '\\':
+ if (pos >= fLength) {
+ buf.append(c);
+ } else {
+ char next = fPattern.charAt(pos++);
+ /* if it's an escape sequence */
+ if (next == '*' || next == '?' || next == '\\') {
+ buf.append(next);
+ } else {
+ /* not an escape sequence, just insert literally */
+ buf.append(c);
+ buf.append(next);
+ }
+ }
+ break;
+ case '*':
+ if (buf.length() > 0) {
+ /* new segment */
+ temp.addElement(buf.toString());
+ fBound += buf.length();
+ buf.setLength(0);
+ }
+ break;
+ case '?':
+ /* append special character representing single match wildcard */
+ buf.append(fSingleWildCard);
+ break;
+ default:
+ buf.append(c);
+ }
+ }
+
+ /* add last buffer to segment list */
+ if (buf.length() > 0) {
+ temp.addElement(buf.toString());
+ fBound += buf.length();
+ }
+
+ fSegments = new String[temp.size()];
+ temp.copyInto(fSegments);
+ }
+
+ /**
+ * @param <code>text</code>, a string which contains no wildcard
+ * @param <code>start</code>, the starting index in the text for search, inclusive
+ * @param <code>end</code>, the stopping point of search, exclusive
+ * @return the starting index in the text of the pattern , or -1 if not found
+ */
+ protected int posIn(String text, int start, int end) {//no wild card in pattern
+ int max = end - fLength;
+
+ if (!fIgnoreCase) {
+ int i = text.indexOf(fPattern, start);
+ if (i == -1 || i > max) {
+ return -1;
+ }
+ return i;
+ }
+
+ for (int i = start; i <= max; ++i) {
+ if (text.regionMatches(true, i, fPattern, 0, fLength)) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * @param <code>text</code>, a simple regular expression that may only contain '?'(s)
+ * @param <code>start</code>, the starting index in the text for search, inclusive
+ * @param <code>end</code>, the stopping point of search, exclusive
+ * @param <code>p</code>, a simple regular expression that may contains '?'
+ * @param <code>caseIgnored</code>, wether the pattern is not casesensitive
+ * @return the starting index in the text of the pattern , or -1 if not found
+ */
+ protected int regExpPosIn(String text, int start, int end, String p) {
+ int plen = p.length();
+
+ int max = end - plen;
+ for (int i = start; i <= max; ++i) {
+ if (regExpRegionMatches(text, i, p, 0, plen)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ *
+ * @return boolean
+ * @param <code>text</code>, a String to match
+ * @param <code>start</code>, int that indicates the starting index of match, inclusive
+ * @param <code>end</code> int that indicates the ending index of match, exclusive
+ * @param <code>p</code>, String, String, a simple regular expression that may contain '?'
+ * @param <code>ignoreCase</code>, boolean indicating wether code>p</code> is case sensitive
+ */
+ protected boolean regExpRegionMatches(String text, int tStart, String p,
+ int pStart, int plen) {
+ while (plen-- > 0) {
+ char tchar = text.charAt(tStart++);
+ char pchar = p.charAt(pStart++);
+
+ /* process wild cards */
+ if (!fIgnoreWildCards) {
+ /* skip single wild cards */
+ if (pchar == fSingleWildCard) {
+ continue;
+ }
+ }
+ if (pchar == tchar) {
+ continue;
+ }
+ if (fIgnoreCase) {
+ if (Character.toUpperCase(tchar) == Character
+ .toUpperCase(pchar)) {
+ continue;
+ }
+ // comparing after converting to upper case doesn't handle all cases;
+ // also compare after converting to lower case
+ if (Character.toLowerCase(tchar) == Character
+ .toLowerCase(pchar)) {
+ continue;
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @param <code>text</code>, the string to match
+ * @param <code>start</code>, the starting index in the text for search, inclusive
+ * @param <code>end</code>, the stopping point of search, exclusive
+ * @param code>p</code>, a string that has no wildcard
+ * @param <code>ignoreCase</code>, boolean indicating wether code>p</code> is case sensitive
+ * @return the starting index in the text of the pattern , or -1 if not found
+ */
+ protected int textPosIn(String text, int start, int end, String p) {
+
+ int plen = p.length();
+ int max = end - plen;
+
+ if (!fIgnoreCase) {
+ int i = text.indexOf(p, start);
+ if (i == -1 || i > max) {
+ return -1;
+ }
+ return i;
+ }
+
+ for (int i = 0; i <= max; ++i) {
+ if (text.regionMatches(true, i, p, 0, plen)) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ToggleLinkingAction.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ToggleLinkingAction.java
new file mode 100644
index 0000000..54b0539
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/ToggleLinkingAction.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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.e4.demio.views.nav;
+
+/**
+ * This action toggles whether this navigator links its selection to the active
+ * editor.
+ *
+ * @since 2.1
+ */
+public class ToggleLinkingAction extends ResourceNavigatorAction {
+
+ private static final String COMMAND_ID = "org.eclipse.ui.navigate.linkWithEditor"; //$NON-NLS-1$
+
+ /**
+ * Constructs a new action.
+ */
+ public ToggleLinkingAction(IResourceNavigator navigator, String label) {
+ super(navigator, label);
+ setActionDefinitionId(COMMAND_ID);
+ setChecked(navigator.isLinkingEnabled());
+ }
+
+ /**
+ * Runs the action.
+ */
+ public void run() {
+ getNavigator().setLinkingEnabled(isChecked());
+ }
+
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/WorkspaceActionGroup.java b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/WorkspaceActionGroup.java
new file mode 100644
index 0000000..2b20d4d
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/WorkspaceActionGroup.java
@@ -0,0 +1,264 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * Sebastian Davids <sdavids@gmx.de> - Images for menu items (27481)
+ *******************************************************************************/
+package org.eclipse.e4.demio.views.nav;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Iterator;
+
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.window.IShellProvider;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.BuildAction;
+import org.eclipse.ui.actions.CloseResourceAction;
+import org.eclipse.ui.actions.CloseUnrelatedProjectsAction;
+import org.eclipse.ui.actions.OpenResourceAction;
+import org.eclipse.ui.actions.RefreshAction;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.ide.IDEActionFactory;
+import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
+import org.eclipse.ui.internal.ide.StatusUtil;
+
+/**
+ * This is the action group for workspace actions such as Build, Refresh Local,
+ * and Open/Close Project.
+ */
+public class WorkspaceActionGroup extends ResourceNavigatorActionGroup {
+
+ private BuildAction buildAction;
+
+ private OpenResourceAction openProjectAction;
+
+ private CloseResourceAction closeProjectAction;
+
+ private CloseUnrelatedProjectsAction closeUnrelatedProjectsAction;
+
+ private RefreshAction refreshAction;
+
+ public WorkspaceActionGroup(IResourceNavigator navigator) {
+ super(navigator);
+ }
+
+ public void fillActionBars(IActionBars actionBars) {
+ actionBars.setGlobalActionHandler(ActionFactory.REFRESH.getId(),
+ refreshAction);
+ actionBars.setGlobalActionHandler(IDEActionFactory.BUILD_PROJECT
+ .getId(), buildAction);
+ actionBars.setGlobalActionHandler(
+ IDEActionFactory.OPEN_PROJECT.getId(), openProjectAction);
+ actionBars.setGlobalActionHandler(IDEActionFactory.CLOSE_PROJECT
+ .getId(), closeProjectAction);
+ actionBars.setGlobalActionHandler(IDEActionFactory.CLOSE_UNRELATED_PROJECTS
+ .getId(), closeUnrelatedProjectsAction);
+ }
+
+ /**
+ * Adds the build, open project, close project and refresh resource
+ * actions to the context menu.
+ * <p>
+ * The following conditions apply:
+ * build-only projects selected, auto build disabled, at least one
+ * builder present
+ * open project-only projects selected, at least one closed project
+ * close project-only projects selected, at least one open project
+ * refresh-no closed project selected
+ * </p>
+ * <p>
+ * Both the open project and close project action may be on the menu
+ * at the same time.
+ * </p>
+ * <p>
+ * No disabled action should be on the context menu.
+ * </p>
+ *
+ * @param menu context menu to add actions to
+ */
+ public void fillContextMenu(IMenuManager menu) {
+ IStructuredSelection selection = (IStructuredSelection) getContext()
+ .getSelection();
+ boolean isProjectSelection = true;
+ boolean hasOpenProjects = false;
+ boolean hasClosedProjects = false;
+ boolean hasBuilder = true; // false if any project is closed or does not have builder
+ Iterator resources = selection.iterator();
+
+ while (resources.hasNext()
+ && (!hasOpenProjects || !hasClosedProjects || hasBuilder || isProjectSelection)) {
+ Object next = resources.next();
+ IProject project = null;
+
+ if (next instanceof IProject) {
+ project = (IProject) next;
+ } else if (next instanceof IAdaptable) {
+ project = (IProject) ((IAdaptable) next)
+ .getAdapter(IProject.class);
+ }
+
+ if (project == null) {
+ isProjectSelection = false;
+ continue;
+ }
+ if (project.isOpen()) {
+ hasOpenProjects = true;
+ if (hasBuilder && !hasBuilder(project)) {
+ hasBuilder = false;
+ }
+ } else {
+ hasClosedProjects = true;
+ hasBuilder = false;
+ }
+ }
+ if (!selection.isEmpty() && isProjectSelection
+ && !ResourcesPlugin.getWorkspace().isAutoBuilding()
+ && hasBuilder) {
+ // Allow manual incremental build only if auto build is off.
+ buildAction.selectionChanged(selection);
+ menu.add(buildAction);
+ }
+ if (!hasClosedProjects) {
+ refreshAction.selectionChanged(selection);
+ menu.add(refreshAction);
+ }
+ if (isProjectSelection) {
+ if (hasClosedProjects) {
+ openProjectAction.selectionChanged(selection);
+ menu.add(openProjectAction);
+ }
+ if (hasOpenProjects) {
+ closeProjectAction.selectionChanged(selection);
+ menu.add(closeProjectAction);
+ closeUnrelatedProjectsAction.selectionChanged(selection);
+ menu.add(closeUnrelatedProjectsAction);
+ }
+ }
+ }
+
+ /**
+ * Handles a key pressed event by invoking the appropriate action.
+ */
+ public void handleKeyPressed(KeyEvent event) {
+ if (event.keyCode == SWT.F5 && event.stateMask == 0) {
+ if (refreshAction.isEnabled()) {
+ refreshAction.refreshAll();
+ }
+
+ // Swallow the event
+ event.doit = false;
+ }
+ }
+
+ /**
+ * Returns whether there are builders configured on the given project.
+ *
+ * @return <code>true</code> if it has builders,
+ * <code>false</code> if not, or if this could not be determined
+ */
+ boolean hasBuilder(IProject project) {
+ try {
+ ICommand[] commands = project.getDescription().getBuildSpec();
+ if (commands.length > 0) {
+ return true;
+ }
+ } catch (CoreException e) {
+ // Cannot determine if project has builders. Project is closed
+ // or does not exist. Fall through to return false.
+ }
+ return false;
+ }
+
+ protected void makeActions() {
+ final IShellProvider provider = navigator.getSite();
+ openProjectAction = new OpenResourceAction(provider);
+ closeProjectAction = new CloseResourceAction(provider);
+ closeUnrelatedProjectsAction = new CloseUnrelatedProjectsAction(provider);
+ refreshAction = new RefreshAction(provider) {
+ public void run() {
+ final IStatus[] errorStatus = new IStatus[1];
+ errorStatus[0] = Status.OK_STATUS;
+ final WorkspaceModifyOperation op = (WorkspaceModifyOperation) createOperation(errorStatus);
+ WorkspaceJob job = new WorkspaceJob("refresh") { //$NON-NLS-1$
+
+ public IStatus runInWorkspace(IProgressMonitor monitor)
+ throws CoreException {
+ try {
+ op.run(monitor);
+ Shell shell = provider.getShell();
+ if (shell != null && !shell.isDisposed()) {
+ shell.getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ TreeViewer viewer = navigator
+ .getViewer();
+ if (viewer != null
+ && viewer.getControl() != null
+ && !viewer.getControl()
+ .isDisposed()) {
+ viewer.refresh();
+ }
+ }
+ });
+ }
+ } catch (InvocationTargetException e) {
+ String msg = NLS.bind(
+ IDEWorkbenchMessages.WorkspaceAction_logTitle, getClass()
+ .getName(), e.getTargetException());
+ throw new CoreException(StatusUtil.newStatus(IStatus.ERROR,
+ msg, e.getTargetException()));
+ } catch (InterruptedException e) {
+ return Status.CANCEL_STATUS;
+ }
+ return errorStatus[0];
+ }
+
+ };
+ ISchedulingRule rule = op.getRule();
+ if (rule != null) {
+ job.setRule(rule);
+ }
+ job.setUser(true);
+ job.schedule();
+ }
+ };
+ refreshAction
+ .setDisabledImageDescriptor(getImageDescriptor("dlcl16/refresh_nav.gif"));//$NON-NLS-1$
+ refreshAction
+ .setImageDescriptor(getImageDescriptor("elcl16/refresh_nav.gif"));//$NON-NLS-1$
+ buildAction = new BuildAction(provider,
+ IncrementalProjectBuilder.INCREMENTAL_BUILD);
+ }
+
+ public void updateActionBars() {
+ IStructuredSelection selection = (IStructuredSelection) getContext()
+ .getSelection();
+ refreshAction.selectionChanged(selection);
+ buildAction.selectionChanged(selection);
+ openProjectAction.selectionChanged(selection);
+ closeUnrelatedProjectsAction.selectionChanged(selection);
+ closeProjectAction.selectionChanged(selection);
+ }
+}
diff --git a/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/package.html b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/package.html
new file mode 100644
index 0000000..c0507a1
--- /dev/null
+++ b/examples/org.eclipse.e4.demo.views/src/org/eclipse/e4/demio/views/nav/package.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="IBM">
+ <meta name="GENERATOR" content="Mozilla/4.5 [en] (Win98; I) [Netscape]">
+ <title>Package-level Javadoc</title>
+</head>
+<body>
+Provides the standard Resource Navigator view which
+presents the tree of resources in the workspace.
+<br>
+</body>
+</html>
diff --git a/examples/org.eclipse.e4.ui.examples.css.nebula/.classpath b/examples/org.eclipse.e4.ui.examples.css.nebula/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.css.nebula/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.ui.examples.css.nebula/.project b/examples/org.eclipse.e4.ui.examples.css.nebula/.project
new file mode 100644
index 0000000..6c802f9
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.css.nebula/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.ui.examples.css.nebula</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.ui.examples.css.nebula/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.ui.examples.css.nebula/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..8a79738
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.css.nebula/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Wed Jan 28 18:12:20 EST 2009
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
diff --git a/examples/org.eclipse.e4.ui.examples.css.nebula/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.ui.examples.css.nebula/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..48d2d30
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.css.nebula/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Nebula CSS example (Incubation)
+Bundle-SymbolicName: org.eclipse.e4.ui.examples.css.nebula
+Bundle-Version: 0.9.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.swt;bundle-version="3.5.0",
+ org.eclipse.e4.ui.css.core;bundle-version="0.9.0",
+ org.eclipse.e4.ui.css.swt;bundle-version="0.9.0",
+ org.eclipse.e4.ui.examples.css;bundle-version="0.9.0",
+ org.eclipse.e4.ui.css.nebula;bundle-version="0.9.0",
+ org.eclipse.nebula.widgets.gallery;bundle-version="1.0.0",
+ org.apache.batik.css;bundle-version="[1.6.0,1.7.0)",
+ org.apache.batik.util;bundle-version="[1.6.0,1.7.0)",
+ org.apache.batik.util.gui;bundle-version="[1.6.0,1.7.0)",
+ org.apache.batik.xml;bundle-version="[1.6.0,1.7.0)"
diff --git a/examples/org.eclipse.e4.ui.examples.css.nebula/build.properties b/examples/org.eclipse.e4.ui.examples.css.nebula/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.css.nebula/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/examples/org.eclipse.e4.ui.examples.css.nebula/src/org/eclipse/e4/ui/examples/css/nebula/AbstractCSSNebulaEditor.java b/examples/org.eclipse.e4.ui.examples.css.nebula/src/org/eclipse/e4/ui/examples/css/nebula/AbstractCSSNebulaEditor.java
new file mode 100644
index 0000000..b189dd7
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.css.nebula/src/org/eclipse/e4/ui/examples/css/nebula/AbstractCSSNebulaEditor.java
@@ -0,0 +1,30 @@
+package org.eclipse.e4.ui.examples.css.nebula;
+
+import org.eclipse.e4.ui.css.core.dom.IElementProvider;
+import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.css.nebula.dom.NebulaElementProvider;
+import org.eclipse.e4.ui.css.nebula.engine.CSSNebulaEngineImpl;
+import org.eclipse.e4.ui.examples.css.editor.AbstractCSSSWTEditor;
+
+/**
+ * Abstract CSS SWT Editor.
+ */
+public abstract class AbstractCSSNebulaEditor extends AbstractCSSSWTEditor {
+
+ public AbstractCSSNebulaEditor() {
+ super("nebula", null);
+ }
+
+ protected CSSEngine createCSSEngine() {
+ return new CSSNebulaEngineImpl(shell.getDisplay());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.e4.ui.core.css.examples.csseditors.AbstractCSSEditor#getNativeWidgetElementProvider()
+ */
+ protected IElementProvider getNativeWidgetElementProvider() {
+ return NebulaElementProvider.INSTANCE;
+ }
+}
diff --git a/examples/org.eclipse.e4.ui.examples.css.nebula/src/org/eclipse/e4/ui/examples/css/nebula/CSSEditorNebulaGallery.java b/examples/org.eclipse.e4.ui.examples.css.nebula/src/org/eclipse/e4/ui/examples/css/nebula/CSSEditorNebulaGallery.java
new file mode 100644
index 0000000..8bad973
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.css.nebula/src/org/eclipse/e4/ui/examples/css/nebula/CSSEditorNebulaGallery.java
@@ -0,0 +1,67 @@
+package org.eclipse.e4.ui.examples.css.nebula;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.nebula.widgets.gallery.DefaultGalleryGroupRenderer;
+import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer;
+import org.eclipse.nebula.widgets.gallery.Gallery;
+import org.eclipse.nebula.widgets.gallery.GalleryItem;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.program.Program;
+import org.eclipse.swt.widgets.Composite;
+
+public class CSSEditorNebulaGallery extends AbstractCSSNebulaEditor {
+
+ public void createContent(Composite parent) {
+
+ Image itemImage = new Image(parent.getDisplay(), Program.findProgram(
+ "jpg").getImageData());
+ Gallery gallery = new Gallery(parent, SWT.V_SCROLL | SWT.MULTI);
+
+ // Renderers
+ DefaultGalleryGroupRenderer gr = new DefaultGalleryGroupRenderer();
+ gr.setMinMargin(2);
+ gr.setItemHeight(56);
+ gr.setItemWidth(72);
+ gr.setAutoMargin(true);
+ gallery.setGroupRenderer(gr);
+
+ DefaultGalleryItemRenderer ir = new DefaultGalleryItemRenderer();
+ gallery.setItemRenderer(ir);
+
+ int nbGalleryItemSelected = 0;
+ int nbTotalGalleryItemSelected = 2;
+ List selectedItems = new ArrayList();
+
+ for (int g = 0; g < 2; g++) {
+ GalleryItem group = new GalleryItem(gallery, SWT.NONE);
+ group.setText("Group " + g);
+ group.setExpanded(true);
+
+ for (int i = 0; i < 50; i++) {
+ GalleryItem item = new GalleryItem(group, SWT.NONE);
+ if (nbGalleryItemSelected < nbTotalGalleryItemSelected) {
+ nbGalleryItemSelected++;
+ selectedItems.add(item);
+ }
+ if (itemImage != null) {
+ item.setImage(itemImage);
+ }
+ item.setText("Item " + i);
+ }
+ }
+ gallery.setSelection((GalleryItem[]) selectedItems
+ .toArray(new GalleryItem[0]));
+
+ // if (itemImage != null)
+ // itemImage.dispose();
+ // display.dispose();
+ }
+
+ public static void main(String[] args) {
+ CSSEditorNebulaGallery editor = new CSSEditorNebulaGallery();
+ editor.display();
+ }
+}
diff --git a/examples/org.eclipse.e4.ui.examples.css.nebula/styles/nebula/Gallery.css b/examples/org.eclipse.e4.ui.examples.css.nebula/styles/nebula/Gallery.css
new file mode 100644
index 0000000..27dec93
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.css.nebula/styles/nebula/Gallery.css
@@ -0,0 +1,14 @@
+GalleryItem {
+ color: gray;
+ background-color: #D0D0B0;
+}
+
+GalleryItem:selected {
+ color: purple;
+ background-color:orange;
+ font:bold;
+}
+
+Gallery {
+ background-color: #F3F3E3;
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/.classpath b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/.project b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.project
new file mode 100644
index 0000000..ef93968
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.ui.examples.legacy.workbench</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.core.prefs b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..58c5f8b
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,108 @@
+#Fri Feb 13 13:56:23 EST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=error
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=error
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unsafeTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.launching.prefs b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.launching.prefs
new file mode 100644
index 0000000..c73f9ad
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.launching.prefs
@@ -0,0 +1,3 @@
+#Fri Feb 13 13:56:23 EST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..5b675a9
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,61 @@
+#Fri Feb 13 13:56:23 EST 2009
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=false
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=false
+cleanup.format_source_code=false
+cleanup.format_source_code_changes_only=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=false
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_trailing_whitespaces=false
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_blocks=false
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_this_for_non_static_field_access=false
+cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup_profile=org.eclipse.jdt.ui.default.eclipse_clean_up_profile
+cleanup_settings_version=2
+eclipse.preferences.version=1
+formatter_settings_version=11
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.javadoc=true
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/*******************************************************************************\n * Copyright (c) ${year} IBM Corporation and others.\n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n * IBM Corporation - initial API and implementation\n ******************************************************************************/\n</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/META-INF/MANIFEST.MF b/examples/org.eclipse.e4.ui.examples.legacy.workbench/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..19c7ef9
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/META-INF/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.e4.ui.examples.legacy.workbench;singleton:=true
+Bundle-Version: 0.9.1.qualifier
+Bundle-Activator: org.eclipse.e4.ui.examples.legacy.workbench.Activator
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.e4.ui.workbench,
+ org.eclipse.e4.core.services;bundle-version="0.9.0",
+ org.eclipse.core.resources;bundle-version="3.5.0",
+ org.eclipse.e4.ui.css.core;bundle-version="0.9.0",
+ org.w3c.css.sac;bundle-version="1.3.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.e4.ui.examples.legacy.workbench
+Import-Package: org.eclipse.e4.core.contexts
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/about.html b/examples/org.eclipse.e4.ui.examples.legacy.workbench/about.html
new file mode 100644
index 0000000..4602330
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 2, 2006</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/build.properties b/examples/org.eclipse.e4.ui.examples.legacy.workbench/build.properties
new file mode 100644
index 0000000..6ee7fb2
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/build.properties
@@ -0,0 +1,29 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ css/,\
+ plugin_customization.ini,\
+ plugin_customization.properties,\
+ eclipse.gif,\
+ eclipse.png,\
+ eclipse24.gif,\
+ eclipse32.gif,\
+ eclipse32.png,\
+ eclipse48.gif,\
+ eclipse48.png,\
+ eclipse_lg.gif,\
+ about.html,\
+ introData.xml,\
+ intro-eclipse.png,\
+ plugin.properties,\
+ splash/,\
+ splash.bmp
+src.includes = src/,\
+ plugin.xml,\
+ about.html,\
+ css/,\
+ p2.inf,\
+ legacy-eclipse.product,\
+ plugin.properties
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/css/webby.css b/examples/org.eclipse.e4.ui.examples.legacy.workbench/css/webby.css
new file mode 100644
index 0000000..4660676
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/css/webby.css
@@ -0,0 +1,87 @@
+ETabFolder {
+ background-color: rgb(246, 246, 251);
+ simple: true;
+ maximize-visible: false;
+ minimize-visible: false;
+ webby-style: true;
+ margin: 2px;
+ tab-margin-offset: 4px;
+
+ border-color: rgb(201, 200, 204)
+/* Can be expressed individually
+ border-top-color: rgb(201, 200, 204);
+ border-bottom-color: rgb(201, 200, 204);
+*/
+}
+
+ETabFolder.active {
+ background-color: rgb(224, 226, 235);
+}
+
+ETabItem {
+ color: black;
+ background-color: rgb(241, 240, 245); /* unselected tabs can have diff color than folder background */
+ padding-top: 4px;
+ padding-bottom: 4px;
+ margin-top: 3px;
+ margin-left: 2px;
+ margin-right: 0px;
+ border-color: rgb(208, 207, 212);
+}
+
+ETabItem:selected {
+ background-color: rgb(255, 255, 255) rgb(246, 245, 250);
+ padding-top: 7px; /* make the selected tab a bit taller */
+}
+
+ETabItem.active {
+ background-color: rgb(241, 240, 245);
+}
+
+ETabItem.active:selected {
+ background-color: rgb(255, 255, 255) rgb(255, 247, 229);
+}
+
+#PerspectiveStack {
+ background-color: rgb(241, 240, 245);
+ margin: 0px;
+ tab-margin-offset: 9px;
+}
+
+#PerspectiveStack > ETabItem {
+ background-color: rgb(246, 246, 251);
+ padding-top: 4px;
+ padding-bottom: 2px;
+ margin-top: 0px;
+}
+
+#PerspectiveStack > ETabItem:selected {
+ margin-top: 0px;
+}
+
+#PerspectiveStack > ETabItem.active {
+ background-color: rgb(241, 240, 245);
+}
+
+#PerspectiveStack > ETabItem.active:selected {
+ background-color: rgb(255, 255, 255) rgb(246, 245, 250);
+}
+
+.perspectiveLayout, .marginWrapper {
+ background-color: rgb(241, 240, 245);
+}
+
+ToolBar.inactive {
+ background-color: rgb(246, 246, 251);
+}
+
+ToolBar.active {
+ background-color: rgb(224, 226, 235);
+}
+
+SashForm {
+ background-color: rgb(241, 240, 245);
+
+Label {
+ background-color: rgb(246, 246, 251);
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/css/xp-silver-legacy.css b/examples/org.eclipse.e4.ui.examples.legacy.workbench/css/xp-silver-legacy.css
new file mode 100644
index 0000000..618dbfd
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/css/xp-silver-legacy.css
@@ -0,0 +1,31 @@
+CTabFolder {
+ font: Tahoma 8px;
+ color: black;
+ background-color: rgb(224, 223, 227);
+ font: normal;
+ simple: false;
+ maximize-visible: true;
+ minimize-visible: true;
+ tab-height: 20;
+}
+
+CTabFolder:selected {
+ background-color: rgb(254, 254, 254) rgb(224, 223, 227);
+}
+
+CTabFolder.active {
+ background-color: rgb(224, 223, 227);
+}
+
+CTabFolder.active:selected {
+ background-color: rgb(237, 237, 237) rgb(192, 192, 192);
+ font: bold;
+}
+
+Text {
+ font: "Courier-New" 10px;
+}
+
+ToolBar {
+ background-color: rgb(224, 223, 227);
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse.gif b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse.gif
new file mode 100644
index 0000000..7d7e32b
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse.png b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse.png
new file mode 100644
index 0000000..25e3bb5
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse.png
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse24.gif b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse24.gif
new file mode 100644
index 0000000..24296ac
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse24.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse32.gif b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse32.gif
new file mode 100644
index 0000000..e6ad7cc
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse32.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse32.png b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse32.png
new file mode 100644
index 0000000..568fac1
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse32.png
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse48.gif b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse48.gif
new file mode 100644
index 0000000..80a40d6
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse48.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse48.png b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse48.png
new file mode 100644
index 0000000..1c939c8
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse48.png
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse_lg.gif b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse_lg.gif
new file mode 100644
index 0000000..bf8b872
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/eclipse_lg.gif
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/intro-eclipse.png b/examples/org.eclipse.e4.ui.examples.legacy.workbench/intro-eclipse.png
new file mode 100644
index 0000000..015e7fc
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/intro-eclipse.png
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/introData.xml b/examples/org.eclipse.e4.ui.examples.legacy.workbench/introData.xml
new file mode 100644
index 0000000..2b1c002
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/introData.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<extensions>
+ <page id="tutorials">
+ <group path="page-content/bottom-left" default="true">
+ </group>
+ <group path="page-content/bottom-right" default="true">
+ </group>
+ <group path="page-content/top-left">
+ <extension id="org.eclipse.jdt" importance="low"/>
+ <extension id="org.eclipse.team" importance="low"/>
+ </group>
+ <group path="page-content/top-right">
+ <extension id="org.eclipse.pde" importance="low"/>
+ </group>
+ </page>
+ <page id="whatsnew">
+ <group path="page-content/bottom-left" default="true">
+ </group>
+ <group path="page-content/bottom-right" default="true">
+ </group>
+ <group path="page-content/top-left">
+ <extension id="org.eclipse.ui.workbench.news" importance="low"/>
+ <extension id="org.eclipse.jdt" importance="low"/>
+ <extension id="org.eclipse.pde.changes" importance="low"/>
+ <extension id="org.eclipse.ui.workbench.migration" importance="callout"/>
+ </group>
+ <group path="page-content/top-right">
+ <extension id="org.eclipse.ui.workbench" importance="low"/>
+ </group>
+ </page>
+ <page id="samples">
+ <group path="page-content/bottom-left" default="true">
+ </group>
+ <group path="page-content/bottom-right" default="true">
+ </group>
+ <group path="page-content/top-left">
+ <extension id="org.eclipse.pde.workbench" importance="low"/>
+ </group>
+ <group path="page-content/top-right">
+ <extension id="org.eclipse.jdt" importance="low"/>
+ <extension id="org.eclipse.pde.swt" importance="low"/>
+ </group>
+ </page>
+ <page id="overview">
+ <group path="page-content/bottom-left" default="true">
+ </group>
+ <group path="page-content/bottom-right" default="true">
+ </group>
+ <group path="page-content/top-left">
+ <extension id="org.eclipse.ui.workbench" importance="low"/>
+ </group>
+ <group path="page-content/top-right">
+ <extension id="org.eclipse.jdt" importance="low"/>
+ <extension id="org.eclipse.pde" importance="low"/>
+ </group>
+ </page>
+</extensions>
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/legacy-eclipse.product b/examples/org.eclipse.e4.ui.examples.legacy.workbench/legacy-eclipse.product
new file mode 100644
index 0000000..00d732d
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/legacy-eclipse.product
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?pde version="3.5"?>
+
+<product name="e4 SDK" uid="org.eclipse.e4.workbench.sdk" id="org.eclipse.e4.ui.examples.legacy.workbench.product" version="0.9.0.@qualifier@" useFeatures="true" includeLaunchers="true">
+
+ <aboutInfo>
+ <image path="/org.eclipse.e4.ui.examples.legacy.workbench/eclipse_lg.gif"/>
+ </aboutInfo>
+
+ <configIni use="default">
+ </configIni>
+
+ <launcherArgs>
+ <programArgs>--launcher.XXMaxPermSize 256m</programArgs>
+ <vmArgs>-Xms256m -Xmx512m</vmArgs>
+ <vmArgsMac>-Xdock:icon=../Resources/Eclipse.icns -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts</vmArgsMac>
+ </launcherArgs>
+
+ <windowImages i16="/org.eclipse.e4.ui.examples.legacy.workbench/eclipse.gif" i32="/org.eclipse.e4.ui.examples.legacy.workbench/eclipse32.gif" i48="/org.eclipse.e4.ui.examples.legacy.workbench/eclipse48.gif"/>
+
+ <splash
+ location="org.eclipse.e4.ui.examples.legacy.workbench" />
+ <launcher name="eclipse">
+ <solaris/>
+ <win useIco="false">
+ <bmp/>
+ </win>
+ </launcher>
+
+ <vm>
+ </vm>
+
+ <plugins>
+ </plugins>
+
+ <features>
+ <feature id="org.eclipse.sdk" version="0.0.0"/>
+ <feature id="org.eclipse.equinox.p2.user.ui" version="0.0.0"/>
+ <feature id="org.eclipse.equinox.p2.user.ui.source" version="0.0.0"/>
+ <feature id="org.eclipse.emf.sdk" version="0.0.0"/>
+ <feature id="org.eclipse.wst.xml_ui.feature" version="0.0.0"/>
+ <feature id="org.eclipse.gef" version="0.0.0"/>
+ <feature id="org.eclipse.rcp.configuration" version="0.0.0"/>
+ <feature id="org.eclipse.e4.sdk.runtime.feature" version="0.0.0"/>
+ <feature id="org.eclipse.e4.sdk.source.feature" version="0.0.0"/>
+ <feature id="org.eclipse.releng.tools" version="0.0.0"/>
+ </features>
+
+ <configurations>
+ <plugin id="org.eclipse.core.runtime" autoStart="true" startLevel="4" />
+ <plugin id="org.eclipse.equinox.common" autoStart="true" startLevel="2" />
+ <plugin id="org.eclipse.equinox.ds" autoStart="true" startLevel="2" />
+ <plugin id="org.eclipse.equinox.p2.reconciler.dropins" autoStart="true" startLevel="4" />
+ <plugin id="org.eclipse.equinox.simpleconfigurator" autoStart="true" startLevel="1" />
+ <plugin id="org.eclipse.update.configurator" autoStart="true" startLevel="3" />
+ <property name="eclipse.buildId" value="@qualifier@"/>
+ </configurations>
+
+</product>
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/p2.inf b/examples/org.eclipse.e4.ui.examples.legacy.workbench/p2.inf
new file mode 100644
index 0000000..9843e61
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/p2.inf
@@ -0,0 +1,60 @@
+instructions.configure=\
+addRepository(type:0,location:http${#58}//download.eclipse.org/eclipse/updates/3.6-I-builds,name:Eclipse 3.6 I-builds);\
+addRepository(type:1,location:http${#58}//download.eclipse.org/eclipse/updates/3.6-I-builds,name:Eclipse 3.6 I-builds);\
+addRepository(type:0,location:http${#58}//download.eclipse.org/modeling/emf/updates/interim,name:EMF I-builds);\
+addRepository(type:1,location:http${#58}//download.eclipse.org/modeling/emf/updates/interim,name:EMF I-builds);\
+addRepository(type:0,location:http${#58}//download.eclipse.org/tools/gef/updates/interim,name:GEF I-builds);\
+addRepository(type:1,location:http${#58}//download.eclipse.org/tools/gef/updates/interim,name:GEF I-builds);\
+addRepository(type:0,location:http${#58}//download.eclipse.org/webtools/downloads/drops/R3.2/S-3.2.0M2-20090924194346/updateSite,name:WTP R3.2 update site);\
+addRepository(type:1,location:http${#58}//download.eclipse.org/webtools/downloads/drops/R3.2/S-3.2.0M2-20090924194346/updateSite,name:WTP R3.2 update site);\
+ mkdir(path:${installFolder}/dropins);
+requires.1.namespace=org.eclipse.equinox.p2.iu
+requires.1.name=toolingorg.eclipse.configuration.macosx
+requires.1.filter=(osgi.os=macosx)
+requires.1.range=[1.0.0,1.0.0]
+requires.1.greedy=true
+
+requires.2.namespace=org.eclipse.equinox.p2.iu
+requires.2.name=toolingorg.eclipse.configuration
+requires.2.filter=(!(osgi.os=macosx))
+requires.2.range=[1.0.0,1.0.0]
+requires.2.greedy=true
+
+requires.3.namespace=org.eclipse.equinox.p2.iu
+requires.3.name=toolingorg.eclipse.configuration.macosx.x86_64
+requires.3.filter=(&(osgi.os=macosx) (osgi.arch=x86_64))
+requires.3.range=[1.0.0,1.0.0]
+requires.3.greedy=true
+
+units.1.id=toolingorg.eclipse.configuration.macosx
+units.1.version=1.0.0
+units.1.provides.1.namespace=org.eclipse.equinox.p2.iu
+units.1.provides.1.name=toolingorg.eclipse.configuration.macosx
+units.1.provides.1.version=1.0.0
+units.1.filter=(osgi.os=macosx)
+units.1.touchpoint.id=org.eclipse.equinox.p2.osgi
+units.1.touchpoint.version=1.0.0
+units.1.instructions.configure=setProgramProperty(propName:osgi.instance.area.default,propValue:@user.home/Documents/workspace);
+units.1.instructions.unconfigure=setProgramProperty(propName:osgi.instance.area.default,propValue:);
+
+units.2.id=toolingorg.eclipse.configuration
+units.2.version=1.0.0
+units.2.provides.1.namespace=org.eclipse.equinox.p2.iu
+units.2.provides.1.name=toolingorg.eclipse.configuration
+units.2.provides.1.version=1.0.0
+units.2.filter=(!(osgi.os=macosx))
+units.2.touchpoint.id=org.eclipse.equinox.p2.osgi
+units.2.touchpoint.version=1.0.0
+units.2.instructions.configure=setProgramProperty(propName:osgi.instance.area.default,propValue:@user.home/workspace);
+units.2.instructions.unconfigure=setProgramProperty(propName:osgi.instance.area.default,propValue:);
+
+units.3.id=toolingorg.eclipse.configuration.macosx.x86_64
+units.3.version=1.0.0
+units.3.provides.1.namespace=org.eclipse.equinox.p2.iu
+units.3.provides.1.name=toolingorg.eclipse.configuration.macosx.x86_64
+units.3.provides.1.version=1.0.0
+units.3.filter=(&(osgi.os=macosx) (osgi.arch=x86_64))
+units.3.touchpoint.id=org.eclipse.equinox.p2.osgi
+units.3.touchpoint.version=1.0.0
+units.3.instructions.configure=addJvmArg(jvmArg:-Xms40m);addJvmArg(jvmArg:-Xmx512m);
+units.3.instructions.unconfigure=removeJvmArg(jvmArg:-Xms40m);removeJvmArg(jvmArg:-Xmx512m);
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin.properties b/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin.properties
new file mode 100644
index 0000000..31761b1
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin.properties
@@ -0,0 +1,27 @@
+pluginName=Eclipse e4 SDK (Incubation)
+providerName=Eclipse.org
+
+productName=e4 SDK
+productBlurb=e4 SDK\n\
+\n\
+Version: July 2010\n\
+Build id: {0}\n\
+\n\
+(c) Copyright Eclipse contributors and others 2000, 2010. All rights reserved.\n\
+Visit http://www.eclipse.org/e4\n\
+\n\
+This product includes software developed by the\n\
+Apache Software Foundation http://www.apache.org/
+
+productIntroTitle = Welcome to e4
+productIntroBrandingText = Eclipse Project
+introDescription-overview = The e4 SDK includes all the software required to develop and run
+experimental technology from the e4 incubator
+introDescription-tutorials = Learn how to be productive using Eclipse by completing end-to-end tutorials that will guide you along the way.
+introDescription-samples = Explore Eclipse by installing prefabricated samples (may require Internet connection).
+
+shortcut.overview.tooltip = Overview
+shortcut.tutorials.tooltip = Tutorials
+shortcut.samples.tooltip = Samples
+shortcut.whatsnew.tooltip = What's New
+
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin.xml b/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin.xml
new file mode 100644
index 0000000..7c36626
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.ui.perspectives">
+ <perspective
+ class="org.eclipse.e4.ui.examples.legacy.workbench.TestPerspectiveFactory"
+ id="org.eclipse.e4.ui.examples.legacy.workbench.perspective"
+ name="Legacy Perspective">
+ </perspective>
+ </extension>
+ <extension
+ id="product"
+ point="org.eclipse.core.runtime.products">
+ <product
+ application="org.eclipse.ui.ide.workbench"
+ name="e4 Compatibility Platform">
+ <property name="windowImages" value="eclipse.gif,eclipse32.gif,eclipse48.gif"/>
+ <property name="aboutImage" value="eclipse_lg.gif"/>
+ <property
+ name="appName"
+ value="e4 Compatibility Platform">
+ </property>
+ <property
+ name="preferenceCustomization"
+ value="plugin_customization.ini">
+ </property>
+ <property
+ name="applicationCSS"
+ value="platform:/plugin/org.eclipse.e4.ui.examples.legacy.workbench/css/webby.css">
+ </property>
+ <property
+ name="introTitle"
+ value="%productIntroTitle"/>
+ <property
+ name="introBrandingImage"
+ value="product:intro-eclipse.png"/>
+ <property
+ name="introBrandingImageText"
+ value="%productIntroBrandingText"/>
+ <property
+ name="introDescription-overview"
+ value="%introDescription-overview"/>
+ <property
+ name="introDescription-tutorials"
+ value="%introDescription-tutorials"/>
+ <property
+ name="introDescription-samples"
+ value="%introDescription-samples"/>
+ <property
+ name="aboutText"
+ value="%productBlurb">
+ </property>
+ </product>
+ </extension>
+ <extension
+ point="org.eclipse.ui.intro">
+ <introProductBinding
+ introId="org.eclipse.ui.intro.universal"
+ productId="org.eclipse.e4.ui.examples.legacy.workbench.product">
+ </introProductBinding>
+ </extension>
+ <extension
+ point="org.eclipse.ui.splashHandlers">
+ <splashHandler
+ class="org.eclipse.e4.ui.examples.legacy.workbench.AnimationSplashHandler"
+ id="org.eclipse.e4.ui.examples.legacy.workbench.splashHandlers.browser">
+ </splashHandler>
+ </extension>
+</plugin>
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin_customization.ini b/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin_customization.ini
new file mode 100644
index 0000000..5f74564
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin_customization.ini
@@ -0,0 +1,41 @@
+# plugin_customization.ini
+# sets default values for plug-in-specific preferences
+# keys are qualified by plug-in id
+# e.g., com.example.acmeplugin/myproperty=myvalue
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# "%key" are externalized strings defined in plugin_customization.properties
+# This file does not need to be translated.
+
+# Property "org.eclipse.ui/defaultPerspectiveId" controls the
+# perspective that the workbench opens initially
+org.eclipse.ui/defaultPerspectiveId=org.eclipse.jdt.ui.JavaPerspective
+#org.eclipse.ui/defaultPerspectiveId=org.eclipse.e4.ui.examples.legacy.workbench.perspective
+
+# new-style tabs by default
+org.eclipse.ui/SHOW_TRADITIONAL_STYLE_TABS=false
+
+# put the perspective switcher on the top right
+org.eclipse.ui/DOCK_PERSPECTIVE_BAR=topRight
+
+# show progress on startup
+org.eclipse.ui/SHOW_PROGRESS_ON_STARTUP = false
+
+# show build id in the splash - only for nightly, integration, and milestone builds
+org.eclipse.ui.workbench/SHOW_BUILDID_ON_STARTUP=true
+
+# use the window set by default
+org.eclipse.ui/USE_WINDOW_WORKING_SET_BY_DEFAULT=true
+
+# Intro-related preferences (since 3.2)
+
+# Welcome theme to use
+org.eclipse.ui.intro/INTRO_THEME = org.eclipse.ui.intro.universal.slate
+
+# Root page links to show in the Universal Welcome
+org.eclipse.ui.intro.universal/INTRO_ROOT_PAGES = overview,tutorials,samples,whatsnew
+
+# Initial page layout of the Universal Welcome
+org.eclipse.ui.intro.universal/INTRO_DATA = product:introData.xml
+
+# Order help books in table of contents
+org.eclipse.help/HELP_DATA = helpData.xml
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin_customization.properties b/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin_customization.properties
new file mode 100644
index 0000000..4943101
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/plugin_customization.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2000, 2005 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
+###############################################################################
+# plugin_customization.properties
+# contains externalized strings for plugin_customization.ini
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash.bmp b/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash.bmp
new file mode 100644
index 0000000..ac8039e
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash.bmp
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash/progress-dark.png b/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash/progress-dark.png
new file mode 100644
index 0000000..65fd673
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash/progress-dark.png
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash/progress-light.png b/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash/progress-light.png
new file mode 100644
index 0000000..8a8f43c
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/splash/progress-light.png
Binary files differ
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/Activator.java b/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/Activator.java
new file mode 100644
index 0000000..b2cdf36
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/Activator.java
@@ -0,0 +1,49 @@
+package org.eclipse.e4.ui.examples.legacy.workbench;
+
+import org.osgi.framework.BundleActivator;
+
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator implements BundleActivator {
+
+ // The bundle id
+ public static final String BUNDLE_ID = "org.eclipse.e4.ui.examples.legacy.workbench"; //$NON-NLS-1$
+
+ // The shared instance
+ private static BundleContext context;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext aContext) throws Exception {
+ context = aContext;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext aContext) throws Exception {
+ context = null;
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static BundleContext getContext() {
+ return context;
+ }
+
+}
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/AnimationSplashHandler.java b/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/AnimationSplashHandler.java
new file mode 100644
index 0000000..8de17b9
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/AnimationSplashHandler.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Benjamin Cabe 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:
+ * Benjamin Cabe - initial API and implementation
+ * IBM Corporation - ongoing development
+ *******************************************************************************/
+package org.eclipse.e4.ui.examples.legacy.workbench;
+
+import java.io.IOException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.ImageLoader;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.splash.AbstractSplashHandler;
+
+/**
+ *
+ */
+public class AnimationSplashHandler extends AbstractSplashHandler {
+
+ private final class BundleProgressMonitor extends NullProgressMonitor {
+ private static final int NB_TICKS = 42;
+ private int worked = 0 ;
+ private int total = 0 ;
+
+ public void worked(int work) {
+ worked++ ;
+ updateProgressBar();
+ }
+
+ public void done() {
+ worked = total ;
+ updateProgressBar();
+ }
+
+ public void beginTask(String name, int totalWork) {
+ // there are exactly 19 bundles being loaded in the legacy workbench as of 20090722
+ // thus, we prefer to use an hardcoded value for the "length" of the monitor, instead of relying
+ // on the arbitrary rule assuming there are 1/10 of the installed bundles which are actually loaded
+ total = 19 ; // total = totalWork ;
+ updateProgressBar();
+ }
+
+ private void updateProgressBar() {
+ int currentImgIdx = (int) (NB_TICKS / (float)total * worked) ;
+ for (int i = 0 ; i < NB_TICKS ; i++) {
+ Image imgToDraw = (i <= currentImgIdx) ? imgProgressDark : imgProgressLight ;
+ synchronized (shellGC) {
+ shellGC.drawImage(imgToDraw, 11 + (11 * i), 292);
+ }
+ }
+ }
+ }
+
+ private Image imgProgressDark = null;
+ private Image imgProgressLight = null;
+
+ private GC shellGC;
+
+ /**
+ *
+ */
+ public AnimationSplashHandler() {
+ super();
+ }
+
+ private void configureUISplash() {
+ getSplash().setSize(480, 320);
+ getSplash().setVisible(true);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.internal.splash.AbstractSplashHandler#init(org.eclipse.swt.widgets.Shell,
+ * org.eclipse.ui.IWorkbench)
+ */
+ public void init(final Shell splash) {
+ // Store the shell
+ super.init(splash);
+ // Load image sequence
+ loadImages();
+ // Configure the shell layout
+ configureUISplash();
+ // Force the UI to layout
+ splash.layout(true);
+ // create the GC we will draw on
+ shellGC = new GC(getSplash());
+ }
+
+ private void loadImages() {
+ ImageLoader loader = new ImageLoader();
+
+ try {
+ ImageData imageDataProgressDark = loader.load(Activator.getContext().getBundle().getEntry("splash/progress-dark.png").openStream())[0];//$NON-NLS-1$
+ ImageData imageDataProgressLight = loader.load(Activator.getContext().getBundle().getEntry("splash/progress-light.png").openStream())[0]; //$NON-NLS-1$
+
+ imgProgressDark = new Image(getSplash().getDisplay(), imageDataProgressDark) ;
+ imgProgressLight = new Image(getSplash().getDisplay(), imageDataProgressLight) ;
+ } catch (IOException e1) {
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.splash.AbstractSplashHandler#getBundleProgressMonitor()
+ */
+ @Override
+ public IProgressMonitor getBundleProgressMonitor() {
+ return new BundleProgressMonitor();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.splash.AbstractSplashHandler#dispose()
+ */
+ public void dispose() {
+ if (shellGC != null) {
+ synchronized (shellGC) {
+ shellGC.dispose();
+ }
+ }
+ if (imgProgressDark != null)
+ imgProgressDark.dispose() ;
+ if (imgProgressLight != null)
+ imgProgressLight.dispose() ;
+
+ super.dispose();
+ }
+}
\ No newline at end of file
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/TestPerspectiveFactory.java b/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/TestPerspectiveFactory.java
new file mode 100755
index 0000000..4b84a00
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/TestPerspectiveFactory.java
@@ -0,0 +1,86 @@
+package org.eclipse.e4.ui.examples.legacy.workbench;
+
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+public class TestPerspectiveFactory implements IPerspectiveFactory {
+
+ public void createInitialLayout(IPageLayout layout) {
+ String editorArea = layout.getEditorArea();
+
+ IFolderLayout folder= layout.createFolder("left", IPageLayout.LEFT, (float)0.25, editorArea); //$NON-NLS-1$
+ //folder.addView("org.eclipse.jdt.ui.PackageExplorer"); //$NON-NLS-1$
+ //folder.addView("org.eclipse.jdt.ui.TypeHierarchy"); //$NON-NLS-1$
+// folder.addView("LegacyViews.ResourceView"); //$NON-NLS-1$
+ //folder.addPlaceholder(IPageLayout.ID_RES_NAV);
+ folder.addPlaceholder("org.eclipse.ui.navigator.ProjectExplorer"); //$NON-NLS-1$
+
+ IFolderLayout outputfolder= layout.createFolder("bottom", IPageLayout.BOTTOM, (float)0.75, editorArea); //$NON-NLS-1$
+ outputfolder.addView(IPageLayout.ID_PROBLEM_VIEW);
+ outputfolder.addView("org.eclipse.jdt.ui.JavadocView"); //$NON-NLS-1$
+ outputfolder.addView("org.eclipse.team.ccvs.ui.RepositoriesView"); //$NON-NLS-1$
+ outputfolder.addView("org.eclipse.debug.ui.DebugView"); //$NON-NLS-1$
+ outputfolder.addView("org.eclipse.debug.ui.BreakpointView"); //$NON-NLS-1$
+// outputfolder.addView("org.eclipse.jdt.ui.SourceView"); //$NON-NLS-1$
+// outputfolder.addPlaceholder("org.eclipse.search.ui.views.SearchView"); //$NON-NLS-1$
+ outputfolder.addPlaceholder("org.eclipse.ui.console.ConsoleView"); //$NON-NLS-1$
+ outputfolder.addView("org.eclipse.pde.runtime.LogView"); //$NON-NLS-1$
+// outputfolder.addPlaceholder(IPageLayout.ID_BOOKMARKS);
+ outputfolder.addPlaceholder("org.eclipse.ui.views.ProgressView"); //$NON-NLS-1$
+//
+
+// IFolderLayout outlineFolder = layout.createFolder("right", IPageLayout.RIGHT, (float)0.75, editorArea); //$NON-NLS-1$
+// outlineFolder.addView("platform:/plugin/org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.ElementView"); //$NON-NLS-1$
+// IFolderLayout rightFolder = layout.createFolder("right", IPageLayout.RIGHT, (float)0.75, editorArea); //$NON-NLS-1$
+// rightFolder.addView("platform:/plugin/org.eclipse.e4.demo.modifier/org.eclipse.e4.demo.modifier.ModelView"); //$NON-NLS-1$
+
+// outlineFolder.addView(IPageLayout.ID_OUTLINE);
+//
+// outlineFolder.addPlaceholder("org.eclipse.ui.texteditor.TemplatesView");
+// // XXX: in 3.4 M7 to be replaced by:
+//// outlineFolder.addView(TemplatesView.ID);
+//
+// layout.addActionSet("org.eclipse.debug.ui.launchActionSet");
+// layout.addActionSet("org.eclipse.jdt.ui.JavaActionSet");
+// layout.addActionSet("org.eclipse.jdt.ui.JavaElementCreationActionSet");
+// layout.addActionSet(IPageLayout.ID_NAVIGATE_ACTION_SET);
+//
+// // views - java
+// layout.addShowViewShortcut("org.eclipse.jdt.ui.PackageExplorer");
+// layout.addShowViewShortcut("org.eclipse.jdt.ui.TypeHierarchy");
+// layout.addShowViewShortcut("org.eclipse.jdt.ui.SourceView");
+// layout.addShowViewShortcut("org.eclipse.jdt.ui.JavadocView");
+//
+//
+// // views - search
+// layout.addShowViewShortcut("org.eclipse.search.ui.views.SearchView");
+//
+// // views - debugging
+// layout.addShowViewShortcut("org.eclipse.ui.console.ConsoleView");
+//
+// // views - standard workbench
+// layout.addShowViewShortcut(IPageLayout.ID_OUTLINE);
+// layout.addShowViewShortcut(IPageLayout.ID_PROBLEM_VIEW);
+// layout.addShowViewShortcut(IPageLayout.ID_RES_NAV);
+// layout.addShowViewShortcut(IPageLayout.ID_TASK_LIST);
+// layout.addShowViewShortcut("org.eclipse.ui.views.ProgressView");
+// layout.addShowViewShortcut("org.eclipse.ui.navigator.ProjectExplorer");
+// layout.addShowViewShortcut("org.eclipse.ui.texteditor.TemplatesView");
+//
+// // new actions - Java project creation wizard
+// layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.JavaProjectWizard"); //$NON-NLS-1$
+// layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewPackageCreationWizard"); //$NON-NLS-1$
+// layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewClassCreationWizard"); //$NON-NLS-1$
+// layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewInterfaceCreationWizard"); //$NON-NLS-1$
+// layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewEnumCreationWizard"); //$NON-NLS-1$
+// layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewAnnotationCreationWizard"); //$NON-NLS-1$
+// layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewSourceFolderCreationWizard"); //$NON-NLS-1$
+// layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewSnippetFileCreationWizard"); //$NON-NLS-1$
+// layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewJavaWorkingSetWizard"); //$NON-NLS-1$
+// layout.addNewWizardShortcut("org.eclipse.ui.wizards.new.folder");//$NON-NLS-1$
+// layout.addNewWizardShortcut("org.eclipse.ui.wizards.new.file");//$NON-NLS-1$
+// layout.addNewWizardShortcut("org.eclipse.ui.editors.wizards.UntitledTextFileWizard");//$NON-NLS-1$
+ }
+
+}
diff --git a/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/WorkspaceValue.java b/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/WorkspaceValue.java
new file mode 100644
index 0000000..6fc0bf7
--- /dev/null
+++ b/examples/org.eclipse.e4.ui.examples.legacy.workbench/src/org/eclipse/e4/ui/examples/legacy/workbench/WorkspaceValue.java
@@ -0,0 +1,17 @@
+package org.eclipse.e4.ui.examples.legacy.workbench;
+
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.e4.core.contexts.IContextFunction;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+
+public class WorkspaceValue implements IContextFunction {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.e4.core.contexts.IContextFunction#compute(org.eclipse.e4.core.contexts.IEclipseContext)
+ */
+ public Object compute(IEclipseContext context) {
+ ResourcesPlugin.getPlugin().getPluginPreferences().setValue(ResourcesPlugin.PREF_AUTO_REFRESH, true);
+ return ResourcesPlugin.getWorkspace();
+ }
+
+}
diff --git a/features/.gitignore b/features/.gitignore
new file mode 100644
index 0000000..d8fe4fa
--- /dev/null
+++ b/features/.gitignore
@@ -0,0 +1 @@
+/.project
diff --git a/features/org.eclipse.e4.master/.project b/features/org.eclipse.e4.master/.project
new file mode 100644
index 0000000..9bf17ac
--- /dev/null
+++ b/features/org.eclipse.e4.master/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.master</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.master/build.properties b/features/org.eclipse.e4.master/build.properties
new file mode 100644
index 0000000..18c0521
--- /dev/null
+++ b/features/org.eclipse.e4.master/build.properties
@@ -0,0 +1,5 @@
+bin.includes = feature.xml,\
+ feature.properties
+
+generate.feature@org.eclipse.e4.swt.as.source.feature=org.eclipse.e4.swt.as.feature
+
diff --git a/features/org.eclipse.e4.master/feature.properties b/features/org.eclipse.e4.master/feature.properties
new file mode 100644
index 0000000..c527e56
--- /dev/null
+++ b/features/org.eclipse.e4.master/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 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
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 Master Build Feature (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=Eclipse e4 Master Build Feature
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2009 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+ IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+ - Content may be structured and packaged into modules to facilitate delivering,\n\
+ extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+ plug-in fragments ("Fragments"), and features ("Features").\n\
+ - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+ in a directory named "plugins".\n\
+ - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+ Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+ Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+ numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+ - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+ named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+ - The top-level (root) directory\n\
+ - Plug-in and Fragment directories\n\
+ - Inside Plug-ins and Fragments packaged as JARs\n\
+ - Sub-directories of the directory named "src" of certain Plug-ins\n\
+ - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+ - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+ - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+ - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+ - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+ - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+ - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.master/feature.xml b/features/org.eclipse.e4.master/feature.xml
new file mode 100644
index 0000000..931f293
--- /dev/null
+++ b/features/org.eclipse.e4.master/feature.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.e4.master"
+ label="%featureName"
+ version="0.11.0.qualifier"
+ provider-name="%providerName">
+
+ <description>
+ %description
+ </description>
+
+ <copyright>
+ %copyright
+ </copyright>
+
+ <license url="%licenseURL">
+ %license
+ </license>
+
+ <includes
+ id="org.eclipse.e4.ui.examples.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.ui.tests.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.xwt.tests.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.tm.tests.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.tests.base.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.sdk.runtime.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.sdk.source.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.resources.tests.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.platform.discovery.master"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.tools.e3x.bridge.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.tools.css.editor.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.tools.css.spy.feature"
+ version="0.0.0"/>
+
+</feature>
diff --git a/features/org.eclipse.e4.sdk.runtime.feature/.project b/features/org.eclipse.e4.sdk.runtime.feature/.project
new file mode 100644
index 0000000..426d87f
--- /dev/null
+++ b/features/org.eclipse.e4.sdk.runtime.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.sdk.runtime.feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.sdk.runtime.feature/build.properties b/features/org.eclipse.e4.sdk.runtime.feature/build.properties
new file mode 100755
index 0000000..f12f4e5
--- /dev/null
+++ b/features/org.eclipse.e4.sdk.runtime.feature/build.properties
@@ -0,0 +1,3 @@
+bin.includes = feature.xml,\
+ feature.properties
+
diff --git a/features/org.eclipse.e4.sdk.runtime.feature/feature.properties b/features/org.eclipse.e4.sdk.runtime.feature/feature.properties
new file mode 100644
index 0000000..14562f3
--- /dev/null
+++ b/features/org.eclipse.e4.sdk.runtime.feature/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 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
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 SDK runtime (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=Includes all of the e4 features to build an SDK
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2009 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+ IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+ - Content may be structured and packaged into modules to facilitate delivering,\n\
+ extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+ plug-in fragments ("Fragments"), and features ("Features").\n\
+ - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+ in a directory named "plugins".\n\
+ - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+ Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+ Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+ numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+ - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+ named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+ - The top-level (root) directory\n\
+ - Plug-in and Fragment directories\n\
+ - Inside Plug-ins and Fragments packaged as JARs\n\
+ - Sub-directories of the directory named "src" of certain Plug-ins\n\
+ - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+ - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+ - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+ - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+ - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+ - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+ - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.sdk.runtime.feature/feature.xml b/features/org.eclipse.e4.sdk.runtime.feature/feature.xml
new file mode 100755
index 0000000..35a37e6
--- /dev/null
+++ b/features/org.eclipse.e4.sdk.runtime.feature/feature.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.e4.sdk.runtime.feature"
+ label="%featureName"
+ version="0.11.0.qualifier"
+ provider-name="%providerName">
+
+ <description>
+ %description
+ </description>
+
+ <copyright>
+ %copyright
+ </copyright>
+
+ <license url="%licenseURL">
+ %license
+ </license>
+
+ <includes
+ id="org.eclipse.e4.ui.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.ui.css.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.xwt.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.xwt.tools.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.ui.compatibility.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.runtime.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.server.bespin.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.xwt.css.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.tm.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.xwt.emf.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.xwt.workbench.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.resources.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.core.tools.feature"
+ version="0.0.0"/>
+
+</feature>
diff --git a/features/org.eclipse.e4.sdk.source.feature/.project b/features/org.eclipse.e4.sdk.source.feature/.project
new file mode 100644
index 0000000..77ce76f
--- /dev/null
+++ b/features/org.eclipse.e4.sdk.source.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.sdk.source.feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.sdk.source.feature/build.properties b/features/org.eclipse.e4.sdk.source.feature/build.properties
new file mode 100755
index 0000000..b9a9a08
--- /dev/null
+++ b/features/org.eclipse.e4.sdk.source.feature/build.properties
@@ -0,0 +1,19 @@
+bin.includes = feature.xml,\
+ feature.properties
+
+generate.feature@org.eclipse.e4.ui.source.feature=org.eclipse.e4.ui.feature,plugin@javax.inject.source;unpack="false",plugin@javax.annotation.source;unpack="false"
+generate.feature@org.eclipse.e4.ui.compatibility.source.feature=org.eclipse.e4.ui.compatibility.feature
+generate.feature@org.eclipse.e4.ui.css.source.feature=org.eclipse.e4.ui.css.feature
+generate.feature@org.eclipse.e4.xwt.source.feature=org.eclipse.e4.xwt.feature
+generate.feature@org.eclipse.e4.xwt.tools.source.feature=org.eclipse.e4.xwt.tools.feature
+generate.feature@org.eclipse.e4.languages.source.feature=org.eclipse.e4.languages.feature,plugin@org.eclipse.wst.jsdt.core.source;unpack="false",plugin@org.eclipse.wst.jsdt.manipulation.source;unpack="false",plugin@org.eclipse.wst.jsdt.ui.source;unpack="false",plugin@org.mozilla.javascript.source;unpack="false"
+generate.feature@org.eclipse.e4.server.bespin.source.feature=org.eclipse.e4.server.bespin.feature
+generate.feature@org.eclipse.e4.xwt.css.source.feature=org.eclipse.e4.xwt.css.feature
+generate.feature@org.eclipse.e4.xwt.emf.source.feature=org.eclipse.e4.xwt.emf.feature
+generate.feature@org.eclipse.e4.xwt.workbench.source.feature=org.eclipse.e4.xwt.workbench.feature
+generate.feature@org.eclipse.e4.tm.source.feature=org.eclipse.e4.tm.feature
+generate.feature@org.eclipse.e4.ui.compatibility.source.feature=org.eclipse.e4.ui.compatibility.feature
+generate.feature@org.eclipse.e4.ui.web.source.feature=org.eclipse.e4.ui.web.feature
+generate.feature@org.eclipse.e4.resources.source.feature=org.eclipse.e4.resources.feature
+generate.feature@org.eclipse.e4.core.tools.source.feature=org.eclipse.e4.core.tools.feature
+generate.feature@org.eclipse.e4.tools.e3x.bridge.source.feature=org.eclipse.e4.tools.e3x.bridge.feature
diff --git a/features/org.eclipse.e4.sdk.source.feature/feature.properties b/features/org.eclipse.e4.sdk.source.feature/feature.properties
new file mode 100644
index 0000000..e18b6f8
--- /dev/null
+++ b/features/org.eclipse.e4.sdk.source.feature/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 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
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 SDK source (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=Includes all of the source features for the SDK runtime
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2009 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+ IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+ - Content may be structured and packaged into modules to facilitate delivering,\n\
+ extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+ plug-in fragments ("Fragments"), and features ("Features").\n\
+ - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+ in a directory named "plugins".\n\
+ - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+ Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+ Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+ numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+ - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+ named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+ - The top-level (root) directory\n\
+ - Plug-in and Fragment directories\n\
+ - Inside Plug-ins and Fragments packaged as JARs\n\
+ - Sub-directories of the directory named "src" of certain Plug-ins\n\
+ - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+ - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+ - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+ - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+ - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+ - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+ - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.sdk.source.feature/feature.xml b/features/org.eclipse.e4.sdk.source.feature/feature.xml
new file mode 100755
index 0000000..77370f2
--- /dev/null
+++ b/features/org.eclipse.e4.sdk.source.feature/feature.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.e4.sdk.source.feature"
+ label="%featureName"
+ version="0.12.0.qualifier"
+ provider-name="%providerName">
+
+ <description>
+ %description
+ </description>
+
+ <copyright>
+ %copyright
+ </copyright>
+
+ <license url="%licenseURL">
+ %license
+ </license>
+
+ <includes
+ id="org.eclipse.e4.ui.source.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.ui.css.source.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.xwt.source.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.xwt.tools.source.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.ui.compatibility.source.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.server.bespin.source.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.xwt.css.source.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.tm.source.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.xwt.emf.source.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.xwt.workbench.source.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.ui.web.source.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.resources.source.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.core.tools.source.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.e4.tools.e3x.bridge.source.feature"
+ version="0.0.0"/>
+
+ <includes
+ id="org.eclipse.platform.discovery.source.master"
+ version="0.0.0"/>
+
+ <requires>
+ <import feature="org.eclipse.e4.sdk.runtime.feature" version="0.9.0" match="compatible"/>
+ </requires>
+
+</feature>
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/.project b/features/org.eclipse.e4.ui.compatibility.feature/.project
new file mode 100644
index 0000000..61d873c
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.ui.compatibility.feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/build.properties b/features/org.eclipse.e4.ui.compatibility.feature/build.properties
new file mode 100644
index 0000000..f12f4e5
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/build.properties
@@ -0,0 +1,3 @@
+bin.includes = feature.xml,\
+ feature.properties
+
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/feature.properties b/features/org.eclipse.e4.ui.compatibility.feature/feature.properties
new file mode 100644
index 0000000..ebf4120
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 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
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 UI Compatibility Layer (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=Eclipse e4 UI Compatibility Layer
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2009 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+ IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+ - Content may be structured and packaged into modules to facilitate delivering,\n\
+ extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+ plug-in fragments ("Fragments"), and features ("Features").\n\
+ - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+ in a directory named "plugins".\n\
+ - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+ Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+ Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+ numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+ - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+ named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+ - The top-level (root) directory\n\
+ - Plug-in and Fragment directories\n\
+ - Inside Plug-ins and Fragments packaged as JARs\n\
+ - Sub-directories of the directory named "src" of certain Plug-ins\n\
+ - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+ - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+ - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+ - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+ - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+ - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+ - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/feature.xml b/features/org.eclipse.e4.ui.compatibility.feature/feature.xml
new file mode 100644
index 0000000..1c416c5
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/feature.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.e4.ui.compatibility.feature"
+ label="%featureName"
+ version="0.9.1.qualifier"
+ provider-name="%providerName"
+ image="eclipse_update_120.jpg">
+
+ <description>
+ %description
+ </description>
+
+ <copyright>
+ %copyright
+ </copyright>
+
+ <license url="%licenseURL">
+ %license
+ </license>
+
+ <requires>
+ <import feature="org.eclipse.e4.ui.feature" version="0.9.0" match="compatible"/>
+ </requires>
+
+ <plugin
+ id="org.eclipse.e4.ui.examples.legacy.workbench"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"/>
+
+ <plugin
+ id="org.eclipse.xsd"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.xsd.edit"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.wst.common.project.facet.core"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+
+</feature>
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/eclipse_update_120.jpg b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/eclipse_update_120.jpg
new file mode 100755
index 0000000..bfdf708
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/eclipse_update_120.jpg
Binary files differ
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/epl-v10.html b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/epl-v10.html
new file mode 100755
index 0000000..ed4b196
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/epl-v10.html
@@ -0,0 +1,328 @@
+<html xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link rel=File-List
+href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
+<title>Eclipse Public License - Version 1.0</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+ <o:Revision>2</o:Revision>
+ <o:TotalTime>3</o:TotalTime>
+ <o:Created>2004-03-05T23:03:00Z</o:Created>
+ <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
+ <o:Pages>4</o:Pages>
+ <o:Words>1626</o:Words>
+ <o:Characters>9270</o:Characters>
+ <o:Lines>77</o:Lines>
+ <o:Paragraphs>18</o:Paragraphs>
+ <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
+ <o:Version>9.4402</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:WordDocument>
+ <w:TrackRevisions/>
+ </w:WordDocument>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+@font-face
+ {font-family:Tahoma;
+ panose-1:2 11 6 4 3 5 4 4 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:553679495 -2147483648 8 0 66047 0;}
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+ {mso-style-parent:"";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";}
+p
+ {margin-right:0in;
+ mso-margin-top-alt:auto;
+ mso-margin-bottom-alt:auto;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";}
+p.BalloonText, li.BalloonText, div.BalloonText
+ {mso-style-name:"Balloon Text";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:8.0pt;
+ font-family:Tahoma;
+ mso-fareast-font-family:"Times New Roman";}
+@page Section1
+ {size:8.5in 11.0in;
+ margin:1.0in 1.25in 1.0in 1.25in;
+ mso-header-margin:.5in;
+ mso-footer-margin:.5in;
+ mso-paper-source:0;}
+div.Section1
+ {page:Section1;}
+-->
+</style>
+</head>
+
+<body lang=EN-US style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
+</p>
+
+<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
+THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE,
+REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
+OF THIS AGREEMENT.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>"Contribution" means:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+in the case of the initial Contributor, the initial code and documentation
+distributed under this Agreement, and<br clear=left>
+b) in the case of each subsequent Contributor:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+changes to the Program, and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+additions to the Program;</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
+such changes and/or additions to the Program originate from and are distributed
+by that particular Contributor. A Contribution 'originates' from a Contributor
+if it was added to the Program by such Contributor itself or anyone acting on
+such Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in conjunction
+with the Program under their own license agreement, and (ii) are not derivative
+works of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>"Contributor" means any person or
+entity that distributes the Program.</span> </p>
+
+<p><span style='font-size:10.0pt'>"Licensed Patents " mean patent
+claims licensable by a Contributor which are necessarily infringed by the use
+or sale of its Contribution alone or when combined with the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>"Program" means the Contributions
+distributed in accordance with this Agreement.</span> </p>
+
+<p><span style='font-size:10.0pt'>"Recipient" means anyone who
+receives the Program under this Agreement, including all Contributors.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+Subject to the terms of this Agreement, each Contributor hereby grants Recipient
+a non-exclusive, worldwide, royalty-free copyright license to<span
+style='color:red'> </span>reproduce, prepare derivative works of, publicly
+display, publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and object code
+form.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
+patent license under Licensed Patents to make, use, sell, offer to sell, import
+and otherwise transfer the Contribution of such Contributor, if any, in source
+code and object code form. This patent license shall apply to the combination
+of the Contribution and the Program if, at the time the Contribution is added
+by the Contributor, such addition of the Contribution causes such combination
+to be covered by the Licensed Patents. The patent license shall not apply to
+any other combinations which include the Contribution. No hardware per se is
+licensed hereunder. </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
+Recipient understands that although each Contributor grants the licenses to its
+Contributions set forth herein, no assurances are provided by any Contributor
+that the Program does not infringe the patent or other intellectual property
+rights of any other entity. Each Contributor disclaims any liability to Recipient
+for claims brought by any other entity based on infringement of intellectual
+property rights or otherwise. As a condition to exercising the rights and
+licenses granted hereunder, each Recipient hereby assumes sole responsibility
+to secure any other intellectual property rights needed, if any. For example,
+if a third party patent license is required to allow Recipient to distribute
+the Program, it is Recipient's responsibility to acquire that license before
+distributing the Program.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
+Each Contributor represents that to its knowledge it has sufficient copyright
+rights in its Contribution, if any, to grant the copyright license set forth in
+this Agreement. </span></p>
+
+<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
+Program in object code form under its own license agreement, provided that:</span>
+</p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it complies with the terms and conditions of this Agreement; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+its license agreement:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title
+and non-infringement, and implied warranties or conditions of merchantability
+and fitness for a particular purpose; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+effectively excludes on behalf of all Contributors all liability for damages,
+including direct, indirect, special, incidental and consequential damages, such
+as lost profits; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
+states that any provisions which differ from this Agreement are offered by that
+Contributor alone and not by any other party; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
+states that source code for the Program is available from such Contributor, and
+informs licensees how to obtain it in a reasonable manner on or through a
+medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
+
+<p><span style='font-size:10.0pt'>When the Program is made available in source
+code form:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it must be made available under this Agreement; and </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
+copy of this Agreement must be included with each copy of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
+copyright notices contained within the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
+originator of its Contribution, if any, in a manner that reasonably allows
+subsequent Recipients to identify the originator of the Contribution. </span></p>
+
+<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
+
+<p><span style='font-size:10.0pt'>Commercial distributors of software may
+accept certain responsibilities with respect to end users, business partners
+and the like. While this license is intended to facilitate the commercial use
+of the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes the
+Program in a commercial product offering, such Contributor ("Commercial
+Contributor") hereby agrees to defend and indemnify every other
+Contributor ("Indemnified Contributor") against any losses, damages and
+costs (collectively "Losses") arising from claims, lawsuits and other
+legal actions brought by a third party against the Indemnified Contributor to
+the extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may participate
+in any such claim at its own expense.</span> </p>
+
+<p><span style='font-size:10.0pt'>For example, a Contributor might include the
+Program in a commercial product offering, Product X. That Contributor is then a
+Commercial Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance claims and
+warranties are such Commercial Contributor's responsibility alone. Under this
+section, the Commercial Contributor would have to defend claims against the
+other Contributors related to those performance claims and warranties, and if a
+court requires any other Contributor to pay any damages as a result, the
+Commercial Contributor must pay those damages.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
+WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and distributing the
+Program and assumes all risks associated with its exercise of rights under this
+Agreement , including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs or
+equipment, and unavailability or interruption of operations. </span></p>
+
+<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
+THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
+
+<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
+or unenforceable under applicable law, it shall not affect the validity or
+enforceability of the remainder of the terms of this Agreement, and without
+further action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.</span> </p>
+
+<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
+against any entity (including a cross-claim or counterclaim in a lawsuit)
+alleging that the Program itself (excluding combinations of the Program with
+other software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the date
+such litigation is filed. </span></p>
+
+<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
+shall terminate if it fails to comply with any of the material terms or
+conditions of this Agreement and does not cure such failure in a reasonable
+period of time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive. </span></p>
+
+<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
+copies of this Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The Agreement
+Steward reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement Steward has
+the right to modify this Agreement. The Eclipse Foundation is the initial
+Agreement Steward. The Eclipse Foundation may assign the responsibility to
+serve as the Agreement Steward to a suitable separate entity. Each new version
+of the Agreement will be given a distinguishing version number. The Program
+(including Contributions) may always be distributed subject to the version of
+the Agreement under which it was received. In addition, after a new version of
+the Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly stated
+in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.</span> </p>
+
+<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
+State of New York and the intellectual property laws of the United States of
+America. No party to this Agreement will bring a legal action under this
+Agreement more than one year after the cause of action arose. Each party waives
+its rights to a jury trial in any resulting litigation.</span> </p>
+
+<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html>
\ No newline at end of file
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/feature.properties b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/feature.properties
new file mode 100755
index 0000000..1f250af
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/feature.properties
@@ -0,0 +1,144 @@
+###############################################################################
+# Copyright (c) 2000, 2007 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
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse E4 UI Compatibility Source (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "description" property - description of the feature
+description=Source code zips for Eclipse E4 initiative.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2007 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+ IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+ - Content may be structured and packaged into modules to facilitate delivering,\n\
+ extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+ plug-in fragments ("Fragments"), and features ("Features").\n\
+ - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+ in a directory named "plugins".\n\
+ - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+ Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+ Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+ numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+ - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+ named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+ - The top-level (root) directory\n\
+ - Plug-in and Fragment directories\n\
+ - Inside Plug-ins and Fragments packaged as JARs\n\
+ - Sub-directories of the directory named "src" of certain Plug-ins\n\
+ - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+ - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+ - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+ - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+ - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+ - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+ - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/license.html b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/license.html
new file mode 100755
index 0000000..c6af966
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplateFeature/license.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=iso-8859-1">
+<title>Eclipse.org Software User Agreement</title>
+</head>
+
+<body lang="EN-US" link=blue vlink=purple>
+<h2>Eclipse Foundation Software User Agreement</h2>
+<p>March 17, 2005</p>
+
+<h3>Usage Of Content</h3>
+
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+ (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+ CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+ OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+ NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+ CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
+
+<h3>Applicable Licenses</h3>
+
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
+ ("EPL"). A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+ For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS
+ modules ("Modules") and made available as downloadable archives ("Downloads").</p>
+
+<ul>
+ <li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").</li>
+ <li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".</li>
+ <li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins
+ and/or Fragments associated with that Feature.</li>
+ <li>Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.</li>
+</ul>
+
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and
+Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p>
+
+<ul>
+ <li>The top-level (root) directory</li>
+ <li>Plug-in and Fragment directories</li>
+ <li>Inside Plug-ins and Fragments packaged as JARs</li>
+ <li>Sub-directories of the directory named "src" of certain Plug-ins</li>
+ <li>Feature directories</li>
+</ul>
+
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the
+installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p>
+
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
+
+<ul>
+ <li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
+ <li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
+ <li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
+ <li>IBM Public License 1.0 (available at <a href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</a>)</li>
+ <li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
+ <li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
+</ul>
+
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
+
+<h3>Cryptography</h3>
+
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+ another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+ possession, or use, and re-export of encryption software, to see if this is permitted.</p>
+
+<small>Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.</small>
+</body>
+</html>
diff --git a/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplatePlugin/build.properties b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplatePlugin/build.properties
new file mode 100755
index 0000000..cdb3ab3
--- /dev/null
+++ b/features/org.eclipse.e4.ui.compatibility.feature/sourceTemplatePlugin/build.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2000, 2006 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
+###############################################################################
+bin.includes = plugin.xml, src/**, META-INF/
+sourcePlugin = true
diff --git a/features/org.eclipse.e4.ui.css.feature/.project b/features/org.eclipse.e4.ui.css.feature/.project
new file mode 100644
index 0000000..eb3439f
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.ui.css.feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.ui.css.feature/build.properties b/features/org.eclipse.e4.ui.css.feature/build.properties
new file mode 100644
index 0000000..655791e
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/build.properties
@@ -0,0 +1,15 @@
+###############################################################################
+# Copyright (c) 2010 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
+###############################################################################
+bin.includes = feature.xml,\
+ feature.properties
+
+#generate.feature@org.eclipse.e4.resources.rcp.patch.source = org.eclipse.e4.resources.rcp.patch
+#generate.feature@org.eclipse.e4.resources.platform.patch.source = org.eclipse.e4.resources.platform.patch
diff --git a/features/org.eclipse.e4.ui.css.feature/feature.properties b/features/org.eclipse.e4.ui.css.feature/feature.properties
new file mode 100644
index 0000000..f66fea6
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 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
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 CSS Support (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=Eclipse e4 CSS Support
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2009 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+ IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+ - Content may be structured and packaged into modules to facilitate delivering,\n\
+ extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+ plug-in fragments ("Fragments"), and features ("Features").\n\
+ - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+ in a directory named "plugins".\n\
+ - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+ Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+ Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+ numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+ - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+ named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+ - The top-level (root) directory\n\
+ - Plug-in and Fragment directories\n\
+ - Inside Plug-ins and Fragments packaged as JARs\n\
+ - Sub-directories of the directory named "src" of certain Plug-ins\n\
+ - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+ - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+ - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+ - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+ - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+ - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+ - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.css.feature/feature.xml b/features/org.eclipse.e4.ui.css.feature/feature.xml
new file mode 100644
index 0000000..c0773a0
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/feature.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.e4.ui.css.feature"
+ label="%featureName"
+ version="0.9.1.qualifier"
+ provider-name="%providerName"
+ image="eclipse_update_120.jpg">
+
+ <description>
+ %description
+ </description>
+
+ <copyright>
+ %copyright
+ </copyright>
+
+ <license url="%licenseURL">
+ %license
+ </license>
+
+ <plugin
+ id="org.eclipse.e4.ui.css.core"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.css.jface"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.css.swt"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.apache.batik.css"
+ download-size="0"
+ install-size="0"
+ version="1.6.0.qualifier"
+ unpack="false"/>
+
+ <plugin
+ id="org.apache.batik.util"
+ download-size="0"
+ install-size="0"
+ version="1.6.0.qualifier"
+ unpack="false"/>
+
+ <plugin
+ id="org.apache.batik.util.gui"
+ download-size="0"
+ install-size="0"
+ version="1.6.0.qualifier"
+ unpack="false"/>
+
+ <plugin
+ id="org.apache.batik.xml"
+ download-size="0"
+ install-size="0"
+ version="1.6.0.qualifier"
+ unpack="false"/>
+
+ <plugin
+ id="org.w3c.css.sac"
+ download-size="0"
+ install-size="0"
+ version="1.3.0.qualifier"
+ unpack="false"/>
+
+ <plugin
+ id="org.w3c.dom.smil"
+ download-size="0"
+ install-size="0"
+ version="1.0.0.qualifier"
+ unpack="false"/>
+
+ <plugin
+ id="org.w3c.dom.svg"
+ download-size="0"
+ install-size="0"
+ version="1.1.0.qualifier"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.nebula.widgets.gallery"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.css.nebula"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.css.swt.theme"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+</feature>
diff --git a/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/eclipse_update_120.jpg b/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/eclipse_update_120.jpg
new file mode 100755
index 0000000..bfdf708
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/eclipse_update_120.jpg
Binary files differ
diff --git a/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/epl-v10.html b/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/epl-v10.html
new file mode 100755
index 0000000..ed4b196
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/epl-v10.html
@@ -0,0 +1,328 @@
+<html xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link rel=File-List
+href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
+<title>Eclipse Public License - Version 1.0</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+ <o:Revision>2</o:Revision>
+ <o:TotalTime>3</o:TotalTime>
+ <o:Created>2004-03-05T23:03:00Z</o:Created>
+ <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
+ <o:Pages>4</o:Pages>
+ <o:Words>1626</o:Words>
+ <o:Characters>9270</o:Characters>
+ <o:Lines>77</o:Lines>
+ <o:Paragraphs>18</o:Paragraphs>
+ <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
+ <o:Version>9.4402</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:WordDocument>
+ <w:TrackRevisions/>
+ </w:WordDocument>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+@font-face
+ {font-family:Tahoma;
+ panose-1:2 11 6 4 3 5 4 4 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:553679495 -2147483648 8 0 66047 0;}
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+ {mso-style-parent:"";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";}
+p
+ {margin-right:0in;
+ mso-margin-top-alt:auto;
+ mso-margin-bottom-alt:auto;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";}
+p.BalloonText, li.BalloonText, div.BalloonText
+ {mso-style-name:"Balloon Text";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:8.0pt;
+ font-family:Tahoma;
+ mso-fareast-font-family:"Times New Roman";}
+@page Section1
+ {size:8.5in 11.0in;
+ margin:1.0in 1.25in 1.0in 1.25in;
+ mso-header-margin:.5in;
+ mso-footer-margin:.5in;
+ mso-paper-source:0;}
+div.Section1
+ {page:Section1;}
+-->
+</style>
+</head>
+
+<body lang=EN-US style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
+</p>
+
+<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
+THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE,
+REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
+OF THIS AGREEMENT.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>"Contribution" means:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+in the case of the initial Contributor, the initial code and documentation
+distributed under this Agreement, and<br clear=left>
+b) in the case of each subsequent Contributor:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+changes to the Program, and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+additions to the Program;</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
+such changes and/or additions to the Program originate from and are distributed
+by that particular Contributor. A Contribution 'originates' from a Contributor
+if it was added to the Program by such Contributor itself or anyone acting on
+such Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in conjunction
+with the Program under their own license agreement, and (ii) are not derivative
+works of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>"Contributor" means any person or
+entity that distributes the Program.</span> </p>
+
+<p><span style='font-size:10.0pt'>"Licensed Patents " mean patent
+claims licensable by a Contributor which are necessarily infringed by the use
+or sale of its Contribution alone or when combined with the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>"Program" means the Contributions
+distributed in accordance with this Agreement.</span> </p>
+
+<p><span style='font-size:10.0pt'>"Recipient" means anyone who
+receives the Program under this Agreement, including all Contributors.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+Subject to the terms of this Agreement, each Contributor hereby grants Recipient
+a non-exclusive, worldwide, royalty-free copyright license to<span
+style='color:red'> </span>reproduce, prepare derivative works of, publicly
+display, publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and object code
+form.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
+patent license under Licensed Patents to make, use, sell, offer to sell, import
+and otherwise transfer the Contribution of such Contributor, if any, in source
+code and object code form. This patent license shall apply to the combination
+of the Contribution and the Program if, at the time the Contribution is added
+by the Contributor, such addition of the Contribution causes such combination
+to be covered by the Licensed Patents. The patent license shall not apply to
+any other combinations which include the Contribution. No hardware per se is
+licensed hereunder. </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
+Recipient understands that although each Contributor grants the licenses to its
+Contributions set forth herein, no assurances are provided by any Contributor
+that the Program does not infringe the patent or other intellectual property
+rights of any other entity. Each Contributor disclaims any liability to Recipient
+for claims brought by any other entity based on infringement of intellectual
+property rights or otherwise. As a condition to exercising the rights and
+licenses granted hereunder, each Recipient hereby assumes sole responsibility
+to secure any other intellectual property rights needed, if any. For example,
+if a third party patent license is required to allow Recipient to distribute
+the Program, it is Recipient's responsibility to acquire that license before
+distributing the Program.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
+Each Contributor represents that to its knowledge it has sufficient copyright
+rights in its Contribution, if any, to grant the copyright license set forth in
+this Agreement. </span></p>
+
+<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
+Program in object code form under its own license agreement, provided that:</span>
+</p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it complies with the terms and conditions of this Agreement; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+its license agreement:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title
+and non-infringement, and implied warranties or conditions of merchantability
+and fitness for a particular purpose; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+effectively excludes on behalf of all Contributors all liability for damages,
+including direct, indirect, special, incidental and consequential damages, such
+as lost profits; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
+states that any provisions which differ from this Agreement are offered by that
+Contributor alone and not by any other party; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
+states that source code for the Program is available from such Contributor, and
+informs licensees how to obtain it in a reasonable manner on or through a
+medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
+
+<p><span style='font-size:10.0pt'>When the Program is made available in source
+code form:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it must be made available under this Agreement; and </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
+copy of this Agreement must be included with each copy of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
+copyright notices contained within the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
+originator of its Contribution, if any, in a manner that reasonably allows
+subsequent Recipients to identify the originator of the Contribution. </span></p>
+
+<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
+
+<p><span style='font-size:10.0pt'>Commercial distributors of software may
+accept certain responsibilities with respect to end users, business partners
+and the like. While this license is intended to facilitate the commercial use
+of the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes the
+Program in a commercial product offering, such Contributor ("Commercial
+Contributor") hereby agrees to defend and indemnify every other
+Contributor ("Indemnified Contributor") against any losses, damages and
+costs (collectively "Losses") arising from claims, lawsuits and other
+legal actions brought by a third party against the Indemnified Contributor to
+the extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may participate
+in any such claim at its own expense.</span> </p>
+
+<p><span style='font-size:10.0pt'>For example, a Contributor might include the
+Program in a commercial product offering, Product X. That Contributor is then a
+Commercial Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance claims and
+warranties are such Commercial Contributor's responsibility alone. Under this
+section, the Commercial Contributor would have to defend claims against the
+other Contributors related to those performance claims and warranties, and if a
+court requires any other Contributor to pay any damages as a result, the
+Commercial Contributor must pay those damages.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
+WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and distributing the
+Program and assumes all risks associated with its exercise of rights under this
+Agreement , including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs or
+equipment, and unavailability or interruption of operations. </span></p>
+
+<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
+THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
+
+<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
+or unenforceable under applicable law, it shall not affect the validity or
+enforceability of the remainder of the terms of this Agreement, and without
+further action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.</span> </p>
+
+<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
+against any entity (including a cross-claim or counterclaim in a lawsuit)
+alleging that the Program itself (excluding combinations of the Program with
+other software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the date
+such litigation is filed. </span></p>
+
+<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
+shall terminate if it fails to comply with any of the material terms or
+conditions of this Agreement and does not cure such failure in a reasonable
+period of time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive. </span></p>
+
+<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
+copies of this Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The Agreement
+Steward reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement Steward has
+the right to modify this Agreement. The Eclipse Foundation is the initial
+Agreement Steward. The Eclipse Foundation may assign the responsibility to
+serve as the Agreement Steward to a suitable separate entity. Each new version
+of the Agreement will be given a distinguishing version number. The Program
+(including Contributions) may always be distributed subject to the version of
+the Agreement under which it was received. In addition, after a new version of
+the Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly stated
+in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.</span> </p>
+
+<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
+State of New York and the intellectual property laws of the United States of
+America. No party to this Agreement will bring a legal action under this
+Agreement more than one year after the cause of action arose. Each party waives
+its rights to a jury trial in any resulting litigation.</span> </p>
+
+<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html>
\ No newline at end of file
diff --git a/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/feature.properties b/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/feature.properties
new file mode 100755
index 0000000..be93723
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/feature.properties
@@ -0,0 +1,144 @@
+###############################################################################
+# Copyright (c) 2000, 2007 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
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse E4 UI CSS Source (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "description" property - description of the feature
+description=Source code zips for Eclipse E4 initiative.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2007 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+ IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+ - Content may be structured and packaged into modules to facilitate delivering,\n\
+ extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+ plug-in fragments ("Fragments"), and features ("Features").\n\
+ - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+ in a directory named "plugins".\n\
+ - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+ Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+ Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+ numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+ - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+ named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+ - The top-level (root) directory\n\
+ - Plug-in and Fragment directories\n\
+ - Inside Plug-ins and Fragments packaged as JARs\n\
+ - Sub-directories of the directory named "src" of certain Plug-ins\n\
+ - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+ - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+ - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+ - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+ - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+ - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+ - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/license.html b/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/license.html
new file mode 100755
index 0000000..c6af966
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/sourceTemplateFeature/license.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=iso-8859-1">
+<title>Eclipse.org Software User Agreement</title>
+</head>
+
+<body lang="EN-US" link=blue vlink=purple>
+<h2>Eclipse Foundation Software User Agreement</h2>
+<p>March 17, 2005</p>
+
+<h3>Usage Of Content</h3>
+
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+ (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+ CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+ OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+ NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+ CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
+
+<h3>Applicable Licenses</h3>
+
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
+ ("EPL"). A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+ For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS
+ modules ("Modules") and made available as downloadable archives ("Downloads").</p>
+
+<ul>
+ <li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").</li>
+ <li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".</li>
+ <li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins
+ and/or Fragments associated with that Feature.</li>
+ <li>Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.</li>
+</ul>
+
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and
+Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p>
+
+<ul>
+ <li>The top-level (root) directory</li>
+ <li>Plug-in and Fragment directories</li>
+ <li>Inside Plug-ins and Fragments packaged as JARs</li>
+ <li>Sub-directories of the directory named "src" of certain Plug-ins</li>
+ <li>Feature directories</li>
+</ul>
+
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the
+installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p>
+
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
+
+<ul>
+ <li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
+ <li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
+ <li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
+ <li>IBM Public License 1.0 (available at <a href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</a>)</li>
+ <li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
+ <li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
+</ul>
+
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
+
+<h3>Cryptography</h3>
+
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+ another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+ possession, or use, and re-export of encryption software, to see if this is permitted.</p>
+
+<small>Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.</small>
+</body>
+</html>
diff --git a/features/org.eclipse.e4.ui.css.feature/sourceTemplatePlugin/build.properties b/features/org.eclipse.e4.ui.css.feature/sourceTemplatePlugin/build.properties
new file mode 100755
index 0000000..45f08b3
--- /dev/null
+++ b/features/org.eclipse.e4.ui.css.feature/sourceTemplatePlugin/build.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2000, 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
+###############################################################################
+bin.includes = plugin.xml, src/**, META-INF/
+sourcePlugin = true
diff --git a/features/org.eclipse.e4.ui.examples.feature/.project b/features/org.eclipse.e4.ui.examples.feature/.project
new file mode 100644
index 0000000..4ed0358
--- /dev/null
+++ b/features/org.eclipse.e4.ui.examples.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.ui.examples.feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.ui.examples.feature/build.properties b/features/org.eclipse.e4.ui.examples.feature/build.properties
new file mode 100644
index 0000000..b3a611b
--- /dev/null
+++ b/features/org.eclipse.e4.ui.examples.feature/build.properties
@@ -0,0 +1,2 @@
+bin.includes = feature.xml,\
+ feature.properties
diff --git a/features/org.eclipse.e4.ui.examples.feature/feature.properties b/features/org.eclipse.e4.ui.examples.feature/feature.properties
new file mode 100644
index 0000000..b7176f3
--- /dev/null
+++ b/features/org.eclipse.e4.ui.examples.feature/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 2005 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
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 UI Examples Build feature (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=Eclipse e4 UI Examples
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2008 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+ IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+ - Content may be structured and packaged into modules to facilitate delivering,\n\
+ extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+ plug-in fragments ("Fragments"), and features ("Features").\n\
+ - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+ in a directory named "plugins".\n\
+ - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+ Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+ Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+ numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+ - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+ named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+ - The top-level (root) directory\n\
+ - Plug-in and Fragment directories\n\
+ - Inside Plug-ins and Fragments packaged as JARs\n\
+ - Sub-directories of the directory named "src" of certain Plug-ins\n\
+ - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+ - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+ - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+ - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+ - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+ - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+ - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.examples.feature/feature.xml b/features/org.eclipse.e4.ui.examples.feature/feature.xml
new file mode 100644
index 0000000..d785c88
--- /dev/null
+++ b/features/org.eclipse.e4.ui.examples.feature/feature.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.e4.ui.examples.feature"
+ label="%featureName"
+ version="0.9.0.qualifier"
+ provider-name="%providerName">
+
+ <description>
+ %description
+ </description>
+
+ <copyright>
+ %copyright
+ </copyright>
+
+ <license url="%licenseURL">
+ %license
+ </license>
+
+ <requires>
+ <import feature="org.eclipse.e4.ui.feature" version="0.9.0" match="compatible"/>
+ <import feature="org.eclipse.e4.ui.css.feature" version="0.9.0" match="compatible"/>
+ <import feature="org.eclipse.e4.ui.compatibility.feature" version="0.9.0" match="compatible"/>
+ </requires>
+
+ <plugin
+ id="org.eclipse.e4.demo.e4photo"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.examples.css"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.examples.css.nebula"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.examples.css.rcp"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+ <!-- Temporarily remove for bug 332576
+ <plugin
+ id="org.eclipse.e4.ui.css.legacy"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+-->
+ <plugin
+ id="org.eclipse.e4.demo.contacts"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+</feature>
diff --git a/features/org.eclipse.e4.ui.feature/.project b/features/org.eclipse.e4.ui.feature/.project
new file mode 100644
index 0000000..d2c42bf
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.ui.feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.ui.feature/build.properties b/features/org.eclipse.e4.ui.feature/build.properties
new file mode 100644
index 0000000..5aafe93
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/build.properties
@@ -0,0 +1,5 @@
+bin.includes = feature.xml,\
+ feature.properties
+
+#generate.feature@org.eclipse.e4.resources.rcp.patch.source = org.eclipse.e4.resources.rcp.patch
+#generate.feature@org.eclipse.e4.resources.platform.patch.source = org.eclipse.e4.resources.platform.patch
diff --git a/features/org.eclipse.e4.ui.feature/feature.properties b/features/org.eclipse.e4.ui.feature/feature.properties
new file mode 100644
index 0000000..8df942c
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 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
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 Modeled Workbench (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=The main modeled workbench, SWT renderers, and core services/contexts.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2009 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+ IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+ - Content may be structured and packaged into modules to facilitate delivering,\n\
+ extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+ plug-in fragments ("Fragments"), and features ("Features").\n\
+ - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+ in a directory named "plugins".\n\
+ - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+ Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+ Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+ numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+ - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+ named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+ - The top-level (root) directory\n\
+ - Plug-in and Fragment directories\n\
+ - Inside Plug-ins and Fragments packaged as JARs\n\
+ - Sub-directories of the directory named "src" of certain Plug-ins\n\
+ - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+ - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+ - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+ - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+ - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+ - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+ - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.feature/feature.xml b/features/org.eclipse.e4.ui.feature/feature.xml
new file mode 100644
index 0000000..82a0255
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/feature.xml
@@ -0,0 +1,236 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.e4.ui.feature"
+ label="%featureName"
+ version="0.10.0.qualifier"
+ provider-name="%providerName"
+ image="eclipse_update_120.jpg">
+
+ <description>
+ %description
+ </description>
+
+ <copyright>
+ %copyright
+ </copyright>
+
+ <license url="%licenseURL">
+ %license
+ </license>
+
+ <includes
+ id="org.eclipse.e4.ui.web.feature"
+ version="0.0.0"/>
+
+ <requires>
+ <import feature="org.eclipse.emf.databinding" version="1.0.0.v200808251517" match="compatible"/>
+ <import feature="org.eclipse.emf.ecore" version="2.4.1.v200808251517" match="compatible"/>
+ </requires>
+
+ <plugin
+ id="org.eclipse.e4.core.services"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.model.workbench"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.model.workbench.edit"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.services"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.workbench"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.core.javascript"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.mozilla.javascript"
+ download-size="0"
+ install-size="0"
+ version="1.7.2.qualifier"
+ unpack="false"/>
+
+ <plugin
+ id="javax.xml"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.workbench.renderers.swt"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.workbench.addons.swt"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.workbench.swt"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.pde.ui"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.pde.webui"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.dojotoolkit"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.core.commands"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="javax.inject"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="javax.annotation"
+ download-size="0"
+ install-size="0"
+ version="1.0.0.qualifier"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.bindings"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.workbench3"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.pushingpixels.trident"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.core.contexts"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.core.contexts.debug"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.core.di"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.core.di.extensions"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.di"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.widgets"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.workbench.renderers.swt.cocoa"
+ os="macosx"
+ ws="cocoa"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ fragment="true"
+ unpack="false"/>
+
+ <plugin
+ id="org.apache.commons.jxpath"
+ download-size="0"
+ install-size="0"
+ version="1.3.0.qualifier"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.emf.xpath"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+</feature>
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/eclipse_update_120.jpg b/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/eclipse_update_120.jpg
new file mode 100755
index 0000000..bfdf708
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/eclipse_update_120.jpg
Binary files differ
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/epl-v10.html b/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/epl-v10.html
new file mode 100755
index 0000000..ed4b196
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/epl-v10.html
@@ -0,0 +1,328 @@
+<html xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link rel=File-List
+href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
+<title>Eclipse Public License - Version 1.0</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+ <o:Revision>2</o:Revision>
+ <o:TotalTime>3</o:TotalTime>
+ <o:Created>2004-03-05T23:03:00Z</o:Created>
+ <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
+ <o:Pages>4</o:Pages>
+ <o:Words>1626</o:Words>
+ <o:Characters>9270</o:Characters>
+ <o:Lines>77</o:Lines>
+ <o:Paragraphs>18</o:Paragraphs>
+ <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
+ <o:Version>9.4402</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:WordDocument>
+ <w:TrackRevisions/>
+ </w:WordDocument>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+@font-face
+ {font-family:Tahoma;
+ panose-1:2 11 6 4 3 5 4 4 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:553679495 -2147483648 8 0 66047 0;}
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+ {mso-style-parent:"";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";}
+p
+ {margin-right:0in;
+ mso-margin-top-alt:auto;
+ mso-margin-bottom-alt:auto;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";}
+p.BalloonText, li.BalloonText, div.BalloonText
+ {mso-style-name:"Balloon Text";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:8.0pt;
+ font-family:Tahoma;
+ mso-fareast-font-family:"Times New Roman";}
+@page Section1
+ {size:8.5in 11.0in;
+ margin:1.0in 1.25in 1.0in 1.25in;
+ mso-header-margin:.5in;
+ mso-footer-margin:.5in;
+ mso-paper-source:0;}
+div.Section1
+ {page:Section1;}
+-->
+</style>
+</head>
+
+<body lang=EN-US style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
+</p>
+
+<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
+THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE,
+REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
+OF THIS AGREEMENT.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>"Contribution" means:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+in the case of the initial Contributor, the initial code and documentation
+distributed under this Agreement, and<br clear=left>
+b) in the case of each subsequent Contributor:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+changes to the Program, and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+additions to the Program;</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
+such changes and/or additions to the Program originate from and are distributed
+by that particular Contributor. A Contribution 'originates' from a Contributor
+if it was added to the Program by such Contributor itself or anyone acting on
+such Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in conjunction
+with the Program under their own license agreement, and (ii) are not derivative
+works of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>"Contributor" means any person or
+entity that distributes the Program.</span> </p>
+
+<p><span style='font-size:10.0pt'>"Licensed Patents " mean patent
+claims licensable by a Contributor which are necessarily infringed by the use
+or sale of its Contribution alone or when combined with the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>"Program" means the Contributions
+distributed in accordance with this Agreement.</span> </p>
+
+<p><span style='font-size:10.0pt'>"Recipient" means anyone who
+receives the Program under this Agreement, including all Contributors.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+Subject to the terms of this Agreement, each Contributor hereby grants Recipient
+a non-exclusive, worldwide, royalty-free copyright license to<span
+style='color:red'> </span>reproduce, prepare derivative works of, publicly
+display, publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and object code
+form.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
+patent license under Licensed Patents to make, use, sell, offer to sell, import
+and otherwise transfer the Contribution of such Contributor, if any, in source
+code and object code form. This patent license shall apply to the combination
+of the Contribution and the Program if, at the time the Contribution is added
+by the Contributor, such addition of the Contribution causes such combination
+to be covered by the Licensed Patents. The patent license shall not apply to
+any other combinations which include the Contribution. No hardware per se is
+licensed hereunder. </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
+Recipient understands that although each Contributor grants the licenses to its
+Contributions set forth herein, no assurances are provided by any Contributor
+that the Program does not infringe the patent or other intellectual property
+rights of any other entity. Each Contributor disclaims any liability to Recipient
+for claims brought by any other entity based on infringement of intellectual
+property rights or otherwise. As a condition to exercising the rights and
+licenses granted hereunder, each Recipient hereby assumes sole responsibility
+to secure any other intellectual property rights needed, if any. For example,
+if a third party patent license is required to allow Recipient to distribute
+the Program, it is Recipient's responsibility to acquire that license before
+distributing the Program.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
+Each Contributor represents that to its knowledge it has sufficient copyright
+rights in its Contribution, if any, to grant the copyright license set forth in
+this Agreement. </span></p>
+
+<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
+Program in object code form under its own license agreement, provided that:</span>
+</p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it complies with the terms and conditions of this Agreement; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+its license agreement:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title
+and non-infringement, and implied warranties or conditions of merchantability
+and fitness for a particular purpose; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+effectively excludes on behalf of all Contributors all liability for damages,
+including direct, indirect, special, incidental and consequential damages, such
+as lost profits; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
+states that any provisions which differ from this Agreement are offered by that
+Contributor alone and not by any other party; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
+states that source code for the Program is available from such Contributor, and
+informs licensees how to obtain it in a reasonable manner on or through a
+medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
+
+<p><span style='font-size:10.0pt'>When the Program is made available in source
+code form:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it must be made available under this Agreement; and </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
+copy of this Agreement must be included with each copy of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
+copyright notices contained within the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
+originator of its Contribution, if any, in a manner that reasonably allows
+subsequent Recipients to identify the originator of the Contribution. </span></p>
+
+<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
+
+<p><span style='font-size:10.0pt'>Commercial distributors of software may
+accept certain responsibilities with respect to end users, business partners
+and the like. While this license is intended to facilitate the commercial use
+of the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes the
+Program in a commercial product offering, such Contributor ("Commercial
+Contributor") hereby agrees to defend and indemnify every other
+Contributor ("Indemnified Contributor") against any losses, damages and
+costs (collectively "Losses") arising from claims, lawsuits and other
+legal actions brought by a third party against the Indemnified Contributor to
+the extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may participate
+in any such claim at its own expense.</span> </p>
+
+<p><span style='font-size:10.0pt'>For example, a Contributor might include the
+Program in a commercial product offering, Product X. That Contributor is then a
+Commercial Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance claims and
+warranties are such Commercial Contributor's responsibility alone. Under this
+section, the Commercial Contributor would have to defend claims against the
+other Contributors related to those performance claims and warranties, and if a
+court requires any other Contributor to pay any damages as a result, the
+Commercial Contributor must pay those damages.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
+WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and distributing the
+Program and assumes all risks associated with its exercise of rights under this
+Agreement , including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs or
+equipment, and unavailability or interruption of operations. </span></p>
+
+<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
+THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
+
+<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
+or unenforceable under applicable law, it shall not affect the validity or
+enforceability of the remainder of the terms of this Agreement, and without
+further action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.</span> </p>
+
+<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
+against any entity (including a cross-claim or counterclaim in a lawsuit)
+alleging that the Program itself (excluding combinations of the Program with
+other software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the date
+such litigation is filed. </span></p>
+
+<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
+shall terminate if it fails to comply with any of the material terms or
+conditions of this Agreement and does not cure such failure in a reasonable
+period of time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive. </span></p>
+
+<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
+copies of this Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The Agreement
+Steward reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement Steward has
+the right to modify this Agreement. The Eclipse Foundation is the initial
+Agreement Steward. The Eclipse Foundation may assign the responsibility to
+serve as the Agreement Steward to a suitable separate entity. Each new version
+of the Agreement will be given a distinguishing version number. The Program
+(including Contributions) may always be distributed subject to the version of
+the Agreement under which it was received. In addition, after a new version of
+the Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly stated
+in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.</span> </p>
+
+<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
+State of New York and the intellectual property laws of the United States of
+America. No party to this Agreement will bring a legal action under this
+Agreement more than one year after the cause of action arose. Each party waives
+its rights to a jury trial in any resulting litigation.</span> </p>
+
+<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html>
\ No newline at end of file
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/feature.properties b/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/feature.properties
new file mode 100755
index 0000000..cfedcc8
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/feature.properties
@@ -0,0 +1,144 @@
+###############################################################################
+# Copyright (c) 2000, 2007 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
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 Modeled Workbench Source (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "description" property - description of the feature
+description=Source code zips for Eclipse E4 initiative.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2007 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+ IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+ - Content may be structured and packaged into modules to facilitate delivering,\n\
+ extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+ plug-in fragments ("Fragments"), and features ("Features").\n\
+ - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+ in a directory named "plugins".\n\
+ - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+ Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+ Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+ numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+ - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+ named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+ - The top-level (root) directory\n\
+ - Plug-in and Fragment directories\n\
+ - Inside Plug-ins and Fragments packaged as JARs\n\
+ - Sub-directories of the directory named "src" of certain Plug-ins\n\
+ - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+ - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+ - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+ - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+ - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+ - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+ - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/license.html b/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/license.html
new file mode 100755
index 0000000..c6af966
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplateFeature/license.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=iso-8859-1">
+<title>Eclipse.org Software User Agreement</title>
+</head>
+
+<body lang="EN-US" link=blue vlink=purple>
+<h2>Eclipse Foundation Software User Agreement</h2>
+<p>March 17, 2005</p>
+
+<h3>Usage Of Content</h3>
+
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+ (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+ CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+ OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+ NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+ CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
+
+<h3>Applicable Licenses</h3>
+
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
+ ("EPL"). A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+ For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS
+ modules ("Modules") and made available as downloadable archives ("Downloads").</p>
+
+<ul>
+ <li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").</li>
+ <li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".</li>
+ <li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins
+ and/or Fragments associated with that Feature.</li>
+ <li>Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.</li>
+</ul>
+
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and
+Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p>
+
+<ul>
+ <li>The top-level (root) directory</li>
+ <li>Plug-in and Fragment directories</li>
+ <li>Inside Plug-ins and Fragments packaged as JARs</li>
+ <li>Sub-directories of the directory named "src" of certain Plug-ins</li>
+ <li>Feature directories</li>
+</ul>
+
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the
+installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p>
+
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
+
+<ul>
+ <li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
+ <li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
+ <li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
+ <li>IBM Public License 1.0 (available at <a href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</a>)</li>
+ <li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
+ <li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
+</ul>
+
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
+
+<h3>Cryptography</h3>
+
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+ another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+ possession, or use, and re-export of encryption software, to see if this is permitted.</p>
+
+<small>Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.</small>
+</body>
+</html>
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.html b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.html
new file mode 100755
index 0000000..c207d05
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>May 10, 2006</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+<h3>Source Code</h3>
+<p>This plug-in contains source code zip files ("Source Zips") that correspond to binary content in other plug-ins. These Source Zips may be distributed under different license
+agreements and/or notices. Details about these license agreements and notices are contained in "about.html" files ("Abouts") located in sub-directories in the
+src/ directory of this plug-in. Such Abouts govern your use of the Source Zips in that directory, not the EPL.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.ini b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.ini
new file mode 100755
index 0000000..5dfa1c0
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.ini
@@ -0,0 +1,29 @@
+# about.ini
+# contains information about a feature
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# "%key" are externalized strings defined in about.properties
+# This file does not need to be translated.
+
+# Property "aboutText" contains blurb for "About" dialog (translated)
+aboutText=%blurb
+
+# Property "windowImage" contains path to window icon (16x16)
+# needed for primary features only
+
+# Property "featureImage" contains path to feature image (32x32)
+featureImage=eclipse32.png
+
+# Property "aboutImage" contains path to product image (500x330 or 115x164)
+# needed for primary features only
+
+# Property "appName" contains name of the application (not translated)
+# needed for primary features only
+
+# Property "welcomePage" contains path to welcome page (special XML-based format)
+# optional
+
+# Property "welcomePerspective" contains the id of the perspective in which the
+# welcome page is to be opened.
+# optional
+
+
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.mappings b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.mappings
new file mode 100755
index 0000000..0dfb735
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.mappings
@@ -0,0 +1,6 @@
+# about.mappings
+# contains fill-ins for about.properties
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file does not need to be translated.
+
+0=@build@
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.properties b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.properties
new file mode 100755
index 0000000..8087967
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/about.properties
@@ -0,0 +1,24 @@
+###############################################################################
+# Copyright (c) 2000, 2007 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
+###############################################################################
+# about.properties
+# contains externalized strings for about.ini
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# fill-ins are supplied by about.mappings
+# This file should be translated.
+
+blurb=Eclipse E4 SDK\n\
+\n\
+Version: {featureVersion}\n\
+Build id: {0}\n\
+\n\
+(c) Copyright Eclipse contributors and others 2000, 2007. All rights reserved.\n\
+Visit http://wiki.eclipse.org/E4
+
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/build.properties b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/build.properties
new file mode 100755
index 0000000..df97790
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/build.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2000, 2006 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
+###############################################################################
+bin.includes = about.html, about.ini, about.mappings, about.properties, eclipse32.png, plugin.properties, plugin.xml, src/**, META-INF/
+sourcePlugin = true
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/eclipse32.gif b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/eclipse32.gif
new file mode 100755
index 0000000..e6ad7cc
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/eclipse32.gif
Binary files differ
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/eclipse32.png b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/eclipse32.png
new file mode 100755
index 0000000..568fac1
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/eclipse32.png
Binary files differ
diff --git a/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/plugin.properties b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/plugin.properties
new file mode 100755
index 0000000..625bcdc
--- /dev/null
+++ b/features/org.eclipse.e4.ui.feature/sourceTemplatePlugin/plugin.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2000, 2005 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
+###############################################################################
+pluginName=Eclipse E4 SDK
+providerName=Eclipse.org
diff --git a/features/org.eclipse.e4.ui.tests.feature/.project b/features/org.eclipse.e4.ui.tests.feature/.project
new file mode 100644
index 0000000..2695291
--- /dev/null
+++ b/features/org.eclipse.e4.ui.tests.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.ui.tests.feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.ui.tests.feature/build.properties b/features/org.eclipse.e4.ui.tests.feature/build.properties
new file mode 100644
index 0000000..b3a611b
--- /dev/null
+++ b/features/org.eclipse.e4.ui.tests.feature/build.properties
@@ -0,0 +1,2 @@
+bin.includes = feature.xml,\
+ feature.properties
diff --git a/features/org.eclipse.e4.ui.tests.feature/feature.properties b/features/org.eclipse.e4.ui.tests.feature/feature.properties
new file mode 100644
index 0000000..e836e78
--- /dev/null
+++ b/features/org.eclipse.e4.ui.tests.feature/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 2005 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
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 Modeled Workbench Tests (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=Tests for the modeled workbench
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2008 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+ IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+ - Content may be structured and packaged into modules to facilitate delivering,\n\
+ extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+ plug-in fragments ("Fragments"), and features ("Features").\n\
+ - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+ in a directory named "plugins".\n\
+ - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+ Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+ Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+ numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+ - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+ named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+ - The top-level (root) directory\n\
+ - Plug-in and Fragment directories\n\
+ - Inside Plug-ins and Fragments packaged as JARs\n\
+ - Sub-directories of the directory named "src" of certain Plug-ins\n\
+ - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+ - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+ - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+ - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+ - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+ - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+ - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.tests.feature/feature.xml b/features/org.eclipse.e4.ui.tests.feature/feature.xml
new file mode 100644
index 0000000..4162d22
--- /dev/null
+++ b/features/org.eclipse.e4.ui.tests.feature/feature.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.e4.ui.tests.feature"
+ label="%featureName"
+ version="0.9.1.qualifier"
+ provider-name="%providerName">
+
+ <description>
+ %description
+ </description>
+
+ <copyright>
+ %copyright
+ </copyright>
+
+ <license url="%licenseURL">
+ %license
+ </license>
+
+ <requires>
+ <import feature="org.eclipse.e4.ui.css.feature" version="0.9.0" match="compatible"/>
+ <import feature="org.eclipse.e4.ui.feature" version="0.9.0" match="compatible"/>
+ <import feature="org.eclipse.e4.tests.base.feature" version="0.9.0" match="compatible"/>
+ </requires>
+
+ <plugin
+ id="org.eclipse.e4.ui.tests.css.swt"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.tests.css.core"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"/>
+
+ <plugin
+ id="org.eclipse.e4.core.tests.services"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.tests"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"/>
+
+ <plugin
+ id="org.eclipse.e4.core.commands.tests"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.bindings.tests"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"/>
+
+ <plugin
+ id="org.eclipse.e4.core.tests"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"/>
+
+ <plugin
+ id="com.google.code.atinject.tck"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.menu.tests"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.menu.tests.p1"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+ <plugin
+ id="org.eclipse.e4.ui.menu.tests.p2"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+ <plugin
+ id="org.eclipse.e4.ui.menu.tests.p3"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+ <plugin
+ id="org.eclipse.e4.ui.menu.tests.p4"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+</feature>
diff --git a/features/org.eclipse.e4.ui.web.feature/.project b/features/org.eclipse.e4.ui.web.feature/.project
new file mode 100644
index 0000000..cf972dd
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.ui.web.feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/features/org.eclipse.e4.ui.web.feature/build.properties b/features/org.eclipse.e4.ui.web.feature/build.properties
new file mode 100644
index 0000000..b3a611b
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/build.properties
@@ -0,0 +1,2 @@
+bin.includes = feature.xml,\
+ feature.properties
diff --git a/features/org.eclipse.e4.ui.web.feature/feature.properties b/features/org.eclipse.e4.ui.web.feature/feature.properties
new file mode 100755
index 0000000..2f654ba
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/feature.properties
@@ -0,0 +1,148 @@
+###############################################################################
+# Copyright (c) 2000, 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
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 Web Gadget (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "secondarySiteName" property - label for the update site
+secondaryUpdateSiteName=Ganymede Discovery Site
+
+
+# "description" property - description of the feature
+description=Provides web support for views and for loading in Social Gadgets
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2009 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+ IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+ - Content may be structured and packaged into modules to facilitate delivering,\n\
+ extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+ plug-in fragments ("Fragments"), and features ("Features").\n\
+ - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+ in a directory named "plugins".\n\
+ - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+ Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+ Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+ numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+ - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+ named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+ - The top-level (root) directory\n\
+ - Plug-in and Fragment directories\n\
+ - Inside Plug-ins and Fragments packaged as JARs\n\
+ - Sub-directories of the directory named "src" of certain Plug-ins\n\
+ - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+ - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+ - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+ - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+ - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+ - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+ - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.web.feature/feature.xml b/features/org.eclipse.e4.ui.web.feature/feature.xml
new file mode 100644
index 0000000..b739511
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/feature.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.e4.ui.web.feature"
+ label="%featureName"
+ version="0.9.0.qualifier"
+ provider-name="%providerName"
+ image="eclipse_update_120.jpg">
+
+ <description>
+ %description
+ </description>
+
+ <copyright>
+ %copyright
+ </copyright>
+
+ <license url="%licenseURL">
+ %license
+ </license>
+
+ <plugin
+ id="org.eclipse.e4.ui.web"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.eclipse.e4.ui.gadgets"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+</feature>
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/eclipse_update_120.jpg b/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/eclipse_update_120.jpg
new file mode 100755
index 0000000..bfdf708
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/eclipse_update_120.jpg
Binary files differ
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/epl-v10.html b/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/epl-v10.html
new file mode 100755
index 0000000..ed4b196
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/epl-v10.html
@@ -0,0 +1,328 @@
+<html xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link rel=File-List
+href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
+<title>Eclipse Public License - Version 1.0</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+ <o:Revision>2</o:Revision>
+ <o:TotalTime>3</o:TotalTime>
+ <o:Created>2004-03-05T23:03:00Z</o:Created>
+ <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
+ <o:Pages>4</o:Pages>
+ <o:Words>1626</o:Words>
+ <o:Characters>9270</o:Characters>
+ <o:Lines>77</o:Lines>
+ <o:Paragraphs>18</o:Paragraphs>
+ <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
+ <o:Version>9.4402</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:WordDocument>
+ <w:TrackRevisions/>
+ </w:WordDocument>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+@font-face
+ {font-family:Tahoma;
+ panose-1:2 11 6 4 3 5 4 4 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:553679495 -2147483648 8 0 66047 0;}
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+ {mso-style-parent:"";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";}
+p
+ {margin-right:0in;
+ mso-margin-top-alt:auto;
+ mso-margin-bottom-alt:auto;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";}
+p.BalloonText, li.BalloonText, div.BalloonText
+ {mso-style-name:"Balloon Text";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:8.0pt;
+ font-family:Tahoma;
+ mso-fareast-font-family:"Times New Roman";}
+@page Section1
+ {size:8.5in 11.0in;
+ margin:1.0in 1.25in 1.0in 1.25in;
+ mso-header-margin:.5in;
+ mso-footer-margin:.5in;
+ mso-paper-source:0;}
+div.Section1
+ {page:Section1;}
+-->
+</style>
+</head>
+
+<body lang=EN-US style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
+</p>
+
+<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
+THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE,
+REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
+OF THIS AGREEMENT.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>"Contribution" means:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+in the case of the initial Contributor, the initial code and documentation
+distributed under this Agreement, and<br clear=left>
+b) in the case of each subsequent Contributor:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+changes to the Program, and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+additions to the Program;</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
+such changes and/or additions to the Program originate from and are distributed
+by that particular Contributor. A Contribution 'originates' from a Contributor
+if it was added to the Program by such Contributor itself or anyone acting on
+such Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in conjunction
+with the Program under their own license agreement, and (ii) are not derivative
+works of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>"Contributor" means any person or
+entity that distributes the Program.</span> </p>
+
+<p><span style='font-size:10.0pt'>"Licensed Patents " mean patent
+claims licensable by a Contributor which are necessarily infringed by the use
+or sale of its Contribution alone or when combined with the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>"Program" means the Contributions
+distributed in accordance with this Agreement.</span> </p>
+
+<p><span style='font-size:10.0pt'>"Recipient" means anyone who
+receives the Program under this Agreement, including all Contributors.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+Subject to the terms of this Agreement, each Contributor hereby grants Recipient
+a non-exclusive, worldwide, royalty-free copyright license to<span
+style='color:red'> </span>reproduce, prepare derivative works of, publicly
+display, publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and object code
+form.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
+patent license under Licensed Patents to make, use, sell, offer to sell, import
+and otherwise transfer the Contribution of such Contributor, if any, in source
+code and object code form. This patent license shall apply to the combination
+of the Contribution and the Program if, at the time the Contribution is added
+by the Contributor, such addition of the Contribution causes such combination
+to be covered by the Licensed Patents. The patent license shall not apply to
+any other combinations which include the Contribution. No hardware per se is
+licensed hereunder. </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
+Recipient understands that although each Contributor grants the licenses to its
+Contributions set forth herein, no assurances are provided by any Contributor
+that the Program does not infringe the patent or other intellectual property
+rights of any other entity. Each Contributor disclaims any liability to Recipient
+for claims brought by any other entity based on infringement of intellectual
+property rights or otherwise. As a condition to exercising the rights and
+licenses granted hereunder, each Recipient hereby assumes sole responsibility
+to secure any other intellectual property rights needed, if any. For example,
+if a third party patent license is required to allow Recipient to distribute
+the Program, it is Recipient's responsibility to acquire that license before
+distributing the Program.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
+Each Contributor represents that to its knowledge it has sufficient copyright
+rights in its Contribution, if any, to grant the copyright license set forth in
+this Agreement. </span></p>
+
+<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
+Program in object code form under its own license agreement, provided that:</span>
+</p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it complies with the terms and conditions of this Agreement; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+its license agreement:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title
+and non-infringement, and implied warranties or conditions of merchantability
+and fitness for a particular purpose; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+effectively excludes on behalf of all Contributors all liability for damages,
+including direct, indirect, special, incidental and consequential damages, such
+as lost profits; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
+states that any provisions which differ from this Agreement are offered by that
+Contributor alone and not by any other party; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
+states that source code for the Program is available from such Contributor, and
+informs licensees how to obtain it in a reasonable manner on or through a
+medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
+
+<p><span style='font-size:10.0pt'>When the Program is made available in source
+code form:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it must be made available under this Agreement; and </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
+copy of this Agreement must be included with each copy of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
+copyright notices contained within the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
+originator of its Contribution, if any, in a manner that reasonably allows
+subsequent Recipients to identify the originator of the Contribution. </span></p>
+
+<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
+
+<p><span style='font-size:10.0pt'>Commercial distributors of software may
+accept certain responsibilities with respect to end users, business partners
+and the like. While this license is intended to facilitate the commercial use
+of the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes the
+Program in a commercial product offering, such Contributor ("Commercial
+Contributor") hereby agrees to defend and indemnify every other
+Contributor ("Indemnified Contributor") against any losses, damages and
+costs (collectively "Losses") arising from claims, lawsuits and other
+legal actions brought by a third party against the Indemnified Contributor to
+the extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may participate
+in any such claim at its own expense.</span> </p>
+
+<p><span style='font-size:10.0pt'>For example, a Contributor might include the
+Program in a commercial product offering, Product X. That Contributor is then a
+Commercial Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance claims and
+warranties are such Commercial Contributor's responsibility alone. Under this
+section, the Commercial Contributor would have to defend claims against the
+other Contributors related to those performance claims and warranties, and if a
+court requires any other Contributor to pay any damages as a result, the
+Commercial Contributor must pay those damages.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
+WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and distributing the
+Program and assumes all risks associated with its exercise of rights under this
+Agreement , including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs or
+equipment, and unavailability or interruption of operations. </span></p>
+
+<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
+THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
+
+<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
+or unenforceable under applicable law, it shall not affect the validity or
+enforceability of the remainder of the terms of this Agreement, and without
+further action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.</span> </p>
+
+<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
+against any entity (including a cross-claim or counterclaim in a lawsuit)
+alleging that the Program itself (excluding combinations of the Program with
+other software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the date
+such litigation is filed. </span></p>
+
+<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
+shall terminate if it fails to comply with any of the material terms or
+conditions of this Agreement and does not cure such failure in a reasonable
+period of time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive. </span></p>
+
+<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
+copies of this Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The Agreement
+Steward reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement Steward has
+the right to modify this Agreement. The Eclipse Foundation is the initial
+Agreement Steward. The Eclipse Foundation may assign the responsibility to
+serve as the Agreement Steward to a suitable separate entity. Each new version
+of the Agreement will be given a distinguishing version number. The Program
+(including Contributions) may always be distributed subject to the version of
+the Agreement under which it was received. In addition, after a new version of
+the Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly stated
+in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.</span> </p>
+
+<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
+State of New York and the intellectual property laws of the United States of
+America. No party to this Agreement will bring a legal action under this
+Agreement more than one year after the cause of action arose. Each party waives
+its rights to a jury trial in any resulting litigation.</span> </p>
+
+<p class=MsoNormal><![if !supportEmptyParas]> <![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html>
\ No newline at end of file
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/feature.properties b/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/feature.properties
new file mode 100755
index 0000000..dbf3795
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/feature.properties
@@ -0,0 +1,144 @@
+###############################################################################
+# Copyright (c) 2000, 2007 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
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse e4 Web Gadget Source (Incubation)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Project Updates
+
+# "description" property - description of the feature
+description=Source code zips for Eclipse E4 initiative.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2007 IBM Corporation and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+ IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+March 17, 2005\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+ - Content may be structured and packaged into modules to facilitate delivering,\n\
+ extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+ plug-in fragments ("Fragments"), and features ("Features").\n\
+ - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+ in a directory named "plugins".\n\
+ - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+ Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+ Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+ numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+ - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+ named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+ - The top-level (root) directory\n\
+ - Plug-in and Fragment directories\n\
+ - Inside Plug-ins and Fragments packaged as JARs\n\
+ - Sub-directories of the directory named "src" of certain Plug-ins\n\
+ - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+ - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+ - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+ - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+ - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+ - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+ - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/license.html b/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/license.html
new file mode 100755
index 0000000..c6af966
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplateFeature/license.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=iso-8859-1">
+<title>Eclipse.org Software User Agreement</title>
+</head>
+
+<body lang="EN-US" link=blue vlink=purple>
+<h2>Eclipse Foundation Software User Agreement</h2>
+<p>March 17, 2005</p>
+
+<h3>Usage Of Content</h3>
+
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+ (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+ CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+ OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+ NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+ CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
+
+<h3>Applicable Licenses</h3>
+
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
+ ("EPL"). A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+ For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse.org CVS repository ("Repository") in CVS
+ modules ("Modules") and made available as downloadable archives ("Downloads").</p>
+
+<ul>
+ <li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").</li>
+ <li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".</li>
+ <li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins
+ and/or Fragments associated with that Feature.</li>
+ <li>Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.</li>
+</ul>
+
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and
+Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p>
+
+<ul>
+ <li>The top-level (root) directory</li>
+ <li>Plug-in and Fragment directories</li>
+ <li>Inside Plug-ins and Fragments packaged as JARs</li>
+ <li>Sub-directories of the directory named "src" of certain Plug-ins</li>
+ <li>Feature directories</li>
+</ul>
+
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Eclipse Update Manager, you must agree to a license ("Feature Update License") during the
+installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p>
+
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
+
+<ul>
+ <li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
+ <li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
+ <li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
+ <li>IBM Public License 1.0 (available at <a href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</a>)</li>
+ <li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
+ <li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
+</ul>
+
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
+
+<h3>Cryptography</h3>
+
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+ another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+ possession, or use, and re-export of encryption software, to see if this is permitted.</p>
+
+<small>Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.</small>
+</body>
+</html>
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.html b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.html
new file mode 100755
index 0000000..c207d05
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>May 10, 2006</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+<h3>Source Code</h3>
+<p>This plug-in contains source code zip files ("Source Zips") that correspond to binary content in other plug-ins. These Source Zips may be distributed under different license
+agreements and/or notices. Details about these license agreements and notices are contained in "about.html" files ("Abouts") located in sub-directories in the
+src/ directory of this plug-in. Such Abouts govern your use of the Source Zips in that directory, not the EPL.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.ini b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.ini
new file mode 100755
index 0000000..5dfa1c0
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.ini
@@ -0,0 +1,29 @@
+# about.ini
+# contains information about a feature
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# "%key" are externalized strings defined in about.properties
+# This file does not need to be translated.
+
+# Property "aboutText" contains blurb for "About" dialog (translated)
+aboutText=%blurb
+
+# Property "windowImage" contains path to window icon (16x16)
+# needed for primary features only
+
+# Property "featureImage" contains path to feature image (32x32)
+featureImage=eclipse32.png
+
+# Property "aboutImage" contains path to product image (500x330 or 115x164)
+# needed for primary features only
+
+# Property "appName" contains name of the application (not translated)
+# needed for primary features only
+
+# Property "welcomePage" contains path to welcome page (special XML-based format)
+# optional
+
+# Property "welcomePerspective" contains the id of the perspective in which the
+# welcome page is to be opened.
+# optional
+
+
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.mappings b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.mappings
new file mode 100755
index 0000000..0dfb735
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.mappings
@@ -0,0 +1,6 @@
+# about.mappings
+# contains fill-ins for about.properties
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file does not need to be translated.
+
+0=@build@
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.properties b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.properties
new file mode 100755
index 0000000..8087967
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/about.properties
@@ -0,0 +1,24 @@
+###############################################################################
+# Copyright (c) 2000, 2007 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
+###############################################################################
+# about.properties
+# contains externalized strings for about.ini
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# fill-ins are supplied by about.mappings
+# This file should be translated.
+
+blurb=Eclipse E4 SDK\n\
+\n\
+Version: {featureVersion}\n\
+Build id: {0}\n\
+\n\
+(c) Copyright Eclipse contributors and others 2000, 2007. All rights reserved.\n\
+Visit http://wiki.eclipse.org/E4
+
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/build.properties b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/build.properties
new file mode 100755
index 0000000..df97790
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/build.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2000, 2006 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
+###############################################################################
+bin.includes = about.html, about.ini, about.mappings, about.properties, eclipse32.png, plugin.properties, plugin.xml, src/**, META-INF/
+sourcePlugin = true
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/eclipse32.gif b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/eclipse32.gif
new file mode 100755
index 0000000..e6ad7cc
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/eclipse32.gif
Binary files differ
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/eclipse32.png b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/eclipse32.png
new file mode 100755
index 0000000..568fac1
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/eclipse32.png
Binary files differ
diff --git a/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/plugin.properties b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/plugin.properties
new file mode 100755
index 0000000..ca5f27f
--- /dev/null
+++ b/features/org.eclipse.e4.ui.web.feature/sourceTemplatePlugin/plugin.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2000, 2005 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
+###############################################################################
+pluginName=Eclipse e4 Web Gadgets Source
+providerName=Eclipse.org
diff --git a/tests/org.eclipse.e4.ui.selection.tests/.classpath b/tests/org.eclipse.e4.ui.selection.tests/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.selection.tests/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tests/org.eclipse.e4.ui.selection.tests/.project b/tests/org.eclipse.e4.ui.selection.tests/.project
new file mode 100644
index 0000000..09827d4
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.selection.tests/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.ui.selection.tests</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/tests/org.eclipse.e4.ui.selection.tests/.settings/org.eclipse.jdt.core.prefs b/tests/org.eclipse.e4.ui.selection.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..ce20b75
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.selection.tests/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Thu Nov 12 13:03:36 EST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/tests/org.eclipse.e4.ui.selection.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.e4.ui.selection.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..da95fee
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.selection.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Selection Tests
+Bundle-SymbolicName: org.eclipse.e4.ui.selection.tests
+Bundle-Version: 0.9.0.qualifier
+Bundle-Activator: org.eclipse.e4.ui.selection.tests.Activator
+Require-Bundle: org.eclipse.core.runtime,
+ org.junit
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Import-Package: javax.inject;version="1.0.0",
+ org.eclipse.e4.core.services,
+ org.eclipse.e4.core.services.annotations,
+ org.eclipse.e4.core.services.context,
+ org.eclipse.e4.core.services.context.spi,
+ org.eclipse.e4.ui.selection,
+ org.osgi.service.log;version="1.3.0"
diff --git a/tests/org.eclipse.e4.ui.selection.tests/build.properties b/tests/org.eclipse.e4.ui.selection.tests/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.selection.tests/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/Activator.java b/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/Activator.java
new file mode 100644
index 0000000..826d941
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/Activator.java
@@ -0,0 +1,85 @@
+package org.eclipse.e4.ui.selection.tests;
+
+import org.eclipse.e4.core.services.IDisposable;
+import org.eclipse.e4.core.services.context.EclipseContextFactory;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+public class Activator implements BundleActivator {
+
+ private static Activator plugin = null;
+ private IEclipseContext appContext;
+ private IEclipseContext serviceContext;
+
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ public void start(BundleContext context) throws Exception {
+ plugin = this;
+ serviceContext = EclipseContextFactory.getServiceContext(context);
+ appContext = EclipseContextFactory.create(serviceContext, null);
+ addLogService(appContext);
+ }
+
+ private void addLogService(IEclipseContext context) {
+ context.set(LogService.class.getName(), new LogService() {
+
+ public void log(int level, String message) {
+ System.out.println(level + ": " + message);
+ }
+
+ public void log(int level, String message, Throwable exception) {
+ System.out.println(level + ": " + message);
+ if (exception != null) {
+ exception.printStackTrace();
+ }
+ }
+
+ public void log(ServiceReference sr, int level, String message) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void log(ServiceReference sr, int level, String message,
+ Throwable exception) {
+ // TODO Auto-generated method stub
+
+ }
+ });
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ if (serviceContext instanceof IDisposable) {
+ ((IDisposable) serviceContext).dispose();
+ }
+ plugin = null;
+ }
+
+ public IEclipseContext getGlobalContext() {
+ return appContext;
+ }
+
+ public PackageAdmin getBundleAdmin() {
+ return (PackageAdmin) serviceContext.get(PackageAdmin.class.getName());
+ }
+
+ public Bundle getBundleForName(String bundleName) {
+ Bundle[] bundles = getBundleAdmin().getBundles(bundleName, null);
+ if (bundles == null)
+ return null;
+ // Return the first bundle that is not installed or uninstalled
+ for (int i = 0; i < bundles.length; i++) {
+ if ((bundles[i].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {
+ return bundles[i];
+ }
+ }
+ return null;
+ }
+}
+
diff --git a/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/SelectionTest.java b/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/SelectionTest.java
new file mode 100644
index 0000000..1745714
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/SelectionTest.java
@@ -0,0 +1,245 @@
+package org.eclipse.e4.ui.selection.tests;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import junit.framework.TestCase;
+
+import org.eclipse.e4.core.services.IDisposable;
+import org.eclipse.e4.core.services.annotations.Optional;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.ContextInjectionFactory;
+import org.eclipse.e4.core.services.context.spi.IContextConstants;
+import org.eclipse.e4.ui.selection.ESelectionService;
+
+public class SelectionTest extends TestCase {
+
+ private static final String SEL_TWO = "two";
+ private static final String SEL_ONE = "one";
+
+ static class ConsumerPart {
+ public String input;
+
+ @Inject
+ @Optional
+ public void setInput(@Named(ESelectionService.SELECTION) String current) {
+ input = current;
+ }
+ }
+
+ static class ProviderPart extends ConsumerPart {
+ private ESelectionService selectionService;
+
+ @Inject
+ public void setSelectionService(ESelectionService s) {
+ selectionService = s;
+ }
+
+ public void setSelection(String s) {
+ selectionService.setSelection(s);
+ }
+ }
+
+ static class TrackingProviderPart extends ProviderPart {
+ public String otherSelection;
+
+ public void setOtherSelection(String s) {
+ otherSelection = s;
+ }
+ }
+
+ private IEclipseContext workbenchContext;
+
+ public void testOnePartSelection() throws Exception {
+ ProviderPart p = new ProviderPart();
+ ContextInjectionFactory.inject(p, workbenchContext);
+
+ assertNull(p.input);
+
+ p.setSelection(SEL_ONE);
+ assertEquals(SEL_ONE, p.input);
+ p.setSelection(null);
+ assertNull(p.input);
+ }
+
+ static class UseSelectionHandler {
+ public String selection;
+
+ public void execute(
+ @Optional @Named(ESelectionService.SELECTION) String s) {
+ selection = s;
+ }
+ }
+
+ public void testTwoPartHandlerExecute() throws Exception {
+ IEclipseContext window = TestUtil.createContext(workbenchContext,
+ "windowContext");
+ workbenchContext.set(IContextConstants.ACTIVE_CHILD, window);
+
+ IEclipseContext partOne = TestUtil.createContext(window, "partOne");
+ window.set(IContextConstants.ACTIVE_CHILD, partOne);
+ ProviderPart partOneImpl = new ProviderPart();
+ ContextInjectionFactory.inject(partOneImpl, partOne);
+
+ IEclipseContext partTwo = TestUtil.createContext(window, "partTwo");
+ ConsumerPart partTwoImpl = new ConsumerPart();
+ ContextInjectionFactory.inject(partTwoImpl, partTwo);
+
+ partOneImpl.setSelection(SEL_ONE);
+
+ UseSelectionHandler handler = new UseSelectionHandler();
+ assertNull(handler.selection);
+
+ ContextInjectionFactory.invoke(handler, "execute", workbenchContext,
+ null);
+ assertEquals(SEL_ONE, handler.selection);
+ ContextInjectionFactory.invoke(handler, "execute", window, null);
+ assertEquals(SEL_ONE, handler.selection);
+ ContextInjectionFactory.invoke(handler, "execute", partOne, null);
+ assertEquals(SEL_ONE, handler.selection);
+ ContextInjectionFactory.invoke(handler, "execute", partTwo, null);
+ assertNull(handler.selection);
+
+ window.set(IContextConstants.ACTIVE_CHILD, partTwo);
+
+ ContextInjectionFactory.invoke(handler, "execute", workbenchContext,
+ null);
+ assertNull(handler.selection);
+ ContextInjectionFactory.invoke(handler, "execute", window, null);
+ assertNull(handler.selection);
+ ContextInjectionFactory.invoke(handler, "execute", partOne, null);
+ assertEquals(SEL_ONE, handler.selection);
+ ContextInjectionFactory.invoke(handler, "execute", partTwo, null);
+ assertNull(handler.selection);
+ }
+
+ public void testThreePartSelection() throws Exception {
+ ESelectionService workbenchService = (ESelectionService) workbenchContext
+ .get(ESelectionService.class.getName());
+ IEclipseContext window = TestUtil.createContext(workbenchContext,
+ "windowContext");
+ workbenchContext.set(IContextConstants.ACTIVE_CHILD, window);
+ ESelectionService windowService = (ESelectionService) window
+ .get(ESelectionService.class.getName());
+
+ IEclipseContext partOne = TestUtil.createContext(window, "partOne");
+ window.set(IContextConstants.ACTIVE_CHILD, partOne);
+ ProviderPart partOneImpl = new ProviderPart();
+ ContextInjectionFactory.inject(partOneImpl, partOne);
+
+ IEclipseContext partTwo = TestUtil.createContext(window, "partTwo");
+ ConsumerPart partTwoImpl = new ConsumerPart();
+ ContextInjectionFactory.inject(partTwoImpl, partTwo);
+
+ IEclipseContext partThree = TestUtil.createContext(window, "partThree");
+ ProviderPart partThreeImpl = new ProviderPart();
+ ContextInjectionFactory.inject(partThreeImpl, partThree);
+
+ assertNull(workbenchService.getSelection());
+ assertNull(windowService.getSelection());
+ assertNull(partOneImpl.input);
+ assertNull(partTwoImpl.input);
+ assertNull(partThreeImpl.input);
+
+ partOneImpl.setSelection(SEL_ONE);
+ assertEquals(SEL_ONE, workbenchService.getSelection());
+ assertEquals(SEL_ONE, windowService.getSelection());
+ assertEquals(SEL_ONE, partOneImpl.input);
+ assertNull(partTwoImpl.input);
+ assertNull(partThreeImpl.input);
+
+ partThreeImpl.setSelection(SEL_TWO);
+ assertEquals(SEL_ONE, workbenchService.getSelection());
+ assertEquals(SEL_ONE, windowService.getSelection());
+ assertEquals(SEL_ONE, partOneImpl.input);
+ assertNull(partTwoImpl.input);
+ assertEquals(SEL_TWO, partThreeImpl.input);
+
+ window.set(IContextConstants.ACTIVE_CHILD, partTwo);
+ assertNull(workbenchService.getSelection());
+ assertNull(windowService.getSelection());
+ assertEquals(SEL_ONE, partOneImpl.input);
+ assertNull(partTwoImpl.input);
+ assertEquals(SEL_TWO, partThreeImpl.input);
+
+ window.set(IContextConstants.ACTIVE_CHILD, partThree);
+ assertEquals(SEL_TWO, workbenchService.getSelection());
+ assertEquals(SEL_TWO, windowService.getSelection());
+ assertEquals(SEL_ONE, partOneImpl.input);
+ assertNull(partTwoImpl.input);
+ assertEquals(SEL_TWO, partThreeImpl.input);
+ }
+
+ public void testPartOneTracksPartThree() throws Exception {
+ IEclipseContext window = TestUtil.createContext(workbenchContext,
+ "windowContext");
+ workbenchContext.set(IContextConstants.ACTIVE_CHILD, window);
+
+ IEclipseContext partOne = TestUtil.createContext(window, "partOne");
+ window.set(IContextConstants.ACTIVE_CHILD, partOne);
+ final TrackingProviderPart partOneImpl = new TrackingProviderPart();
+ ContextInjectionFactory.inject(partOneImpl, partOne);
+
+ IEclipseContext partTwo = TestUtil.createContext(window, "partTwo");
+ ConsumerPart partTwoImpl = new ConsumerPart();
+ ContextInjectionFactory.inject(partTwoImpl, partTwo);
+
+ final IEclipseContext partThree = TestUtil.createContext(window,
+ "partThree");
+ ProviderPart partThreeImpl = new ProviderPart();
+ ContextInjectionFactory.inject(partThreeImpl, partThree);
+
+ partOneImpl.setSelection(SEL_ONE);
+ partThreeImpl.setSelection(SEL_TWO);
+ assertEquals(SEL_ONE, partOneImpl.input);
+ assertNull(partOneImpl.otherSelection);
+ assertNull(partTwoImpl.input);
+ assertEquals(SEL_TWO, partThreeImpl.input);
+
+ // part one tracks down part three. this could just as easily be
+ // fronted by the mediator.addSelectionListener(*)
+ partThree.runAndTrack(new Runnable() {
+ public void run() {
+ ESelectionService s = (ESelectionService) partThree
+ .get(ESelectionService.class.getName());
+ partOneImpl.setOtherSelection((String) s.getSelection());
+ }
+ });
+ assertEquals(SEL_ONE, partOneImpl.input);
+ assertEquals(SEL_TWO, partOneImpl.otherSelection);
+ assertNull(partTwoImpl.input);
+ assertEquals(SEL_TWO, partThreeImpl.input);
+
+ partThreeImpl.setSelection(SEL_ONE);
+ assertEquals(SEL_ONE, partOneImpl.input);
+ assertEquals(SEL_ONE, partOneImpl.otherSelection);
+ assertNull(partTwoImpl.input);
+ assertEquals(SEL_ONE, partThreeImpl.input);
+
+ partThreeImpl.setSelection(null);
+ assertEquals(SEL_ONE, partOneImpl.input);
+ assertNull(partOneImpl.otherSelection);
+ assertNull(partTwoImpl.input);
+ assertNull(partThreeImpl.input);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ workbenchContext = createWorkbenchContext(Activator.getDefault()
+ .getGlobalContext());
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (workbenchContext instanceof IDisposable) {
+ ((IDisposable) workbenchContext).dispose();
+ }
+ workbenchContext = null;
+ }
+
+ private IEclipseContext createWorkbenchContext(IEclipseContext globalContext) {
+ IEclipseContext wb = TestUtil.createContext(globalContext,
+ "workbenchContext");
+ return wb;
+ }
+}
diff --git a/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/TestUtil.java b/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/TestUtil.java
new file mode 100644
index 0000000..ccb3935
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.selection.tests/src/org/eclipse/e4/ui/selection/tests/TestUtil.java
@@ -0,0 +1,13 @@
+package org.eclipse.e4.ui.selection.tests;
+
+import org.eclipse.e4.core.services.context.EclipseContextFactory;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.IContextConstants;
+
+public class TestUtil {
+ public static IEclipseContext createContext(IEclipseContext parent, String name) {
+ IEclipseContext wb = EclipseContextFactory.create(parent, null);
+ wb.set(IContextConstants.DEBUG_STRING, name);
+ return wb;
+ }
+}