From 505dadca2a1da4555712201f81df2726d9877b22 Mon Sep 17 00:00:00 2001 From: Florian Hoelzl <hoelzl@fortiss.org> Date: Tue, 8 Mar 2011 09:00:22 +0000 Subject: [PATCH] command stack service trial implementation --- .../kernel/internal/ActionService.java | 94 +++++++ .../kernel/internal/CommandStackService.java | 264 +++++++++++++++++- .../kernel/internal/ContextMenuService.java | 16 ++ .../internal/navigator/NavigatorViewPart.java | 25 +- .../kernel/internal/navigator/NewMenu.java | 7 +- .../kernel/services/IActionService.java | 46 +++ .../kernel/services/ICommandStackService.java | 12 + .../kernel/services/IContextMenuService.java | 4 +- .../kernel/util/EObjectSelectionUtils.java | 17 ++ 9 files changed, 461 insertions(+), 24 deletions(-) create mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/ActionService.java create mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/IActionService.java diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/ActionService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/ActionService.java new file mode 100644 index 000000000..95c5fe5e1 --- /dev/null +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/ActionService.java @@ -0,0 +1,94 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.internal; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.ActionFactory; +import org.fortiss.tooling.kernel.services.IActionService; +import org.fortiss.tooling.kernel.services.ICommandStackService; +import org.fortiss.tooling.kernel.util.EObjectSelectionUtils; + +/** + * This class implements the {@link IActionService} interface. + * + * @author hoelzlf + * @author $Author$ + * @version $Rev$ + * @levd.rating RED Rev: + */ +public class ActionService implements IActionService { + + /** The global undo action. */ + public final IAction globalUndoAction = new Action("Undo", PlatformUI + .getWorkbench().getSharedImages() + .getImageDescriptor(ISharedImages.IMG_TOOL_UNDO)) { + + @Override + public void run() { + EObject selectedObject = EObjectSelectionUtils + .getCurrentSelectionFirstElement(); + if (selectedObject != null) { + ICommandStackService.INSTANCE.undo(selectedObject); + } + } + + @Override + public boolean isEnabled() { + EObject selectedObject = EObjectSelectionUtils + .getCurrentSelectionFirstElement(); + return selectedObject != null + && ICommandStackService.INSTANCE.canUndo(selectedObject); + } + }; + + /** {@inheritDoc} */ + @Override + public void registerGlobalActions(IViewSite site) { + fillActionBars(site.getActionBars()); + } + + /** {@inheritDoc} */ + @Override + public void registerGlobalActions(IEditorSite site) { + fillActionBars(site.getActionBars()); + } + + /** Fills the given action bar with the global actions. */ + private void fillActionBars(IActionBars actionBars) { + globalUndoAction.setId(ActionFactory.UNDO.getId()); + globalUndoAction.setActionDefinitionId(ActionFactory.UNDO + .getCommandId()); + actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), + globalUndoAction); + + actionBars.updateActionBars(); + } + + /** {@inheritDoc} */ + @Override + public void update() { + globalUndoAction.setEnabled(globalUndoAction.isEnabled()); + } +} diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/CommandStackService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/CommandStackService.java index 01b057fcc..5c37766d1 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/CommandStackService.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/CommandStackService.java @@ -17,15 +17,33 @@ $Id$ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.kernel.internal; +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; + +import org.conqat.ide.commons.ui.logging.LoggingUtils; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.emf.common.command.Command; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.impl.AdapterImpl; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.edit.command.ChangeCommand; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.fortiss.tooling.kernel.ToolingKernelActivator; import org.fortiss.tooling.kernel.services.ICommandStackService; import org.unicase.ecp.model.ECPWorkspaceManager; import org.unicase.ecp.model.NoWorkspaceException; import org.unicase.ecp.model.workSpaceModel.ECPProject; -import org.unicase.ui.common.commands.ECPCommand; +import org.unicase.ecp.model.workSpaceModel.ECPProjectListener; +import org.unicase.ecp.model.workSpaceModel.ECPWorkspace; +import org.unicase.ecp.model.workSpaceModel.WorkSpaceModelPackage; +import org.unicase.workspace.ProjectSpace; /** - * This class implements the {@link ICommandStackService} interface. + * This class implements the {@link ICommandStackService} interface. We have to + * mimic the command stack behavior, because EMFStore does not support redo of + * commands. Once this capability is available, this service class could be + * simplified. * * @author hoelzl * @author $Author$ @@ -34,22 +52,246 @@ import org.unicase.ui.common.commands.ECPCommand; */ public class CommandStackService implements ICommandStackService { + /** Stores the workspace listener. */ + private AdapterImpl workspaceListener; + + /** Stores the EmfStore workspace. */ + private ECPWorkspace workspace; + + /** Stores the project command stacks. */ + private Map<ECPProject, CommandStackInfo> commandStackMap = new HashMap<ECPProject, CommandStackInfo>(); + + /** Constructor. */ + public CommandStackService() { + try { + workspace = ECPWorkspaceManager.getInstance().getWorkSpace(); + } catch (NoWorkspaceException e) { + LoggingUtils.log(ToolingKernelActivator.getDefault(), + e.getMessage(), IStatus.ERROR, e); + return; + } + + createWorkspaceListener(); + workspace.eAdapters().add(workspaceListener); + + for (ECPProject project : workspace.getProjects()) { + addCommandStackInfo(project); + } + } + + /** {@inheritDoc} */ + @Override + public void runAsCommand(EObject target, final Runnable runner) { + commandStackMap.get(getECPProject(target)).execute(target, runner); + } + /** {@inheritDoc} */ @Override - public void runAsCommand(final EObject target, final Runnable runner) { - ECPProject project; + public boolean canUndo(EObject target) { + return commandStackMap.get(getECPProject(target)).canUndo(); + } + + /** {@inheritDoc} */ + @Override + public boolean canRedo(EObject target) { + return commandStackMap.get(getECPProject(target)).canRedo(); + } + + /** {@inheritDoc} */ + @Override + public void undo(EObject target) { + if (canUndo(target)) { + commandStackMap.get(getECPProject(target)).undo(); + } + } + + /** {@inheritDoc} */ + @Override + public void redo(EObject target) { + if (canRedo(target)) { + commandStackMap.get(getECPProject(target)).redo(); + } + } + + /** + * Creates the workspace listener, which registers the project listener on + * added projects. It also unregisters the project listener from removed + * projects. + */ + private void createWorkspaceListener() { + workspaceListener = new AdapterImpl() { + + @Override + public void notifyChanged(Notification msg) { + if ((msg.getFeatureID(ECPWorkspace.class)) == WorkSpaceModelPackage.ECP_WORKSPACE__PROJECTS) { + if (msg.getEventType() == Notification.ADD + && WorkSpaceModelPackage.eINSTANCE.getECPProject() + .isInstance(msg.getNewValue())) { + addCommandStackInfo((ECPProject) msg.getNewValue()); + } else if (msg.getEventType() == Notification.REMOVE + && WorkSpaceModelPackage.eINSTANCE.getECPProject() + .isInstance(msg.getOldValue())) { + removeCommandStackInfo((ECPProject) msg.getOldValue()); + } + } + super.notifyChanged(msg); + } + }; + } + + /** + * Returns the model element's ECP project or <code>null</code> . + */ + private ECPProject getECPProject(EObject target) { try { - project = ECPWorkspaceManager.getInstance().getWorkSpace() + return ECPWorkspaceManager.getInstance().getWorkSpace() .getProject(target); - } catch (NoWorkspaceException e) { - return; + } catch (Exception e) { + LoggingUtils.error(ToolingKernelActivator.getDefault(), + "Unable to find ECP project!", e); } - new ECPCommand(project.getRootObject()) { + return null; + } + + /** + * Stores project-specific information about the command stack of an + * EMFStore proejct. + */ + private class CommandStackInfo { + + /** + * Stores the initial size of the operations list, which may be greater + * than zero. This happens when uncommitted changes are in a project, + * while the workbench is restarted, i.e., the command stack service + * forgets, while the EMFStore workspace does not. + */ + private int initialOperationListSize = 0; + + /** Stores the project undo stack. */ + private final Stack<Command> undoStack = new Stack<Command>(); + + /** Stores the roject redo stack. */ + private final Stack<Command> redoStack = new Stack<Command>(); + + /** Stores the ECP project. */ + private final ECPProject ecpProject; + + /** Stores the workspace project space. */ + private ProjectSpace projectSpace; + + /** Stores the editing domain. */ + private EditingDomain editingDomain; + + /** Stores the current command execution flag. */ + private boolean inExecution = false; + + /** Stores the project listener. */ + private ECPProjectListener projectListener = new ECPProjectListener() { + + @Override + public void projectDeleted() { + CommandStackService.this.removeCommandStackInfo(ecpProject); + } + + @Override + public void projectChanged() { + updateCommandStackInfo(); + } @Override - protected void doRun() { - runner.run(); + public void modelelementDeleted(EObject eobject) { + // ignore for now } - }.run(false); + }; + + /** Constructor. */ + public CommandStackInfo(ECPProject project) { + this.ecpProject = project; + this.projectSpace = (ProjectSpace) project.getRootObject(); + project.addECPProjectListener(projectListener); + this.initialOperationListSize = projectSpace.getOperations().size(); + this.editingDomain = project.getEditingDomain(); + } + + /** Perform redo. */ + public void redo() { + Command cmd = redoStack.pop(); + executeOnEMFStore(cmd); + undoStack.push(cmd); + } + + /** Perform undo. */ + public void undo() { + Command cmd = undoStack.pop(); + projectSpace.undoLastOperation(); + redoStack.push(cmd); + } + + /** Returns whether undo is possible. */ + public boolean canUndo() { + return !undoStack.isEmpty(); + } + + /** Returns whether redo is possible. */ + public boolean canRedo() { + return !redoStack.isEmpty(); + } + + /** Executes the given command using the target's command stack. */ + public void execute(EObject target, final Runnable runner) { + // sanity check + if (getECPProject(target) == ecpProject) { + ChangeCommand cmd = new ChangeCommand(target) { + @Override + protected void doExecute() { + CommandStackInfo.this.inExecution = true; + runner.run(); + CommandStackInfo.this.inExecution = false; + } + }; + executeOnEMFStore(cmd); + undoStack.push(cmd); + redoStack.clear(); + } + } + + /** Native command execution on EMFStore editing domain. */ + private void executeOnEMFStore(Command cmd) { + editingDomain.getCommandStack().execute(cmd); + } + + /** React to project changes and update the command stack. */ + private void updateCommandStackInfo() { + int currentOperationListSize = projectSpace.getOperations().size(); + if (currentOperationListSize == undoStack.size() + + initialOperationListSize - 1) { + System.out.println("Und occured."); + redoStack.push(undoStack.pop()); + } else if (currentOperationListSize == undoStack.size() + + initialOperationListSize) { + System.out + .println("A push to the undo stack occured. Resetting redo stack. inExecution = " + + inExecution); + redoStack.empty(); + } else { + System.out + .println("Unknown project change received: undoStackSize = " + + undoStack.size() + + "; redoStackSize = " + + redoStack.size() + + "; operationsListSize = " + + currentOperationListSize); + } + } + } + + /** Adds the command stack for the given project. */ + private void addCommandStackInfo(ECPProject project) { + commandStackMap.put(project, new CommandStackInfo(project)); + } + + /** Removes the command stack for the given project. */ + private void removeCommandStackInfo(ECPProject project) { + commandStackMap.remove(project); } } diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/ContextMenuService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/ContextMenuService.java index d9945d0b0..b4a708132 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/ContextMenuService.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/ContextMenuService.java @@ -17,6 +17,9 @@ $Id$ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.kernel.internal; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.fortiss.tooling.kernel.services.IActionService; import org.fortiss.tooling.kernel.services.IContextMenuService; /** @@ -29,4 +32,17 @@ import org.fortiss.tooling.kernel.services.IContextMenuService; */ public class ContextMenuService implements IContextMenuService { + /** The group id of the global default action group. */ + public static final String GROUP_GLOBAL_DEFAULTS = "globalDefaults"; + + /** {@inheritDoc} */ + @Override + public void addGlobalDefaultActionSection(MenuManager menuManager) { + Separator globalDefaults = new Separator(GROUP_GLOBAL_DEFAULTS); + globalDefaults.setVisible(true); + menuManager.add(globalDefaults); + + menuManager.appendToGroup(GROUP_GLOBAL_DEFAULTS, + ((ActionService) IActionService.INSTANCE).globalUndoAction); + } } diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NavigatorViewPart.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NavigatorViewPart.java index 27cfc1351..cc106d17c 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NavigatorViewPart.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NavigatorViewPart.java @@ -47,6 +47,8 @@ import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.progress.UIJob; import org.fortiss.tooling.kernel.ToolingKernelActivator; import org.fortiss.tooling.kernel.internal.NavigatorService; +import org.fortiss.tooling.kernel.services.IActionService; +import org.fortiss.tooling.kernel.services.IContextMenuService; import org.fortiss.tooling.kernel.services.IEditorService; import org.fortiss.tooling.kernel.services.INavigatorService; import org.fortiss.tooling.kernel.util.EObjectSelectionUtils; @@ -186,6 +188,8 @@ public final class NavigatorViewPart extends ViewPart implements createContextMenu(); + IActionService.INSTANCE.registerGlobalActions(getViewSite()); + PlatformUI.getWorkbench().getActiveWorkbenchWindow() .getSelectionService().addSelectionListener(this); getSite().setSelectionProvider(viewer); @@ -205,6 +209,8 @@ public final class NavigatorViewPart extends ViewPart implements repositorySection.setVisible(true); menuManager.add(repositorySection); + IContextMenuService.INSTANCE.addGlobalDefaultActionSection(menuManager); + Separator additions = new Separator( IWorkbenchActionConstants.MB_ADDITIONS); additions.setVisible(true); @@ -228,19 +234,26 @@ public final class NavigatorViewPart extends ViewPart implements /** {@inheritDoc} */ @Override public void selectionChanged(IWorkbenchPart part, ISelection selection) { + IActionService.INSTANCE.update(); // TODO (FH): implement link with editor feature here } /** {@inheritDoc} */ @Override public void selectionChanged(SelectionChangedEvent event) { - if (event.getSelection() instanceof IStructuredSelection) { - IStructuredSelection selection = (IStructuredSelection) event - .getSelection(); - Object obj = selection.getFirstElement(); - // FIXME: Whats that good for? - // setActiveECPProject(obj); + EObject selectedElement = EObjectSelectionUtils + .getCurrentSelectionFirstElement(); + if (selectedElement != null) { + IActionService.INSTANCE.update(); } + + // if (event.getSelection() instanceof IStructuredSelection) { + // IStructuredSelection selection = (IStructuredSelection) event + // .getSelection(); + // Object obj = selection.getFirstElement(); + // FIXME: Whats that good for? + // setActiveECPProject(obj); + // } } /** Sets the active ECPProject element. */ diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NewMenu.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NewMenu.java index 54cab87af..583819daf 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NewMenu.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NewMenu.java @@ -21,8 +21,6 @@ import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.IContributionItem; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.CompoundContributionItem; import org.fortiss.tooling.kernel.interfaces.IPrototypeProvider; import org.fortiss.tooling.kernel.services.ICommandStackService; @@ -62,11 +60,8 @@ public class NewMenu extends CompoundContributionItem { /** {@inheritDoc} */ @Override protected IContributionItem[] getContributionItems() { - ISelection selection = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow().getSelectionService() - .getSelection(); EObject selectedObject = EObjectSelectionUtils - .getFirstElement(selection); + .getCurrentSelectionFirstElement(); List<IContributionItem> contributionItems = new ArrayList<IContributionItem>(); if (selectedObject != null) { diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/IActionService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/IActionService.java new file mode 100644 index 000000000..90cf40fa9 --- /dev/null +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/IActionService.java @@ -0,0 +1,46 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.services; + +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.IViewSite; +import org.fortiss.tooling.kernel.internal.ActionService; + +/** + * The action service manages registration and execution of actions including + * global actions like undo and redo. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @levd.rating RED Rev: + */ +public interface IActionService { + + /** Returns the singleton instance of the service. */ + public static final IActionService INSTANCE = new ActionService(); + + /** Registers global actions with a view site. */ + void registerGlobalActions(IViewSite site); + + /** Registers global actions with an editor site. */ + void registerGlobalActions(IEditorSite site); + + /** Updates the enabled state of the global actions. */ + void update(); +} diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/ICommandStackService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/ICommandStackService.java index 4301b8191..e4b941dcb 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/ICommandStackService.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/ICommandStackService.java @@ -36,4 +36,16 @@ public interface ICommandStackService { /** Runs the given Runnable within a emfStore transaction. */ void runAsCommand(EObject target, Runnable runner); + + /** Checks if an undo action is possible. */ + boolean canUndo(EObject target); + + /** Executes the undo action. */ + void undo(EObject target); + + /** Checks if a redo action is possible. */ + boolean canRedo(EObject target); + + /** Executes the redo action. */ + void redo(EObject target); } diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/IContextMenuService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/IContextMenuService.java index e5a94923e..c4aff7d48 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/IContextMenuService.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/IContextMenuService.java @@ -17,6 +17,7 @@ $Id$ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.kernel.services; +import org.eclipse.jface.action.MenuManager; import org.fortiss.tooling.kernel.internal.ContextMenuService; /** @@ -33,5 +34,6 @@ public interface IContextMenuService { /** Returns the singleton instance of the service. */ public static final IContextMenuService INSTANCE = new ContextMenuService(); - // TODO (FH): define + /** Adds the global default actions like undo to the given context menu. */ + void addGlobalDefaultActionSection(MenuManager menuManager); } diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/EObjectSelectionUtils.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/EObjectSelectionUtils.java index 04cd15ce4..146f1a58b 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/EObjectSelectionUtils.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/EObjectSelectionUtils.java @@ -20,6 +20,7 @@ package org.fortiss.tooling.kernel.util; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.PlatformUI; /** * Utility methods for {@link EObject} selections. @@ -31,6 +32,14 @@ import org.eclipse.jface.viewers.IStructuredSelection; */ public final class EObjectSelectionUtils { + /** + * Returns the first selected element if it is an EObject or + * <code>null</code> otherwise. + */ + public static EObject getCurrentSelectionFirstElement() { + return getFirstElement(getCurrentSelection()); + } + /** * Returns the first selected EObject or <code>null</code> if no EObject is * selected. @@ -44,4 +53,12 @@ public final class EObjectSelectionUtils { } return null; } + + /** + * Returns the current selection obtained from the platform. + */ + public static ISelection getCurrentSelection() { + return PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getSelectionService().getSelection(); + } } -- GitLab