Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Create Submenu for EMF Model(Create Submenu for EMF Model)
Create Submenu for EMF Model [message #889976] Wed, 20 June 2012 13:05 Go to next message
Markus G is currently offline Markus GFriend
Messages: 23
Registered: June 2012
Junior Member
Hi everyone,

my problem is the following: I have created an ecore metamodel and generated the editor for this and adjusted it a little bit to my needs.
What I want to do is offer additional operations for some of the elements. More specifically, I want to extend the right-click-menu of one kind of elements with an operation that opens a dialog which in turn changes an attribute of that element.

I am somehow having big trouble finding an example how to develop an additional ui-dialog-like plugin and adding this as an operation into the context-menu of my ecore model.

Does anyone possibly have an example of how that works?

Thanks a lot!


EDIT: I keep reading that supposedly this should be very simple. So if someone could point me to a walk-through of how to implement a simple plugin showing a pop-up menu which will appear as a contribution in the model's context menu to change an attribute of the selected item, that would be awesome.

Thanks

[Updated on: Wed, 20 June 2012 13:53]

Report message to a moderator

Re: Create Submenu for EMF Model [message #890008 is a reply to message #889976] Wed, 20 June 2012 14:40 Go to previous messageGo to next message
Tim Schaefer is currently offline Tim SchaeferFriend
Messages: 49
Registered: June 2011
Location: Marburg, Germany
Member
Hi,

you can use the extension-point org.eclipse.ui.popupMenus:

<extension point="org.eclipse.ui.popupMenus">
      <objectContribution id="com.example.actions.MyAction" objectClass="com.example.MyEClass">
         <action class="com.example.actions.MyCustomAction" enablesFor="1"
               id="com.example.MyActionImpl" label="My Custom Action"
               menubarPath="additions">
         </action>
      </objectContribution>
   </extension>

where com.example.MyEClass is the class in your ecore model you want the action for.
Then write a class com.example.actions.MyCustomAction that implements org.eclipse.ui.IObjectActionDelegate.

This way, the action will not only be available in your editor, but also in other views where instances of the objectClass are displayed.

If you want the action only for your editor, you need to programmatically do this in your XXActionBarContributor.addGlobalActions(IMenuManager menuManager).

Regards,
Tim
Re: Create Submenu for EMF Model [message #890015 is a reply to message #890008] Wed, 20 June 2012 15:10 Go to previous messageGo to next message
Markus G is currently offline Markus GFriend
Messages: 23
Registered: June 2012
Junior Member
Hi Tim,

thank you very much for the quick reply!

After creating a new plugin-project, I put in the code for the extension point in the plugin.xml of the new plugin, right?
Just to make sure...

Unfortunately I won't have time to get that done today, but I will try tomorrow.

Thanks again,
Markus
Re: Create Submenu for EMF Model [message #890019 is a reply to message #890015] Wed, 20 June 2012 15:29 Go to previous messageGo to next message
Tim Schaefer is currently offline Tim SchaeferFriend
Messages: 49
Registered: June 2011
Location: Marburg, Germany
Member
Markus G wrote on Wed, 20 June 2012 17:10

After creating a new plugin-project, I put in the code for the extension point in the plugin.xml of the new plugin, right?

Yes, and of course your implementation of IObjectActionDelegate must also be in the plug-in that makes the extension-point contribution.
Re: Create Submenu for EMF Model [message #890169 is a reply to message #890019] Thu, 21 June 2012 11:07 Go to previous messageGo to next message
Markus G is currently offline Markus GFriend
Messages: 23
Registered: June 2012
Junior Member
Awesome, that did the trick, thanks!

It brought me a step further, but I have a different problem.

I managed to change an attribute in MyEClass (to stick to the naming of your code snipplet), but the change is not displayed in my model. Actually, the model doesn't realize that is has been changed at all (I can't save the changes because the state is "already oldest change").
On top of that, I'd like to refresh all the viewers after having changed the attribute in my dialog-handler-function, as the attribute this changes is a filter. Classes with that attribute set are not being displayed in the model (I solved that changing the getChildren method of the parent-class).

So the two things I want to do is make the model realize it's been changed and refresh all viewers.

What's weird to me is that in the MyEClassImpl.java in the method setAttribute(), the
eNotificationRequired() 

returns true so that

eNotify(new ENotificationImpl(this, Notification.SET, MyPackage.CLASS_ATTRIBUTE, oldAttributeValue, newAttributeValue));

is being executed. Still the model doesn't seem to realize the change.

Another thought concerning the view-refreshers: the command already exists in the editor menu "refresh". That does exactly what I want, refresh all viewers.

My problem is that I don't know how to access the right classes. All I have access for in my handler is the EClass and the selection, but how do I get to the corresponding AdapterFactory, ItemProvider or even the Model object?

Thanks for any help!
Markus
Re: Create Submenu for EMF Model [message #890173 is a reply to message #890169] Thu, 21 June 2012 11:14 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 30354
Registered: July 2009
Senior Member
Markus,

Comments below.

On 21/06/2012 7:07 AM, Markus G wrote:
> Awesome, that did the trick, thanks!
>
> It brought me a step further, but I have a different problem.
> I managed to change an attribute in MyEClass (to stick to the naming
> of your code snipplet), but the change is not displayed in my model.
> Actually, the model doesn't realize that is has been changed at all (I
> can't save the changes because the state is "already oldest change").
> On top of that, I'd like to refresh all the viewers after having
> changed the attribute in my dialog-handler-function, as the attribute
> this changes is a filter. Classes with that attribute set are not
> being displayed in the model (I solved that changing the getChildren
> method of the parent-class).
If the object is being viewed, I'd expect there to be an adapter
attached to it that responds to notification. But keep in mind that if
you're making changes in an editor, you really should (must) use a
command, otherwise undo will be broken and the editor won't realize it's
gotten dirty.
>
> So the two things I want to do is make the model realize it's been
> changed and refresh all viewers.
>
> What's weird to me is that in the MyEClassImpl.java in the method
> setAttribute(), the eNotificationRequired() returns true so that
> eNotify(new ENotificationImpl(this, Notification.SET,
> MyPackage.CLASS_ATTRIBUTE, oldAttributeValue, newAttributeValue));
> is being executed. Still the model doesn't seem to realize the change.
Are there adapters in the object's eAdapers() list? They should update
the views automatically.
>
> Another thought concerning the view-refreshers: the command already
> exists in the editor menu "refresh". That does exactly what I want,
> refresh all viewers.
Yes, but that's brute force. You should only need to refresh the one
object, and that should happen automatically (as it does when you make
changes in the editor using, for example, the properties view).
>
> My problem is that I don't know how to access the right classes. All I
> have access for in my handler is the EClass and the selection, but how
> do I get to the corresponding AdapterFactory, ItemProvider or even the
> Model object?
You should be able to use
AdapterFactoryEditingDomain.getEditingDomainFor and then use it to
create a command (SetCommand) and use its command stack to execute that
command.
>
> Thanks for any help!
> Markus
Re: Create Submenu for EMF Model [message #890185 is a reply to message #890173] Thu, 21 June 2012 11:54 Go to previous messageGo to next message
Markus G is currently offline Markus GFriend
Messages: 23
Registered: June 2012
Junior Member
Hi Ed,

thanks so much for the amazingly quick reply. It's very helpful to get answers to those specific questions, would take multiple amount of time to figure it out myself, so a big thanks for the help! I had it mixed up there, I thought that the setAttribute would itself create a command at some point, but of course it doesn't.

So that solved my first problem.

About refreshing the viewers:
The thing is that even if I set the filter attribute in the properties view, it doesn't refresh the whole viewer. The problem might be that my filter logic is implemented in the parent of my object, more specifically in its ItemProvider's getChildren() function. I've overridden that function to take the original Children-collection, check for the value of this one attribute, and if it's set, do not include it into its children. So I guess I would need to tell the editor to refresh my changed object's parent, then, wouldn't I?

Thanks,
Markus


EDIT: By parent, I mean the Class that MyClass is contained in. The relationship is containment.

[Updated on: Thu, 21 June 2012 11:59]

Report message to a moderator

Re: Create Submenu for EMF Model [message #890219 is a reply to message #890185] Thu, 21 June 2012 13:51 Go to previous messageGo to next message
Markus G is currently offline Markus GFriend
Messages: 23
Registered: June 2012
Junior Member
Sorry for writing again, but one more aspect:

It seems that even notifying the container doesn't solve my problem, because when I change another attribute of the container itself (in the property view), it doesn't refresh the view which would make my class disappear. What I really need is a refresh of the view which results in calling the getChildren() method of the container again..

Any ideas?
Re: Create Submenu for EMF Model [message #890226 is a reply to message #890219] Thu, 21 June 2012 14:12 Go to previous messageGo to next message
Tim Schaefer is currently offline Tim SchaeferFriend
Messages: 49
Registered: June 2011
Location: Marburg, Germany
Member
If you really want to update the whole view you could call refresh() on the treeviewer of your editor.
In your action you can get the editor in IObjectActionDelegate.setActivePart(IAction action, IWorkbenchPart targetPart). The ItemProvider should be in your objects adapters, in case you need it.

But I think that's a bit dirty.
Re: Create Submenu for EMF Model [message #890252 is a reply to message #890226] Thu, 21 June 2012 15:40 Go to previous messageGo to next message
Markus G is currently offline Markus GFriend
Messages: 23
Registered: June 2012
Junior Member
Hi Tim,

yes, I agree with you that it's a bit dirty and worth thinking about changing the whole "architecture" of my filtering thing.

But nontheless I'd like to get it done this way first.

You say I can get the editor in setActivePart, but that's a method I have to override implementing IObjectActionDelegate. Can you tell me how exactly I get the editor and call refresh on it?

Thanks!
Markus
Re: Create Submenu for EMF Model [message #890266 is a reply to message #890252] Thu, 21 June 2012 16:57 Go to previous messageGo to next message
Tim Schaefer is currently offline Tim SchaeferFriend
Messages: 49
Registered: June 2011
Location: Marburg, Germany
Member
Hi Markus,

if the Action you wrote and registered via extension-point is an implementation of IObjectActionDelegate you already (must) have implemented the method setActivePart.
The argument targetPart should be your editor.
Just store it in a member var
if (targetPart instanceof XYEditor) {
	editor = (XYEditor) targetPart;
}

and then at the end of run(), after you did the change in your model
editor.getViewer().refresh();
Re: Create Submenu for EMF Model [message #890373 is a reply to message #890219] Fri, 22 June 2012 07:16 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 30354
Registered: July 2009
Senior Member
Markus,

How exactly did you notify the container?

On 21/06/2012 9:51 AM, Markus G wrote:
> Sorry for writing again, but one more aspect:
>
> It seems that even notifying the container doesn't solve my problem,
> because when I change another attribute of the container itself (in
> the property view), it doesn't refresh the view which would make my
> class disappear. What I really need is a refresh of the view which
> results in calling the getChildren() method of the container again..
>
> Any ideas?
Re: Create Submenu for EMF Model [message #890385 is a reply to message #890373] Fri, 22 June 2012 07:40 Go to previous messageGo to next message
Markus G is currently offline Markus GFriend
Messages: 23
Registered: June 2012
Junior Member
Hi Ed,

well first I tried by setting an attribute of the container in my EClass's notifyChange() method like this:

((Container) (((EObject) notification.getNotifier()).eContainer()))
					.setAttribute("someValue");


If I exchanged the "someValue" with the current attributeValue it should then call the notifyChanged of the container without changing anything which should be fine for me.

This changed the attribute in my container object and the change appeared in my editor, but it didn't refresh the children (I need the getChildren() method to be called in order for my filter to work.)

Maybe I do have to refresh the whole viewer, after all, to make sure getChildren() is being called for each container element?

Thanks
Re: Create Submenu for EMF Model [message #890388 is a reply to message #890266] Fri, 22 June 2012 07:48 Go to previous messageGo to next message
Markus G is currently offline Markus GFriend
Messages: 23
Registered: June 2012
Junior Member
Hi Tim,

this now does exactly what I want. Now the only thing I need to figure out is how to refresh the viewer on an undo action as well Wink

Thanks a lot to you and Ed for helping me out and really improving my understanding of EMF!


Tim Schaefer wrote on Thu, 21 June 2012 12:57
Hi Markus,

if the Action you wrote and registered via extension-point is an implementation of IObjectActionDelegate you already (must) have implemented the method setActivePart.
The argument targetPart should be your editor.
Just store it in a member var
if (targetPart instanceof XYEditor) {
	editor = (XYEditor) targetPart;
}

and then at the end of run(), after you did the change in your model
editor.getViewer().refresh();

Re: Create Submenu for EMF Model [message #890401 is a reply to message #890385] Fri, 22 June 2012 08:30 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 30354
Registered: July 2009
Senior Member
Markus,

Comments below.

On 22/06/2012 3:40 AM, Markus G wrote:
> Hi Ed,
>
> well first I tried by setting an attribute of the container in my
> EClass's notifyChange() method like this:
>
> ((Container) (((EObject) notification.getNotifier()).eContainer()))
> .setAttribute("someValue");
That will likely only produce a label update ViewerNotification...
>
> If I exchanged the "someValue" with the current attributeValue it
> should then call the notifyChanged of the container without changing
> anything which should be fine for me.
>
> This changed the attribute in my container object and the change
> appeared in my editor, but it didn't refresh the children (I need the
> getChildren() method to be called in order for my filter to work.)
Have a look at the generated item provider's notifiyChanged methods.
You want to forward a notification that will cause a children refresh.
I'm sure you'll get the idea if you look at the generated code...
>
> Maybe I do have to refresh the whole viewer, after all, to make sure
> getChildren() is being called for each container element?
Better to produce viewer refresh notifications then all views will
update properly...
>
> Thanks
Re: Create Submenu for EMF Model [message #890416 is a reply to message #890401] Fri, 22 June 2012 09:06 Go to previous message
Markus G is currently offline Markus GFriend
Messages: 23
Registered: June 2012
Junior Member
Thanks for the point in the right direction. Makes sense, and that's the best about it! Wink

"Embedding" this into the whole notification mechanism also makes my undo work again. Great!

To others who might have the same problem:
Forward the notification to the container in the ItemProvider like this:

fireNotifyChanged(new ViewerNotification(notification,
					((EObject) notification.getNotifier()).eContainer(), true,
					true));


Thanks Ed and Tim, great help!


Ed Merks wrote on Fri, 22 June 2012 04:30
Markus,
Have a look at the generated item provider's notifiyChanged methods.
You want to forward a notification that will cause a children refresh.
I'm sure you'll get the idea if you look at the generated code...

Previous Topic:Xfeature
Next Topic:[CDO] number of threads, what is normal (to be expected)
Goto Forum:
  


Current Time: Thu Aug 22 06:46:53 GMT 2019

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

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

Back to the top