diff options
| author | dsciamma | 2007-11-07 15:11:23 +0000 |
|---|---|---|
| committer | dsciamma | 2007-11-07 15:11:23 +0000 |
| commit | c1b36cd32007882356de08a69febedb1d3c0662a (patch) | |
| tree | 9ad57a39da03da65fc605b8049ecb844cd2c5e28 | |
| parent | 6746deec4a31dca29f7b3598a78d2f9913ea07d0 (diff) | |
| download | org.eclipse.ecoretools-c1b36cd32007882356de08a69febedb1d3c0662a.tar.gz org.eclipse.ecoretools-c1b36cd32007882356de08a69febedb1d3c0662a.tar.xz org.eclipse.ecoretools-c1b36cd32007882356de08a69febedb1d3c0662a.zip | |
Initial contribution
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 ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>. +For purposes of the EPL, "Program" will mean the Content.</p> + +<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p> + + +</body> +</html>
\ No newline at end of file diff --git a/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 |
