execute the command after having modified the inner state.
[EMFCompare2.git] / plugins / org.eclipse.emf.compare.edit / src / org / eclipse / emf / compare / command / impl / DualCompareCommandStack.java
blob02c1f44874404ef59624dbac507b542e3c7e37a9
1 /*******************************************************************************
2 * Copyright (c) 2012 Obeo.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Obeo - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.emf.compare.command.impl;
13 import static com.google.common.collect.Lists.newArrayList;
15 import com.google.common.base.Preconditions;
17 import java.util.Iterator;
18 import java.util.List;
20 import org.eclipse.emf.common.command.BasicCommandStack;
21 import org.eclipse.emf.common.command.Command;
22 import org.eclipse.emf.common.command.CommandStackListener;
23 import org.eclipse.emf.compare.command.ICompareCommandStack;
24 import org.eclipse.emf.compare.command.ICompareCopyCommand;
26 public class DualCompareCommandStack implements ICompareCommandStack {
28 private final BasicCommandStack leftCommandStack;
30 private final BasicCommandStack rightCommandStack;
32 private final List<BasicCommandStack> commandStackStack;
34 private int top;
36 private BasicCommandStack mostRecentCommandStack;
38 private int saveIndex = -1;
40 public DualCompareCommandStack(BasicCommandStack leftCommandStack, BasicCommandStack rightCommandStack) {
41 this.leftCommandStack = Preconditions.checkNotNull(leftCommandStack);
42 this.rightCommandStack = Preconditions.checkNotNull(rightCommandStack);
43 this.commandStackStack = newArrayList();
44 this.top = -1;
47 /**
48 * {@inheritDoc}
50 * @see org.eclipse.emf.common.command.CommandStack#execute(org.eclipse.emf.common.command.Command)
52 public void execute(Command command) {
53 // should do that AFTER delegate.execute, but in this this case, notifiers will not see change in
54 // side lists.
55 if (command instanceof ICompareCopyCommand) {
56 final BasicCommandStack commandStack;
57 final ICompareCopyCommand compareCommand = (ICompareCopyCommand)command;
58 if (compareCommand.isLeftToRight()) {
59 commandStack = rightCommandStack;
60 } else {
61 commandStack = leftCommandStack;
64 // Clear the list past the top.
66 Iterator<BasicCommandStack> commandStacks = commandStackStack.listIterator(top + 1);
67 while (commandStacks.hasNext()) {
68 commandStacks.next();
69 commandStacks.remove();
72 // Record the successfully executed command.
74 mostRecentCommandStack = commandStack;
75 commandStackStack.add(commandStack);
76 ++top;
78 // This is kind of tricky.
79 // If the saveIndex was in the redo part of the command list which has now been wiped out,
80 // then we can never reach a point where a save is not necessary, not even if we undo all the
81 // way back to the beginning.
83 if (saveIndex >= top) {
84 // This forces isSaveNeded to always be true.
86 saveIndex = -2;
89 commandStack.execute(compareCommand);
93 /**
94 * {@inheritDoc}
96 * @see org.eclipse.emf.common.command.CommandStack#canUndo()
98 public boolean canUndo() {
99 return top != -1 && commandStackStack.get(top).canUndo();
103 * {@inheritDoc}
105 * @see org.eclipse.emf.common.command.CommandStack#undo()
107 public void undo() {
108 if (canUndo()) {
109 BasicCommandStack commandStack = commandStackStack.get(top--);
110 commandStack.undo();
111 mostRecentCommandStack = commandStack;
116 * {@inheritDoc}
118 * @see org.eclipse.emf.common.command.CommandStack#canRedo()
120 public boolean canRedo() {
121 return top < commandStackStack.size() - 1;
125 * {@inheritDoc}
127 * @see org.eclipse.emf.common.command.CommandStack#getUndoCommand()
129 public Command getUndoCommand() {
130 return top == -1 || top == commandStackStack.size() ? null : commandStackStack.get(top)
131 .getUndoCommand();
135 * {@inheritDoc}
137 * @see org.eclipse.emf.common.command.CommandStack#getRedoCommand()
139 public Command getRedoCommand() {
140 return top + 1 >= commandStackStack.size() ? null : commandStackStack.get(top + 1)
141 .getRedoCommand();
145 * {@inheritDoc}
147 * @see org.eclipse.emf.common.command.CommandStack#getMostRecentCommand()
149 public Command getMostRecentCommand() {
150 if (mostRecentCommandStack != null) {
151 return mostRecentCommandStack.getMostRecentCommand();
153 return null;
157 * {@inheritDoc}
159 * @see org.eclipse.emf.common.command.CommandStack#redo()
161 public void redo() {
162 if (canRedo()) {
163 BasicCommandStack commandStack = commandStackStack.get(++top);
164 commandStack.redo();
165 mostRecentCommandStack = commandStack;
170 * {@inheritDoc}
172 * @see org.eclipse.emf.common.command.CommandStack#flush()
174 public void flush() {
175 Iterator<BasicCommandStack> commands = commandStackStack.listIterator();
176 while (commands.hasNext()) {
177 commands.next();
178 commands.remove();
180 commandStackStack.clear();
181 top = -1;
182 saveIndex = -1;
183 mostRecentCommandStack = null;
187 * {@inheritDoc}
189 * @see org.eclipse.emf.common.command.CommandStack#addCommandStackListener(org.eclipse.emf.common.command.CommandStackListener)
191 public void addCommandStackListener(CommandStackListener listener) {
192 leftCommandStack.addCommandStackListener(listener);
193 rightCommandStack.addCommandStackListener(listener);
197 * {@inheritDoc}
199 * @see org.eclipse.emf.common.command.CommandStack#removeCommandStackListener(org.eclipse.emf.common.command.CommandStackListener)
201 public void removeCommandStackListener(CommandStackListener listener) {
202 leftCommandStack.removeCommandStackListener(listener);
203 rightCommandStack.removeCommandStackListener(listener);
207 * {@inheritDoc}
209 * @see org.eclipse.emf.compare.command.ICompareCommandStack#isLeftSaveNeeded()
211 public boolean isLeftSaveNeeded() {
212 return leftCommandStack.isSaveNeeded();
216 * {@inheritDoc}
218 * @see org.eclipse.emf.compare.command.ICompareCommandStack#isRightSaveNeeded()
220 public boolean isRightSaveNeeded() {
221 return rightCommandStack.isSaveNeeded();
225 * {@inheritDoc}
227 * @see org.eclipse.emf.compare.command.ICompareCommandStack#leftSaveIsDone()
229 public void leftSaveIsDone() {
230 leftCommandStack.saveIsDone();
234 * {@inheritDoc}
236 * @see org.eclipse.emf.compare.command.ICompareCommandStack#rightSaveIsDone()
238 public void rightSaveIsDone() {
239 rightCommandStack.saveIsDone();