Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » GEF » PropertiesView based on EMF.edit Framework [partly solved]
PropertiesView based on EMF.edit Framework [partly solved] [message #188595] Thu, 21 July 2005 16:54 Go to next message
Andreas Holtz is currently offline Andreas HoltzFriend
Messages: 53
Registered: July 2009
Member
Hi,

Today I found an easy way to use EMF generated properties. But it does not work complety (undo does not work). The problem is, that within
the execute()-method of org.eclipse.gef.ui.properties.SetValueCommand there is a cast to IPropertySource. But EMF uses IItemPropertySource.
I read in the buglist (bug 37716) that there will be a global command-framework introduced. How far is it?
I post my solution for discussion (perhaps somebody finds it interesting). It should work for nonchangeable properties.

Andreas


Using EMF-generated properties:

I asume, that you generated the EMF.edit-part of you model and so, EMF generated a lot of factories. To get an overwiew of those, generate
the editor of your model and look in the generate editor-class. Within the constructor EMF.editor lists a lot of generated factories.
Remember this code (*)

In normal GEF-development (as shown in the examples) you use the getAdapter()-method within the EditPart and return the needed
PropertySource-class:

public Object getAdapter(Class key) {
if (IPropertySource.class == key) {
return getPropertySource(); //here you create your propertySource
}
return super.getAdapter(key);
}

That's fine, because the content of the PropertyPage depends on the selected EditPart. But that's not "really" correct. The content bases on
the *model* of the EditPart. Normally you fix this issue by using the getAdapter()-method of the EditPart, the reason for this is the
getPropertySource()-method of org.eclipse.ui.views.properties.PropertySheetEntry

protected IPropertySource getPropertySource(Object object) {
if (sources.containsKey(object))
return (IPropertySource) sources.get(object);

IPropertySource result = null;
if (propertySourceProvider != null)
result = propertySourceProvider.getPropertySource(object);
else if (object instanceof IPropertySource)
result = (IPropertySource) object;
else if (object instanceof IAdaptable)
result = (IPropertySource) ((IAdaptable) object)
.getAdapter(IPropertySource.class);

sources.put(object, result);
return result;
}
The object is the selected EditPart. Because you did not set an PropertySourceProvider and it is not an IPropertySource its
getAdapter()-method is used.

EMF instead uses a PropertySourceProvider. It bases on all the factories in (*). In my Editor it looks something like this:

List factories = new ArrayList();
factories.add(new ResourceItemProviderAdapterFactory());
//lot of factories ...
factories.add(new ReflectiveItemProviderAdapterFactory());

adapterFactory = new ComposedAdapterFactory(factories);

and within the getPropertySheetPage()-method:

propertySheetPage.setPropertySourceProvider(new
AdapterFactoryContentProvider(adapterFactory));

My first idea was to copy the code of the EMF.editor Editor and use it within my editor. But this does not work, because of the selection
behavoir of GEF. If you select an object within the generated editor of EMF you select the object, in GEF you select an EditPart. So the
AdapterFactoryContentProvider would find no provider for the EditPart. The solution was to implement a kind of Delegator:

public class MyPropertySourceProvider implements IPropertySourceProvider {
private final IPropertySourceProvider itsModelSourceProvider;
public MyPropertySourceProvider(IPropertySourceProvider
modelSourceProvider) {
itsModelSourceProvider = modelSourceProvider;
}

public IPropertySource getPropertySource(Object object) {
if(object instanceof EditPart) {
return itsModelSourceProvider.getPropertySource(((EditPart)
object).getModel());
}
return itsModelSourceProvider.getPropertySource(object);
}
}

and use this as the PropertySourceProvider within the GEF-Editor for your PropertyPage:

protected PropertySheetPage getPropertySheetPage() {
if (undoablePropertySheetPage == null) {
undoablePropertySheetPage = new PropertySheetPage();
AdapterFactoryContentProvider modelSourceProvider = new
AdapterFactoryContentProvider(adapterFactory);
UndoablePropertySheetEntry root = new
UndoablePropertySheetEntry(getCommandStack());
MyPropertySourceProvider sourceProvider = new
MyPropertySourceProvider(modelSourceProvider);

root.setPropertySourceProvider(sourceProvider);
undoablePropertySheetPage.setPropertySourceProvider(sourcePr ovider);
undoablePropertySheetPage.setRootEntry(root);
}

The getAdapter()-method within the editparts is not used for the PropertySource anymore.

In the end, your PropertyPage should show all the properties of the model-element. The disadvantage of this solution is that it could be
hard to add properties to the PropertyPage which do not base directly on the model (for example layout information from the view model), but
I did not tried it yet and perhaps there a lot of issues which I did not recognize. :-)
Re: PropertiesView based on EMF.edit Framework [partly solved] [message #188714 is a reply to message #188595] Fri, 22 July 2005 14:41 Go to previous messageGo to next message
kiril mitov is currently offline kiril mitovFriend
Messages: 128
Registered: July 2009
Senior Member
Hi,
I just want to make a reply of what Andreas said.
I use the EMF.edit plugin to display the properties of the objects. And I
have also found a workaround (a hack) to made the undo to work.
The problem from my point of view is that the emf.edit framework wrapes
the values that have been edited in the properties view and we undo is
called a ClassCastException is raised.
The solution is to write your own ItemPropertyDescriptor - for example
MyItemPropertyDescriptor. This class must extend
org.eclipse.emf.edit.provider.ItemPropertyDescriptor.
The you override the setPropertyValue method as follows:

public void setPropertyValue(Object object, Object value) {
if(value instanceof PropertyValueWrapper) {
super.setPropertyValue(object,
((PropertyValueWrapper)value).getEditableValue(object));
}
else {
super.setPropertyValue(object, value);
}
}

Then you must make sure that your ItemProviders use
MyItemPropertyDescriptor.
I now that this is just a workaround(a hack) but it works.
And the undo of the editing also works.

kiril



Andreas Holtz wrote:

> Hi,

> Today I found an easy way to use EMF generated properties. But it does not
work complety (undo does not work). The problem is, that within
> the execute()-method of org.eclipse.gef.ui.properties.SetValueCommand there
is a cast to IPropertySource. But EMF uses IItemPropertySource.
> I read in the buglist (bug 37716) that there will be a global
command-framework introduced. How far is it?
> I post my solution for discussion (perhaps somebody finds it interesting).
It should work for nonchangeable properties.

> Andreas


> Using EMF-generated properties:

> I asume, that you generated the EMF.edit-part of you model and so, EMF
generated a lot of factories. To get an overwiew of those, generate
> the editor of your model and look in the generate editor-class. Within the
constructor EMF.editor lists a lot of generated factories.
> Remember this code (*)

> In normal GEF-development (as shown in the examples) you use the
getAdapter()-method within the EditPart and return the needed
> PropertySource-class:

> public Object getAdapter(Class key) {
> if (IPropertySource.class == key) {
> return getPropertySource(); //here you create your propertySource
> }
> return super.getAdapter(key);
> }

> That's fine, because the content of the PropertyPage depends on the selected
EditPart. But that's not "really" correct. The content bases on
> the *model* of the EditPart. Normally you fix this issue by using the
getAdapter()-method of the EditPart, the reason for this is the
> getPropertySource()-method of
org.eclipse.ui.views.properties.PropertySheetEntry

> protected IPropertySource getPropertySource(Object object) {
> if (sources.containsKey(object))
> return (IPropertySource) sources.get(object);

> IPropertySource result = null;
> if (propertySourceProvider != null)
> result = propertySourceProvider.getPropertySource(object);
> else if (object instanceof IPropertySource)
> result = (IPropertySource) object;
> else if (object instanceof IAdaptable)
> result = (IPropertySource) ((IAdaptable) object)
> .getAdapter(IPropertySource.class);

> sources.put(object, result);
> return result;
> }
> The object is the selected EditPart. Because you did not set an
PropertySourceProvider and it is not an IPropertySource its
> getAdapter()-method is used.

> EMF instead uses a PropertySourceProvider. It bases on all the factories in
(*). In my Editor it looks something like this:

> List factories = new ArrayList();
> factories.add(new ResourceItemProviderAdapterFactory());
> //lot of factories ...
> factories.add(new ReflectiveItemProviderAdapterFactory());

> adapterFactory = new ComposedAdapterFactory(factories);

> and within the getPropertySheetPage()-method:

> propertySheetPage.setPropertySourceProvider(new
> AdapterFactoryContentProvider(adapterFactory));

> My first idea was to copy the code of the EMF.editor Editor and use it
within my editor. But this does not work, because of the selection
> behavoir of GEF. If you select an object within the generated editor of EMF
you select the object, in GEF you select an EditPart. So the
> AdapterFactoryContentProvider would find no provider for the EditPart. The
solution was to implement a kind of Delegator:

> public class MyPropertySourceProvider implements IPropertySourceProvider {
> private final IPropertySourceProvider itsModelSourceProvider;
> public MyPropertySourceProvider(IPropertySourceProvider
> modelSourceProvider) {
> itsModelSourceProvider = modelSourceProvider;
> }

> public IPropertySource getPropertySource(Object object) {
> if(object instanceof EditPart) {
> return itsModelSourceProvider.getPropertySource(((EditPart)
> object).getModel());
> }
> return itsModelSourceProvider.getPropertySource(object);
> }
> }

> and use this as the PropertySourceProvider within the GEF-Editor for your
PropertyPage:

> protected PropertySheetPage getPropertySheetPage() {
> if (undoablePropertySheetPage == null) {
> undoablePropertySheetPage = new PropertySheetPage();
> AdapterFactoryContentProvider modelSourceProvider = new
> AdapterFactoryContentProvider(adapterFactory);
> UndoablePropertySheetEntry root = new
> UndoablePropertySheetEntry(getCommandStack());
> MyPropertySourceProvider sourceProvider = new
> MyPropertySourceProvider(modelSourceProvider);

> root.setPropertySourceProvider(sourceProvider);
> undoablePropertySheetPage.setPropertySourceProvider(sourcePr ovider);
> undoablePropertySheetPage.setRootEntry(root);
> }

> The getAdapter()-method within the editparts is not used for the
PropertySource anymore.

> In the end, your PropertyPage should show all the properties of the
model-element. The disadvantage of this solution is that it could be
> hard to add properties to the PropertyPage which do not base directly on the
model (for example layout information from the view model), but
> I did not tried it yet and perhaps there a lot of issues which I did not
recognize. :-)
Re: PropertiesView based on EMF.edit Framework [partly solved] [message #223558 is a reply to message #188595] Thu, 28 September 2006 22:48 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: something.eclipse.org

Thanks! This helps a lot. The only thing I would add for others is to
make sure to return the propertysheet in getAdapter from the editor
when passed an IPropertySheet reference.

Andreas Holtz wrote:
> Hi,
>
> Today I found an easy way to use EMF generated properties. But it does
> not work complety (undo does not work). The problem is, that within the
> execute()-method of org.eclipse.gef.ui.properties.SetValueCommand there
> is a cast to IPropertySource. But EMF uses IItemPropertySource. I read
> in the buglist (bug 37716) that there will be a global command-framework
> introduced. How far is it?
> I post my solution for discussion (perhaps somebody finds it
> interesting). It should work for nonchangeable properties.
>
> Andreas
>
>
> Using EMF-generated properties:
>
> I asume, that you generated the EMF.edit-part of you model and so, EMF
> generated a lot of factories. To get an overwiew of those, generate the
> editor of your model and look in the generate editor-class. Within the
> constructor EMF.editor lists a lot of generated factories. Remember this
> code (*)
>
> In normal GEF-development (as shown in the examples) you use the
> getAdapter()-method within the EditPart and return the needed
> PropertySource-class:
>
> public Object getAdapter(Class key) {
> if (IPropertySource.class == key) {
> return getPropertySource(); //here you create your propertySource
> }
> return super.getAdapter(key);
> }
>
> That's fine, because the content of the PropertyPage depends on the
> selected EditPart. But that's not "really" correct. The content bases on
> the *model* of the EditPart. Normally you fix this issue by using the
> getAdapter()-method of the EditPart, the reason for this is the
> getPropertySource()-method of
> org.eclipse.ui.views.properties.PropertySheetEntry
>
> protected IPropertySource getPropertySource(Object object) {
> if (sources.containsKey(object))
> return (IPropertySource) sources.get(object);
>
> IPropertySource result = null;
> if (propertySourceProvider != null)
> result = propertySourceProvider.getPropertySource(object);
> else if (object instanceof IPropertySource)
> result = (IPropertySource) object;
> else if (object instanceof IAdaptable)
> result = (IPropertySource) ((IAdaptable) object)
> .getAdapter(IPropertySource.class);
>
> sources.put(object, result);
> return result;
> }
> The object is the selected EditPart. Because you did not set an
> PropertySourceProvider and it is not an IPropertySource its
> getAdapter()-method is used.
>
> EMF instead uses a PropertySourceProvider. It bases on all the factories
> in (*). In my Editor it looks something like this:
>
> List factories = new ArrayList();
> factories.add(new ResourceItemProviderAdapterFactory());
> //lot of factories ...
> factories.add(new ReflectiveItemProviderAdapterFactory());
>
> adapterFactory = new ComposedAdapterFactory(factories);
>
> and within the getPropertySheetPage()-method:
>
> propertySheetPage.setPropertySourceProvider(new
> AdapterFactoryContentProvider(adapterFactory));
>
> My first idea was to copy the code of the EMF.editor Editor and use it
> within my editor. But this does not work, because of the selection
> behavoir of GEF. If you select an object within the generated editor of
> EMF you select the object, in GEF you select an EditPart. So the
> AdapterFactoryContentProvider would find no provider for the EditPart.
> The solution was to implement a kind of Delegator:
>
> public class MyPropertySourceProvider implements IPropertySourceProvider {
> private final IPropertySourceProvider itsModelSourceProvider;
> public MyPropertySourceProvider(IPropertySourceProvider
> modelSourceProvider) {
> itsModelSourceProvider = modelSourceProvider;
> }
>
> public IPropertySource getPropertySource(Object object) {
> if(object instanceof EditPart) {
> return itsModelSourceProvider.getPropertySource(((EditPart)
> object).getModel());
> }
> return itsModelSourceProvider.getPropertySource(object);
> }
> }
>
> and use this as the PropertySourceProvider within the GEF-Editor for
> your PropertyPage:
>
> protected PropertySheetPage getPropertySheetPage() {
> if (undoablePropertySheetPage == null) {
> undoablePropertySheetPage = new PropertySheetPage();
> AdapterFactoryContentProvider modelSourceProvider = new
> AdapterFactoryContentProvider(adapterFactory);
> UndoablePropertySheetEntry root = new
> UndoablePropertySheetEntry(getCommandStack());
> MyPropertySourceProvider sourceProvider = new
> MyPropertySourceProvider(modelSourceProvider);
>
> root.setPropertySourceProvider(sourceProvider);
> undoablePropertySheetPage.setPropertySourceProvider(sourcePr ovider);
> undoablePropertySheetPage.setRootEntry(root);
> }
>
> The getAdapter()-method within the editparts is not used for the
> PropertySource anymore.
>
> In the end, your PropertyPage should show all the properties of the
> model-element. The disadvantage of this solution is that it could be
> hard to add properties to the PropertyPage which do not base directly on
> the model (for example layout information from the view model), but I
> did not tried it yet and perhaps there a lot of issues which I did not
> recognize. :-)
Re: PropertiesView based on EMF.edit Framework [partly solved] [message #717563 is a reply to message #188595] Sun, 21 August 2011 11:47 Go to previous message
Arieh Bibliowicz is currently offline Arieh BibliowiczFriend
Messages: 18
Registered: June 2011
Junior Member
I extended the solution to handle undo, as shown here: www.vainolo.com/2011/08/22/creating-an-opm-gef-editor-part-16-displaying-emf-properties-in-a-gef-editor/

[Updated on: Mon, 22 August 2011 09:44]

Report message to a moderator

Previous Topic:Gef FreeForm LAyout
Next Topic:Adding Connection as Element to its Parent Element to reflect in XML
Goto Forum:
  


Current Time: Sun Nov 23 22:47:43 GMT 2014

Powered by FUDForum. Page generated in 0.02405 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software