Lai
Lai

Reputation: 482

Context issue whilst adding IUndoableOperation to my EditorPart

I was following the example described in http://help.eclipse.org/indigo/topic/org.eclipse.platform.doc.isv/guide/wrkAdv_undo.htm

in the init() method of my EditorPart

    /**
     * @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite,
     * org.eclipse.ui.IEditorInput)
     */
    @Override
    public void init(IEditorSite site,IEditorInput input)
    throws PartInitException {
        ...
        IWorkbench workbench = getSite().getWorkbenchWindow().getWorkbench();
        myUndoContext= workbench.getOperationSupport().getUndoContext();


        UndoRedoActionGroup historyActionGroup = new UndoRedoActionGroup(site, myUndoContext, true);
        historyActionGroup.fillActionBars(site.getActionBars());
        }

... I added the following to a method in my EditorPart

        IUndoableOperation operation = new MyOperation("My Action");
        operation.addContext(myUndoContext);
        try {
            IStatus status = OperationHistoryFactory.getOperationHistory().execute(operation, null, null);
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

I was able to add undo actions but I noticed that the undo actions gets added to all files opened by my custom editor. When I make changes to a file, all other opened files gets the undo operation added to the edit menu. How can I make it only applicable to the currently active file?

Upvotes: 2

Views: 263

Answers (2)

Alex K.
Alex K.

Reputation: 3304

I've fixed similar problem just a minute ago. My problem was following: UndoRedo actions were appearing for all opened editors. The reason was, that UndoActionHandler and RedoActionHandler were created and added for each editor, like this:

if (undoCmdHandler == null || !contains(undoCmdHandler)) {
    undoCmdHandler = new UndoActionHandler(site, undoContext);
    actionBars.getToolBarManager().add(undoCmdHandler);
}

#contains() method was always returning false (since it was buggy), so the handler was always created. So, I removed it:)

In your example you also always create UndoRedoActionGroup for each editor and fill action bars with it. I would suggest you not to use action group, but rather create UndoActionHandler and RedoActionHandler by yourself, as shown above.

I you have control over your handlers, then the solution is to create only one instance of UndoActionHandler and RedoActionHandler, fill actions bar with it, but when your context changes (when user navigates between editors (you should listen to this event) ) just update context on your Handler, like this:

redoCmdHandler.setContext(undoContext);

So, in the end you would end up with something similar:

public static RedoActionHandler getRedoActionHandler(IWorkbenchPartSite site, IActionBars actionBars, IUndoContext undoContext) {
        if (redoCmdHandler == null) {
            redoCmdHandler = new RedoActionHandler(site, undoContext);
            actionBars.getToolBarManager().add(redoCmdHandler);
        } else {
            redoCmdHandler.setContext(undoContext);
        }
        return redoCmdHandler;
    }

Upvotes: 0

greg-449
greg-449

Reputation: 111142

I think the problem is this line:

  myUndoContext= workbench.getOperationSupport().getUndoContext();

This gives you an undo context which is for the whole workbench. I think you need an undo context which is specific to your editor. org.eclipse.core.commands.operations.ObjectUndoContext looks suitable. It is probably enough just to do

  myUndoContext = new ObjectUndoContext(this);

although many of the uses in the Eclipse editors use and document or undo manager as the object.

Upvotes: 1

Related Questions