Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordsciamma2007-11-07 15:11:23 +0000
committerdsciamma2007-11-07 15:11:23 +0000
commitc1b36cd32007882356de08a69febedb1d3c0662a (patch)
tree9ad57a39da03da65fc605b8049ecb844cd2c5e28
parent6746deec4a31dca29f7b3598a78d2f9913ea07d0 (diff)
downloadorg.eclipse.ecoretools-c1b36cd32007882356de08a69febedb1d3c0662a.tar.gz
org.eclipse.ecoretools-c1b36cd32007882356de08a69febedb1d3c0662a.tar.xz
org.eclipse.ecoretools-c1b36cd32007882356de08a69febedb1d3c0662a.zip
Initial contribution
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/.classpath7
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/.project28
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/META-INF/MANIFEST.MF24
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/about.html29
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/build.properties7
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/plugin.properties31
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/AbstractTabbedPropertySheetPage.java126
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/EMFRecordingChangeCommand.java117
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/TabbedPropertiesTypeMapper.java42
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/TabbedPropertiesPlugin.java61
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/sections/TableObjectManager.java394
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/sections/listeners/CellModifier.java112
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/sections/listeners/PropertiesAdapterImpl.java64
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/utils/ColorRegistry.java202
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/utils/MessageManager.java505
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/utils/Messages.java38
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/utils/Messages.properties2
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/providers/AbstractSectionLabelProvider.java111
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/providers/TabbedPropertiesContentProvider.java48
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/providers/TabbedPropertiesLabelProvider.java60
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractBooleanPropertySection.java154
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractChooserPropertySection.java238
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractColorPropertySection.java104
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractDetailedObjectPropertySection.java320
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractDoublePropertySection.java93
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractEnumerationPropertySection.java186
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractFileChooserPropertySection.java212
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractFontPropertySection.java122
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractIntegerPropertySection.java88
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractListPropertySection.java148
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractReferencePropertySection.java65
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractStringPropertySection.java59
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractTabbedPropertySection.java533
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractTextPropertySection.java240
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AdvancedPropertySection.java92
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/CSingleObjectChooser.java317
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/ChooseDialog.java184
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/FileChooser.java351
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/GoToReferenceComposite.java83
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/ReferenceViewerComposite.java72
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/SearchableTree.java252
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/TableViewerComposite.java644
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/utils/ObjectAdapter.java64
-rw-r--r--plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/utils/TextChangeListener.java181
44 files changed, 6810 insertions, 0 deletions
diff --git a/plugins/org.eclipse.emf.tabbedproperties/.classpath b/plugins/org.eclipse.emf.tabbedproperties/.classpath
new file mode 100644
index 0000000..751c8f2
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/.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"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.emf.tabbedproperties/.project b/plugins/org.eclipse.emf.tabbedproperties/.project
new file mode 100644
index 0000000..204018c
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.emf.tabbedproperties</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/plugins/org.eclipse.emf.tabbedproperties/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.tabbedproperties/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..d817f13
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/META-INF/MANIFEST.MF
@@ -0,0 +1,24 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName (Incubation)
+Bundle-Vendor: %providerName
+Bundle-SymbolicName: org.eclipse.emf.tabbedproperties;singleton:=true
+Bundle-Version: 0.8.0.qualifier
+Bundle-Activator: org.eclipse.emf.tabbedproperties.internal.TabbedPropertiesPlugin
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.ui.views.properties.tabbed;visibility:=reexport,
+ org.eclipse.emf.ecore;visibility:=reexport,
+ org.eclipse.emf.edit.ui;visibility:=reexport,
+ org.eclipse.emf.ecore.edit;visibility:=reexport
+Eclipse-LazyStart: true
+Export-Package: org.eclipse.emf.tabbedproperties,
+ org.eclipse.emf.tabbedproperties.internal;x-internal:=true,
+ org.eclipse.emf.tabbedproperties.internal.sections;x-internal:=true,
+ org.eclipse.emf.tabbedproperties.internal.sections.listeners;x-internal:=true,
+ org.eclipse.emf.tabbedproperties.internal.utils;x-internal:=true,
+ org.eclipse.emf.tabbedproperties.providers,
+ org.eclipse.emf.tabbedproperties.sections,
+ org.eclipse.emf.tabbedproperties.sections.widgets,
+ org.eclipse.emf.tabbedproperties.utils
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ClassPath: .
diff --git a/plugins/org.eclipse.emf.tabbedproperties/about.html b/plugins/org.eclipse.emf.tabbedproperties/about.html
new file mode 100644
index 0000000..984e460
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/about.html
@@ -0,0 +1,29 @@
+<!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 7, 2007</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). 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, &quot;Program&quot; 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 (&quot;Redistributor&quot;) 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/plugins/org.eclipse.emf.tabbedproperties/build.properties b/plugins/org.eclipse.emf.tabbedproperties/build.properties
new file mode 100644
index 0000000..dda44b3
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/build.properties
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties,\
+ about.html
+
diff --git a/plugins/org.eclipse.emf.tabbedproperties/plugin.properties b/plugins/org.eclipse.emf.tabbedproperties/plugin.properties
new file mode 100644
index 0000000..18e6906
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/plugin.properties
@@ -0,0 +1,31 @@
+# /**
+# *
+# * Copyright (c) 2007 Anyware Technologies.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Anyware Technologies - Initial API and implementation
+# *
+# * $Id: plugin.properties,v 1.1 2007/11/07 15:11:26 dsciamma Exp $
+# */
+
+# NLS_MESSAGEFORMAT_VAR
+
+# ==============================================================================
+# Do not change the properties between this line and the last line containing:
+# %%% END OF TRANSLATED PROPERTIES %%%
+# Instead, either redefine an existing property, or create a new property,
+# append it to the end of the file, and change the code to use the new name.
+# ==============================================================================
+
+pluginName=EMF Tabbed Properties
+providerName=Eclipse.org
+copyright=Copyright (c) 2006, 2007 Anyware Technologies. All rights reserved.
+
+# ==============================================================================
+# %%% END OF TRANSLATED PROPERTIES %%%
+# The above properties have been shipped for translation.
+# ==============================================================================
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/AbstractTabbedPropertySheetPage.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/AbstractTabbedPropertySheetPage.java
new file mode 100644
index 0000000..1652f6f
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/AbstractTabbedPropertySheetPage.java
@@ -0,0 +1,126 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.ecore.provider.EcoreItemProviderAdapterFactory;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * The property sheet page to implement to provide the tabbed UI.
+ *
+ * Creation 4 august 06 Last Modified 17 august 06
+ *
+ * @author <a href="alfredo@anyware-tech.com">Jose Alfredo SERRANO</a> *
+ */
+public class AbstractTabbedPropertySheetPage extends TabbedPropertySheetPage {
+
+ /**
+ * This is the adapter factory used for providing views of the model.
+ */
+ private AdapterFactory adapterFactory;
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage#TabbedPropertySheetPage(ITabbedPropertySheetPageContributor)
+ */
+ public AbstractTabbedPropertySheetPage(ITabbedPropertySheetPageContributor tabbedPropertySheetPageContributor) {
+ super(tabbedPropertySheetPageContributor);
+ }
+
+ /**
+ * This method creates a list of factories used by the editor. <br>
+ *
+ * Resource, Ecore, GenModel, and Reflective adapter factories are added
+ * here
+ *
+ * @return the factories' list
+ */
+ public static List<? extends AdapterFactory> getPrincipalAdapterFactories() {
+ List<AdapterFactory> factories = new ArrayList<AdapterFactory>();
+ factories.add(new ResourceItemProviderAdapterFactory());
+ factories.add(new EcoreItemProviderAdapterFactory());
+
+ // REV Remove the Reflective adapter, this causes bad issues in labels
+ // displayed
+ // in the advanced tab when the corresponding factory is not added to
+ // the list
+ // factories.add(new ReflectiveItemProviderAdapterFactory());
+
+ return factories;
+ }
+
+ /**
+ * This method creates the ComposedAdapterFactory that groups all the
+ * factories used by the editor. <br>
+ * <br>
+ *
+ * @return the multi-factory
+ */
+ protected ComposedAdapterFactory createAdapterFactory() {
+ // Create an adapter factory that yields item providers.
+ return new ComposedAdapterFactory(getAdapterFactories());
+ }
+
+ /**
+ * Get the EMF AdapterFactory from a workbench part.
+ *
+ * @return the EMF AdapterFactory from a workbench part.
+ */
+ public AdapterFactory getAdapterFactory() {
+ if (adapterFactory == null) {
+ adapterFactory = createAdapterFactory();
+ }
+
+ return adapterFactory;
+ }
+
+ /**
+ * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart,
+ * org.eclipse.jface.viewers.ISelection)
+ */
+ public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+ ISelection newSel = selection;
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection ssel = (IStructuredSelection) selection;
+ List<Object> selectedObjects = new ArrayList<Object>();
+ for (Object element : ssel.toList()) {
+ Object unwrapObj = AdapterFactoryEditingDomain.unwrap(element);
+ selectedObjects.add(unwrapObj);
+ }
+ newSel = new StructuredSelection(selectedObjects);
+ }
+
+ super.selectionChanged(part, newSel);
+ }
+
+ /**
+ * <b>This method could be overridden to add specific factories before
+ * those. </b> <br>
+ *
+ * @return List a list where contents are of type AdapterFactory
+ */
+ protected List<? extends AdapterFactory> getAdapterFactories() {
+ return getPrincipalAdapterFactories();
+ }
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/EMFRecordingChangeCommand.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/EMFRecordingChangeCommand.java
new file mode 100644
index 0000000..6cedd69
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/EMFRecordingChangeCommand.java
@@ -0,0 +1,117 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.eclipse.emf.common.command.AbstractCommand;
+import org.eclipse.emf.ecore.change.ChangeDescription;
+import org.eclipse.emf.ecore.change.util.ChangeRecorder;
+import org.eclipse.emf.ecore.resource.Resource;
+
+/**
+ * An automatic command
+ *
+ * @author David Sciamma
+ */
+public abstract class EMFRecordingChangeCommand extends AbstractCommand {
+
+ private Set<Resource> notifiers;
+
+ private ChangeRecorder recorder;
+
+ private ChangeDescription change;
+
+ /**
+ * Constructor
+ *
+ * @param resource
+ */
+ public EMFRecordingChangeCommand(Resource resource) {
+ super("Recording Change Command");
+ recorder = new ChangeRecorder();
+ notifiers = Collections.singleton(resource);
+ }
+
+ /**
+ * I run the runnable when I execute the first time.
+ */
+ public void execute() {
+ try {
+ recorder.beginRecording(notifiers);
+ doExecute();
+ } finally {
+ change = recorder.endRecording();
+ }
+ }
+
+ /**
+ * I am ready to execute if I haven't recorded any changes, yet.
+ *
+ * @return boolean
+ */
+ protected boolean prepare() {
+ return change == null;
+ }
+
+ /**
+ * TODO comment this method
+ */
+ protected abstract void doExecute();
+
+ /**
+ * Applies (undoes) changes recorded previously, recording the new changes
+ * meanwhile.
+ */
+ private void applyChanges() {
+ try {
+ recorder.beginRecording(notifiers);
+ change.apply();
+ } finally {
+ change = recorder.endRecording();
+ }
+ }
+
+ /**
+ * I can undo if I have recorded any changes previously.
+ *
+ * @return boolean
+ */
+ public boolean canUndo() {
+ return change != null;
+ }
+
+ /**
+ * Undoes by applying recorded changes.
+ */
+ public void undo() {
+ applyChanges();
+ }
+
+ /**
+ * Redoes by applying changes recorded in the last undo.
+ */
+ public void redo() {
+ applyChanges();
+ }
+
+ /**
+ * @see org.eclipse.emf.common.command.AbstractCommand#dispose()
+ */
+ public void dispose() {
+ change = null;
+ recorder = null;
+ notifiers = null;
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/TabbedPropertiesTypeMapper.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/TabbedPropertiesTypeMapper.java
new file mode 100644
index 0000000..31f3885
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/TabbedPropertiesTypeMapper.java
@@ -0,0 +1,42 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.tabbedproperties.utils.ObjectAdapter;
+import org.eclipse.ui.views.properties.tabbed.AbstractTypeMapper;
+
+/**
+ * An implementation of AbstractTypeMapper. This class matches the type of
+ * selected objects inside the workbench part with the input type attributes
+ * defined in the PropertySection extensions. We can either match objects from a
+ * tree editor or elements based on Eclipse GEF like EditParts.
+ *
+ * Creation 19 sept. 06
+ *
+ * @author alfredo
+ */
+public class TabbedPropertiesTypeMapper extends AbstractTypeMapper {
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractTypeMapper#mapType(java.lang.Object)
+ */
+ public Class<?> mapType(Object object) {
+
+ EObject eObject = ObjectAdapter.adaptObject(object);
+ if (eObject != null) {
+ return eObject.getClass();
+ }
+ return super.mapType(object);
+ }
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/TabbedPropertiesPlugin.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/TabbedPropertiesPlugin.java
new file mode 100644
index 0000000..0cdf3f8
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/TabbedPropertiesPlugin.java
@@ -0,0 +1,61 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.internal;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ *
+ */
+public class TabbedPropertiesPlugin extends AbstractUIPlugin {
+
+ /** The plug-in ID */
+ public static final String PLUGIN_ID = "org.eclipse.emf.tabbedproperties";
+
+ /** The shared instance */
+ private static TabbedPropertiesPlugin plugin;
+
+ /**
+ * The constructor
+ */
+ public TabbedPropertiesPlugin() {
+ plugin = this;
+ }
+
+ /**
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ }
+
+ /**
+ * @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 TabbedPropertiesPlugin getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/sections/TableObjectManager.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/sections/TableObjectManager.java
new file mode 100644
index 0000000..ff9761e
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/sections/TableObjectManager.java
@@ -0,0 +1,394 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.internal.sections;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EEnumLiteral;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.edit.command.AddCommand;
+import org.eclipse.emf.edit.command.CommandParameter;
+import org.eclipse.emf.edit.command.DeleteCommand;
+import org.eclipse.emf.edit.command.RemoveCommand;
+import org.eclipse.emf.edit.command.SetCommand;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.edit.provider.ItemPropertyDescriptor;
+import org.eclipse.emf.edit.ui.celleditor.FeatureEditorDialog;
+import org.eclipse.emf.tabbedproperties.sections.widgets.ChooseDialog;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Class that manages model changes. This manager supports four basic types such
+ * as boolean, string, int and enumerations.
+ *
+ * Creation 10 august 06
+ *
+ * @author <a href="alfredo@anyware-tech.com">Jose Alfredo SERRANO</a>
+ */
+public class TableObjectManager {
+
+ /** The object id for the '<em>EBoolean</em>' data type */
+ public static final int BOOL = 1;
+
+ /** The object id for the '<em>EENUM</em>' data type */
+ public static final int ENUM = 2;
+
+ /** The object id for the '<em>EString</em>' data type */
+ public static final int STR = 3;
+
+ /** The object id for the '<em>EInteger</em>' data type */
+ public static final int INT = 4;
+
+ /** The object id for the '<em>BIG_Integer</em>' data type */
+ public static final int B_INT = 6;
+
+ /** The object id for the '<em>EReference</em>' */
+ public static final int REF = 5;
+
+ /** The object id for the '<em>EDouble</em>' */
+ public static final int DBL = 7;
+
+ private EObject inputEObject;
+
+ private EStructuralFeature feature;
+
+ private EClassifier type;
+
+ private EditingDomain editingDomain;
+
+ private ILabelProvider labelProvider;
+
+ /**
+ * Constructor Creates a new instance of an EObjectManager.
+ *
+ * @param eObject
+ * Object to manage
+ * @param structuralFeature
+ * Structural Feature to edit. Actually this may be a List type
+ */
+ public TableObjectManager(EObject eObject, EStructuralFeature structuralFeature) {
+ inputEObject = eObject;
+ feature = structuralFeature;
+ type = feature.getEType();
+ }
+
+ /**
+ * Add a new task to the collection of elements
+ */
+ public void addElement() {
+ addElement(createNewElement());
+ }
+
+ /**
+ * Add a new element to the collection of elements
+ *
+ * @param newElement
+ * the Element to add
+ */
+ public void addElement(Object newElement) {
+ if (newElement == null) {
+ return;
+ }
+
+ Command command;
+ if (newElement instanceof List) {
+ List<?> newElements = (List<?>) newElement;
+ CompoundCommand cpcmd = new CompoundCommand();
+ for (Object element : newElements) {
+ cpcmd.append(AddCommand.create(editingDomain, inputEObject, feature, element));
+ }
+ command = cpcmd;
+ } else {
+ command = AddCommand.create(editingDomain, inputEObject, feature, newElement);
+ }
+ editingDomain.getCommandStack().execute(command);
+ }
+
+ /**
+ * Removes the given element from the feature list
+ *
+ * @param element
+ * Element to remove
+ */
+ public void removeElement(Object element) {
+ Command removeCmd = RemoveCommand.create(editingDomain, inputEObject, feature, element);
+ editingDomain.getCommandStack().execute(removeCmd);
+ }
+
+ /**
+ * Updates the Structural Feature setting its value with the given object
+ *
+ * @param newValue
+ * The new element to set.
+ */
+ public void updateElement(Object newValue) {
+ if (newValue == null) {
+ return;
+ }
+
+ Command command;
+ List<?> oldValues = (List<?>) inputEObject.eGet(feature);
+ if (newValue instanceof List) {
+ List<?> newElements = (List<?>) newValue;
+ CompoundCommand cpcmd = new CompoundCommand();
+ // Search for deleted items
+ for (Object element : oldValues) {
+ if (!newElements.contains(element)) {
+ cpcmd.append(RemoveCommand.create(editingDomain, inputEObject, feature, element));
+ }
+ }
+ // Search for added items
+ for (Object element : newElements) {
+ if (!oldValues.contains(element)) {
+ cpcmd.append(AddCommand.create(editingDomain, inputEObject, feature, element));
+ }
+ }
+ command = cpcmd;
+ } else {
+ command = AddCommand.create(editingDomain, inputEObject, feature, newValue, oldValues.size());
+ }
+ editingDomain.getCommandStack().execute(command);
+ }
+
+ /**
+ * Modifies the value of an element in the list
+ *
+ * @param oldValue
+ * old value in order to get its place
+ * @param newValue
+ * new value to insert that the olds value place
+ */
+ public void elementChanged(Object oldValue, Object newValue) {
+ if (!oldValue.equals(newValue)) {
+ Command command = null;
+ if (feature.isMany()) {
+ List<?> list = (List<?>) inputEObject.eGet(feature);
+ int index = list.indexOf(oldValue);
+
+ CompoundCommand cpcmd = new CompoundCommand();
+ cpcmd.append(DeleteCommand.create(editingDomain, oldValue));
+ cpcmd.append(AddCommand.create(editingDomain, inputEObject, feature, Collections.singleton(newValue), index));
+ command = cpcmd;
+ } else {
+ command = SetCommand.create(editingDomain, inputEObject, feature, newValue);
+ }
+ editingDomain.getCommandStack().execute(command);
+ }
+ }
+
+ /**
+ * This method should be calld if client wants to manage model changements
+ *
+ * @param editingDomain
+ * the editingDomain to set
+ */
+ public void setEditingDomain(EditingDomain editingDomain) {
+ this.editingDomain = editingDomain;
+ }
+
+ /**
+ * Set the LabelProvider to use
+ *
+ * @param labelProvider
+ */
+ public void setLabelProvider(ILabelProvider labelProvider) {
+ this.labelProvider = labelProvider;
+ }
+
+ /**
+ * @return the feature to edit
+ */
+ public EStructuralFeature getManagedFeature() {
+ return feature;
+ }
+
+ /**
+ * @return Returns the input Eobject
+ */
+ public EObject getInputEObject() {
+ return inputEObject;
+ }
+
+ /**
+ * Get the Feature type of the EObject feature of the manager This class
+ * manages list. The return type will be certainly a EList/List type
+ *
+ * @return feature type
+ */
+ public List<?> eGet() {
+ if (feature.isMany()) {
+ return (List<?>) inputEObject.eGet(feature);
+ }
+ return new ArrayList<Object>(1);
+ }
+
+ /**
+ * TODO Comment this method
+ *
+ * @return String[]
+ */
+ public String[] getEnumLiterals() {
+ List<EEnumLiteral> literals = ((EEnum) type).getELiterals();
+ String[] result = new String[literals.size()];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = literals.get(i).getLiteral();
+ }
+ return result;
+ }
+
+ /**
+ * TODO Comment this method
+ *
+ * @param value
+ * @return Object
+ */
+ public Object createEnum(int value) {
+ String literal = ((EEnum) type).getEEnumLiteral(value).getLiteral();
+ return EcoreUtil.createFromString((EDataType) type, literal);
+ }
+
+ /**
+ * Creates a new type of elements
+ *
+ * @return The new element
+ */
+ private Object createNewElement() {
+ Object newElement = null;
+ switch (getEType()) {
+ case BOOL: // TODO this case may be removed
+ newElement = new Boolean(false);
+ break;
+ case ENUM: // TODO this case may be removed
+ newElement = createEnum(0);
+ break;
+ case INT:
+ newElement = new Integer(0);
+ break;
+ case B_INT:
+ newElement = new BigInteger("0");
+ break;
+ case DBL:
+ newElement = new Double(0);
+ break;
+ case STR:
+ newElement = "New String";
+ break;
+ case REF:
+ if (((EClass) type).isAbstract()) {
+ newElement = createObjectFromDialog();
+ } else {
+ newElement = EcoreUtil.create((EClass) type);
+ }
+ break;
+ default:
+ break;
+ }
+ return newElement;
+ }
+
+ /**
+ * Computes the EStructuralFeature type. When the type is an enumeration
+ * this function will initialize the literals array
+ *
+ * @see EcorePackage#EBOOLEAN , EcorePackage#ESTRING , EcorePackage#EINT or
+ * EcorePackage#EEnum
+ * @see #BOOL
+ * @see #INT
+ * @see #STR
+ * @see #ENUM
+ *
+ * @return An integer code which determine the type
+ */
+ public int getEType() {
+ if (type instanceof EEnum) {
+ return ENUM;
+ } else if (type instanceof EDataType) {
+ Class<?> clazz = type.getInstanceClass();
+ if (clazz == int.class || clazz == Integer.class) {
+ return INT;
+ } else if (clazz == double.class || clazz == Double.class) {
+ return DBL;
+ } else if (clazz == BigInteger.class) {
+ return B_INT;
+ } else if (clazz == String.class) {
+ return STR;
+ } else if (clazz == boolean.class || clazz == Boolean.class) {
+ return BOOL;
+ } else {
+ return 0;
+ }
+ } else if (type instanceof EClass) {
+ return REF;
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Return the new List of elements that have been specified in the
+ * FeatureEditorDialog.
+ *
+ * @return List
+ */
+ public List<?> chooseObjectsFromDialog() {
+ Collection<EObject> choiceOfValues = ItemPropertyDescriptor.getReachableObjectsOfType(inputEObject, feature.getEType());
+ Shell shell = Display.getDefault().getActiveShell();
+ String displayName = "Choose the objects to add";
+ List<?> choices = new ArrayList<EObject>(choiceOfValues);
+ FeatureEditorDialog dialog = new FeatureEditorDialog(shell, labelProvider, inputEObject, feature, displayName, choices);
+ dialog.open();
+ return dialog.getResult();
+ }
+
+ /**
+ * @return Object
+ */
+ public Object createObjectFromDialog() {
+ Collection<?> descriptors = editingDomain.getNewChildDescriptors(inputEObject, null);
+ Object[] selection = descriptors.toArray();
+ if (selection.length > 1) {
+ Object[] values = new Object[selection.length];
+ for (int i = 0; i < selection.length; i++) {
+ values[i] = ((CommandParameter) selection[i]).getEValue();
+ }
+ Shell shell = Display.getDefault().getActiveShell();
+ ChooseDialog dialog = new ChooseDialog(shell, values);
+ dialog.setLabelProvider(labelProvider);
+ if (dialog.open() == Window.OK) {
+ selection = dialog.getResult();
+ } else {
+ selection = new Object[0];
+ }
+ }
+ if (selection.length > 0) {
+ return selection[0];
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/sections/listeners/CellModifier.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/sections/listeners/CellModifier.java
new file mode 100644
index 0000000..8eab952
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/sections/listeners/CellModifier.java
@@ -0,0 +1,112 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.internal.sections.listeners;
+
+import java.math.BigInteger;
+
+import org.eclipse.emf.common.util.AbstractEnumerator;
+import org.eclipse.emf.tabbedproperties.sections.widgets.TableViewerComposite;
+import org.eclipse.jface.viewers.ICellModifier;
+import org.eclipse.swt.widgets.TableItem;
+
+/**
+ * This class implements an ICellModifier An ICellModifier is called when the
+ * user modifies a cell in the tableViewer
+ *
+ * @author Alfredo Serrano
+ */
+
+public class CellModifier implements ICellModifier {
+
+ private TableViewerComposite tableViewer;
+
+ /**
+ * Constructor
+ *
+ * @param tableViewer
+ * an instance of a TableViewerExample
+ */
+ public CellModifier(TableViewerComposite tableViewer) {
+ this.tableViewer = tableViewer;
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object,
+ * java.lang.String)
+ */
+ public boolean canModify(Object element, String property) {
+ return true;
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object,
+ * java.lang.String)
+ */
+ public Object getValue(Object element, String property) {
+ if (element instanceof String) {
+ return element;
+ } else if (element instanceof Integer) {
+ return ((Integer) element).toString();
+ } else if (element instanceof BigInteger) {
+ return ((BigInteger) element).toString();
+ } else if (element instanceof AbstractEnumerator) {
+ String stringValue = ((AbstractEnumerator) element).getLiteral();
+ String[] choices = tableViewer.getObjectManager().getEnumLiterals();
+ int i = choices.length - 1;
+ while (!stringValue.equals(choices[i]) && i > 0) {
+ --i;
+ }
+ return new Integer(i);
+ }
+ return element;
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.ICellModifier#modify(java.lang.Object,
+ * java.lang.String, java.lang.Object)
+ */
+ public void modify(Object element, String property, Object value) {
+ // Find the index of the column
+ TableItem item = (TableItem) element;
+ Object oldValue = item.getData();
+ Object newValue = null;
+
+ if (oldValue instanceof String) {
+ String string = (String) value;
+ newValue = string.trim();
+ item.setText((String) newValue);
+ item.setData(newValue);
+ } else if (oldValue instanceof Integer) {
+ int i = Integer.parseInt((String) value);
+ newValue = new Integer(i);
+ item.setText(i + "");
+ item.setData(newValue);
+ } else if (oldValue instanceof BigInteger) {
+ newValue = new BigInteger((String) value);
+ item.setText(newValue.toString());
+ item.setData(newValue);
+ } else if (oldValue instanceof Double) {
+ newValue = new Double((String) value);
+ item.setText(newValue.toString());
+ item.setData(newValue);
+ } else if (oldValue instanceof Boolean) {
+ newValue = value; // Boolean has not real interest
+ } else {
+ newValue = tableViewer.getObjectManager().createEnum(((Integer) value).intValue());
+ // TODO something with enums. This is not going to work because we
+ // have to create an instance of the
+ // enumeration
+ }
+ tableViewer.getObjectManager().elementChanged(oldValue, newValue);
+ }
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/sections/listeners/PropertiesAdapterImpl.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/sections/listeners/PropertiesAdapterImpl.java
new file mode 100644
index 0000000..57fc8dc
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/sections/listeners/PropertiesAdapterImpl.java
@@ -0,0 +1,64 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.internal.sections.listeners;
+
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * This EMF listener receives an event and then handles this event in the UI
+ * thread
+ *
+ * @author <a href="david.sciamma@anyware-tech.com">David Sciamma</a>
+ * @author <a href="alfredo@anyware-tech.com">Jose Alfredo SERRANO</a>
+ */
+public abstract class PropertiesAdapterImpl extends AdapterImpl {
+
+ /**
+ * Call the handlePropertyChanged method in the UI thread
+ *
+ * @see org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common.notify.Notification)
+ */
+ public final void notifyChanged(Notification msg) {
+ if (Display.getCurrent() != Display.getDefault()) {
+ syncNotifyChanged(msg);
+ } else {
+ safeNotifyChanged(msg);
+ }
+ }
+
+ /**
+ * Handles the event notification in the UI thread
+ *
+ * @param msg
+ * the event notification
+ */
+ private void syncNotifyChanged(final Notification msg) {
+ Display.getDefault().syncExec(new Runnable() {
+
+ public void run() {
+ safeNotifyChanged(msg);
+ }
+ });
+ }
+
+ /**
+ * This method is called when an event occurred on the model objects.<br>
+ * This method is always called in the UI thread
+ *
+ * @param msg
+ * the event notification
+ */
+ protected abstract void safeNotifyChanged(Notification msg);
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/utils/ColorRegistry.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/utils/ColorRegistry.java
new file mode 100644
index 0000000..56b0417
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/utils/ColorRegistry.java
@@ -0,0 +1,202 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.internal.utils;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.resource.StringConverter;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * The color registry class helps client to color its sections.<br>
+ * This registry manages all the allocated colors and dispose its when the
+ * current display is disposed. <br>
+ *
+ * Creation : 8 oct. 2004
+ *
+ * @author <a href="mailto:david.sciamma@anyware-tech.com">David Sciamma </a>
+ */
+public final class ColorRegistry {
+
+ /**
+ * Constant for error color.
+ */
+ public static Color COLOR_ERROR = getInstance().get("255,128,128");
+
+ /**
+ * Constant for warning color.
+ */
+ public static Color COLOR_WARNING = getInstance().get("249,240,163");
+
+ /**
+ * Constant for info color.
+ */
+ public static Color COLOR_INFO = getInstance().get("128,128,255");
+
+ /**
+ * Constant for black color.
+ */
+ public static Color COLOR_BLACK = getInstance().get("0,0,0");
+
+ /**
+ * Constant for white color.
+ */
+ public static Color COLOR_WHITE = getInstance().get("255,255,255");
+
+ /**
+ * Constant for red color.
+ */
+ public static Color COLOR_RED = getInstance().get("255,0,0");
+
+ /**
+ * Constant for green color.
+ */
+ public static Color COLOR_GREEN = getInstance().get("0,255,0");
+
+ /**
+ * Constant for blue color.
+ */
+ public static Color COLOR_BLUE = getInstance().get("0,0,255");
+
+ /**
+ * Constant for a soft grey color.
+ */
+ public static Color COLOR_SOFT_GREY = getInstance().get("219,211,203");
+
+ private static ColorRegistry _instance;
+
+ /**
+ * Returns the singleton registry instance
+ *
+ * @return the registry
+ */
+ public static ColorRegistry getInstance() {
+ if (_instance == null) {
+ _instance = new ColorRegistry();
+ }
+
+ return _instance;
+ }
+
+ /**
+ * This registries <code>Display</code>. All colors will be allocated
+ * using it.
+ */
+ protected Display _display;
+
+ /**
+ * Table of known colors, keyed by symbolic color name (key type:
+ * <code>String</code>, value type:
+ * <code>org.eclipse.swt.graphics.Color</code>.
+ */
+ private Map<String, Color> _stringToColor = new HashMap<String, Color>(7);
+
+ /**
+ * Runnable that cleans up the manager on disposal of the display.
+ */
+ protected Runnable _displayRunnable = new Runnable() {
+
+ public void run() {
+ _clearCaches();
+ }
+ };
+
+ /**
+ * Create a new instance of the receiver that is hooked to the current
+ * display.
+ *
+ * @see org.eclipse.swt.widgets.Display#getCurrent()
+ */
+ private ColorRegistry() {
+ this(Display.getCurrent());
+ }
+
+ /**
+ * Create a new instance of the receiver.
+ *
+ * @param display
+ * the <code>Display</code> to hook into.
+ */
+ private ColorRegistry(Display display) {
+ Assert.isNotNull(display);
+ this._display = display;
+ hookDisplayDispose();
+ }
+
+ /**
+ * Hook a dispose listener on the SWT display.
+ */
+ private void hookDisplayDispose() {
+ _display.disposeExec(_displayRunnable);
+ }
+
+ /**
+ * Releases all the allocated colors
+ */
+ private void _clearCaches() {
+ Collection<Color> colors = _stringToColor.values();
+ for (Color color : colors) {
+ color.dispose();
+ }
+ _stringToColor.clear();
+ }
+
+ /**
+ * Returns the <code>color</code> associated with the given symbolic color
+ * name, or <code>null</code> if no such definition exists.
+ *
+ * @param symbolicName
+ * symbolic color name
+ * @return the <code>Color</code> or <code>null</code>
+ */
+ public Color get(String symbolicName) {
+ Assert.isNotNull(symbolicName);
+ if ("".equals(symbolicName)) //$NON-NLS-1$
+ {
+ return new Color(_display, new RGB(0, 0, 0));
+ }
+
+ return get(StringConverter.asRGB(symbolicName));
+ }
+
+ /**
+ * Returns the <code>color</code> associated with the given RGB object, or
+ * <code>null</code> if no such definition exists.
+ *
+ * @param rgb
+ * the rgb color
+ * @return the <code>Color</code> or <code>null</code>
+ */
+ public Color get(RGB rgb) {
+ if (rgb == null) {
+ return null;
+ }
+
+ String symbolicName = StringConverter.asString(rgb);
+ Object result = _stringToColor.get(symbolicName);
+ if (result != null) {
+ return (Color) result;
+ }
+
+ Color color = new Color(_display, rgb);
+
+ _stringToColor.put(symbolicName, color);
+
+ return color;
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/utils/MessageManager.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/utils/MessageManager.java
new file mode 100644
index 0000000..bb02cf6
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/utils/MessageManager.java
@@ -0,0 +1,505 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.internal.utils;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.forms.IMessage;
+import org.eclipse.ui.forms.IMessageManager;
+import org.eclipse.ui.forms.IMessagePrefixProvider;
+import org.eclipse.ui.forms.widgets.Hyperlink;
+
+/**
+ * TODO Comment this method
+ *
+ * @Created 2 mars 07
+ *
+ * @author <a href="mailto:alfredo@anyware-tech.com">Jose Alfredo SERRANO</a>
+ *
+ */
+public class MessageManager implements IMessageManager {
+
+ private static final DefaultPrefixProvider DEFAULT_PREFIX_PROVIDER = new DefaultPrefixProvider();
+
+ private List<Message> messages = new ArrayList<Message>();
+
+ private Hashtable<Control, ControlDecorator> decorators = new Hashtable<Control, ControlDecorator>();
+
+ private boolean autoUpdate = true;
+
+ private IMessagePrefixProvider prefixProvider = DEFAULT_PREFIX_PROVIDER;
+
+ private int decorationPosition = SWT.LEFT | SWT.BOTTOM;
+
+ private static FieldDecoration standardError = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
+
+ private static FieldDecoration standardWarning = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_WARNING);
+
+ static class Message implements IMessage {
+
+ Control control;
+
+ Object data;
+
+ Object key;
+
+ String message;
+
+ int type;
+
+ String prefix;
+
+ Message(Object key, String message, int type, Object data) {
+ this.key = key;
+ this.message = message;
+ this.type = type;
+ this.data = data;
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessage#getKey()
+ */
+ public Object getKey() {
+ return key;
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.IMessageProvider#getMessage()
+ */
+ public String getMessage() {
+ return message;
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.IMessageProvider#getMessageType()
+ */
+ public int getMessageType() {
+ return type;
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessage#getControl()
+ */
+ public Control getControl() {
+ return control;
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessage#getData()
+ */
+ public Object getData() {
+ return data;
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessage#getPrefix()
+ */
+ public String getPrefix() {
+ return prefix;
+ }
+ }
+
+ static class DefaultPrefixProvider implements IMessagePrefixProvider {
+
+ /**
+ * @see org.eclipse.ui.forms.IMessagePrefixProvider#getPrefix(org.eclipse.swt.widgets.Control)
+ */
+ public String getPrefix(Control c) {
+ Composite parent = c.getParent();
+ Control[] siblings = parent.getChildren();
+ for (int i = 0; i < siblings.length; i++) {
+ if (siblings[i] == c) {
+ // this is us - go backward until you hit
+ // a label-like widget
+ for (int j = i - 1; j >= 0; j--) {
+ Control label = siblings[j];
+ String ltext = null;
+ if (label instanceof Label) {
+ ltext = ((Label) label).getText();
+ } else if (label instanceof Hyperlink) {
+ ltext = ((Hyperlink) label).getText();
+ } else if (label instanceof CLabel) {
+ ltext = ((CLabel) label).getText();
+ }
+ if (ltext != null) {
+ if (!ltext.endsWith(":")) //$NON-NLS-1$
+ return ltext + ": "; //$NON-NLS-1$
+ return ltext + " "; //$NON-NLS-1$
+ }
+ }
+ break;
+ }
+ }
+ return null;
+ }
+ }
+
+ class ControlDecorator {
+
+ private ControlDecoration decoration;
+
+ private List<Message> controlMessages = new ArrayList<Message>();
+
+ private String prefix;
+
+ ControlDecorator(Control control) {
+ this.decoration = new ControlDecoration(control, decorationPosition);
+ }
+
+ /**
+ * Return true whether the control is disposed
+ *
+ * @return true if the control is disposed
+ */
+ public boolean isDisposed() {
+ return decoration.getControl() == null;
+ }
+
+ void updatePrefix() {
+ prefix = null;
+ }
+
+ void updatePosition() {
+ Control control = decoration.getControl();
+ decoration.dispose();
+ this.decoration = new ControlDecoration(control, decorationPosition);
+ update();
+ }
+
+ String getPrefix() {
+ if (prefix == null)
+ createPrefix();
+ return prefix;
+ }
+
+ private void createPrefix() {
+ if (prefixProvider == null) {
+ prefix = ""; //$NON-NLS-1$
+ return;
+ }
+ prefix = prefixProvider.getPrefix(decoration.getControl());
+ if (prefix == null)
+ // make a prefix anyway
+ prefix = ""; //$NON-NLS-1$
+ }
+
+ void addAll(List<Message> target) {
+ target.addAll(controlMessages);
+ }
+
+ void addMessage(Object key, String text, Object data, int type) {
+ Message message = MessageManager.this.addMessage(getPrefix(), key, text, data, type, controlMessages);
+ message.control = decoration.getControl();
+ if (isAutoUpdate())
+ update();
+ }
+
+ boolean removeMessage(Object key) {
+ Message message = findMessage(key, controlMessages);
+ if (message != null) {
+ controlMessages.remove(message);
+ if (isAutoUpdate())
+ update();
+ }
+ return message != null;
+ }
+
+ boolean removeMessages() {
+ if (controlMessages.isEmpty())
+ return false;
+ controlMessages.clear();
+ if (isAutoUpdate())
+ update();
+ return true;
+ }
+
+ /**
+ * Update
+ */
+ public void update() {
+ if (controlMessages.isEmpty()) {
+ decoration.setDescriptionText(null);
+ decoration.hide();
+ } else {
+ List<Message> peers = createPeers(controlMessages);
+ int type = ((IMessage) peers.get(0)).getMessageType();
+ String description = createDetails(createPeers(peers), true);
+ if (type == IMessageProvider.ERROR)
+ decoration.setImage(standardError.getImage());
+ else if (type == IMessageProvider.WARNING)
+ decoration.setImage(standardWarning.getImage());
+ decoration.setDescriptionText(description);
+ decoration.show();
+ }
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessageManager#addMessage(java.lang.Object,
+ * java.lang.String, java.lang.Object, int)
+ */
+ public void addMessage(Object key, String messageText, Object data, int type) {
+ addMessage(null, key, messageText, data, type, messages);
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessageManager#addMessage(java.lang.Object,
+ * java.lang.String, java.lang.Object, int,
+ * org.eclipse.swt.widgets.Control)
+ */
+ public void addMessage(Object key, String messageText, Object data, int type, Control control) {
+ ControlDecorator dec = decorators.get(control);
+
+ if (dec == null) {
+ dec = new ControlDecorator(control);
+ decorators.put(control, dec);
+ }
+ dec.addMessage(key, messageText, data, type);
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessageManager#removeMessage(java.lang.Object)
+ */
+ public void removeMessage(Object key) {
+ Message message = findMessage(key, messages);
+ if (message != null) {
+ messages.remove(message);
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessageManager#removeMessages()
+ */
+ public void removeMessages() {
+ if (!messages.isEmpty()) {
+ messages.clear();
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessageManager#removeMessage(java.lang.Object,
+ * org.eclipse.swt.widgets.Control)
+ */
+ public void removeMessage(Object key, Control control) {
+ ControlDecorator dec = decorators.get(control);
+ if (dec == null)
+ return;
+ dec.removeMessage(key);
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessageManager#removeMessages(org.eclipse.swt.widgets.Control)
+ */
+ public void removeMessages(Control control) {
+ ControlDecorator dec = decorators.get(control);
+ if (dec != null) {
+ dec.removeMessages();
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessageManager#removeAllMessages()
+ */
+ public void removeAllMessages() {
+ for (Enumeration<ControlDecorator> enm = decorators.elements(); enm.hasMoreElements();) {
+ ControlDecorator control = enm.nextElement();
+ control.removeMessages();
+ }
+ if (!messages.isEmpty()) {
+ messages.clear();
+ }
+ }
+
+ /**
+ * Adds the message if it does not already exist in the provided list.
+ *
+ * @param prefix
+ * @param key
+ * @param messageText
+ * @param data
+ * @param type
+ * @param list
+ * @return Message
+ */
+ private Message addMessage(String prefix, Object key, String messageText, Object data, int type, List<Message> list) {
+ Message message = findMessage(key, list);
+ if (message == null) {
+ message = new Message(key, messageText, type, data);
+ message.prefix = prefix;
+ list.add(message);
+ } else {
+ message.message = messageText;
+ message.type = type;
+ message.data = data;
+ }
+ return message;
+ }
+
+ /**
+ * Finds the message with the provided key in the provided list.
+ *
+ * @param key
+ * @param list
+ * @return Message
+ */
+ private Message findMessage(Object key, List<Message> list) {
+ for (int i = 0; i < list.size(); i++) {
+ Message message = list.get(i);
+ if (message.getKey().equals(key))
+ return message;
+ }
+ return null;
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessageManager#update()
+ */
+ public void update() {
+ // Update decorations
+ for (ControlDecorator dec : decorators.values()) {
+ dec.update();
+ }
+ }
+
+ private static String getFullMessage(IMessage message) {
+ if (message.getPrefix() == null)
+ return message.getMessage();
+ return message.getPrefix() + message.getMessage();
+ }
+
+ private List<Message> createPeers(List<Message> msges) {
+ List<Message> peers = new ArrayList<Message>();
+ int maxType = 0;
+ for (int i = 0; i < msges.size(); i++) {
+ Message message = msges.get(i);
+ if (message.type > maxType) {
+ peers.clear();
+ maxType = message.type;
+ }
+ if (message.type == maxType)
+ peers.add(message);
+ }
+ return peers;
+ }
+
+ /**
+ * @param msges
+ * @param excludePrefix
+ * @return String
+ */
+ private String createDetails(List<Message> msges, boolean excludePrefix) {
+ StringWriter sw = new StringWriter();
+ PrintWriter out = new PrintWriter(sw);
+
+ for (int i = 0; i < msges.size(); i++) {
+ if (i > 0)
+ out.println();
+ IMessage m = msges.get(i);
+ out.print(excludePrefix ? m.getMessage() : getFullMessage(m));
+ }
+ out.flush();
+ return sw.toString();
+ }
+
+ /**
+ * @param messages
+ * @return String
+ */
+ public static String createDetails(IMessage[] messages) {
+ if (messages == null || messages.length == 0)
+ return null;
+ StringWriter sw = new StringWriter();
+ PrintWriter out = new PrintWriter(sw);
+
+ for (int i = 0; i < messages.length; i++) {
+ if (i > 0)
+ out.println();
+ out.print(getFullMessage(messages[i]));
+ }
+ out.flush();
+ return sw.toString();
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessageManager#createSummary(org.eclipse.ui.forms.IMessage[])
+ */
+ public String createSummary(IMessage[] msges) {
+ return createDetails(msges);
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessageManager#getMessagePrefixProvider()
+ */
+ public IMessagePrefixProvider getMessagePrefixProvider() {
+ return prefixProvider;
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessageManager#setMessagePrefixProvider(org.eclipse.ui.forms.IMessagePrefixProvider)
+ */
+ public void setMessagePrefixProvider(IMessagePrefixProvider provider) {
+ this.prefixProvider = provider;
+ for (ControlDecorator dec : decorators.values()) {
+ dec.updatePrefix();
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessageManager#getDecorationPosition()
+ */
+ public int getDecorationPosition() {
+ return decorationPosition;
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessageManager#setDecorationPosition(int)
+ */
+ public void setDecorationPosition(int position) {
+ this.decorationPosition = position;
+ for (ControlDecorator dec : decorators.values()) {
+ dec.updatePosition();
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessageManager#isAutoUpdate()
+ */
+ public boolean isAutoUpdate() {
+ return autoUpdate;
+ }
+
+ /**
+ * @see org.eclipse.ui.forms.IMessageManager#setAutoUpdate(boolean)
+ */
+ public void setAutoUpdate(boolean autoUpdate) {
+ boolean needsUpdate = !this.autoUpdate && autoUpdate;
+ this.autoUpdate = autoUpdate;
+ if (needsUpdate)
+ update();
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/utils/Messages.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/utils/Messages.java
new file mode 100644
index 0000000..4e6b7ba
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/utils/Messages.java
@@ -0,0 +1,38 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.internal.utils;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * TODO Comment this class
+ */
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.ui.internal.forms.Messages"; //$NON-NLS-1$
+
+ private Messages() {
+ // Do nothing
+ }
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ /** Warning message */
+ public static String MessageManager_pWarningSummary;
+
+ /** Error message */
+ public static String MessageManager_pErrorSummary;
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/utils/Messages.properties b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/utils/Messages.properties
new file mode 100644
index 0000000..97e8436
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/internal/utils/Messages.properties
@@ -0,0 +1,2 @@
+MessageManager_pWarningSummary = {0} warnings detected
+MessageManager_pErrorSummary = {0} errors detected
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/providers/AbstractSectionLabelProvider.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/providers/AbstractSectionLabelProvider.java
new file mode 100644
index 0000000..863835b
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/providers/AbstractSectionLabelProvider.java
@@ -0,0 +1,111 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.providers;
+
+import java.util.Iterator;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * An abstract labelProvider that is associated with the PropertyContributor of
+ * a TabbedPropertiesView.
+ *
+ * Creation 2 oct. 06
+ *
+ * @author <a href="mailto:jacques.lescot@anyware-tech.com">Jacques LESCOT</a>
+ */
+public abstract class AbstractSectionLabelProvider extends LabelProvider {
+
+ /**
+ * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
+ */
+ public Image getImage(Object element) {
+ if (element == null || element.equals(StructuredSelection.EMPTY)) {
+ return null;
+ }
+ Object selection = element;
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+ if (areDifferentTypes(structuredSelection)) {
+ return null;
+ }
+ selection = structuredSelection.getFirstElement();
+ }
+ selection = AdapterFactoryEditingDomain.unwrap(selection);
+ if (selection instanceof EObject || selection instanceof Resource) {
+ return getAdapterFactoryLabelProvider().getImage(selection);
+ }
+ return null;
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
+ */
+ public String getText(Object element) {
+ if (element == null || element.equals(StructuredSelection.EMPTY)) {
+ return null;
+ }
+ Object selection = element;
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+ if (areDifferentTypes(structuredSelection)) {
+ return structuredSelection.size() + " items selected";//$NON-NLS-1$
+ }
+ selection = structuredSelection.getFirstElement();
+ }
+ selection = AdapterFactoryEditingDomain.unwrap(selection);
+ if (selection instanceof EObject) {
+ return getAdapterFactoryLabelProvider().getText(selection);
+ }
+
+ return null;
+ }
+
+ /**
+ * Determine there are objects in the structured selection of different
+ * types.
+ *
+ * @param structuredSelection
+ * the structured selection.
+ * @return true if there are objects of different types in the selection.
+ */
+ private boolean areDifferentTypes(IStructuredSelection structuredSelection) {
+ if (structuredSelection.size() == 1) {
+ return false;
+ }
+ Iterator<?> iter = structuredSelection.iterator();
+ Object element = iter.next();
+ while (iter.hasNext()) {
+ if (iter.next().getClass() != element.getClass()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Construct a new label provider factory if it is not null
+ *
+ * @return the AdapterFactoryLabelProvider
+ */
+ protected abstract ILabelProvider getAdapterFactoryLabelProvider();
+
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/providers/TabbedPropertiesContentProvider.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/providers/TabbedPropertiesContentProvider.java
new file mode 100644
index 0000000..d831d2b
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/providers/TabbedPropertiesContentProvider.java
@@ -0,0 +1,48 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.providers;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
+import org.eclipse.emf.tabbedproperties.utils.ObjectAdapter;
+import org.eclipse.ui.views.properties.IPropertySource;
+
+/**
+ * Creation 19 sept. 06
+ *
+ * @author alfredo
+ * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider
+ */
+public class TabbedPropertiesContentProvider extends AdapterFactoryContentProvider {
+
+ /**
+ * This constructs an instance that wraps this factory.
+ *
+ * @param adapterFactory
+ */
+ public TabbedPropertiesContentProvider(AdapterFactory adapterFactory) {
+ super(adapterFactory);
+ }
+
+ /**
+ * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider#getPropertySource(java.lang.Object)
+ */
+ public IPropertySource getPropertySource(Object object) {
+ EObject eObject = ObjectAdapter.adaptObject(object);
+ if (eObject != null) {
+ return super.getPropertySource(eObject);
+ }
+ return super.getPropertySource(object);
+ }
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/providers/TabbedPropertiesLabelProvider.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/providers/TabbedPropertiesLabelProvider.java
new file mode 100644
index 0000000..c7f2fb9
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/providers/TabbedPropertiesLabelProvider.java
@@ -0,0 +1,60 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.providers;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+
+/**
+ * A Label Provider that formats the provided String text The text will be
+ * displayed like:
+ *
+ * <code>FEATURENAME : CLASSNAME - MODELNAME</code>
+ *
+ * @author alfredo
+ *
+ */
+public class TabbedPropertiesLabelProvider extends AdapterFactoryLabelProvider {
+
+ /**
+ * Constructor
+ *
+ * @param adapterFactory
+ */
+ public TabbedPropertiesLabelProvider(AdapterFactory adapterFactory) {
+ super(adapterFactory);
+ }
+
+ /**
+ * This method overrides the AdapterFactoryLabelProvider getText method in
+ * order to obtain the desired label values. The returned string will have
+ * the StructuralFeature with a description of its EcoreClass and its model.
+ *
+ * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getText(Object)
+ */
+ public String getText(Object object) {
+ String resultText = null;
+ if (object instanceof String) {
+ // When the given object is a string we return it
+ resultText = (String) object;
+ }
+
+ // This is the case of references between EcoreItems.
+ // When no resultText applies for this EObject
+ // we adapt try to adapt it with the EcoreItemProviderAdapterFactory.
+ if (resultText == null) {
+ resultText = super.getText(object);
+ }
+ return resultText;
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractBooleanPropertySection.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractBooleanPropertySection.java
new file mode 100644
index 0000000..bba0de5
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractBooleanPropertySection.java
@@ -0,0 +1,154 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * An abstract implementation of a section with a check button. It represents a
+ * boolean field.
+ *
+ * Creation 5 apr. 2006 Updated 7 aug. 2006
+ *
+ * @author Jacques Lescot
+ * @author Alfredo Serrano
+ */
+public abstract class AbstractBooleanPropertySection extends AbstractTabbedPropertySection {
+
+ /**
+ * The checkButton control for the section.
+ */
+ private Button checkButton;
+
+ /**
+ * Listen events when the check box is selected
+ */
+ private SelectionListener listener = new SelectionListener() {
+
+ public void widgetSelected(SelectionEvent e) {
+ handleCheckButtonModified();
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // Do nothing
+ }
+ };
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#createControls(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
+ */
+ public void createControls(Composite parent, TabbedPropertySheetPage tabbedPropertySheetPage) {
+ super.createControls(parent, tabbedPropertySheetPage);
+ // Composite composite =
+ // getWidgetFactory().createFlatFormComposite(parent);
+ // checkButton = getWidgetFactory().createButton(composite,
+ // getLabelText(), SWT.CHECK);
+ //
+ // FormData data;
+ // data = new FormData();
+ // data.left = new FormAttachment(0, 0);
+ // data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
+ // checkButton.setLayoutData(data);
+
+ // checkButton.addSelectionListener(listener);
+ //
+ // if (getFeature() != null)
+ // {
+ // checkButton.setEnabled(getFeature().isChangeable());
+ // }
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#createWidgets(org.eclipse.swt.widgets.Composite)
+ */
+ protected void createWidgets(Composite composite) {
+ checkButton = getWidgetFactory().createButton(composite, getLabelText(), SWT.CHECK);
+
+ if (getFeature() != null) {
+ checkButton.setEnabled(getFeature().isChangeable());
+ }
+
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#setSectionData(org.eclipse.swt.widgets.Composite)
+ */
+ protected void setSectionData(Composite composite) {
+ FormData data;
+ data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
+ checkButton.setLayoutData(data);
+
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#hookListeners()
+ */
+ protected void hookListeners() {
+ checkButton.addSelectionListener(listener);
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
+ */
+ public void refresh() {
+ checkButton.setSelection(getFeatureValue());
+ }
+
+ /**
+ * Handle the checkbutton modified event.
+ */
+ protected void handleCheckButtonModified() {
+ createCommand(Boolean.valueOf(getFeatureValue()), Boolean.valueOf(checkButton.getSelection()));
+ }
+
+ /**
+ * @return the checkButton
+ */
+ protected Button getCheckButton() {
+ return checkButton;
+ }
+
+ /**
+ * Get the new value of the feature for the text field for the section.
+ *
+ * @return the boolean value of the feature.
+ */
+ protected boolean getFeatureValue() {
+ Object bool = getEObject().eGet(getFeature());
+ if (bool == null || !(bool instanceof Boolean)) {
+ return false;
+ }
+ return ((Boolean) bool).booleanValue();
+
+ }
+
+ /**
+ * By default, return the name of the Feature
+ *
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#getLabelText()
+ */
+ protected String getLabelText() {
+ return getFeature().getName();
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractChooserPropertySection.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractChooserPropertySection.java
new file mode 100644
index 0000000..bc3a92a
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractChooserPropertySection.java
@@ -0,0 +1,238 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.provider.EcoreItemProviderAdapterFactory;
+import org.eclipse.emf.edit.command.SetCommand;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.edit.provider.ItemPropertyDescriptor;
+import org.eclipse.emf.tabbedproperties.providers.TabbedPropertiesLabelProvider;
+import org.eclipse.emf.tabbedproperties.sections.widgets.CSingleObjectChooser;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * An abstract implementation of a section with a field using a
+ * CSingleObjectChooser composite (CCombo with a Button).
+ *
+ * Creation 5 apr. 2006 Updated 7 aug. 2006
+ *
+ * @author Jacques LESCOT
+ * @author Alfredo SERRANO
+ */
+public abstract class AbstractChooserPropertySection extends AbstractTabbedPropertySection {
+
+ /**
+ * A boolean that store if refreshing is happening and no model
+ * modifications should be performed
+ */
+ private boolean isRefreshing = false;
+
+ /**
+ * The combo box control for the section.
+ */
+ private CSingleObjectChooser cSingleObjectChooser;
+
+ /**
+ * The label for this section
+ */
+ private CLabel labelCombo;
+
+ /**
+ * Section composite. This composite can be return if client desire to
+ * implement other widgets in relation with the list represented by this
+ * instance.
+ */
+ // private Composite sectionComposite;
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.ISection#createControls(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
+ */
+ public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage) {
+ super.createControls(parent, aTabbedPropertySheetPage);
+ // sectionComposite =
+ // getWidgetFactory().createFlatFormComposite(parent);
+ //
+ // labelCombo = getWidgetFactory().createCLabel(sectionComposite,
+ // getLabelText());
+ //
+ // cSingleObjectChooser = new CSingleObjectChooser(sectionComposite,
+ // getWidgetFactory(), SWT.NONE);
+ // cSingleObjectChooser.setLabelProvider(getLabelProvider());
+ //
+ //
+ // if (getFeature() != null)
+ // {
+ // cSingleObjectChooser.setChangeable(getFeature().isChangeable());
+ // }
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#createWidgets(org.eclipse.swt.widgets.Composite)
+ */
+ protected void createWidgets(Composite composite) {
+ labelCombo = getWidgetFactory().createCLabel(composite, getLabelText());
+
+ cSingleObjectChooser = new CSingleObjectChooser(composite, getWidgetFactory(), SWT.NONE);
+ cSingleObjectChooser.setLabelProvider(getLabelProvider());
+
+ if (getFeature() != null) {
+ cSingleObjectChooser.setChangeable(getFeature().isChangeable());
+ }
+
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#setSectionData(org.eclipse.swt.widgets.Composite)
+ */
+ protected void setSectionData(Composite composite) {
+ FormData data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.right = new FormAttachment(cSingleObjectChooser, -ITabbedPropertyConstants.HSPACE);
+ data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
+ labelCombo.setLayoutData(data);
+
+ data = new FormData();
+ data.left = new FormAttachment(0, getStandardLabelWidth(composite, new String[] { getLabelText() }));
+ data.right = new FormAttachment(100, 0);
+ data.top = new FormAttachment(labelCombo, 0, SWT.CENTER);
+ cSingleObjectChooser.setLayoutData(data);
+
+ }
+
+ /**
+ * Adds the listeners on the widgets
+ */
+ protected void hookListeners() {
+ cSingleObjectChooser.addSelectionListener(new SelectionAdapter() {
+
+ /**
+ * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ handleComboModified();
+ }
+ });
+ }
+
+ /**
+ * Handle the combo modified event.
+ */
+ protected void handleComboModified() {
+ if (!isRefreshing && getFeatureValue() != cSingleObjectChooser.getSelection()) {
+ EditingDomain editingDomain = getEditingDomain();
+ if (getEObjectList().size() == 1) {
+ /* apply the property change to single selected object */
+ editingDomain.getCommandStack().execute(SetCommand.create(editingDomain, getEObject(), getFeature(), cSingleObjectChooser.getSelection()));
+ } else {
+ CompoundCommand compoundCommand = new CompoundCommand();
+ /* apply the property change to all selected elements */
+ for (EObject nextObject : getEObjectList()) {
+ compoundCommand.append(SetCommand.create(editingDomain, nextObject, getFeature(), cSingleObjectChooser.getSelection()));
+ }
+ editingDomain.getCommandStack().execute(compoundCommand);
+ }
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.ISection#refresh()
+ */
+ public void refresh() {
+ isRefreshing = true;
+ cSingleObjectChooser.setChoices(getComboFeatureValues());
+ cSingleObjectChooser.setSelection(getFeatureValue());
+ isRefreshing = false;
+ }
+
+ /**
+ * @return the cSingleObjectChooser
+ */
+ protected CSingleObjectChooser getCSingleObjectChooser() {
+ return cSingleObjectChooser;
+ }
+
+ /**
+ * @return the isRefreshing
+ */
+ protected boolean isRefreshing() {
+ return isRefreshing;
+ }
+
+ /**
+ * Returns an array of all reachable objects of a given type from the
+ * current selection.
+ *
+ * @param object
+ * current EObject selection
+ * @param type
+ * Reachable object which have this type
+ * @return An array of objects of the given type
+ */
+ protected Object[] getChoices(EObject object, EClassifier type) {
+ List<Object> choices = new ArrayList<Object>();
+ choices.add("");
+ choices.addAll(ItemPropertyDescriptor.getReachableObjectsOfType(getEObject(), type));
+
+ return choices.toArray();
+ }
+
+ /**
+ * Returns the label text for the given item
+ *
+ * @param object
+ * the item to find the name
+ * @return The found name of the given item
+ */
+ protected String getItemLabelText(EObject object) {
+ return object.toString();
+ }
+
+ /**
+ * Get the LabelProvider to use to display the Object
+ *
+ * @return ILabelProvider
+ */
+ protected ILabelProvider getLabelProvider() {
+ return new TabbedPropertiesLabelProvider(new EcoreItemProviderAdapterFactory());
+ }
+
+ /**
+ * Get the current feature value of the selected model object.
+ *
+ * @return the feature value to select in the ccombo.
+ */
+ protected abstract Object getFeatureValue();
+
+ /**
+ * Get the enumeration values of the feature for the combo field for the
+ * section.
+ *
+ * @return the list of values of the feature as text.
+ */
+ protected abstract Object[] getComboFeatureValues();
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractColorPropertySection.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractColorPropertySection.java
new file mode 100644
index 0000000..6d579d6
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractColorPropertySection.java
@@ -0,0 +1,104 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections;
+
+import org.eclipse.jface.preference.ColorSelector;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
+
+/**
+ * An abstract Color section used to select a Color.
+ *
+ * Creation 29 sept. 06
+ *
+ * @author <a href="mailto:jacques.lescot@anyware-tech.com">Jacques LESCOT</a>
+ */
+public abstract class AbstractColorPropertySection extends AbstractTabbedPropertySection {
+
+ private ColorSelector colorSelector;
+
+ private CLabel colorLabel;
+
+ private Composite compositeColorSelector;
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#createWidgets(org.eclipse.swt.widgets.Composite)
+ */
+ protected void createWidgets(Composite composite) {
+ colorLabel = getWidgetFactory().createCLabel(composite, getLabelText());
+ compositeColorSelector = getWidgetFactory().createFlatFormComposite(composite);
+ colorSelector = new ColorSelector(compositeColorSelector);
+
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#setSectionData(org.eclipse.swt.widgets.Composite)
+ */
+ protected void setSectionData(Composite composite) {
+ FormData data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.top = new FormAttachment(0, 0);
+ data.right = new FormAttachment(compositeColorSelector, -ITabbedPropertyConstants.HSPACE);
+ colorLabel.setLayoutData(data);
+
+ data = new FormData();
+ data.right = new FormAttachment(100, 0);
+ data.top = new FormAttachment(colorLabel, 0, SWT.CENTER);
+ data.left = new FormAttachment(colorLabel, ITabbedPropertyConstants.HSPACE);
+ compositeColorSelector.setLayoutData(data);
+
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#hookListeners()
+ */
+ protected void hookListeners() {
+ colorSelector.addListener(new IPropertyChangeListener() {
+
+ public void propertyChange(PropertyChangeEvent event) {
+ handleColorChanged();
+ }
+ });
+
+ }
+
+ /**
+ * Called when the selected color changes
+ */
+ protected void handleColorChanged() {
+ createCommand(new Color(null, getRGBValue()), new Color(null, colorSelector.getColorValue()));
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
+ */
+ public void refresh() {
+ colorSelector.setColorValue(getRGBValue());
+ }
+
+ /**
+ * Get the new RGB value of the color feature for the section.
+ *
+ * @return the RGB value of the feature.
+ */
+ protected abstract RGB getRGBValue();
+
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractDetailedObjectPropertySection.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractDetailedObjectPropertySection.java
new file mode 100644
index 0000000..51ab878
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractDetailedObjectPropertySection.java
@@ -0,0 +1,320 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.provider.EcoreItemProviderAdapterFactory;
+import org.eclipse.emf.edit.command.CommandParameter;
+import org.eclipse.emf.tabbedproperties.providers.TabbedPropertiesLabelProvider;
+import org.eclipse.emf.tabbedproperties.sections.widgets.ChooseDialog;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+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.Group;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * An abstract section used to create a model object inside the selected
+ * element. You can then, depending on the selected model object edit its
+ * properties through a detailed Composite which is dynamically updated.
+ *
+ * Creation 10 nov. 06
+ *
+ * @author <a href="mailto:jacques.lescot@anyware-tech.com">Jacques LESCOT</a>
+ */
+public abstract class AbstractDetailedObjectPropertySection extends AbstractTabbedPropertySection {
+
+ /** The label used with to identify the Section */
+ private CLabel nameLabel;
+
+ /** The Text control for the section. */
+ private Text text;
+
+ /** The button used to create a new Element */
+ private Button createButton;
+
+ /**
+ * The Group used to edit the Details of the selected Constraint. Its
+ * contents depends on the type of Constraint that is selected in the other
+ * widget.
+ */
+ private Group groupDetails;
+
+ /** The Composite used to edit the selected Constraint properties */
+ private Composite detailsComposite;
+
+ private SelectionListener createButtonListener = new SelectionAdapter() {
+
+ /**
+ * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ Object[] availableTypes = getAvailableTypes();
+ Object selectedType = null;
+
+ if (availableTypes.length == 1) {
+ selectedType = availableTypes[0];
+ }
+ // When more than one concrete Types are available, a ChooseDialog
+ // is prompted
+ else if (availableTypes.length > 1) {
+ // Open the dialog used to choose the type of Constraint
+ ChooseDialog dialog = new ChooseDialog(Display.getDefault().getActiveShell(), getAvailableTypes());
+ dialog.setLabelProvider(getLabelProvider());
+ if (dialog.open() == Window.OK) {
+ if (dialog.getResult().length > 0) {
+ selectedType = dialog.getResult()[0];
+ }
+ }
+ }
+
+ if (selectedType != null) {
+ // Create the Command to add the selected Constraint
+ createCommand(getRelatedEObject(), selectedType);
+
+ // Update the group contents when the type has changed
+ updateGroupContents();
+ }
+ }
+ };
+
+ private Object[] getAvailableTypes() {
+ Collection<?> allTypes = getEditingDomain().getNewChildDescriptors(getEObject(), null);
+ List<EObject> availableTypes = new ArrayList<EObject>();
+
+ for (Object currentType : allTypes) {
+ if (currentType instanceof CommandParameter && getFeature().equals(((CommandParameter) currentType).getFeature())) {
+ availableTypes.add(((CommandParameter) currentType).getEValue());
+ }
+ }
+ return availableTypes.toArray();
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#createControls(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
+ */
+ public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage) {
+ super.createControls(parent, aTabbedPropertySheetPage);
+
+ // Composite composite =
+ // getWidgetFactory().createFlatFormComposite(parent);
+
+ // // The Widget used to select/create the corresponding Constraint
+ // nameLabel = getWidgetFactory().createCLabel(composite,
+ // getLabelText());
+ // text = getWidgetFactory().createText(composite, "", SWT.READ_ONLY);
+ // createButton = getWidgetFactory().createButton(composite, "Create
+ // ...", SWT.NONE);
+ //
+ // // The group that is used to edit the Details of the selected
+ // Constraint
+ // groupDetails = getWidgetFactory().createGroup(composite, "Details");
+ // groupDetails.setLayout(new GridLayout());
+
+ // FormData data = new FormData();
+ // data.left = new FormAttachment(0, 0);
+ // data.top = new FormAttachment(createButton, 0, SWT.CENTER);
+ // nameLabel.setLayoutData(data);
+ //
+ // data = new FormData();
+ // data.left = new FormAttachment(nameLabel,
+ // ITabbedPropertyConstants.HSPACE);
+ // data.right = new FormAttachment(createButton,
+ // -ITabbedPropertyConstants.HSPACE);
+ // data.top = new FormAttachment(createButton, 0, SWT.CENTER);
+ // text.setLayoutData(data);
+ //
+ // data = new FormData();
+ // data.right = new FormAttachment(100, 0);
+ // data.top = new FormAttachment(0, 0);
+ // createButton.setLayoutData(data);
+ //
+ // data = new FormData();
+ // data.left = new FormAttachment(0, 0);
+ // data.right = new FormAttachment(100, 0);
+ // data.top = new FormAttachment(nameLabel,
+ // ITabbedPropertyConstants.VSPACE);
+ // groupDetails.setLayoutData(data);
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#createWidgets(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected void createWidgets(Composite composite) {
+ // The Widget used to select/create the corresponding Constraint
+ nameLabel = getWidgetFactory().createCLabel(composite, getLabelText());
+ text = getWidgetFactory().createText(composite, "", SWT.READ_ONLY);
+ createButton = getWidgetFactory().createButton(composite, "Create ...", SWT.NONE);
+
+ // The group that is used to edit the Details of the selected Constraint
+ groupDetails = getWidgetFactory().createGroup(composite, "Details");
+ groupDetails.setLayout(new GridLayout());
+
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#setSectionData(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected void setSectionData(Composite composite) {
+ FormData data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.top = new FormAttachment(createButton, 0, SWT.CENTER);
+ nameLabel.setLayoutData(data);
+
+ data = new FormData();
+ data.left = new FormAttachment(nameLabel, ITabbedPropertyConstants.HSPACE);
+ data.right = new FormAttachment(createButton, -ITabbedPropertyConstants.HSPACE);
+ data.top = new FormAttachment(createButton, 0, SWT.CENTER);
+ text.setLayoutData(data);
+
+ data = new FormData();
+ data.right = new FormAttachment(100, 0);
+ data.top = new FormAttachment(0, 0);
+ createButton.setLayoutData(data);
+
+ data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.right = new FormAttachment(100, 0);
+ data.top = new FormAttachment(nameLabel, ITabbedPropertyConstants.VSPACE);
+ groupDetails.setLayoutData(data);
+
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.ISection#refresh()
+ */
+ public void refresh() {
+ super.refresh();
+
+ text.setText(updateConstraintText());
+ updateGroupContents();
+ }
+
+ private String updateConstraintText() {
+ String name = "";
+ if (getRelatedEObject() != null) {
+ name = getLabelProvider().getText(getRelatedEObject());
+ if (name == null) {
+ name = "";
+ }
+ }
+ return name;
+ }
+
+ /**
+ * This method should be called when the contents of the groupDetails should
+ * be updated.
+ */
+ protected void updateGroupContents() {
+ if (getRelatedEObject() != null) {
+ if (detailsComposite != null && !detailsComposite.isDisposed()) {
+ detailsComposite.dispose();
+ }
+
+ // create the new Composite associated with the related model object
+ detailsComposite = getDetailsComposite();
+ if (detailsComposite != null) {
+ getWidgetFactory().adapt(detailsComposite);
+ }
+
+ // Update the groupDetails composite by forcing it to layout its
+ // children
+ groupDetails.getParent().layout();
+ groupDetails.layout();
+ }
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#aboutToBeShown()
+ */
+ public void aboutToBeShown() {
+ super.aboutToBeShown();
+ if (createButton != null && !createButton.isDisposed()) {
+ createButton.addSelectionListener(createButtonListener);
+ }
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#aboutToBeHidden()
+ */
+ public void aboutToBeHidden() {
+ if (createButton != null && !createButton.isDisposed()) {
+ createButton.removeSelectionListener(createButtonListener);
+ }
+ super.aboutToBeHidden();
+ }
+
+ /**
+ * Get the LabelProvider to use to display the Constraint element
+ *
+ * @return ILabelProvider
+ */
+ protected ILabelProvider getLabelProvider() {
+ return new TabbedPropertiesLabelProvider(new EcoreItemProviderAdapterFactory());
+ }
+
+ /**
+ * This method returns the groupDetails composite. Subclasses should used it
+ * to retrieve that composite and add the custom detailsComposite
+ *
+ * @return Group the Group Composite used to display details informations
+ * about the relatedEObject
+ */
+ public Group getGroupDetails() {
+ return groupDetails;
+ }
+
+ /**
+ * Get the text value corresponding to the selected Constraint
+ *
+ * @return String
+ */
+ protected abstract String getFeatureAsText();
+
+ /**
+ * Return the model object associated with the section. This is not the same
+ * model object returned by the getEObject() method, but this is generally
+ * an internal model object that can be edited.
+ *
+ * @return EObject model object
+ */
+ protected abstract EObject getRelatedEObject();
+
+ /**
+ * This method should return the Composite that should be associated with
+ * the details Group
+ *
+ * @return the Composite used as children of the detailsGroup
+ */
+ protected abstract Composite getDetailsComposite();
+
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractDoublePropertySection.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractDoublePropertySection.java
new file mode 100644
index 0000000..ad85203
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractDoublePropertySection.java
@@ -0,0 +1,93 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections;
+
+import java.util.regex.Pattern;
+
+import org.eclipse.emf.tabbedproperties.internal.utils.ColorRegistry;
+import org.eclipse.swt.widgets.Event;
+
+/**
+ * An abstract implementation of a section for a field with a String property
+ * value.
+ *
+ * Creation 5 apr. 2006 Updated 7 aug. 2006
+ *
+ * @author Jacques Lescot
+ * @author Alfredo Serrano
+ */
+public abstract class AbstractDoublePropertySection extends AbstractTextPropertySection {
+
+ /**
+ * Predefined string pattern value for decimal, absloute with '-' and exp
+ * notation : -25.36e-6
+ */
+ public static final String EXP_NUMERIC_PATTERN = "^[-\\d][\\d]*\\.?[\\d]*((e|E)?-?[\\d]*)"; //$NON-NLS-1$
+
+ /** The Pattern used to check a Double value */
+ public static final Pattern DOUBLE_PATTERN = Pattern.compile(EXP_NUMERIC_PATTERN);
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTextPropertySection#verifyField(Event)
+ */
+ protected void verifyField(Event e) {
+ String value = getText().getText();
+ if (value == null || value.equals("") || isTextValid()) {
+ setErrorMessage(null);
+ getText().setBackground(null);
+ e.doit = true;
+ } else {
+ setErrorMessage("The character is not valid!!!");
+ getText().setBackground(ColorRegistry.COLOR_ERROR);
+ e.doit = false;
+ }
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTextPropertySection#getFeatureAsString()
+ */
+ protected String getFeatureAsString() {
+ return getFeatureDouble().toString();
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTextPropertySection#getOldFeatureValue()
+ */
+ protected Object getOldFeatureValue() {
+ return getFeatureDouble();
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTextPropertySection#getNewFeatureValue(java.lang.String)
+ */
+ protected Object getNewFeatureValue(String newText) {
+ if (newText == null || newText.equals("")) {
+ return null;
+ }
+ return new Double(Double.parseDouble(newText));
+ }
+
+ /**
+ * Get the text value of the feature for the text field for the section.
+ *
+ * @return the text value of the feature.
+ */
+ protected abstract Double getFeatureDouble();
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTextPropertySection#isTextValid()
+ */
+ protected boolean isTextValid() {
+ return DOUBLE_PATTERN.matcher(getText().getText()).matches();
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractEnumerationPropertySection.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractEnumerationPropertySection.java
new file mode 100644
index 0000000..27db254
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractEnumerationPropertySection.java
@@ -0,0 +1,186 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * An abstract implementation of a section with a enumeration field using a
+ * combo box (pulldown).
+ *
+ * Creation 5 apr. 2006 Updated 7 aug. 2006
+ *
+ * @author Jacques Lescot
+ * @author alfredo Serrano
+ */
+public abstract class AbstractEnumerationPropertySection extends AbstractTabbedPropertySection {
+
+ /**
+ * The combo box control for the section.
+ */
+ private CCombo combo;
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.ISection#createControls(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
+ */
+ public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage) {
+ super.createControls(parent, aTabbedPropertySheetPage);
+ // Composite composite =
+ // getWidgetFactory().createFlatFormComposite(parent);
+ //
+ // combo = getWidgetFactory().createCCombo(composite, SWT.FLAT |
+ // SWT.READ_ONLY | SWT.BORDER);
+
+ // FormData data = new FormData();
+ // data.left = new FormAttachment(0, getStandardLabelWidth(composite,
+ // new String[] {getLabelText()}));
+ // data.right = new FormAttachment(100, 0);
+ // data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
+ // combo.setLayoutData(data);
+ //
+ // CLabel nameLabel = getWidgetFactory().createCLabel(composite,
+ // getLabelText());
+ // data = new FormData();
+ // data.left = new FormAttachment(0, 0);
+ // data.right = new FormAttachment(combo,
+ // -ITabbedPropertyConstants.HSPACE);
+ // data.top = new FormAttachment(combo, 0, SWT.CENTER);
+ // nameLabel.setLayoutData(data);
+
+ // combo.addSelectionListener(new SelectionAdapter()
+ // {
+ // public void widgetSelected(SelectionEvent event)
+ // {
+ // handleComboModified();
+ // }
+ // });
+
+ // if (getFeature() != null)
+ // {
+ // boolean isChangeable = getFeature().isChangeable();
+ // combo.setEditable(isChangeable);
+ // combo.setEnabled(isChangeable);
+ // }
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#createWidgets(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected void createWidgets(Composite composite) {
+ combo = getWidgetFactory().createCCombo(composite, SWT.FLAT | SWT.READ_ONLY | SWT.BORDER);
+ if (getFeature() != null) {
+ boolean isChangeable = getFeature().isChangeable();
+ combo.setEditable(false);
+ combo.setEnabled(isChangeable);
+ }
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#setSectionData(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected void setSectionData(Composite composite) {
+ FormData data = new FormData();
+ data.left = new FormAttachment(0, getStandardLabelWidth(composite, new String[] { getLabelText() }));
+ data.right = new FormAttachment(100, 0);
+ data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
+ combo.setLayoutData(data);
+
+ CLabel nameLabel = getWidgetFactory().createCLabel(composite, getLabelText());
+ data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.right = new FormAttachment(combo, -ITabbedPropertyConstants.HSPACE);
+ data.top = new FormAttachment(combo, 0, SWT.CENTER);
+ nameLabel.setLayoutData(data);
+
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#hookListeners()
+ */
+ @Override
+ protected void hookListeners() {
+ combo.addSelectionListener(new SelectionAdapter() {
+
+ public void widgetSelected(SelectionEvent event) {
+ handleComboModified();
+ }
+ });
+
+ }
+
+ /**
+ * Handle the combo modified event.
+ */
+ protected void handleComboModified() {
+ int index = combo.getSelectionIndex();
+ createCommand(getOldFeatureValue(), getFeatureValue(index));
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.ISection#refresh()
+ */
+ public void refresh() {
+ combo.setItems(getEnumerationFeatureValues());
+ combo.setText(getFeatureAsText());
+ }
+
+ /**
+ * @return the combo
+ */
+ protected CCombo getCombo() {
+ return combo;
+ }
+
+ /**
+ * Get the enumeration values of the feature for the combo field for the
+ * section.
+ *
+ * @return the list of values of the feature as text.
+ */
+ protected abstract String[] getEnumerationFeatureValues();
+
+ /**
+ * Get the value of the feature as text for the combo field for the section.
+ *
+ * @return the value of the feature as text.
+ */
+ protected abstract String getFeatureAsText();
+
+ /**
+ * Get the new value of the feature for the text field for the section.
+ *
+ * @param index
+ * the new index in the enumeration.
+ * @return the new value of the feature.
+ */
+ protected abstract Object getFeatureValue(int index);
+
+ /**
+ * Get the old value of the feature
+ *
+ * @return The current value which is going to be modified
+ */
+ protected abstract Object getOldFeatureValue();
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractFileChooserPropertySection.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractFileChooserPropertySection.java
new file mode 100644
index 0000000..21759fd
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractFileChooserPropertySection.java
@@ -0,0 +1,212 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.edit.command.SetCommand;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.tabbedproperties.internal.TabbedPropertiesPlugin;
+import org.eclipse.emf.tabbedproperties.sections.widgets.FileChooser;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * An abstract implementation of a section with a field using a FileChooser
+ * composite (TextField with a browse Button).
+ *
+ * <br>
+ * creation : 3 avr. 07
+ *
+ * @author <a href="mailto:mickael.gerard@anyware-tech.com">Mickael Gerard</a>
+ */
+public abstract class AbstractFileChooserPropertySection extends AbstractTabbedPropertySection {
+
+ /**
+ * A boolean that store if refreshing is happening and no model
+ * modifications should be performed
+ */
+ private boolean isRefreshing = false;
+
+ /**
+ * The text + filechooser button
+ */
+ private FileChooser fileChooser;
+
+ /**
+ * The label for this section
+ */
+ private CLabel labelText;
+
+ /**
+ * Section composite. This composite can be return if client desire to
+ * implement other widgets in relation with the list represented by this
+ * instance.
+ */
+ // private Composite sectionComposite;
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.ISection#createControls(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
+ */
+ public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage) {
+ super.createControls(parent, aTabbedPropertySheetPage);
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#createWidgets(org.eclipse.swt.widgets.Composite)
+ */
+ protected void createWidgets(Composite composite) {
+ labelText = getWidgetFactory().createCLabel(composite, getLabelText());
+
+ fileChooser = new FileChooser(composite, getWidgetFactory(), SWT.NONE);
+ fileChooser.setEditable(true);
+
+ if (getFeature() != null) {
+ fileChooser.setChangeable(getFeature().isChangeable());
+ }
+
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#setSectionData(org.eclipse.swt.widgets.Composite)
+ */
+ protected void setSectionData(Composite composite) {
+ FormData data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.right = new FormAttachment(fileChooser, -ITabbedPropertyConstants.HSPACE);
+ data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
+ labelText.setLayoutData(data);
+
+ data = new FormData();
+ data.left = new FormAttachment(0, getStandardLabelWidth(composite, new String[] { getLabelText() }));
+ data.right = new FormAttachment(100, 0);
+ data.top = new FormAttachment(labelText, 0, SWT.CENTER);
+ fileChooser.setLayoutData(data);
+
+ }
+
+ /**
+ * Adds the listeners on the widgets
+ */
+ protected void hookListeners() {
+ fileChooser.addModifyListener(new ModifyListener() {
+
+ public void modifyText(ModifyEvent e) {
+ handleTextModified();
+ }
+
+ });
+ }
+
+ /**
+ * Handle the combo modified event.
+ */
+ protected void handleTextModified() {
+ if (!isRefreshing && getFeatureValue() != fileChooser.getSelection()) {
+ List<IStatus> status = verifyFile();
+ fileChooser.setStatus(status);
+ if (status.isEmpty()) {
+ EditingDomain editingDomain = getEditingDomain();
+ if (getEObjectList().size() == 1) {
+ /* apply the property change to single selected object */
+ editingDomain.getCommandStack().execute(SetCommand.create(editingDomain, getEObject(), getFeature(), fileChooser.getSelection()));
+ }
+ }
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.ISection#refresh()
+ */
+ public void refresh() {
+ isRefreshing = true;
+ fileChooser.setSelection(getFeatureValue());
+ isRefreshing = false;
+ }
+
+ /**
+ * @return the FileChooser
+ */
+ protected FileChooser getFileChooser() {
+ return fileChooser;
+ }
+
+ /**
+ * @return the isRefreshing
+ */
+ protected boolean isRefreshing() {
+ return isRefreshing;
+ }
+
+ /**
+ * Handler called to verify the file path on user text modification. By
+ * default it checks the file existence is the property checkFileExistence
+ * is set to true
+ *
+ * @return true is the file matches
+ */
+ protected List<IStatus> verifyFile() {
+ List<IStatus> statusList = new ArrayList<IStatus>();
+ if (isCheckFileExistence()) {
+ String selection = fileChooser.getSelection();
+ if (selection != null && !"".equals(selection)) {
+ File file = new File(selection);
+ if (!file.exists()) {
+ statusList.add(new Status(IStatus.ERROR, TabbedPropertiesPlugin.PLUGIN_ID, getLabelText() + " does not exist!"));
+ }
+ if (!file.isFile()) {
+ statusList.add(new Status(IStatus.ERROR, TabbedPropertiesPlugin.PLUGIN_ID, getLabelText() + " cannot be a directory!"));
+ }
+ } else if (cannotBeBlank()) {
+ statusList.add(new Status(IStatus.ERROR, TabbedPropertiesPlugin.PLUGIN_ID, getLabelText() + " cannot be blank!"));
+ }
+ }
+ List<IStatus> emptyList = Collections.emptyList();
+ return statusList.isEmpty() ? emptyList : statusList;
+ }
+
+ /**
+ *
+ * @return true if the file must exist in the file system
+ */
+ public boolean isCheckFileExistence() {
+ return false;
+ }
+
+ /**
+ * @return true if the field is compulsory
+ */
+ public boolean cannotBeBlank() {
+ return false;
+ }
+
+ /**
+ * Get the current feature value of the selected model object.
+ *
+ * @return the feature value to select in the ccombo.
+ */
+ protected abstract String getFeatureValue();
+
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractFontPropertySection.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractFontPropertySection.java
new file mode 100644
index 0000000..9017290
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractFontPropertySection.java
@@ -0,0 +1,122 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections;
+
+import org.eclipse.jface.resource.StringConverter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.FontDialog;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
+
+/**
+ * An abstract Font section used to select a Font.
+ *
+ * Creation 29 sept. 06
+ *
+ * @author <a href="mailto:jacques.lescot@anyware-tech.com">Jacques LESCOT</a>
+ */
+public abstract class AbstractFontPropertySection extends AbstractTabbedPropertySection {
+
+ /**
+ * The text displayed in the Text widget
+ */
+ private Text fontText;
+
+ private CLabel fontLabel;
+
+ private Button fontButton;
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#createWidgets(org.eclipse.swt.widgets.Composite)
+ */
+ protected void createWidgets(Composite composite) {
+ fontLabel = getWidgetFactory().createCLabel(composite, getLabelText());
+
+ fontText = getWidgetFactory().createText(composite, "");
+ fontText.setEditable(false);
+
+ fontButton = getWidgetFactory().createButton(composite, "Change...", SWT.PUSH);
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#setSectionData(org.eclipse.swt.widgets.Composite)
+ */
+ protected void setSectionData(Composite composite) {
+ FormData data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.right = new FormAttachment(fontText, -ITabbedPropertyConstants.HSPACE);
+ data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
+ fontLabel.setLayoutData(data);
+
+ data = new FormData();
+ data.left = new FormAttachment(fontLabel, ITabbedPropertyConstants.HSPACE);
+ data.right = new FormAttachment(fontButton, -ITabbedPropertyConstants.HSPACE);
+ data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
+ fontText.setLayoutData(data);
+
+ data = new FormData();
+ data.right = new FormAttachment(100, 0);
+ data.top = new FormAttachment(fontLabel, ITabbedPropertyConstants.VSPACE, SWT.CENTER);
+ fontButton.setLayoutData(data);
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#hookListeners()
+ */
+ protected void hookListeners() {
+ fontButton.addSelectionListener(new SelectionAdapter() {
+
+ public void widgetSelected(SelectionEvent event) {
+ handleButtonPressed();
+ }
+ });
+ }
+
+ /**
+ * Called when the selected font changes
+ */
+ protected void handleButtonPressed() {
+ FontDialog ftDialog = new FontDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
+ ftDialog.setFontList(getFontValue().getFontData());
+ FontData fData = ftDialog.open();
+
+ if (fData != null) {
+ createCommand(getFontValue(), new Font(null, fData));
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
+ */
+ public void refresh() {
+ fontText.setText(StringConverter.asString(getFontValue().getFontData()));
+ }
+
+ /**
+ * Get the new Font value of the font feature for the section.
+ *
+ * @return the Font value of the feature.
+ */
+ protected abstract Font getFontValue();
+
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractIntegerPropertySection.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractIntegerPropertySection.java
new file mode 100644
index 0000000..e3994d7
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractIntegerPropertySection.java
@@ -0,0 +1,88 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections;
+
+import java.util.regex.Pattern;
+
+import org.eclipse.emf.tabbedproperties.internal.utils.ColorRegistry;
+import org.eclipse.swt.widgets.Event;
+
+/**
+ * An abstract implementation of a section for a field with a String property
+ * value.
+ *
+ * Creation 5 apr. 2006 Updated 7 aug. 2006
+ *
+ * @author Jacques Lescot
+ * @author Alfredo Serrano
+ */
+public abstract class AbstractIntegerPropertySection extends AbstractTextPropertySection {
+
+ /** Predefined string pattern value for numerics and absolute with '-' : -25 */
+ public static final String ABS_NUMERICS_PATTERN = "^[-\\d][\\d]*"; //$NON-NLS-1$
+
+ /** The Pattern used to check an Integer value */
+ public static final Pattern INTEGER_PATTERN = Pattern.compile(ABS_NUMERICS_PATTERN);
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTextPropertySection#verifyField(Event)
+ */
+ protected void verifyField(Event e) {
+ String value = getText().getText();
+ if (value == null || value.equals("") || isTextValid()) {
+ setErrorMessage(null);
+ getText().setBackground(null);
+ e.doit = true;
+ } else {
+ setErrorMessage("The character is not valid!!!");
+ getText().setBackground(ColorRegistry.COLOR_ERROR);
+ e.doit = false;
+ }
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTextPropertySection#getFeatureAsString()
+ */
+ protected String getFeatureAsString() {
+ return getFeatureInteger().toString();
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTextPropertySection#getOldFeatureValue()
+ */
+ protected Object getOldFeatureValue() {
+ return getFeatureInteger();
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTextPropertySection#getNewFeatureValue(java.lang.String)
+ */
+ protected Object getNewFeatureValue(String newText) {
+ return new Integer(Integer.parseInt(newText));
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTextPropertySection#isTextValid()
+ */
+ protected boolean isTextValid() {
+ return INTEGER_PATTERN.matcher(getText().getText()).matches();
+ }
+
+ /**
+ * Get the text value of the feature for the text field for the section.
+ *
+ * @return the text value of the feature.
+ */
+ protected abstract Integer getFeatureInteger();
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractListPropertySection.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractListPropertySection.java
new file mode 100644
index 0000000..60d6791
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractListPropertySection.java
@@ -0,0 +1,148 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections;
+
+import org.eclipse.emf.tabbedproperties.sections.widgets.TableViewerComposite;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * An abstract implementation of a section with a list. It represents a list
+ * field.
+ *
+ * Creation 9 aug. 2006
+ *
+ * @author Alfredo SERRANO
+ */
+public abstract class AbstractListPropertySection extends AbstractTabbedPropertySection {
+
+ /**
+ * The list control for the section
+ */
+ private TableViewerComposite table;
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#createControls(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
+ */
+ public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage) {
+ super.createControls(parent, aTabbedPropertySheetPage);
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#createWidgets(org.eclipse.swt.widgets.Composite)
+ */
+ protected void createWidgets(Composite composite) {
+ table = new TableViewerComposite(composite, new String[] { getLabelText() }, getWidgetFactory()) {
+
+ public void updateSelectedItem(Object data) {
+ updateSelection(data);
+ }
+ };
+ table.setLabelProvider(getLabelProvider());
+
+ if (getFeature() != null) {
+ table.setEnabled(getFeature().isChangeable());
+ }
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#setSectionData(org.eclipse.swt.widgets.Composite)
+ */
+ protected void setSectionData(Composite composite) {
+ FormData data;
+ data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.right = new FormAttachment(100, 0);
+ data.top = new FormAttachment(0, 0);
+ table.setLayoutData(data);
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#hookListeners()
+ */
+ protected void hookListeners() {
+ table.setAddListener(new SelectionAdapter() {
+
+ public void widgetSelected(SelectionEvent event) {
+ addElement();
+ }
+ });
+ }
+
+ /**
+ * This method may be overriden if client want to implement their own add
+ * treatment
+ *
+ */
+ protected void addElement() {
+ table.addElement();
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
+ */
+ public void refresh() {
+ table.setInput(getEObject(), getFeature());
+ table.setEditingDomain(getEditingDomain());
+ table.refresh();
+ }
+
+ /**
+ * @return the table
+ */
+ public TableViewerComposite getTable() {
+ return table;
+ }
+
+ /**
+ * Set the table
+ *
+ * @param table
+ */
+ protected void setTable(TableViewerComposite table) {
+ this.table = table;
+ }
+
+ /**
+ * This method may be overriden if client desire to listen the table
+ * selection
+ *
+ * @param data
+ * the selected data from the listened table.
+ */
+ public void updateSelection(Object data) {
+ // do nothing
+ }
+
+ /**
+ * Returns the feature which is multiple
+ *
+ * @return Object This object is an instance of a java.util.List
+ */
+ protected abstract Object getListValues();
+
+ /**
+ * Returns a label provider to be set for this table.
+ *
+ * @return The Label provider. It may be null when client handles
+ * attributes.
+ */
+ protected abstract IBaseLabelProvider getLabelProvider();
+
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractReferencePropertySection.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractReferencePropertySection.java
new file mode 100644
index 0000000..ed180c1
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractReferencePropertySection.java
@@ -0,0 +1,65 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections;
+
+import org.eclipse.emf.tabbedproperties.sections.widgets.ReferenceViewerComposite;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * This widget let the user to manipulate features with bounds higher than 1
+ * This feature is also also non-containment, so the table will display a single
+ * button to select the references inside the model
+ *
+ * @author Alfredo Serrano
+ */
+public abstract class AbstractReferencePropertySection extends AbstractListPropertySection {
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractListPropertySection#createWidgets(org.eclipse.swt.widgets.Composite)
+ */
+ protected void createWidgets(Composite composite) {
+
+ setTable(new ReferenceViewerComposite(composite, new String[] { getLabelText() }, getWidgetFactory()) {
+
+ public void updateSelectedItem(Object data) {
+ updateSelection(data);
+ }
+ });
+ getTable().setLabelProvider(getLabelProvider());
+
+ if (getFeature() != null) {
+ getTable().setEnabled(getFeature().isChangeable());
+ }
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractListPropertySection#setSectionData(org.eclipse.swt.widgets.Composite)
+ */
+ protected void setSectionData(Composite composite) {
+ FormData data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.right = new FormAttachment(100, 0);
+ data.top = new FormAttachment(0, 0);
+ data.bottom = new FormAttachment(100, 0);
+ getTable().setLayoutData(data);
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractListPropertySection#hookListeners()
+ */
+ protected void hookListeners() {
+ // DO NOTHING
+ }
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractStringPropertySection.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractStringPropertySection.java
new file mode 100644
index 0000000..47f531c
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractStringPropertySection.java
@@ -0,0 +1,59 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections;
+
+import org.eclipse.swt.widgets.Event;
+
+/**
+ * An abstract implementation of a section for a field with a String property
+ * value.
+ *
+ * Creation 5 apr. 2006 Updated 7 aug. 2006
+ *
+ * @author Jacques Lescot
+ * @author Alfredo Serrano
+ */
+public abstract class AbstractStringPropertySection extends AbstractTextPropertySection {
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTextPropertySection#verifyField(Event)
+ */
+ protected void verifyField(Event e) {
+ // do nothing
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTextPropertySection#getFeatureAsString()
+ */
+ protected String getFeatureAsString() {
+ String string = getEObject() == null ? null : (String) getEObject().eGet(getFeature());
+ if (string == null) {
+ return "";
+ }
+ return string;
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTextPropertySection#getNewFeatureValue(java.lang.String)
+ */
+ protected Object getNewFeatureValue(String newText) {
+ return newText;
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTextPropertySection#getOldFeatureValue()
+ */
+ protected Object getOldFeatureValue() {
+ return getFeatureAsString();
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractTabbedPropertySection.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractTabbedPropertySection.java
new file mode 100644
index 0000000..6f3976c
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractTabbedPropertySection.java
@@ -0,0 +1,533 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.edit.command.SetCommand;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.edit.domain.IEditingDomainProvider;
+import org.eclipse.emf.tabbedproperties.internal.sections.listeners.PropertiesAdapterImpl;
+import org.eclipse.emf.tabbedproperties.internal.utils.MessageManager;
+import org.eclipse.emf.tabbedproperties.utils.ObjectAdapter;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.IPage;
+import org.eclipse.ui.part.PageBookView;
+import org.eclipse.ui.views.properties.tabbed.AbstractPropertySection;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * An abstract implementation of a section in a tab in the tabbed property sheet
+ * page for a tree editor. Clients specializing this class may implement the
+ * create widgets, setFormData and hooklisteners rather than overriding the
+ * create controls.
+ *
+ * Creation 5 avr. 2006
+ *
+ * @author Jacques Lescot
+ * @author Alfredo Serrano
+ */
+public abstract class AbstractTabbedPropertySection extends AbstractPropertySection {
+
+ /**
+ * The current selected object or the first object in the selection when
+ * multiple objects are selected.
+ */
+ private EObject eObject;
+
+ /**
+ * A list of selected objects.
+ */
+ private List<EObject> eObjectList;
+
+ /**
+ * The status line manager for showing messages
+ */
+ private IStatusLineManager statusLineManager;
+
+ /**
+ * Field Decorator Manager
+ */
+ private MessageManager messageManager;
+
+ /**
+ * Section composite. This composite can be return if client desire to
+ * implement other widgets in relation with the list represented by this
+ * instance.
+ */
+ private Composite sectionComposite;
+
+ /**
+ * Listener for the model notifications
+ */
+ private Adapter modelListener = new PropertiesAdapterImpl() {
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.internal.sections.listeners.PropertiesAdapterImpl#safeNotifyChanged(org.eclipse.emf.common.notify.Notification)
+ */
+ protected void safeNotifyChanged(Notification msg) {
+ handleModelChanged(msg);
+ }
+ };
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.ISection#createControls(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
+ */
+ public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage) {
+ super.createControls(parent, aTabbedPropertySheetPage);
+ sectionComposite = getMainComposite(parent);
+ createWidgets(sectionComposite);
+ setSectionData(sectionComposite);
+ hookListeners();
+ messageManager = new MessageManager();
+ IActionBars actionBars = aTabbedPropertySheetPage.getSite().getActionBars();
+ makeContributions(actionBars.getMenuManager(), actionBars.getToolBarManager(), actionBars.getStatusLineManager());
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.ISection#setInput(org.eclipse.ui.IWorkbenchPart,
+ * org.eclipse.jface.viewers.ISelection)
+ */
+ public void setInput(IWorkbenchPart part, ISelection selection) {
+ super.setInput(part, selection);
+ if (!(selection instanceof IStructuredSelection)) {
+ return;
+ }
+ Object ssel = ((IStructuredSelection) selection).getFirstElement();
+ removeListener();
+ eObject = ObjectAdapter.adaptObject(ssel);
+ eObjectList = new ArrayList<EObject>();
+ for (Iterator<?> iter = ((IStructuredSelection) selection).iterator(); iter.hasNext();) {
+ EObject element = ObjectAdapter.adaptObject(iter.next());
+ if (element != null) {
+ eObjectList.add(element);
+ }
+ }
+ addListener();
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.ISection#aboutToBeHidden()
+ */
+ public void aboutToBeHidden() {
+ removeListener();
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.ISection#aboutToBeShown()
+ */
+ public void aboutToBeShown() {
+ addListener();
+ }
+
+ /**
+ * Sets the manager this view will use
+ *
+ * @param toolBarManager
+ * the toolBarManager to display buttons on the toolBar
+ * @param menuManager
+ * the Menu manager to display menus
+ * @param statLineManager
+ * the status line manager to show messages
+ */
+ public void makeContributions(IMenuManager menuManager, IToolBarManager toolBarManager, IStatusLineManager statLineManager) {
+ this.statusLineManager = statLineManager;
+ }
+
+ /**
+ * Obtains the currently active workbench page.
+ *
+ * @return the active page, or <code>null</code> if none is active
+ */
+ public IWorkbenchPage getActivePage() {
+ IWorkbenchPage result = null;
+
+ IWorkbench bench = PlatformUI.getWorkbench();
+ if (bench != null) {
+ IWorkbenchWindow window = bench.getActiveWorkbenchWindow();
+
+ if (window != null) {
+ result = window.getActivePage();
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * @return the section Composite
+ */
+ protected Composite getSectionComposite() {
+ return sectionComposite;
+ }
+
+ /**
+ * Build the main composite for this section
+ *
+ * @param parent
+ * The Section
+ * @return The main composite for this section
+ */
+ protected Composite getMainComposite(Composite parent) {
+ return getWidgetFactory().createFlatFormComposite(parent);
+ }
+
+ /**
+ *
+ * This returns whether the resource is read only in editing domain.
+ *
+ * @return <code>false</code> when the file can be written.
+ */
+ protected boolean isReadOnly() {
+ Resource resource = getEObject().eResource();
+ EditingDomain domain = getEditingDomain();
+ if (domain != null && resource != null && domain.isReadOnly(resource)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Sets the error message to be displayed in the status line.
+ *
+ * @param errorMessage
+ * the message to be displayed, or <code>null</code>
+ */
+ protected void setErrorMessage(String errorMessage) {
+ // show the error message
+ if (statusLineManager != null) {
+ statusLineManager.setErrorMessage(errorMessage);
+ }
+ }
+
+ /**
+ * Sets the message to be displayed in the status line. This message is
+ * displayed when there is no error message.
+ *
+ * @param message
+ * the message to be displayed, or <code>null</code>
+ */
+ protected void setMessage(String message) {
+ // show the message
+ if (statusLineManager != null) {
+ statusLineManager.setMessage(message);
+ }
+ }
+
+ /**
+ * Removes the model listener to this object
+ */
+ protected void removeListener() {
+ if (getEObject() == null) {
+ return;
+ }
+ if (getEObject().eAdapters().contains(getModelListener())) {
+ getEObject().eAdapters().remove(getModelListener());
+ }
+ }
+
+ /**
+ * Adds a model listener to this object
+ */
+ protected void addListener() {
+ if (getEObject() == null) {
+ return;
+ }
+ if (!getEObject().eAdapters().contains(getModelListener())) {
+ getEObject().eAdapters().add(getModelListener());
+ }
+ }
+
+ /**
+ * Get the standard label width when labels for sections line up on the left
+ * hand side of the composite. We line up to a fixed position, but if a
+ * string is wider than the fixed position, then we use that widest string.
+ *
+ * @param parent
+ * The parent composite used to create a GC.
+ * @param labels
+ * The list of labels.
+ * @return the standard label width.
+ */
+ protected int getStandardLabelWidth(Composite parent, String[] labels) {
+ int standardLabelWidth = STANDARD_LABEL_WIDTH + 65;
+ GC gc = new GC(parent);
+ int indent = gc.textExtent("XXX").x; //$NON-NLS-1$
+ for (int i = 0; i < labels.length; i++) {
+ int width = gc.textExtent(labels[i]).x;
+ if (width + indent > standardLabelWidth) {
+ standardLabelWidth = width + indent;
+ }
+ }
+ gc.dispose();
+ return standardLabelWidth;
+ }
+
+ /**
+ * This returns the editing domain as required by the
+ * {@link IEditingDomainProvider} interface. This is important for
+ * implementing the static methods of {@link AdapterFactoryEditingDomain}
+ * and for supporting {@link org.eclipse.emf.edit.ui.action.CommandAction}.
+ *
+ * @return The required editing domain
+ * @throws IllegalArgumentException
+ * There is an error when the part cannot be adapted in any
+ * EditingDomain.
+ */
+ protected EditingDomain getEditingDomain() {
+ IWorkbenchPart part = getPart();
+
+ if (part.getAdapter(EditingDomain.class) != null) {
+ return (EditingDomain) getPart().getAdapter(EditingDomain.class);
+ }
+
+ if (part instanceof IEditingDomainProvider) {
+ return ((IEditingDomainProvider) part).getEditingDomain();
+ }
+
+ if (part.getAdapter(IEditingDomainProvider.class) != null) {
+ return ((IEditingDomainProvider) part.getAdapter(IEditingDomainProvider.class)).getEditingDomain();
+ }
+
+ if (part instanceof PageBookView) {
+ IPage page = ((PageBookView) part).getCurrentPage();
+ if (page instanceof IEditingDomainProvider) {
+ return ((IEditingDomainProvider) page).getEditingDomain();
+ }
+ }
+
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Manages a self-contained set of interrelated EMF models and the
+ * {@link Command}s that modify them. The models are maintained in the form
+ * of a {@link ResourceSet}. Commands that modify the model are typically
+ * created through the domain and are executed using the
+ * {@link CommandStack}.
+ *
+ * @param oldValue
+ * The previous property value
+ * @param newValue
+ * The new value to set
+ */
+ protected void createCommand(Object oldValue, Object newValue) {
+ boolean equals = oldValue == null ? false : oldValue.equals(newValue);
+ if (!equals) {
+ EditingDomain editingDomain = getEditingDomain();
+ Object value = newValue;
+ if (getEObjectList().size() == 1) {
+ // apply the property change to single selected object
+ editingDomain.getCommandStack().execute(SetCommand.create(editingDomain, getEObject(), getFeature(), value));
+ } else {
+ CompoundCommand compoundCommand = new CompoundCommand();
+ // apply the property change to all selected elements
+ for (EObject nextObject : getEObjectList()) {
+ compoundCommand.append(SetCommand.create(editingDomain, nextObject, getFeature(), value));
+ }
+ editingDomain.getCommandStack().execute(compoundCommand);
+ }
+ }
+ }
+
+ /**
+ * @return the eObject
+ */
+ protected EObject getEObject() {
+ return eObject;
+ }
+
+ /**
+ * @return the eObjectList
+ */
+ protected List<EObject> getEObjectList() {
+ return eObjectList;
+ }
+
+ /**
+ * @return the statusLineManager
+ */
+ protected IStatusLineManager getStatusLineManager() {
+ return statusLineManager;
+ }
+
+ /**
+ * @return the message manager to which decorates fields
+ */
+ protected MessageManager getMessageManager() {
+ return messageManager;
+ }
+
+ /**
+ * @param control
+ * the Control
+ * @param message
+ * a String
+ * @param type
+ * the type
+ *
+ */
+ protected void setDecorator(Control control, String message, int type) {
+ messageManager.addMessage("", message, null, type, control);
+ }
+
+ /**
+ * Add a decorator to the given control. A tool tip will display the given
+ * message
+ *
+ * @param control
+ * @param message
+ *
+ * @since 1.0 M3
+ */
+ protected void setErrorDecorator(Control control, String message) {
+ setDecorator(control, message, IMessageProvider.ERROR);
+ }
+
+ /**
+ * Add a decorator to the given control. A tool tip will display the given
+ * message
+ *
+ * @param control
+ * @param message
+ *
+ * @since 1.0 M3
+ */
+ protected void setWarningDecorator(Control control, String message) {
+ setDecorator(control, message, IMessageProvider.WARNING);
+ }
+
+ /**
+ * Add a decorator to the given control. A tool tip will display the given
+ * message
+ *
+ * @param control
+ * @param message
+ *
+ * @since 1.0 M3
+ */
+ protected void setInfoDecorator(Control control, String message) {
+ setDecorator(control, message, IMessageProvider.INFORMATION);
+ }
+
+ /**
+ * Clear existing decorators
+ *
+ * @since 1.0 M3
+ */
+ protected void clearDecorators() {
+ messageManager.removeAllMessages();
+ }
+
+ /**
+ * Returns the generic model listener
+ *
+ * @return the model listener
+ */
+ protected Adapter getModelListener() {
+ return modelListener;
+ }
+
+ /**
+ * This method is called when an event occurred on the model objects
+ *
+ * @param msg
+ * the event notification
+ */
+ protected void handleModelChanged(Notification msg) {
+ Object notifier = msg.getNotifier();
+ if (notifier.equals(getEObject()) && getFeature() != null) {
+ if (msg.getFeatureID(getEObject().getClass()) == getFeature().getFeatureID()) {
+ refresh();
+ }
+ }
+ }
+
+ /**
+ * Get the feature for the combo field for the section.
+ *
+ * @return the feature for the text.
+ */
+ protected abstract EStructuralFeature getFeature();
+
+ /**
+ * Get the label for the text field for the section.
+ *
+ * @return the label for the text field.
+ */
+ protected abstract String getLabelText();
+
+ /**
+ * Section widgets should be created inside this method. To set the layout
+ * data please implement the {@link #setSectionData(Composite)} If widgets
+ * has listeners implement the {@link #hookListeners()}.
+ *
+ * @param composite
+ * the parent Composite
+ *
+ * @see #createControls(Composite, TabbedPropertySheetPage)
+ */
+ protected void createWidgets(Composite composite) {
+ // Implement this method
+
+ }
+
+ /**
+ * This method should be implemented to set layout data to the widgets
+ * created at {@link #createWidgets(Composite)}. This improves visibility
+ *
+ * @param composite
+ * Sometimes widgets will be set formDatas and position will
+ * depend on parent composite.
+ */
+ protected void setSectionData(Composite composite) {
+ // Implement this method
+
+ }
+
+ /**
+ * Widgets created at {@link #createWidgets(Composite)} may listen platform
+ * events. Set them here in order to improve visibility
+ */
+ protected void hookListeners() {
+ // Implement this method
+
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractTextPropertySection.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractTextPropertySection.java
new file mode 100644
index 0000000..924c7ed
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AbstractTextPropertySection.java
@@ -0,0 +1,240 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections;
+
+import org.eclipse.emf.tabbedproperties.utils.TextChangeListener;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+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.Text;
+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * An abstract implementation of a section with a text field.<br>
+ *
+ * Creation 5 apr. 2006<br>
+ * Updated 7 aug. 2006
+ *
+ * @author Jacques Lescot
+ * @author Alfredo Serrano
+ */
+public abstract class AbstractTextPropertySection extends AbstractTabbedPropertySection {
+
+ /** The text control for the section. */
+ private Text text;
+
+ /** The label used with to identify the Section */
+ private CLabel nameLabel;
+
+ /**
+ * A helper to listen for events that indicate that a text field has been
+ * changed.
+ */
+ private TextChangeListener listener;
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#createControls(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
+ */
+ public void createControls(Composite parent, TabbedPropertySheetPage tabbedPropertySheetPage) {
+ super.createControls(parent, tabbedPropertySheetPage);
+ // Composite composite =
+ // getWidgetFactory().createFlatFormComposite(parent);
+ // createWidgets(composite);
+ // setFormData(composite);
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#createWidgets(org.eclipse.swt.widgets.Composite)
+ */
+ protected void createWidgets(Composite composite) {
+ text = getWidgetFactory().createText(composite, "", getStyle());
+
+ if (getFeature() != null) {
+ boolean isChangeable = getFeature().isChangeable();
+
+ text.setEditable(isChangeable);
+ text.setEnabled(isChangeable);
+ }
+
+ nameLabel = getWidgetFactory().createCLabel(composite, getLabelText());
+
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#setSectionData(org.eclipse.swt.widgets.Composite)
+ */
+ protected void setSectionData(Composite composite) {
+ FormData data = new FormData();
+ data.left = new FormAttachment(0, getStandardLabelWidth(composite, new String[] { getLabelText() }));
+ data.right = new FormAttachment(100, 0);
+ data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
+ data.bottom = new FormAttachment(100, 0);
+ text.setLayoutData(data);
+
+ data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.right = new FormAttachment(text, -ITabbedPropertyConstants.HSPACE);
+ data.top = new FormAttachment(text, 0, SWT.TOP);
+ nameLabel.setLayoutData(data);
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.AbstractTabbedPropertySection#hookListeners()
+ */
+ protected void hookListeners() {
+ listener = new TextChangeListener() {
+
+ public void textChanged(Control control) {
+ handleTextModified();
+ }
+
+ public void focusIn(Control control) {
+ AbstractTextPropertySection.this.focusIn();
+ }
+
+ public void focusOut(Control control) {
+ AbstractTextPropertySection.this.focusOut();
+ }
+ };
+ listener.startListeningTo(text);
+
+ // Do not listen to the "Enter" key pressed when the widget is a
+ // MultiLine Text
+ if ((getStyle() & SWT.MULTI) == 0) {
+ listener.startListeningForEnter(text);
+ }
+ text.addListener(SWT.Modify, new Listener() {
+
+ public void handleEvent(Event e) {
+ verifyField(e);
+ }
+ });
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
+ */
+ public void refresh() {
+ getText().setText(getFeatureAsString());
+ }
+
+ /**
+ * Handle the text modified event. When there is any problem while creating
+ * and executing the command, the view will be only refreshed
+ */
+ protected void handleTextModified() {
+ if (isTextValid()) {
+ createCommand(getOldFeatureValue(), getNewFeatureValue(getText().getText()));
+ } else {
+ refresh();
+ }
+ }
+
+ /**
+ * Handle action when the focus is gained Default action is to do nothing.
+ * Clients may override this method if they desire a particular action to be
+ * executed when the text control gain the focus.
+ */
+ protected void focusIn() {
+ // Do nothing
+ }
+
+ /**
+ * Handle action when the focus is lost. Default action is to do nothing.
+ * Clients may override this method if they desire a particular action to be
+ * executed when the text control lost the focus.
+ */
+ protected void focusOut() {
+ // Do nothing
+ }
+
+ /**
+ * Get the style of the text widget. By default, this is a single line text
+ *
+ * @return the style
+ */
+ protected int getStyle() {
+ return SWT.SINGLE;
+ }
+
+ /**
+ * @return the listener
+ */
+ protected TextChangeListener getListener() {
+ return listener;
+ }
+
+ /**
+ * @return the text
+ */
+ protected Text getText() {
+ return text;
+ }
+
+ /**
+ * @return the nameLabel
+ */
+ public CLabel getNameLabel() {
+ return nameLabel;
+ }
+
+ /**
+ * Check whether the text entered is valid or not. Subclasses should
+ * override this method to provide their own check. By default, return true.
+ *
+ * @return true if the text entered is valid
+ */
+ protected boolean isTextValid() {
+ return true;
+ }
+
+ /**
+ * Get the value of the feature as text for the text field for the section.
+ *
+ * @return the value of the feature as text.
+ */
+ protected abstract String getFeatureAsString();
+
+ /**
+ * Get the new value of the feature from the text field of the section.
+ *
+ * @param newText
+ * the new value of the feature as a string.
+ * @return the new value of the feature.
+ */
+ protected abstract Object getNewFeatureValue(String newText);
+
+ /**
+ * Returns the feature value from the model as an object type.
+ *
+ * @return the feature object
+ */
+ protected abstract Object getOldFeatureValue();
+
+ /**
+ * Subclasses may provide their own checker on the text that is entered by
+ * the user and update the 'doit' flag of the Event in consequence.
+ *
+ * @param e
+ * the Event that is sent when the Text is modified
+ */
+ protected abstract void verifyField(Event e);
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AdvancedPropertySection.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AdvancedPropertySection.java
new file mode 100644
index 0000000..6118c22
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/AdvancedPropertySection.java
@@ -0,0 +1,92 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections;
+
+import org.eclipse.emf.tabbedproperties.AbstractTabbedPropertySheetPage;
+import org.eclipse.emf.tabbedproperties.providers.TabbedPropertiesContentProvider;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.SubActionBars;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * An implementation of the old PropertyView as a new tab in the Eclipse Tabbed
+ * Properties View
+ *
+ * Creation 5 april 2006<br>
+ * Last Modified 17 august 06
+ *
+ * @author <a href="jacques.lescot@anyware-tech.com">Jacques LESCOT</a>
+ * @author <a href="alfredo@anyware-tech.com">Jose Alfredo SERRANO</a>
+ */
+public class AdvancedPropertySection extends org.eclipse.ui.views.properties.tabbed.AdvancedPropertySection {
+
+ private SubActionBars subActionBars;
+
+ private AbstractTabbedPropertySheetPage propertySheetPage;
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.ISection#createControls(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
+ */
+ public void createControls(Composite parent, TabbedPropertySheetPage tabbedPropertySheetPage) {
+ super.createControls(parent, tabbedPropertySheetPage);
+ if (tabbedPropertySheetPage instanceof AbstractTabbedPropertySheetPage) {
+ propertySheetPage = (AbstractTabbedPropertySheetPage) tabbedPropertySheetPage;
+ page.setPropertySourceProvider(new TabbedPropertiesContentProvider(propertySheetPage.getAdapterFactory()));
+ }
+ subActionBars = new SubActionBars(tabbedPropertySheetPage.getSite().getActionBars());
+ setActionBars(subActionBars);
+ }
+
+ /**
+ * Sets and prepares the actionBars for this section
+ *
+ * @param actionBars
+ * the action bars for this page
+ */
+ protected void setActionBars(IActionBars actionBars) {
+ page.makeContributions(actionBars.getMenuManager(), actionBars.getToolBarManager(), actionBars.getStatusLineManager());
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#aboutToBeHidden()
+ */
+ public void aboutToBeHidden() {
+ super.aboutToBeHidden();
+ if (subActionBars != null) {
+ subActionBars.deactivate();
+ subActionBars.updateActionBars();
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#aboutToBeShown()
+ */
+ public void aboutToBeShown() {
+ super.aboutToBeShown();
+ if (subActionBars != null) {
+ subActionBars.activate();
+ subActionBars.updateActionBars();
+ }
+ }
+
+ /**
+ * Returns the propertySheetPage
+ *
+ * @return The PropertySheetPage
+ */
+ public AbstractTabbedPropertySheetPage getPropertySheetPage() {
+ return propertySheetPage;
+ }
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/CSingleObjectChooser.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/CSingleObjectChooser.java
new file mode 100644
index 0000000..8b7caba
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/CSingleObjectChooser.java
@@ -0,0 +1,317 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections.widgets;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+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.Text;
+import org.eclipse.swt.widgets.TypedListener;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+/**
+ * A field widget and a Button that allow you to retrieve an object contained in
+ * a list of objects
+ *
+ * Creation 6 avr. 2006
+ *
+ * @author David Sciamma
+ */
+public class CSingleObjectChooser extends Composite {
+
+ private Text field;
+
+ private Button chooseBt;
+
+ private Object[] objects;
+
+ private TabbedPropertySheetWidgetFactory widgetFactory;
+
+ private ILabelProvider labelProvider;
+
+ private Object selectedObject;
+
+ /**
+ * Constructor
+ *
+ * @param parent
+ * the parent Composite
+ * @param factory
+ * the factory necessary to create the widget
+ * @param style
+ */
+ public CSingleObjectChooser(Composite parent, TabbedPropertySheetWidgetFactory factory, int style) {
+ super(parent, style);
+
+ this.widgetFactory = factory;
+ createContents(this);
+ widgetFactory.adapt(this);
+ hookListeners();
+ }
+
+ /**
+ * Creates the UI. User must call the super method to create the main
+ * widgets (buttons) to this composite.
+ *
+ * @param parent
+ * this widget
+ */
+ protected void createContents(Composite parent) {
+ setLayout(parent);
+
+ field = widgetFactory.createText(parent, "", SWT.FLAT | SWT.BORDER | SWT.READ_ONLY);
+ field.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ chooseBt = widgetFactory.createButton(parent, "...", SWT.PUSH);
+ }
+
+ /**
+ * This method sets a gridlayout to the composite. The number of columns is
+ * determined by the getNumberOfColumns method. The minimum number of
+ * columns is 2.
+ *
+ * @param parent
+ * the composite featuring a gridlayout
+ */
+ private void setLayout(Composite parent) {
+ int numColumns = getNumberOfColumns();
+ if (numColumns < 2) {
+ numColumns = 2;
+ }
+ GridLayout layout = new GridLayout(numColumns, false);
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ parent.setLayout(layout);
+ }
+
+ /**
+ * Returns the number of columns in this composite. The default object is 2
+ * because the main composite have 2 widgets.
+ *
+ * Returning a number less than 2 will be ingnored.
+ *
+ * @return The number of columns to set in this composite. It must be
+ * greater or equals than 2
+ */
+ protected int getNumberOfColumns() {
+ return 2;
+ }
+
+ /**
+ * Adds the listeners on the choose button. If user overrides this method,
+ * he must call the super method to add the corresponding selection
+ * listener, otherwise disfunctions may occur
+ */
+ protected void hookListeners() {
+ chooseBt.addSelectionListener(new SelectionAdapter() {
+
+ /**
+ * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ handleChoose();
+ }
+ });
+ }
+
+ /**
+ * Set the objects in which the user can choose.
+ *
+ * @param objs
+ * the list of objects
+ */
+ public void setChoices(Object[] objs) {
+ if (objs != null && objs.length > 0) {
+ // replace any null entry with a NullObject
+ Object[] objects2 = new Object[objs.length];
+ for (int cpt = 0; cpt < objs.length; cpt++) {
+ if (objs[cpt] == null) {
+ objects2[cpt] = new NullObject();
+ } else {
+ objects2[cpt] = objs[cpt];
+ }
+ }
+
+ this.objects = objects2;
+ }
+ setSelection(null);
+ }
+
+ /**
+ * Sets the editable state of the text field. The default value is
+ * READ-ONLY. However clients may set this value as true by calling this
+ * method
+ *
+ * @param isEditable
+ */
+ public void setEditable(boolean isEditable) {
+ if (field != null) {
+ field.setEditable(isEditable);
+ }
+ }
+
+ /**
+ * Set the provider that displays the objects
+ *
+ * @param provider
+ * the LabelProvider
+ */
+ public void setLabelProvider(ILabelProvider provider) {
+ labelProvider = provider;
+ }
+
+ /**
+ * Open the dialog to choose in the searchable list
+ */
+ private void handleChoose() {
+ ChooseDialog dialog = new ChooseDialog(getShell(), objects);
+ dialog.setLabelProvider(labelProvider);
+ List<Object> selectedObjects = new ArrayList<Object>();
+ selectedObjects.add(selectedObject);
+ dialog.setInitialElementSelections(selectedObjects);
+
+ if (dialog.open() == Window.OK) {
+ Object[] selection = dialog.getResult();
+
+ if (selection != null && selection.length > 0) {
+ setSelection(selection[0]);
+ } else {
+ setSelection(null);
+ }
+
+ Event e = new Event();
+ notifyListeners(SWT.Selection, e);
+ }
+ }
+
+ /**
+ * Set whether the Choose button is enabled
+ *
+ * @param isChangeable
+ */
+ public void setChangeable(boolean isChangeable) {
+ chooseBt.setEnabled(isChangeable);
+ }
+
+ /**
+ * Returns the selected object
+ *
+ * @return the selection
+ */
+ public Object getSelection() {
+ return selectedObject;
+ }
+
+ /**
+ * Set the selection of the comboViewer
+ *
+ * @param selection
+ * the selected object
+ */
+ public void setSelection(Object selection) {
+ if (selection instanceof NullObject) {
+ selectedObject = null;
+ } else {
+ selectedObject = selection;
+ }
+
+ String name = "";
+ if (selectedObject != null) {
+ name = labelProvider.getText(selectedObject);
+ if (name == null) {
+ name = "";
+ }
+ }
+ field.setText(name);
+ }
+
+ /**
+ * Add a SelectionListener on both the CCombo and the Button
+ *
+ * @param listener
+ */
+ public void addSelectionListener(SelectionListener listener) {
+ if (listener == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ TypedListener typedListener = new TypedListener(listener);
+ addListener(SWT.Selection, typedListener);
+ }
+
+ /**
+ * Remove the SelectionListener of the CCombo and the Button
+ *
+ * @param listener
+ */
+ public void removeSelectionListener(SelectionListener listener) {
+ if (listener == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ removeListener(SWT.Selection, listener);
+ }
+
+ /**
+ * An object used to replace a null entry in the comboViewer choices tab
+ *
+ * Creation 6 avr. 2006
+ *
+ * @author jlescot
+ */
+ static class NullObject {
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return "";
+ }
+
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ return obj instanceof NullObject;
+ }
+
+ }
+
+ /**
+ * @return the widgetFactory
+ */
+ protected TabbedPropertySheetWidgetFactory getWidgetFactory() {
+ return widgetFactory;
+ }
+
+ /**
+ * Enables/disables itself, and also its contained text and button
+ *
+ * @see org.eclipse.swt.widgets.Control#setEnabled(boolean)
+ */
+ @Override
+ public void setEnabled(boolean enabled) {
+ super.setEnabled(enabled);
+ field.setEnabled(enabled);
+ chooseBt.setEnabled(enabled);
+ }
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/ChooseDialog.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/ChooseDialog.java
new file mode 100644
index 0000000..eb36b22
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/ChooseDialog.java
@@ -0,0 +1,184 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections.widgets;
+
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IOpenListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.OpenEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+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.Shell;
+import org.eclipse.ui.dialogs.SelectionDialog;
+
+/**
+ * The dialog used to choose between the different objects
+ *
+ * @author <a href="david.sciamma@anyware-tech.com">David Sciamma</a>
+ */
+public class ChooseDialog extends SelectionDialog {
+
+ /**
+ * The default width of a dialog
+ */
+ private int DEFAULT_DIALOG_WIDTH = 400;
+
+ /**
+ * The default height of a dialog
+ */
+ private int DEFAULT_DIALOG_HEIGHT = 300;
+
+ /**
+ * The minimum width of a dialog
+ */
+ private int MIN_DIALOG_WIDTH = 300;
+
+ /**
+ * The minimum height of a dialog
+ */
+ private int MIN_DIALOG_HEIGHT = 300;
+
+ private SearchableTree tree;
+
+ private ILabelProvider labelProvider;
+
+ private Object[] objects;
+
+ /**
+ * Wrapper to adapt the ArrayContentProvider to a TreeViewer
+ *
+ * @author <a href="david.sciamma@anyware-tech.com">David Sciamma</a>
+ */
+ private class TreeArrayContentProvider extends ArrayContentProvider implements ITreeContentProvider {
+
+ /**
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+ */
+ public Object[] getChildren(Object parentElement) {
+ return new Object[0];
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+ */
+ public Object getParent(Object element) {
+ return null;
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+ */
+ public boolean hasChildren(Object element) {
+ return false;
+ }
+
+ }
+
+ /**
+ * Constructor
+ *
+ * @param parentShell
+ * the paren shell
+ * @param objects
+ * The available objects
+ */
+ public ChooseDialog(Shell parentShell, Object[] objects) {
+ super(parentShell);
+ this.objects = objects;
+
+ setTitle("Object selection");
+ setMessage("Choose an object in the list");
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ }
+
+ /**
+ * @see org.eclipse.ui.dialogs.SelectionDialog#configureShell(org.eclipse.swt.widgets.Shell)
+ */
+ protected void configureShell(Shell shell) {
+ shell.setMinimumSize(MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT);
+
+ super.configureShell(shell);
+ }
+
+ /**
+ * Create the Dialog area
+ *
+ * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+ */
+ protected Control createDialogArea(Composite parent) {
+ // Dialog
+ Composite dialogComposite = (Composite) super.createDialogArea(parent);
+
+ GridLayout dialogLayout = new GridLayout();
+ dialogLayout.marginWidth = 10;
+ dialogLayout.marginHeight = 10;
+ GridData dialogLayoutData = new GridData(GridData.FILL_BOTH);
+ dialogLayoutData.widthHint = DEFAULT_DIALOG_WIDTH;
+ dialogLayoutData.heightHint = DEFAULT_DIALOG_HEIGHT;
+ dialogComposite.setLayout(dialogLayout);
+ dialogComposite.setLayoutData(dialogLayoutData);
+
+ tree = new SearchableTree(dialogComposite, SWT.SINGLE);
+ tree.setLayoutData(new GridData(GridData.FILL_BOTH));
+ tree.setContentProvider(new TreeArrayContentProvider());
+ tree.setLabelProvider(this.labelProvider);
+
+ tree.setInput(this.objects);
+ tree.setInitialSelection(new StructuredSelection(getInitialElementSelections()));
+
+ hookListeners();
+
+ return dialogComposite;
+ }
+
+ /**
+ * This method had the UI listeners on the SWT widgets
+ */
+ private void hookListeners() {
+ tree.getTreeViewer().addOpenListener(new IOpenListener() {
+
+ /**
+ * @see org.eclipse.jface.viewers.IOpenListener#open(org.eclipse.jface.viewers.OpenEvent)
+ */
+ public void open(OpenEvent event) {
+ okPressed();
+ }
+ });
+ }
+
+ /**
+ * Set the provider that displays the objects
+ *
+ * @param provider
+ * the LabelProvider
+ */
+ public void setLabelProvider(ILabelProvider provider) {
+ this.labelProvider = provider;
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.Dialog#okPressed()
+ */
+ protected void okPressed() {
+ IStructuredSelection selection = (IStructuredSelection) tree.getTreeViewer().getSelection();
+ setResult(selection.toList());
+ super.okPressed();
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/FileChooser.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/FileChooser.java
new file mode 100644
index 0000000..da7dd04
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/FileChooser.java
@@ -0,0 +1,351 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections.widgets;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.tabbedproperties.internal.utils.ColorRegistry;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+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.FileDialog;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.TypedListener;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+/**
+ *
+ * A field widget and a Button that allow you to retrieve an a file path from
+ * the filesystem<br>
+ *
+ * Creation : 3 avr. 07
+ *
+ * @author <a href="mailto:mickael.gerard@anyware-tech.com">Mickael Gerard</a>
+ */
+public class FileChooser extends Composite {
+
+ private Text field;
+
+ private Button chooseBt;
+
+ private TabbedPropertySheetWidgetFactory widgetFactory;
+
+ private String selectedFile;
+
+ /**
+ * Holds the fileChooserExtensionFilter
+ */
+ private String[] filterExtensions;
+
+ /**
+ * Constructor
+ *
+ * @param parent
+ * the parent Composite
+ * @param factory
+ * the factory necessary to create the widget
+ * @param style
+ */
+ public FileChooser(Composite parent, TabbedPropertySheetWidgetFactory factory, int style) {
+ super(parent, style);
+
+ this.widgetFactory = factory;
+ // default no filter
+ setFilterExtensions(new String[] { "*.*" });
+ createContents(this);
+ widgetFactory.adapt(this);
+ hookListeners();
+ }
+
+ /**
+ * Creates the UI. User must call the super method to create the main
+ * widgets (buttons) to this composite.
+ *
+ * @param parent
+ * this widget
+ */
+ protected void createContents(Composite parent) {
+ setLayout(parent);
+
+ field = widgetFactory.createText(parent, "", SWT.FLAT | SWT.BORDER | SWT.READ_ONLY);
+ field.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ chooseBt = widgetFactory.createButton(parent, "...", SWT.PUSH);
+ }
+
+ /**
+ * This method sets a gridlayout to the composite. The number of columns is
+ * determined by the getNumberOfColumns method. The minimum number of
+ * columns is 2.
+ *
+ * @param parent
+ * the composite featuring a gridlayout
+ */
+ private void setLayout(Composite parent) {
+ int numColumns = getNumberOfColumns();
+ if (numColumns < 2) {
+ numColumns = 2;
+ }
+ GridLayout layout = new GridLayout(numColumns, false);
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ parent.setLayout(layout);
+ }
+
+ /**
+ * Returns the number of columns in this composite. The default object is 2
+ * because the main composite have 2 widgets.
+ *
+ * Returning a number less than 2 will be ingnored.
+ *
+ * @return The number of columns to set in this composite. It must be
+ * greater or equals than 2
+ */
+ protected int getNumberOfColumns() {
+ return 2;
+ }
+
+ /**
+ * Adds the listeners on the choose button. If user overrides this method,
+ * he must call the super method to add the corresponding selection
+ * listener, otherwise disfunctions may occur
+ */
+ protected void hookListeners() {
+
+ field.addModifyListener(new ModifyListener() {
+
+ public void modifyText(ModifyEvent e) {
+ String oldPath = getSelection();
+ String newPath = field.getText();
+ if (newPath != null) {
+ newPath = newPath.trim();
+ }
+ setSelection(newPath, false);
+ handleFilePathChange(oldPath, newPath);
+ }
+
+ });
+
+ chooseBt.addSelectionListener(new SelectionAdapter() {
+
+ /**
+ * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ handleChoose();
+ }
+ });
+ }
+
+ /**
+ * Sets the editable state of the text field. The default value is
+ * READ-ONLY. However clients may set this value as true by calling this
+ * method
+ *
+ * @param isEditable
+ */
+ public void setEditable(boolean isEditable) {
+ if (field != null) {
+ field.setEditable(isEditable);
+ }
+ }
+
+ /**
+ * Open the dialog to choose in the searchable list
+ */
+ private void handleChoose() {
+ FileDialog dialog = new FileDialog(getShell());
+ dialog.setFilterExtensions(getFilterExtensions());
+ String filePath = dialog.open();
+ if (filePath != null) {
+ String oldPath = getSelection();
+ setSelection(filePath);
+ handleFilePathChange(filePath, oldPath);
+ }
+ }
+
+ /**
+ * Notify listeners when filePath has changed
+ *
+ * @param filePath
+ * @param oldPath
+ */
+ private void handleFilePathChange(String filePath, String oldPath) {
+ if (fileHasChanged(oldPath, filePath)) {
+ // to trigger handler on Modification
+ Event e = new Event();
+ notifyListeners(SWT.Modify, e);
+ }
+ }
+
+ /**
+ * Set whether the Choose button is enabled
+ *
+ * @param isChangeable
+ */
+ public void setChangeable(boolean isChangeable) {
+ chooseBt.setEnabled(isChangeable);
+ }
+
+ /**
+ * Returns the selected object
+ *
+ * @return the selection
+ */
+ public String getSelection() {
+ return selectedFile;
+ }
+
+ /**
+ * Set the selection of the comboViewer
+ *
+ * @param selection
+ * the selected object
+ */
+ public void setSelection(String selection) {
+ setSelection(selection, true);
+ }
+
+ /**
+ * Set the selection of the FileChooser
+ *
+ * @param selection
+ * @param updateField
+ * boolean update text field if true
+ */
+ public void setSelection(String selection, boolean updateField) {
+ String name = "";
+ if (selection != null) {
+ name = selection;
+ }
+ selectedFile = name;
+ if (updateField) {
+ field.setText(name);
+ if (field.isFocusControl()) {
+ field.setSelection(selectedFile.length());
+ }
+ }
+ }
+
+ /**
+ * Add a SelectionListener on the Button
+ *
+ * @param listener
+ */
+ public void addModifyListener(ModifyListener listener) {
+ if (listener == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ TypedListener typedListener = new TypedListener(listener);
+ addListener(SWT.Modify, typedListener);
+ }
+
+ /**
+ * Remove the SelectionListener of the CCombo and the Button
+ *
+ * @param listener
+ */
+ public void removeModifyListener(SelectionListener listener) {
+ if (listener == null) {
+ SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ }
+ removeListener(SWT.Modify, listener);
+ }
+
+ /**
+ * @return the widgetFactory
+ */
+ protected TabbedPropertySheetWidgetFactory getWidgetFactory() {
+ return widgetFactory;
+ }
+
+ /**
+ * Set the file extensions which the dialog will use to filter the files it
+ * shows to the argument, which may be null.
+ * <p>
+ * The strings are platform specific. For example, on Windows, an extension
+ * filter string is typically of the form "*.extension", where "*.*" matches
+ * all files.
+ * </p>
+ *
+ * @return String[]
+ *
+ * @see #setFilterExtensions to specify the user-friendly names
+ * corresponding to the extensions
+ */
+ protected String[] getFilterExtensions() {
+ return filterExtensions;
+ }
+
+ /**
+ * @param filterExtensions
+ * String[]
+ */
+ protected void setFilterExtensions(String[] filterExtensions) {
+ this.filterExtensions = filterExtensions;
+ }
+
+ /**
+ * Return true if newFilePath and oldFilePath are different
+ *
+ * @param oldFilePath
+ * @param newFilePath
+ * @return true if newFilePath and oldFilePath are different
+ */
+ private boolean fileHasChanged(String oldFilePath, String newFilePath) {
+ boolean change = true;
+
+ if (oldFilePath == null && newFilePath == null || oldFilePath != null && oldFilePath.equals(newFilePath)) {
+ change = false;
+ }
+
+ return change;
+ }
+
+ /**
+ * Set widget status
+ *
+ * @param statusList
+ */
+ public void setStatus(List<IStatus> statusList) {
+ if (statusList != null && !statusList.isEmpty()) {
+ int severity = -1;
+ String toolTip = "";
+ for (IStatus status : statusList) {
+ toolTip = "* " + status.getMessage() + "\n";
+ if (severity != IStatus.ERROR) {
+ severity = status.getSeverity();
+ }
+ }
+ field.setToolTipText(toolTip.substring(0, toolTip.length() - 2));
+ if (severity == IStatus.ERROR) {
+ field.setBackground(ColorRegistry.COLOR_ERROR);
+ } else if (severity == IStatus.WARNING) {
+ field.setBackground(ColorRegistry.COLOR_WARNING);
+ }
+ } else {
+ field.setToolTipText("");
+ field.setBackground(ColorRegistry.COLOR_WHITE);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/GoToReferenceComposite.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/GoToReferenceComposite.java
new file mode 100644
index 0000000..db81164
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/GoToReferenceComposite.java
@@ -0,0 +1,83 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections.widgets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+/**
+ * TODO Comment this class
+ */
+public class GoToReferenceComposite extends CSingleObjectChooser {
+
+ /**
+ * This button will perform the change selection
+ */
+ private Button goToBt;
+
+ /**
+ * Constructor
+ *
+ * @param parent
+ * the parent Composite
+ * @param factory
+ * the factory necessary to create the widget
+ * @param style
+ */
+ public GoToReferenceComposite(Composite parent, int style, TabbedPropertySheetWidgetFactory factory) {
+ super(parent, factory, style);
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.widgets.CSingleObjectChooser#createContents(org.eclipse.swt.widgets.Composite)
+ */
+ protected void createContents(Composite parent) {
+ super.createContents(parent);
+
+ goToBt = getWidgetFactory().createButton(parent, "GoTo->", SWT.PUSH);
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.widgets.CSingleObjectChooser#getNumberOfColumns()
+ */
+ protected int getNumberOfColumns() {
+ return 3;
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.widgets.CSingleObjectChooser#hookListeners()
+ */
+ protected void hookListeners() {
+ super.hookListeners();
+ goToBt.addSelectionListener(new SelectionAdapter() {
+
+ /**
+ * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent e) {
+ handleGoTo();
+ }
+ });
+ }
+
+ /**
+ * This method is to be overriden in order to implement the desired behavior
+ */
+ protected void handleGoTo() {
+ // Do nothing
+ }
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/ReferenceViewerComposite.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/ReferenceViewerComposite.java
new file mode 100644
index 0000000..a25223a
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/ReferenceViewerComposite.java
@@ -0,0 +1,72 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections.widgets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+/**
+ * TODO Comment this class
+ */
+public class ReferenceViewerComposite extends TableViewerComposite {
+
+ /**
+ * The button which displays a dialog box to select the pointed references
+ */
+ private Button selectButton;
+
+ /**
+ * Constructor
+ *
+ * @param parent
+ * @param columnNames
+ * @param widgetFactory
+ */
+ public ReferenceViewerComposite(Composite parent, String[] columnNames, TabbedPropertySheetWidgetFactory widgetFactory) {
+ super(parent, columnNames, widgetFactory);
+ }
+
+ /**
+ * Only create a Button used to select References.
+ *
+ * @see org.eclipse.emf.tabbedproperties.sections.widgets.TableViewerComposite#createButtons(org.eclipse.swt.widgets.Composite)
+ */
+ protected void createButtons(Composite parent) {
+ final Composite comp = getWidgetFactory().createComposite(parent);
+ comp.setLayout(new GridLayout());
+
+ selectButton = getWidgetFactory().createButton(comp, "Select...", SWT.NONE);
+ selectButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ hookButtonListeners();
+ }
+
+ /**
+ * @see org.eclipse.emf.tabbedproperties.sections.widgets.TableViewerComposite#hookButtonListeners()
+ */
+ protected void hookButtonListeners() {
+ selectButton.addSelectionListener(new SelectionAdapter() {
+
+ public void widgetSelected(SelectionEvent e) {
+ Object o = getObjectManager().chooseObjectsFromDialog();
+ getObjectManager().updateElement(o);
+ }
+ });
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/SearchableTree.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/SearchableTree.java
new file mode 100644
index 0000000..a2db458
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/SearchableTree.java
@@ -0,0 +1,252 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections.widgets;
+
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.swt.widgets.TreeItem;
+
+/**
+ * This widget displays a tree (or a list) with a text field to allow to filter
+ * the list content using the field content.
+ *
+ * @author <a href="david.sciamma@anyware-tech.com">David Sciamma</a>
+ */
+public class SearchableTree extends Composite {
+
+ private static boolean caseSensitive = true;
+
+ private Text searchField;
+
+ private Button sensitiveBt;
+
+ private TreeViewer treeViewer;
+
+ private IStructuredSelection initialSelection;
+
+ /**
+ * Private filter to search into the object tree
+ *
+ * @author <a href="david.sciamma@anyware-tech.com">David Sciamma</a>
+ */
+ private class SearchFilter extends ViewerFilter {
+
+ /**
+ * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer,
+ * java.lang.Object, java.lang.Object)
+ */
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ String searchedText = SearchableTree.this.searchField.getText();
+ boolean isCaseSensitive = SearchableTree.this.sensitiveBt.getSelection();
+ if (searchedText != null & !"".equals(searchedText)) {
+ IBaseLabelProvider provider = treeViewer.getLabelProvider();
+ if (provider instanceof ILabelProvider) {
+ String text = ((ILabelProvider) provider).getText(element);
+
+ if (!isCaseSensitive) {
+ text = text.toLowerCase();
+ searchedText = searchedText.toLowerCase();
+ }
+
+ if (text.indexOf(searchedText) != -1) {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ }
+
+ /**
+ * Constructor
+ *
+ * @param parent
+ * the parent composite
+ * @param style
+ * the Tree Style
+ */
+ public SearchableTree(Composite parent, int style) {
+ super(parent, SWT.NONE);
+
+ createContents(this, style);
+ hookListeners();
+ }
+
+ /**
+ * Creates the UI
+ *
+ * @param parent
+ * this widget
+ * @param style
+ * the tree style
+ */
+ protected void createContents(Composite parent, int style) {
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ parent.setLayout(layout);
+
+ createSearchComp(parent);
+ createTree(parent, style);
+ }
+
+ /**
+ * Creates the UI for the serach field
+ *
+ * @param parent
+ * the parent composite
+ */
+ private void createSearchComp(Composite parent) {
+ Composite main = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ main.setLayout(layout);
+
+ main.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ // Create search zone
+ Label searchLbl = new Label(main, SWT.NONE);
+ searchLbl.setText("Search : ");
+
+ this.searchField = new Text(main, SWT.BORDER);
+ this.searchField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ // Create case sensitive checkbox
+ this.sensitiveBt = new Button(main, SWT.CHECK);
+ this.sensitiveBt.setText("Case sensitive");
+ this.sensitiveBt.setSelection(caseSensitive);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ this.sensitiveBt.setLayoutData(gd);
+ }
+
+ /**
+ * Creates the tree displaying the objects
+ *
+ * @param parent
+ * the parent composite
+ * @param style
+ * the tree style
+ */
+ private void createTree(Composite parent, int style) {
+ treeViewer = new TreeViewer(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | style);
+ treeViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ treeViewer.addFilter(new SearchFilter());
+ }
+
+ /**
+ * Adds the listeners on the widgets
+ */
+ protected void hookListeners() {
+ this.searchField.addModifyListener(new ModifyListener() {
+
+ public void modifyText(ModifyEvent e) {
+ refresh();
+ }
+ });
+ this.sensitiveBt.addSelectionListener(new SelectionAdapter() {
+
+ public void widgetSelected(SelectionEvent e) {
+ caseSensitive = SearchableTree.this.sensitiveBt.getSelection();
+ refresh();
+ }
+ });
+ }
+
+ /**
+ * Refresh the tree and the selection
+ */
+ protected void refresh() {
+ treeViewer.refresh();
+ // Try to restore initial selection
+ treeViewer.setSelection(initialSelection);
+ // Else select the first object
+ if (((IStructuredSelection) treeViewer.getSelection()).size() == 0) {
+ if (treeViewer.getTree().getItems().length > 0) {
+ TreeItem item = treeViewer.getTree().getItem(0);
+ treeViewer.getTree().setSelection(new TreeItem[] { item });
+ }
+ }
+ }
+
+ /**
+ * Returns the tree used to display the objects
+ *
+ * @return the tree viewer
+ */
+ public TreeViewer getTreeViewer() {
+ return treeViewer;
+ }
+
+ /**
+ * Set the content provider for the tree
+ *
+ * @param provider
+ * the tree content provider
+ */
+ public void setContentProvider(ITreeContentProvider provider) {
+ treeViewer.setContentProvider(provider);
+ }
+
+ /**
+ * Set the label provider for the tree
+ *
+ * @param provider
+ * the tree label provider
+ */
+ public void setLabelProvider(ILabelProvider provider) {
+ treeViewer.setLabelProvider(provider);
+ }
+
+ /**
+ * Set the input model
+ *
+ * @param input
+ * the input object
+ */
+ public void setInput(Object input) {
+ treeViewer.setInput(input);
+ }
+
+ /**
+ * Set the initial selection of the tree
+ *
+ * @param selection
+ * the intial selection
+ */
+ public void setInitialSelection(IStructuredSelection selection) {
+ this.initialSelection = selection;
+ treeViewer.setSelection(this.initialSelection);
+ }
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/TableViewerComposite.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/TableViewerComposite.java
new file mode 100644
index 0000000..aec8e36
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/sections/widgets/TableViewerComposite.java
@@ -0,0 +1,644 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.sections.widgets;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.tabbedproperties.AbstractTabbedPropertySheetPage;
+import org.eclipse.emf.tabbedproperties.internal.sections.TableObjectManager;
+import org.eclipse.emf.tabbedproperties.internal.sections.listeners.CellModifier;
+import org.eclipse.emf.tabbedproperties.providers.TabbedPropertiesLabelProvider;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.CheckboxCellEditor;
+import org.eclipse.jface.viewers.ComboBoxCellEditor;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+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.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+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.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+/**
+ * This widget contains a TableViewer representing the Parameters of an
+ * Operation. There are two Buttons (one for adding a new Parameter, the other
+ * for deleting the current selected Parameter)
+ *
+ * Creation 10 august 06 Last Modified 11 august 06
+ *
+ * @author <a href="alfredo@anyware-tech.com">Jose Alfredo SERRANO</a>
+ */
+public class TableViewerComposite extends Composite {
+
+ private TabbedPropertySheetWidgetFactory widgetFactory;
+
+ private TableObjectManager objectManager;
+
+ private TableViewer tableViewer;
+
+ private Table table;
+
+ private String[] columnNames;
+
+ private Button addButton;
+
+ private Button removeButton;
+
+ private List<Button> otherButtons;
+
+ private ILabelProvider labelProvider;
+
+ private final Set<SelectionListener> selectionListeners;
+
+ private SelectionListener removeListener = new SelectionAdapter() {
+
+ public void widgetSelected(SelectionEvent e) {
+ int index = table.getSelectionIndex();
+ Object object = table.getItem(index).getData();
+ removeElement(object);
+ fireWidgetSelected();
+ }
+ };
+
+ private SelectionListener addListener = new SelectionAdapter() {
+
+ public void widgetSelected(SelectionEvent e) {
+ addElement();
+ fireWidgetSelected();
+ }
+ };
+
+ /**
+ * InnerClass that acts as a proxy for the TableObjectManager providing
+ * content for the Table. It implements the IEObjectModifyListener interface
+ * since it must register changeListeners with the TableObjectManager
+ */
+ class TableContentProvider implements IStructuredContentProvider {
+
+ /**
+ * @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) {
+ // Do nothing
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+ // Do nothing
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ */
+ public Object[] getElements(Object inputElement) {
+ List<?> list = objectManager.eGet();
+ int size = list.size();
+ return list.toArray(new Object[size]);
+ }
+ }
+
+ /**
+ * The constructor
+ *
+ * @param parent
+ * a widget which will be the parent of the new instance (cannot
+ * be null)
+ * @param colNames
+ * the name of the different columns of the table
+ * @param widgetFactory
+ * the widgetFactory to use to create the widgets
+ */
+ public TableViewerComposite(Composite parent, String[] colNames, TabbedPropertySheetWidgetFactory widgetFactory) {
+ super(parent, SWT.NONE);
+
+ this.widgetFactory = widgetFactory;
+ this.widgetFactory.adapt(this);
+
+ setLayout(new GridLayout(2, false));
+
+ this.columnNames = colNames;
+ createContents();
+
+ labelProvider = new TabbedPropertiesLabelProvider(new ComposedAdapterFactory(AbstractTabbedPropertySheetPage.getPrincipalAdapterFactories()));
+
+ selectionListeners = new HashSet<SelectionListener>();
+ }
+
+ /**
+ * Create the Composite composed of a Table and two Buttons
+ */
+ private void createContents() {
+ createTable(this);
+ createButtons(this);
+ createTableViewer();
+ }
+
+ /**
+ * TODO modify the table appearance Create the Table
+ *
+ * @param parent
+ * the parent Composite
+ */
+ protected void createTable(Composite parent) {
+ int style = SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.HIDE_SELECTION;
+
+ table = widgetFactory.createTable(parent, style);
+
+ GridData gridData = new GridData(GridData.FILL_BOTH);
+ gridData.grabExcessVerticalSpace = true;
+ gridData.verticalSpan = 2;
+ table.setLayoutData(gridData);
+
+ table.setLinesVisible(true);
+ table.setHeaderVisible(true);
+
+ createColumns(table, columnNames);
+ }
+
+ /**
+ * Create the table columns
+ *
+ * @param tab
+ * @param colNames
+ */
+ private void createColumns(Table tab, String[] colNames) {
+ for (int i = 0; i < colNames.length; i++) {
+ TableColumn column = new TableColumn(tab, SWT.LEFT, i);
+ column.setText(colNames[i]);
+ column.setWidth(100);
+ }
+ }
+
+ /**
+ * Create the TableViewer
+ */
+ protected void createTableViewer() {
+ tableViewer = new TableViewer(table);
+ tableViewer.setUseHashlookup(true);
+
+ tableViewer.setColumnProperties(columnNames);
+
+ // Set the cell modifier for the viewer
+ tableViewer.setCellModifier(new CellModifier(this));
+ // Setup the table viewer
+ tableViewer.setContentProvider(new TableContentProvider());
+
+ tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+
+ /**
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ if (table.getSelection().length > 0) {
+ updateSelectedItem(table.getSelection()[0].getData());
+ } else {
+ updateSelectedItem(null);
+ }
+ }
+
+ });
+ }
+
+ /**
+ * Create cell type
+ *
+ * @param numberOfCells
+ * @return an array of cell editors
+ */
+ private CellEditor[] createCells(int numberOfCells) {
+ if (numberOfCells < 0) {
+ return new CellEditor[0];
+ }
+
+ CellEditor[] editors = new CellEditor[numberOfCells];
+ for (int i = 0; i < numberOfCells; i++) {
+ CellEditor cellEditor;
+ switch (objectManager.getEType()) {
+ case TableObjectManager.BOOL:
+ cellEditor = new CheckboxCellEditor(table);
+ editors[i] = cellEditor;
+ break;
+ case TableObjectManager.ENUM:
+ cellEditor = new ComboBoxCellEditor(table, objectManager.getEnumLiterals(), SWT.READ_ONLY);
+ editors[i] = cellEditor;
+ break;
+ case TableObjectManager.INT:
+ case TableObjectManager.B_INT:
+ case TableObjectManager.DBL:
+ cellEditor = new TextCellEditor(table);
+ Text text = (Text) cellEditor.getControl();
+ text.setTextLimit(7);
+ text.addVerifyListener(new VerifyListener() {
+
+ public void verifyText(VerifyEvent e) {
+ e.doit = "0123456789".indexOf(e.text) >= 0;
+ }
+ });
+ editors[i] = cellEditor;
+ break;
+ case TableObjectManager.STR:
+ cellEditor = new TextCellEditor(table);
+ ((Text) cellEditor.getControl()).setTextLimit(60);
+ editors[i] = cellEditor;
+ break;
+ default:
+ break;
+ }
+ }
+ return editors;
+ }
+
+ /**
+ * Create ADD and REMOVE buttons in the section composite
+ *
+ * @param parent
+ * the parent Composite
+ */
+ protected void createButtons(Composite parent) {
+ final Composite comp = widgetFactory.createComposite(parent);
+ comp.setLayout(new GridLayout());
+
+ createAddButton(comp);
+ createRemoveButton(comp);
+ createOtherButtons(comp);
+ hookListeners();
+ }
+
+ /**
+ * Create the ADD button
+ *
+ * @param comp
+ * the parent Composite
+ */
+ protected void createAddButton(Composite comp) {
+ addButton = widgetFactory.createButton(comp, "Add", SWT.NONE);
+ addButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ }
+
+ /**
+ * Create the REMOVE button
+ *
+ * @param comp
+ * the parent Composite
+ */
+ protected void createRemoveButton(Composite comp) {
+ removeButton = widgetFactory.createButton(comp, "Remove", SWT.NONE);
+ removeButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ }
+
+ /**
+ * User may implement other buttons to be displayed at the right side of the
+ * table. This method must initialize a list of Buttons.
+ *
+ * @param comp
+ * The composite where buttons are going to be created
+ */
+ protected void createOtherButtons(Composite comp) {
+ otherButtons = new ArrayList<Button>();
+ }
+
+ /**
+ * Hook the listeners
+ */
+ protected void hookListeners() {
+ table.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ fireWidgetSelected();
+ }
+ });
+ hookButtonListeners();
+ }
+
+ /**
+ * Hook the listeners
+ */
+ protected void hookButtonListeners() {
+ if (addButton != null && removeButton != null) {
+ addButton.addSelectionListener(addListener);
+ removeButton.addSelectionListener(removeListener);
+ }
+ }
+
+ /**
+ * Sets or clears the input for this viewer
+ *
+ * @param eObject
+ * EObject to be represented
+ * @param feature
+ * Feature to modify
+ */
+ public void setInput(EObject eObject, EStructuralFeature feature) {
+ if (objectManager == null || !objectManager.getInputEObject().equals(eObject)) {
+ objectManager = new TableObjectManager(eObject, feature);
+ objectManager.setLabelProvider(labelProvider);
+ tableViewer.setInput(objectManager);
+ // Create the cell editors
+ CellEditor[] editors = createCells(columnNames.length);
+
+ // Assign the cell editors to the viewer
+ tableViewer.setCellEditors(editors);
+ }
+ }
+
+ /**
+ * Sets the label provider for this viewer.
+ *
+ * When the given parameter is null, it will set a default label provider,
+ * in particular when the table viewer is going to display multifeature
+ * Attributes. In order to display multifeature references, client may pass
+ * a AdapterFactoryLabelProvider.
+ *
+ * @param labelProvider
+ * The label Provider.
+ */
+ public void setLabelProvider(IBaseLabelProvider labelProvider) {
+ if (labelProvider instanceof ILabelProvider) {
+ this.labelProvider = (ILabelProvider) labelProvider;
+ tableViewer.setLabelProvider(labelProvider);
+ if (objectManager != null) {
+ objectManager.setLabelProvider(this.labelProvider);
+ }
+ }
+ }
+
+ /**
+ * @see org.eclipse.swt.widgets.Control#setEnabled(boolean)
+ */
+ public void setEnabled(boolean enabled) {
+ table.setEnabled(enabled);
+ if (addButton != null && !addButton.isDisposed()) {
+ addButton.setEnabled(enabled);
+ }
+ if (removeButton != null && !removeButton.isDisposed()) {
+ removeButton.setEnabled(enabled);
+ }
+ }
+
+ /**
+ * Modification will be taken in charge by the object manager. Client may
+ * specify an editing domain to consider modifications
+ *
+ * @param editingDomain
+ * Manages a self-contained set of interrelated EMF models and
+ * the {@link Command}s that modify them.
+ */
+ public void setEditingDomain(EditingDomain editingDomain) {
+ objectManager.setEditingDomain(editingDomain);
+ }
+
+ /**
+ * Refresh the Table contents when model has been changed from the outside.
+ */
+ public void refresh() {
+ tableViewer.refresh();
+ }
+
+ /**
+ * Add a new empty Element in the ObjectManager
+ */
+ public void addElement() {
+ if (objectManager != null) {
+ objectManager.addElement();
+ }
+ }
+
+ /**
+ * Add the given Element in the ObjectManager
+ *
+ * @param newElement
+ * the Element to add
+ */
+ public void addElement(Object newElement) {
+ if (objectManager != null) {
+ objectManager.addElement(newElement);
+ }
+ }
+
+ /**
+ * Remove the given Element from the ObjectManager
+ *
+ * @param element
+ * the Element to remove
+ */
+ public void removeElement(Object element) {
+ if (objectManager != null) {
+ objectManager.removeElement(element);
+ }
+ }
+
+ /**
+ * Gets a collection of current column names
+ *
+ * @return List of the current column names
+ */
+ public String[] getColumnHeaders() {
+ return columnNames;
+ }
+
+ /**
+ * Set a new set of columns
+ *
+ * @param newColumnNames
+ * Array containing the column names
+ */
+ public void setColumnNames(String[] newColumnNames) {
+ columnNames = newColumnNames.clone();
+ }
+
+ /**
+ * @return Return the TableObjectManager
+ */
+ public TableObjectManager getObjectManager() {
+ return objectManager;
+ }
+
+ /**
+ * @return Return the add button
+ */
+ public Button getAddButton() {
+ return addButton;
+ }
+
+ /**
+ * @return Return the remove button
+ */
+ public Button getRemoveButton() {
+ return removeButton;
+ }
+
+ /**
+ * @return Returns the list of buttons added if any, otherwise buttons list
+ * is null;
+ */
+ public List<Button> getOtherButtons() {
+ return otherButtons;
+ }
+
+ /**
+ * Update the new Buttons to use with the Composite
+ *
+ * @param buttons
+ * a list of Buttons
+ */
+ public void setOtherButtons(List<Button> buttons) {
+ otherButtons = buttons;
+ }
+
+ /**
+ * Returns the current selection from the table
+ *
+ * @return The Structured selection from this table
+ */
+ public ISelection getSelection() {
+ return tableViewer.getSelection();
+ }
+
+ /**
+ * Returns the first object that has been selected
+ *
+ * @return The first object of the selection
+ */
+ public Object getSelectionItem() {
+ ISelection sel = getSelection();
+ if (sel instanceof IStructuredSelection) {
+ IStructuredSelection ssel = (IStructuredSelection) sel;
+ return ssel.getFirstElement();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the contents of this table as a list.
+ *
+ * @return The list of contest corresponding to this EStructuralFeature
+ */
+ public List<?> getValue() {
+ return objectManager.eGet();
+ }
+
+ /**
+ * Set the Listener to associate with the ADD button
+ *
+ * @param listener
+ * a SelectionListener
+ */
+ public void setAddListener(SelectionListener listener) {
+ SelectionListener oldListener = addListener;
+ addListener = listener;
+ addButton.removeSelectionListener(oldListener);
+ addButton.addSelectionListener(addListener);
+ }
+
+ /**
+ * Set the Listener to associate with the REMOVE button
+ *
+ * @param listener
+ * a SelectionListener
+ */
+ public void setRemoveListener(SelectionListener listener) {
+ SelectionListener oldListener = removeListener;
+ removeListener = listener;
+ removeButton.removeSelectionListener(oldListener);
+ removeButton.addSelectionListener(removeListener);
+ }
+
+ /**
+ * Return the table composite
+ *
+ * @return Table
+ */
+ public Table getTable() {
+ return table;
+ }
+
+ /**
+ * This method is called each time a new item is selected in the Table. When
+ * client desire to do something when an item is selected, this method must
+ * be overrided
+ *
+ * @param data
+ * the new item that was selected
+ */
+ public void updateSelectedItem(Object data) {
+ // do nothing
+ }
+
+ /**
+ * @return the widgetFactory
+ */
+ protected TabbedPropertySheetWidgetFactory getWidgetFactory() {
+ return widgetFactory;
+ }
+
+ /**
+ * Notifies selection listeners
+ */
+ protected void fireWidgetSelected() {
+ for (SelectionListener listener : selectionListeners) {
+ Event e = new Event();
+ e.widget = table;
+ listener.widgetSelected(new SelectionEvent(e));
+ }
+ }
+
+ /**
+ * Adds a selection listener
+ *
+ * @param listener
+ * The listener to add
+ */
+ public void addSelectionListener(SelectionListener listener) {
+ selectionListeners.add(listener);
+ }
+
+ /**
+ * Removes a selection listener
+ *
+ * @param listener
+ * The listener to remove
+ */
+ public void removeSelectionListener(SelectionListener listener) {
+ selectionListeners.remove(listener);
+ }
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/utils/ObjectAdapter.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/utils/ObjectAdapter.java
new file mode 100644
index 0000000..6e9c696
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/utils/ObjectAdapter.java
@@ -0,0 +1,64 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.utils;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * Provides a single static method to adapt a given object in an EObject
+ *
+ * Creation 19 sept. 06
+ *
+ * @author alfredo
+ *
+ */
+public final class ObjectAdapter {
+
+ private ObjectAdapter() {
+ // Instantiation forbidden
+ }
+
+ /**
+ * Returns the EObject associated with the given object. Returns
+ * <code>null</code> if no such object can be found.
+ *
+ *
+ * @param object
+ * The object to look up its associated EObject
+ * @return the EObject associated to the given object, or <code>null</code>
+ * if this object does not have any.
+ */
+ public static EObject adaptObject(Object object) {
+ if (object == null) {
+ return null;
+ } else if (object instanceof EObject) {
+ return (EObject) object;
+ } else if (object instanceof IAdaptable) {
+ // Try IAdaptable
+ IAdaptable adapted = (IAdaptable) object;
+ Object eObject = adapted.getAdapter(EObject.class);
+ if (eObject != null) {
+ return (EObject) eObject;
+ }
+ } else {
+ // Try registered adapter
+ Object adapted = Platform.getAdapterManager().getAdapter(object, EObject.class);
+ if (adapted != null) {
+ return (EObject) adapted;
+ }
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/utils/TextChangeListener.java b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/utils/TextChangeListener.java
new file mode 100644
index 0000000..2df89f8
--- /dev/null
+++ b/plugins/org.eclipse.emf.tabbedproperties/src/org/eclipse/emf/tabbedproperties/utils/TextChangeListener.java
@@ -0,0 +1,181 @@
+/***********************************************************************
+ * Copyright (c) 2007 Anyware Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anyware Technologies - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.emf.tabbedproperties.utils;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * This is a copy of the TextChangeHelper available in GMF with addition to
+ * listener on FocusIn and FocusOut events. We only want to avoid a dependency
+ * to the GMF component
+ *
+ * TextChangeListener notifies the listener of text lifecycle events on behalf
+ * of the widget(s) it listens to.
+ *
+ * @author Anthony Hunter
+ */
+public abstract class TextChangeListener implements Listener {
+
+ private boolean nonUserChange;
+
+ /**
+ * Marks the start of a programmatic change to the widget contents. Clients
+ * must call startNonUserChange() before directly setting the widget
+ * contents to avoid unwanted lifecycle events.
+ *
+ * @throws IllegalArgumentException
+ * if a programmatic change is already in progress.
+ */
+ public void startNonUserChange() {
+ if (nonUserChange) {
+ throw new IllegalStateException("we already started a non user change");//$NON-NLS-1$
+ }
+ nonUserChange = true;
+ }
+
+ /**
+ * Clients who call startNonUserChange() should call finishNonUserChange()
+ * as soon as possible after the change is done.
+ *
+ * @throws IllegalArgumentException
+ * if no change is in progress.
+ */
+ public void finishNonUserChange() {
+ if (!nonUserChange) {
+ throw new IllegalStateException("we are not in a non user change");//$NON-NLS-1$
+ }
+ nonUserChange = false;
+ }
+
+ /**
+ * Determine if a programmatic change is in progress.
+ *
+ * @return <code>true</code> if a programmatic change is in progress.
+ */
+ public boolean isNonUserChange() {
+ return nonUserChange;
+ }
+
+ /**
+ * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+ */
+ public void handleEvent(Event event) {
+ switch (event.type) {
+ case SWT.KeyDown:
+ if (event.character == SWT.CR) {
+ textChanged((Control) event.widget);
+ }
+ break;
+
+ case SWT.FocusOut:
+ focusOut((Control) event.widget);
+ textChanged((Control) event.widget);
+ break;
+
+ case SWT.FocusIn:
+ focusIn((Control) event.widget);
+ break;
+
+ case SWT.Modify:
+ verifyText((Control) event.widget);
+ default:
+ break;
+ }
+ }
+
+ /**
+ * Abstract method notified when a text field has been changed.
+ *
+ * @param control
+ * the given control.
+ */
+ public abstract void textChanged(Control control);
+
+ /**
+ * This method is method notified when the focus is gained Client may
+ * override this method if he desire some particular behavior
+ *
+ * @param control
+ * the given control.
+ */
+ public void focusIn(Control control) {
+ // DO NOTHING
+ }
+
+ /**
+ * This method is notified when the focus is lost Client may override this
+ * method if he desire some particular behavior
+ *
+ * @param control
+ * the given control.
+ */
+ public void focusOut(Control control) {
+ // DO NOTHING
+ }
+
+ /**
+ * This method is notified when text is been modified Client may override
+ * this method if he desire some particular behavior
+ *
+ * @param control
+ * the given control.
+ */
+ public void verifyText(Control control) {
+ // DO NOTHING
+ }
+
+ /**
+ * Registers this helper with the given control to listen for events which
+ * indicate that a change is in progress (or done).
+ *
+ * @param control
+ * the given control.
+ */
+ public void startListeningTo(Control control) {
+ control.addListener(SWT.FocusIn, this);
+ control.addListener(SWT.FocusOut, this);
+ control.addListener(SWT.Modify, this);
+ }
+
+ /**
+ * Registers this helper with the given control to listen for the Enter key.
+ * When Enter is pressed, the change is considered done (this is only
+ * appropriate for single-line Text widgets).
+ *
+ * @param control
+ * the given control.
+ */
+ public void startListeningForEnter(Control control) {
+ // NOTE: KeyDown rather than KeyUp, because of similar usage in CCombo.
+ control.addListener(SWT.KeyDown, this);
+ }
+
+ /**
+ * Unregisters this helper from a control previously passed to
+ * startListeningTo() and/or startListeningForEnter().
+ *
+ * @param control
+ * the given control.
+ */
+ public void stopListeningTo(Control control) {
+ if ((control != null) && !control.isDisposed()) {
+ control.removeListener(SWT.FocusIn, this);
+ control.removeListener(SWT.FocusOut, this);
+ control.removeListener(SWT.Modify, this);
+ control.removeListener(SWT.KeyDown, this);
+ }
+ }
+} \ No newline at end of file

Back to the top