Peter
Peter

Reputation: 191

How to use EMF commands within editor actions?

Summary
I am working on an emf-based editor. Up until now I didn't use EMF commands, but now I want to refactor my code to use them.

Current state
I am using a tree viewer as the main part of my editor. I added all kind of Actions via the org.eclipse.ui.popupMenus extension point. These actions directly interfere with the model, adding and removing objects.

Problems
With this approach I have to manually remove every reference when deleting objects in the model which easily introduces errors. Also the undo/redo actions in the editor don't work.

Goal
Refactor the Actions so they properly use EMF commands to modify the model.


Within the EMF documentation I found this code snippet:

  Department d = ...
  EditingDomain ed = ...
  Command cmd = RemoveCommand.create(ed, d);
  ed.getCommandStack().execute(cmd);

...which looks like the code I have to use. But I don't know where I can get the EditingDomain from.

So these are my questions:

Upvotes: 1

Views: 3176

Answers (2)

Peter
Peter

Reputation: 191

There is an easy way to access the current editing domain. Just add this code to the Action class.

private EditingDomain domain;

public void setActivePart(IAction action, IWorkbenchPart workbenchPart) {
    if (workbenchPart instanceof IEditingDomainProvider) {
        domain = ((IEditingDomainProvider) workbenchPart).getEditingDomain();
    }
}

The method setActivePart will automatically be called from the Eclipse framework. With this technique you should always have access to the editing domain.

Note that this is only true if your editor is based on mostly untouched generated code. If you manage the EditingDomains yourself you should use your own methods.

Upvotes: 2

Max Hohenegger
Max Hohenegger

Reputation: 1639

If you do not already have an EditingDomain you can create one. However, it makes sense to create one globaly and keep it. For example inside a singleton. Below you will find a minimal example deleting the EObject attached to a TreeItem using an AbstractCommand.

AdapterFactoryEditingDomain domain = new AdapterFactoryEditingDomain(new ComposedAdapterFactory(
        ComposedAdapterFactory.Descriptor.Registry.INSTANCE), new BasicCommandStack());

domain.getCommandStack().execute(new AbstractCommand() {
    @Override
    public void redo() {
        // TODO Auto-generated method stub
    }

    @Override
    public void execute() {
        EcoreUtil.delete((EObject) treeItem.getData(), true);
    }

    @Override
    public boolean canExecute() {
        return true;
    }
});

Upvotes: 0

Related Questions