2 * Copyright 2006-2007, Haiku.
3 * Distributed under the terms of the MIT License.
6 * Stephan Aßmus <superstippi@gmx.de>
9 #include "CommandStack.h"
20 CommandStack::CommandStack()
28 CommandStack::~CommandStack()
35 CommandStack::Perform(Command
* command
)
40 status_t ret
= command
? B_OK
: B_BAD_VALUE
;
42 ret
= command
->InitCheck();
45 ret
= command
->Perform();
48 ret
= _AddCommand(command
);
51 // no one else feels responsible...
66 status_t status
= B_ERROR
;
67 if (!fUndoHistory
.empty()) {
68 Command
* command
= fUndoHistory
.top();
70 status
= command
->Undo();
72 fRedoHistory
.push(command
);
74 fUndoHistory
.push(command
);
90 status_t status
= B_ERROR
;
91 if (!fRedoHistory
.empty()) {
92 Command
* command
= fRedoHistory
.top();
94 status
= command
->Redo();
96 fUndoHistory
.push(command
);
98 fRedoHistory
.push(command
);
109 CommandStack::GetUndoName(BString
& name
)
111 bool success
= false;
113 if (!fUndoHistory
.empty()) {
115 fUndoHistory
.top()->GetName(name
);
125 CommandStack::GetRedoName(BString
& name
)
127 bool success
= false;
129 if (!fRedoHistory
.empty()) {
131 fRedoHistory
.top()->GetName(name
);
141 CommandStack::Clear()
144 while (!fUndoHistory
.empty()) {
145 delete fUndoHistory
.top();
148 while (!fRedoHistory
.empty()) {
149 delete fRedoHistory
.top();
163 if (!fUndoHistory
.empty())
164 fSavedCommand
= fUndoHistory
.top();
173 CommandStack::IsSaved()
177 saved
= fUndoHistory
.empty();
178 if (fSavedCommand
&& !saved
) {
179 if (fSavedCommand
== fUndoHistory
.top())
191 CommandStack::_AddCommand(Command
* command
)
193 status_t status
= B_OK
;
196 if (!fUndoHistory
.empty()) {
197 // try to collapse commands to a single command
198 // or remove this and the previous command if
199 // they reverse each other
200 if (Command
* top
= fUndoHistory
.top()) {
201 if (command
->UndoesPrevious(top
)) {
206 } else if (top
->CombineWithNext(command
)) {
209 // after collapsing, the command might
210 // have changed it's mind about InitCheck()
211 // (the commands reversed each other)
212 if (top
->InitCheck() < B_OK
) {
216 } else if (command
->CombineWithPrevious(top
)) {
219 // after collapsing, the command might
220 // have changed it's mind about InitCheck()
221 // (the commands reversed each other)
222 if (command
->InitCheck() < B_OK
) {
231 fUndoHistory
.push(command
);
237 if (status
== B_OK
) {
238 // the redo stack needs to be empty
239 // as soon as a command was added (also in case of collapsing)
240 while (!fRedoHistory
.empty()) {
241 delete fRedoHistory
.top();