void redo() { if (_redoStack.empty()) { rMessage() << "Redo: no redo available" << std::endl; } else { Operation* operation = _redoStack.back(); rMessage() << "Redo: " << operation->_command << std::endl; startUndo(); trackersRedo(); operation->_snapshot.restore(); finishUndo(operation->_command); _redoStack.pop_back(); for (Observers::iterator i = _observers.begin(); i != _observers.end(); /* in-loop */) { Observer* observer = *(i++); observer->postRedo(); } // Trigger the onPostUndo event on all scene nodes PostRedoWalker walker; GlobalSceneGraph().root()->traverse(walker); GlobalSceneGraph().sceneChanged(); } }
void Controller::undo() { UndoStack *stack = selectActiveStack(true); if (stack) { stack->undo(); } }
void Controller::redo() { UndoStack *stack = selectActiveStack(false); if (stack) { stack->redo(); } }
void start() { _redoStack.clear(); if (_undoStack.size() == _undoLevels) { _undoStack.pop_front(); } startUndo(); trackersBegin(); }
void clear() { mark_undoables(0); _undoStack.clear(); _redoStack.clear(); trackersClear(); // greebo: This is called on map shutdown, so don't clear the observers, // there are some "persistent" observers like EntityInspector and ShaderClipboard }
void TextBase::endEdit(EditData& ed) { TextEditData* ted = static_cast<TextEditData*>(ed.getData(this)); score()->undoStack()->remove(ted->startUndoIdx); // remove all undo/redo records // replace all undo/redo records collected during text editing with // one property change QString actualText = xmlText(); if (ted->oldXmlText.isEmpty()) { UndoStack* us = score()->undoStack(); UndoCommand* ucmd = us->last(); if (ucmd) { const QList<UndoCommand*>& cl = ucmd->commands(); const UndoCommand* cmd = cl.back(); if (strncmp(cmd->name(), "Add:", 4) == 0) { const AddElement* ae = static_cast<const AddElement*>(cmd); if (ae->getElement() == this) { if (actualText.isEmpty()) { // we just created this empty text, rollback that operation us->rollback(); score()->update(); ed.element = 0; } else { setXmlText(ted->oldXmlText); // reset text to value before editing us->reopen(); // combine undo records of text creation with text editing undoChangeProperty(Pid::TEXT, actualText); layout1(); score()->endCmd(); } return; } } } } if (actualText.isEmpty()) { qDebug("actual text is empty"); score()->startCmd(); score()->undoRemoveElement(this); ed.element = 0; score()->endCmd(); return; } setXmlText(ted->oldXmlText); // reset text to value before editing score()->startCmd(); undoChangeProperty(Pid::TEXT, actualText); // change property to set text to actual value again // this also changes text of linked elements layout1(); triggerLayout(); // force relayout even if text did not change score()->endCmd(); static const qreal w = 2.0; score()->addRefresh(canvasBoundingRect().adjusted(-w, -w, w, w)); }
// Sets the size of the undoStack void setLevels(std::size_t levels) { if (levels > MAX_UNDO_LEVELS) { levels = MAX_UNDO_LEVELS; } while (_undoStack.size() > levels) { _undoStack.pop_front(); } _undoLevels = levels; }
AnimationRect::AnimationRect(const sf::IntRect& rect, int frame, UndoStack& undo_stack) { this->rect = rect; this->frame = frame; this->undo_stack = &undo_stack; undo_stack.push(*new AnimationRectCreated(this, rect, frame)); }
// greebo: This finishes the current operation and // removes it instantly from the stack void cancel() { // Try to add the last operation as "temp" if (finishUndo("$TEMPORARY")) { // Instantly remove the added operation _undoStack.pop_back(); } }
QStringList UndoManager::getLastFromStack( int count, UndoStack & stack ) { QStringList ret; for( int i = stack.size() - 1; i >= 0 && count > 0; i--, count-- ) { UndoBlock * ub = stack[i]; QString ttl = ub->title(); ret += ttl.isEmpty() ? "Unknown Operation" : ttl; } return ret; }
bool UndoStack::applyLast(UndoStack& counterpart, bool transfer) { if(steps.empty()) { //std::cout << "Nothing to Un/Redo" << std::endl; return(false); } //std::cout << "This stack stack now has " << steps.size() << (steps.size()==1?" item":" items") << std::endl; //TODO: alternative might be to close any open groups if(nestLevel>0) throw std::logic_error("Undo history corruption: open undo group at point of application"); do { if(steps.empty()) throw std::logic_error("Undo history corruption: too many group ending markers"); UndoStep* step=steps.back(); steps.pop_back(); if(nestLevel==0) levelLengths.back()--; //std::cout << "Undoing: "; switch(step->getGroupType()) { case UndoStep::NORMAL: //std::cout << step->description() << std::endl; step->apply(); break; case UndoStep::BEGIN_GROUP: //std::cout << "Group beginning" << std::endl; if(nestLevel==0) throw std::logic_error("Undo history corruption: too many group beginning markers"); nestLevel--; //std::cout << "\tLevel is now " << nestLevel << std::endl; break; case UndoStep::END_GROUP: //std::cout << "Group ending" << std::endl; nestLevel++; //std::cout << "\tLevel is now " << nestLevel << std::endl; break; case UndoStep::SAVE_DELIMITER: //std::cout << "Save delimiter" << std::endl; //TODO: Display a dialog here to ask whether the user wants to undo past the last save point //???: What should be done about older save markers, farther down the stack? break; } if(transfer) { step->invert(); counterpart.appendChange(step); } else delete step; } while(nestLevel); //std::cout << "This stack stack now has " << steps.size() << (steps.size()==1?" item":" items") << std::endl; //std::cout << "Counterpart stack now has " << counterpart.steps.size() << (counterpart.steps.size()==1?" item":" items") << std::endl; return(true); }
bool finishRedo(const std::string& command) { bool changed = _redoStack.finish(command); mark_undoables(0); return changed; }
void startRedo() { _redoStack.start("unnamedCommand"); mark_undoables(&_redoStack); }
std::size_t size() const { return _undoStack.size(); }