bool UndoStack::redo(uint steps, int objectId) { for (uint i = 0; i < steps && !redoActions_.empty(); ++i) { UndoState *tmpRedoState = 0; if (objectId == Um::GLOBAL_UNDO_MODE) { tmpRedoState = redoActions_[0]; redoActions_.erase(redoActions_.begin()); } else { // object specific mode (search the correct state) StateList::iterator it; for (it = redoActions_.begin(); it != redoActions_.end(); ++it) { UndoObject *tmp = (*it)->undoObject(); if (tmp && tmp->getUId() == static_cast<ulong>(objectId)) { tmpRedoState = *it; redoActions_.erase(it); break; } } } undoActions_.insert(undoActions_.begin(), tmpRedoState); // push to the undo actions tmpRedoState->redo(); } return true; }
UndoState* UndoStack::getNextRedo(int objectId) { UndoState *state = 0; if (!redoActions_.empty()) { if (objectId == Um::GLOBAL_UNDO_MODE) state = redoActions_[0]; else { StateList::iterator it; for (it = redoActions_.begin(); it != redoActions_.end(); ++it) { UndoState* tmp = *it; TransactionState *ts = dynamic_cast<TransactionState*>(tmp); if (ts && ts->contains(objectId)) break; else if (!ts && tmp->undoObject() && tmp->undoObject()->getUId() == static_cast<ulong>(objectId)) { state = tmp; break; } } } } return state; }
void UndoManager::setTexts() { ScribusMainWindow* scMW = ScCore->primaryMainWindow(); UndoStack& currentStack = stacks_[currentDoc_]; if (currentStack.undoItems() > 0) { UndoState *state = currentStack.getNextUndo(currentUndoObjectId_); if (state) scMW->scrActions["editUndoAction"]->setTexts(QString(Um::MenuUndo).arg(state->getName())); else scMW->scrActions["editUndoAction"]->setTexts(Um::MenuUndoEmpty); } else scMW->scrActions["editUndoAction"]->setTexts(Um::MenuUndoEmpty); if (currentStack.redoItems() > 0) { UndoState *state = currentStack.getNextRedo(currentUndoObjectId_); if (state) scMW->scrActions["editRedoAction"]->setTexts(QString(Um::MenuRedo).arg(state->getName())); else scMW->scrActions["editRedoAction"]->setTexts(Um::MenuRedoEmpty); } else scMW->scrActions["editRedoAction"]->setTexts(Um::MenuRedoEmpty); }
UndoObject* UndoManager::replaceObject(ulong uid, UndoObject *newUndoObject) { UndoObject *tmp = 0; TransactionState* transaction_ = NULL; if (transactions_.size() > 0) transaction_ = transactions_.at(transactions_.size()-1)->transactionState; for (uint i = 0; i < stacks_[currentDoc_].undoActions_.size(); ++i) { UndoState *tmpState = stacks_[currentDoc_].undoActions_[i]; TransactionState *ts = dynamic_cast<TransactionState*>(tmpState); if (ts) tmp = ts->replace(uid, newUndoObject); else if (tmpState->undoObject() && tmpState->undoObject()->getUId() == uid) { tmp = tmpState->undoObject(); tmpState->setUndoObject(newUndoObject); } } for (uint i = 0; i < stacks_[currentDoc_].redoActions_.size(); ++i) { UndoState *tmpState = stacks_[currentDoc_].redoActions_[i]; TransactionState *ts = dynamic_cast<TransactionState*>(tmpState); if (ts) tmp = ts->replace(uid, newUndoObject); else if (tmpState->undoObject() && tmpState->undoObject()->getUId() == uid) { tmp = tmpState->undoObject(); tmpState->setUndoObject(newUndoObject); } } if (transaction_) // replace also in the currently open transaction tmp = transaction_->replace(uid, newUndoObject); return tmp; }
bool UndoStack::undo(uint steps, int objectId) { for (uint i = 0; i < steps && !undoActions_.empty(); ++i) { UndoState *tmpUndoState = 0; if (objectId == Um::GLOBAL_UNDO_MODE) { tmpUndoState = undoActions_[0]; undoActions_.erase(undoActions_.begin()); } else { // object specific mode (search the correct state) StateList::iterator it; for (it = undoActions_.begin(); it != undoActions_.end(); ++it) { UndoObject *tmp = (*it)->undoObject(); if (tmp && tmp->getUId() == static_cast<ulong>(objectId)) { tmpUndoState = *it; undoActions_.erase(it); break; } else if((*it)->isTransaction()) { TransactionState *ts = dynamic_cast<TransactionState*>(*it); if(ts->containsOnly(objectId)) { tmpUndoState = *it; undoActions_.erase(it); break; } } } } redoActions_.insert(redoActions_.begin(), tmpUndoState); // push to the redo actions tmpUndoState->undo(); } return true; }
void UndoManager::setState(UndoGui* gui, int uid) { gui->clear(); if ( stacks_[currentDoc_].size() == 0 ) return; UndoStack& currentStack = stacks_[currentDoc_]; StateList::iterator itstartU = currentStack.undoActions_.begin(); // undo actions StateList::iterator itendU = currentStack.undoActions_.end(); StateList::iterator itstartR = currentStack.redoActions_.begin(); // redo actions StateList::iterator itendR = currentStack.redoActions_.end(); if (uid > -1) { // find the range from where actions are added when in obj. spec. mode StateList::iterator it2; for (it2 = currentStack.undoActions_.begin(); it2 != currentStack.undoActions_.end(); ++it2) { UndoState* tmp = *it2; TransactionState *ts = dynamic_cast<TransactionState*>(tmp); if (ts && !ts->containsOnly(uid)) { if (it2 != currentStack.undoActions_.begin()) itendU = --it2; break; } } StateList::iterator it3; for (it3 = currentStack.redoActions_.begin(); it3 != currentStack.redoActions_.end(); ++it3) { UndoState* tmp = *it3; TransactionState *ts = dynamic_cast<TransactionState*>(tmp); if (ts && !ts->containsOnly(uid)) { itendR = it3; break; } } } if (currentStack.undoItems() > 0) { if (itendU == currentStack.undoActions_.end()) --itendU; for (; itendU >= itstartU; --itendU) // insert undo actions { UndoState* state = *itendU; UndoObject* target = state->undoObject(); if (target && (uid == -1 || target->getUId() == static_cast<uint>(uid))) gui->insertUndoItem(target, state); if (itendU == itstartU) break; } } if (currentStack.redoItems() > 0) { if (itendR > itstartR) --itendR; for (; itstartR <= itendR; ++itstartR) // insert redo actions { UndoState* state = *itstartR; UndoObject* target = state->undoObject(); if (target && (uid == -1 || target->getUId() == static_cast<uint>(uid))) gui->insertRedoItem(target, state); if (itendR == itstartR) break; } } }