Skip to content
Snippets Groups Projects
Commit d322e17b authored by Florian Hölzl's avatar Florian Hölzl
Browse files

command stack service trial implementation

parent 505dadca
No related branches found
No related tags found
No related merge requests found
......@@ -12,9 +12,9 @@ Require-Bundle: org.eclipse.core.runtime;visibility:=reexport,
org.conqat.ide.commons;bundle-version="2.7.0";visibility:=reexport,
org.conqat.ide.commons.ui;bundle-version="2.7.0";visibility:=reexport,
org.unicase.workspace,
org.unicase.ecp.model;visibility:=reexport,
org.unicase.ecpemfstorebridge,
org.unicase.ui.common
org.unicase.ecp.model,
org.unicase.ui.common,
org.unicase.ecpemfstorebridge
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Export-Package: org.fortiss.tooling.kernel,
......
......@@ -19,25 +19,21 @@ 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.command.BasicCommandStack;
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.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. We have to
......@@ -59,7 +55,7 @@ public class CommandStackService implements ICommandStackService {
private ECPWorkspace workspace;
/** Stores the project command stacks. */
private Map<ECPProject, CommandStackInfo> commandStackMap = new HashMap<ECPProject, CommandStackInfo>();
private Map<ECPProject, BasicCommandStack> commandStackMap = new HashMap<ECPProject, BasicCommandStack>();
/** Constructor. */
public CommandStackService() {
......@@ -75,14 +71,21 @@ public class CommandStackService implements ICommandStackService {
workspace.eAdapters().add(workspaceListener);
for (ECPProject project : workspace.getProjects()) {
addCommandStackInfo(project);
addCommandStack(project);
}
}
/** {@inheritDoc} */
@Override
public void runAsCommand(EObject target, final Runnable runner) {
commandStackMap.get(getECPProject(target)).execute(target, runner);
ChangeCommand chgCommand = new ChangeCommand(target) {
@Override
protected void doExecute() {
runner.run();
}
};
commandStackMap.get(getECPProject(target)).execute(chgCommand);
}
/** {@inheritDoc} */
......@@ -100,23 +103,18 @@ public class CommandStackService implements ICommandStackService {
/** {@inheritDoc} */
@Override
public void undo(EObject target) {
if (canUndo(target)) {
commandStackMap.get(getECPProject(target)).undo();
}
commandStackMap.get(getECPProject(target)).undo();
}
/** {@inheritDoc} */
@Override
public void redo(EObject target) {
if (canRedo(target)) {
commandStackMap.get(getECPProject(target)).redo();
}
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.
* Creates the workspace listener, which adds the command stacks for the
* added projects. It also unregisters command stacks from removed projects.
*/
private void createWorkspaceListener() {
workspaceListener = new AdapterImpl() {
......@@ -127,11 +125,11 @@ public class CommandStackService implements ICommandStackService {
if (msg.getEventType() == Notification.ADD
&& WorkSpaceModelPackage.eINSTANCE.getECPProject()
.isInstance(msg.getNewValue())) {
addCommandStackInfo((ECPProject) msg.getNewValue());
addCommandStack((ECPProject) msg.getNewValue());
} else if (msg.getEventType() == Notification.REMOVE
&& WorkSpaceModelPackage.eINSTANCE.getECPProject()
.isInstance(msg.getOldValue())) {
removeCommandStackInfo((ECPProject) msg.getOldValue());
removeCommandStack((ECPProject) msg.getOldValue());
}
}
super.notifyChanged(msg);
......@@ -153,145 +151,15 @@ public class CommandStackService implements ICommandStackService {
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
public void modelelementDeleted(EObject eobject) {
// ignore for now
}
};
/** 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));
private void addCommandStack(ECPProject project) {
BasicCommandStack cmdStack = (BasicCommandStack) project
.getEditingDomain().getCommandStack();
commandStackMap.put(project, cmdStack);
}
/** Removes the command stack for the given project. */
private void removeCommandStackInfo(ECPProject project) {
private void removeCommandStack(ECPProject project) {
commandStackMap.remove(project);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment