void CUndoRedoStack::remove(QUndoCommand* cmd) { if(!cmd) return; int inUndo = d->undoStack.indexOf(cmd); int inRedo = inUndo >= 0 ? -1 : d->redoStack.indexOf(cmd); CUndoRedoCmdBase* cmd2 = dynamic_cast<CUndoRedoCmdBase*>(cmd); if(cmd2) removeCommand(cmd2); if(inUndo >= 0) { d->undoStack.remove(inUndo); emit canUndoChanged(d->undoStack.count()); } else if(inRedo >= 0) { d->redoStack.remove(inRedo); emit canRedoChanged(d->redoStack.count()); } emit countChanged(count()); }
void QUndoStack::clear() { Q_D(QUndoStack); if (d->command_list.isEmpty()) return; bool was_clean = isClean(); d->macro_stack.clear(); qDeleteAll(d->command_list); d->command_list.clear(); d->index = 0; d->clean_index = 0; emit indexChanged(0); emit canUndoChanged(false); emit undoTextChanged(QString()); emit canRedoChanged(false); emit redoTextChanged(QString()); if (!was_clean) emit cleanChanged(true); }
void KUndo2QStack::setIndex(int idx, bool clean) { bool was_clean = m_index == m_clean_index; if (m_lastMergedIndex <= idx) { m_lastMergedSetCount = idx - m_lastMergedIndex; } else { m_lastMergedSetCount = 1; m_lastMergedIndex = idx-1; } if(idx == 0){ m_lastMergedSetCount = 0; m_lastMergedIndex = 0; } if (idx != m_index) { m_index = idx; emit indexChanged(m_index); emit canUndoChanged(canUndo()); emit undoTextChanged(undoText()); emit canRedoChanged(canRedo()); emit redoTextChanged(redoText()); } if (clean) m_clean_index = m_index; bool is_clean = m_index == m_clean_index; if (is_clean != was_clean) emit cleanChanged(is_clean); }
void GameMovesRegistry::failExecution() { m_performedCmnds.clear(); m_undoneCmnds.clear(); emit canRedoChanged(canRedo()); emit canUndoChanged(canUndo()); emit executionFailed(); }
void GameMovesRegistry::clear() { m_performedCmnds.clear(); m_undoneCmnds.clear(); emit countChanged(count()); emit canRedoChanged(canRedo()); emit canUndoChanged(canUndo()); }
void UndoStack::execCmd(UndoCommand* cmd, bool autoMerge) throw (Exception) { Q_CHECK_PTR(cmd); if (mCommandActive) { delete cmd; throw RuntimeError(__FILE__, __LINE__, QString(), tr("Another command is active " "at the moment. Please finish that command to continue.")); } if (mCleanIndex > mCurrentIndex) mCleanIndex = -1; // the clean state will no longer exist -> make the index invalid // first, delete all commands above the current index (make redo impossible) // --> in reverse order (from top to bottom)! while (mCurrentIndex < mCommands.count()) delete mCommands.takeLast(); Q_ASSERT(mCurrentIndex == mCommands.count()); try { cmd->redo(); // throws an exception on error } catch (Exception& e) { // delete the command because this UndoStack object will NOT take the ownership // over the failed command! and then rethrow the exception... delete cmd; throw; } // command successfully executed, try to merge it with the last executed command bool merged = false; if ((autoMerge) && (mCurrentIndex > 0)) merged = mCommands[mCurrentIndex-1]->mergeWith(cmd); // try merging the commands if (!merged) { // command was not merged --> add it to the command stack and emit signals mCommands.append(cmd); mCurrentIndex++; // emit signals emit undoTextChanged(QString(tr("Undo: %1")).arg(cmd->getText())); emit redoTextChanged(tr("Redo")); emit canUndoChanged(true); emit canRedoChanged(false); emit cleanChanged(false); } }
void UndoStack::beginCommand(const QString& text) throw (Exception) { if (mCommandActive) { throw RuntimeError(__FILE__, __LINE__, QString(), tr("Another command is active " "at the moment. Please finish that command to continue.")); } UndoCommand* cmd = new UndoCommand(text); execCmd(cmd, false); // throws an exception on error; emits all signals; does NOT merge mCommandActive = true; // emit signals emit canUndoChanged(false); }
void UndoStack::redo() throw (Exception) { if (!canRedo()) return; mCommands[mCurrentIndex]->redo(); // throws an exception on error mCurrentIndex++; // emit signals emit undoTextChanged(getUndoText()); emit redoTextChanged(getRedoText()); emit canUndoChanged(canUndo()); emit canRedoChanged(canRedo()); emit cleanChanged(isClean()); }
void UndoStack::undo() throw (Exception) { if ((!canUndo()) || (mCommandActive)) // if a command is active, undo() is not allowed return; mCommands[mCurrentIndex-1]->undo(); // throws an exception on error mCurrentIndex--; // emit signals emit undoTextChanged(getUndoText()); emit redoTextChanged(getRedoText()); emit canUndoChanged(canUndo()); emit canRedoChanged(canRedo()); emit cleanChanged(isClean()); }
void CUndoRedoStack::redo() { QUndoCommand* topCmd = d->redoStack.count() ? d->redoStack.pop() : 0; if(!topCmd) return; QString cmdText = topCmd->text(); topCmd->redo(); d->undoStack.push(topCmd); qWarning("Redo: %s", qPrintable(cmdText)); // emit change notifications. emit redone(cmdText); emit canUndoChanged(d->undoStack.count()); emit canRedoChanged(d->redoStack.count()); }
void CUndoRedoStack::push(QUndoCommand* cmd) { if(!cmd) return; // First register the undo command into the undo stack. QUndoCommand* topCmd = d->undoStack.count() ? d->undoStack.top() : 0; if(!topCmd) { d->undoStack.push(cmd); CUndoRedoCmdBase* cmd2 = dynamic_cast<CUndoRedoCmdBase*>(cmd); if(cmd2) addCommand(cmd2); } else { if(topCmd->id() == cmd->id()) { bool success = topCmd->mergeWith(cmd); if(!success) { d->undoStack.push(cmd); CUndoRedoCmdBase* cmd2 = dynamic_cast<CUndoRedoCmdBase*>(cmd); if(cmd2) addCommand(cmd2); } else delete cmd; } } // Now clear the redo stack. for(int i=0; i<d->redoStack.count(); i++) { QUndoCommand* cmd = d->redoStack.pop(); CUndoRedoCmdBase* cmd2 = dynamic_cast<CUndoRedoCmdBase*>(cmd); if(cmd2) removeCommand(cmd2); delete cmd; } // emit change notifications. emit canUndoChanged(d->undoStack.count()); emit canRedoChanged(d->redoStack.count()); emit countChanged(count()); }
void QUndoStack::push(QUndoCommand *cmd) { Q_D(QUndoStack); cmd->redo(); bool macro = !d->macro_stack.isEmpty(); QUndoCommand *cur = 0; if (macro) { QUndoCommand *macro_cmd = d->macro_stack.last(); if (!macro_cmd->d->child_list.isEmpty()) cur = macro_cmd->d->child_list.last(); } else { if (d->index > 0) cur = d->command_list.at(d->index - 1); while (d->index < d->command_list.size()) delete d->command_list.takeLast(); if (d->clean_index > d->index) d->clean_index = -1; // we've deleted the clean state } bool try_merge = cur != 0 && cur->id() != -1 && cur->id() == cmd->id() && (macro || d->index != d->clean_index); if (try_merge && cur->mergeWith(cmd)) { delete cmd; if (!macro) { emit indexChanged(d->index); emit canUndoChanged(canUndo()); emit undoTextChanged(undoText()); emit canRedoChanged(canRedo()); emit redoTextChanged(redoText()); } } else { if (macro) { d->macro_stack.last()->d->child_list.append(cmd); } else { d->command_list.append(cmd); d->checkUndoLimit(); d->setIndex(d->index + 1, false); } } }
void KUndo2QStack::push(KUndo2Command *cmd) { cmd->redo(); bool macro = !m_macro_stack.isEmpty(); KUndo2Command *cur = 0; if (macro) { KUndo2Command *macro_cmd = m_macro_stack.last(); if (!macro_cmd->d->child_list.isEmpty()) cur = macro_cmd->d->child_list.last(); } else { if (m_index > 0) cur = m_command_list.at(m_index - 1); while (m_index < m_command_list.size()) delete m_command_list.takeLast(); if (m_clean_index > m_index) m_clean_index = -1; // we've deleted the clean state } bool try_merge = cur != 0 && cur->id() != -1 && cur->id() == cmd->id() && (macro || m_index != m_clean_index); if (try_merge && cur->mergeWith(cmd)) { delete cmd; if (!macro) { emit indexChanged(m_index); emit canUndoChanged(canUndo()); emit undoTextChanged(undoText()); emit canRedoChanged(canRedo()); emit redoTextChanged(redoText()); } } else { if (macro) { m_macro_stack.last()->d->child_list.append(cmd); } else { m_command_list.append(cmd); checkUndoLimit(); setIndex(m_index + 1, false); } } }
void KUndo2QStack::setIndex(int idx, bool clean) { bool was_clean = m_index == m_clean_index; if (idx != m_index) { m_index = idx; emit indexChanged(m_index); emit canUndoChanged(canUndo()); emit undoTextChanged(undoText()); emit canRedoChanged(canRedo()); emit redoTextChanged(redoText()); } if (clean) m_clean_index = m_index; bool is_clean = m_index == m_clean_index; if (is_clean != was_clean) emit cleanChanged(is_clean); }
void UndoStack::abortCommand() throw (Exception) { Q_ASSERT(mCurrentIndex == mCommands.count()); if (!mCommandActive) throw LogicError(__FILE__, __LINE__, QString(), tr("No command active!")); mCommands.last()->undo(); // throws an exception on error mCurrentIndex--; mCommandActive = false; delete mCommands.takeLast(); // delete and remove the aborted command from the stack // emit signals emit undoTextChanged(getUndoText()); emit redoTextChanged(tr("Redo")); emit canUndoChanged(canUndo()); emit canRedoChanged(false); emit cleanChanged(isClean()); emit commandAborted(); // this is important! }
void UndoStack::endCommand() throw (Exception) { Q_ASSERT(mCurrentIndex == mCommands.count()); if (!mCommandActive) throw LogicError(__FILE__, __LINE__, QString(), tr("No command active!")); if (mCommands.last()->getChildCount() == 0) { // the last command is empty --> remove it from the stack! abortCommand(); return; } mCommandActive = false; // emit signals emit canUndoChanged(canUndo()); emit commandEnded(); }
void CUndoRedoStack::clear() { qDeleteAll(d->undoStack); qDeleteAll(d->redoStack); d->undoStack.clear(); d->redoStack.clear(); QList<QObject*> objects = d->objectCmdMap.keys(); for(int i=0; i<objects.count(); i++) { if(d->invalidPtrList.contains( objects[i] ) ) continue; disconnect(objects[i], 0, this, 0); } d->objectCmdMap.clear(); emit stackCleared(); emit canUndoChanged(false); emit canRedoChanged(false); emit countChanged(count()); }
int QUndoGroup::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: activeStackChanged((*reinterpret_cast< QUndoStack*(*)>(_a[1]))); break; case 1: indexChanged((*reinterpret_cast< int(*)>(_a[1]))); break; case 2: cleanChanged((*reinterpret_cast< bool(*)>(_a[1]))); break; case 3: canUndoChanged((*reinterpret_cast< bool(*)>(_a[1]))); break; case 4: canRedoChanged((*reinterpret_cast< bool(*)>(_a[1]))); break; case 5: undoTextChanged((*reinterpret_cast< const QString(*)>(_a[1]))); break; case 6: redoTextChanged((*reinterpret_cast< const QString(*)>(_a[1]))); break; case 7: undo(); break; case 8: redo(); break; case 9: setActiveStack((*reinterpret_cast< QUndoStack*(*)>(_a[1]))); break; default: ; } _id -= 10; } return _id; }
/// Reverts the last command issued by undo(). void UndoStack::redo() { if(inGroup()){ endGroup(); } if(!canRedo()){ return; } UndoCommand *command = m_redoStack.top(); m_redoStack.pop(); command->redo(); m_undoStack.push(command); if(m_undoStack.size() == 1){ canUndoChanged(true); } if(m_redoStack.empty()){ canRedoChanged(false); } }
void GameMovesRegistry::undo() { if (!canUndo()) { return; } qDebug() << "Undo"; IMoveCommand::UPtr cmd = std::move(m_performedCmnds.back()); m_performedCmnds.pop_back(); m_undoneCmnds.push_back(std::move(cmd)); if (!m_undoneCmnds.back()->undo(m_board)) { failExecution(); return; } emit newMoveDone(); emit canRedoChanged(canRedo()); emit canUndoChanged(canUndo()); }
void UndoStack::clear() noexcept { if (mCommands.isEmpty()) return; if (mCommandActive) try {abortCommand();} catch (...) {} // delete all commands in the stack from top to bottom (newest first, oldest last)! while (!mCommands.isEmpty()) delete mCommands.takeLast(); mCurrentIndex = 0; mCleanIndex = 0; mCommandActive = false; // emit signals emit undoTextChanged(tr("Undo")); emit redoTextChanged(tr("Redo")); emit canUndoChanged(false); emit canRedoChanged(false); emit cleanChanged(true); }
void KUndo2QStack::beginMacro(const KUndo2MagicString &text) { KUndo2Command *cmd = new KUndo2Command(); cmd->setText(text); if (m_macro_stack.isEmpty()) { while (m_index < m_command_list.size()) delete m_command_list.takeLast(); if (m_clean_index > m_index) m_clean_index = -1; // we've deleted the clean state m_command_list.append(cmd); } else { m_macro_stack.last()->d->child_list.append(cmd); } m_macro_stack.append(cmd); if (m_macro_stack.count() == 1) { emit canUndoChanged(false); emit undoTextChanged(QString()); emit canRedoChanged(false); emit redoTextChanged(QString()); } }
void QtUndoStack::beginMacro(const QString &text) { QtUndoCommand *cmd = new QtUndoCommand(); cmd->setText(text); if (d_ptr->macro_stack.isEmpty()) { while (d_ptr->index < d_ptr->command_list.size()) delete d_ptr->command_list.takeLast(); if (d_ptr->clean_index > d_ptr->index) d_ptr->clean_index = -1; // we've deleted the clean state d_ptr->command_list.append(cmd); } else { d_ptr->macro_stack.last()->d_ptr->child_list.append(cmd); } d_ptr->macro_stack.append(cmd); if (d_ptr->macro_stack.count() == 1) { emit canUndoChanged(false); emit undoTextChanged(QString()); emit canRedoChanged(false); emit redoTextChanged(QString()); } }
void KUndo2QStack::clear() { if (m_command_list.isEmpty()) return; bool was_clean = isClean(); m_macro_stack.clear(); qDeleteAll(m_command_list); m_command_list.clear(); m_index = 0; m_clean_index = 0; emit indexChanged(0); emit canUndoChanged(false); emit undoTextChanged(QString()); emit canRedoChanged(false); emit redoTextChanged(QString()); if (!was_clean) emit cleanChanged(true); }
void disableActions() { canUndoChanged(false); canRedoChanged(false); }
bool KUndo2QStack::push(KUndo2Command *cmd) { cmd->redoMergedCommands(); cmd->setEndTime(); bool macro = !m_macro_stack.isEmpty(); KUndo2Command *cur = 0; if (macro) { KUndo2Command *macro_cmd = m_macro_stack.last(); if (!macro_cmd->d->child_list.isEmpty()) cur = macro_cmd->d->child_list.last(); } else { if (m_index > 0) cur = m_command_list.at(m_index - 1); while (m_index < m_command_list.size()) delete m_command_list.takeLast(); if (m_clean_index > m_index) m_clean_index = -1; // we've deleted the clean state } bool try_merge = cur != 0 && cur->id() != -1 && cur->id() == cmd->id() && (macro || m_index != m_clean_index); /*! *Here we are going to try to merge several commands together using the QVector field in the commands using *3 parameters. N : Number of commands that should remain individual at the top of the stack. T1 : Time lapsed between current command and previously merged command -- signal to *merge throughout the stack. T2 : Time lapsed between two commands signalling both commands belong to the same set *Whenever a KUndo2Command is initialized -- it consists of a start-time and when it is pushed --an end time. *Every time a command is pushed -- it checks whether the command pushed was pushed after T1 seconds of the last merged command *Then the merging begins with each group depending on the time in between each command (T2). * *@TODO : Currently it is not able to merge two merged commands together. */ if (!macro && m_command_list.size() > 1 && cmd->timedId() != -1 && m_useCumulativeUndoRedo) { KUndo2Command* lastcmd = m_command_list.last(); if (qAbs(cmd->time().msecsTo(lastcmd->endTime())) < m_timeT2 * 1000) { m_lastMergedSetCount++; } else { m_lastMergedSetCount = 0; m_lastMergedIndex = m_index-1; } if (lastcmd->timedId() == -1){ m_lastMergedSetCount = 0; m_lastMergedIndex = m_index; } if (m_lastMergedSetCount > m_strokesN) { KUndo2Command* toMerge = m_command_list.at(m_lastMergedIndex); if (toMerge && m_command_list.size() >= m_lastMergedIndex + 1 && m_command_list.at(m_lastMergedIndex + 1)) { if(toMerge->timedMergeWith(m_command_list.at(m_lastMergedIndex + 1))){ m_command_list.removeAt(m_lastMergedIndex + 1); } m_lastMergedSetCount--; m_lastMergedIndex = m_command_list.indexOf(toMerge); } } m_index = m_command_list.size(); if(m_lastMergedIndex<m_index){ if (cmd->time().msecsTo(m_command_list.at(m_lastMergedIndex)->endTime()) < -m_timeT1 * 1000) { //T1 time elapsed QListIterator<KUndo2Command*> it(m_command_list); it.toBack(); m_lastMergedSetCount = 1; while (it.hasPrevious()) { KUndo2Command* curr = it.previous(); KUndo2Command* lastCmdInCurrent = curr; if (!lastcmd->mergeCommandsVector().isEmpty()) { if (qAbs(lastcmd->mergeCommandsVector().last()->time().msecsTo(lastCmdInCurrent->endTime())) < int(m_timeT2 * 1000) && lastcmd != lastCmdInCurrent && lastcmd != curr) { if(lastcmd->timedMergeWith(curr)){ if (m_command_list.contains(curr)) { m_command_list.removeOne(curr); } } } else { lastcmd = curr; //end of a merge set } } else { if (qAbs(lastcmd->time().msecsTo(lastCmdInCurrent->endTime())) < int(m_timeT2 * 1000) && lastcmd != lastCmdInCurrent &&lastcmd!=curr) { if(lastcmd->timedMergeWith(curr)){ if (m_command_list.contains(curr)){ m_command_list.removeOne(curr); } } } else { lastcmd = curr; //end of a merge set } } } m_lastMergedIndex = m_command_list.size()-1; } } m_index = m_command_list.size(); } if (try_merge && cur->mergeWith(cmd)) { delete cmd; cmd = 0; if (!macro) { emit indexChanged(m_index); emit canUndoChanged(canUndo()); emit undoTextChanged(undoText()); emit canRedoChanged(canRedo()); emit redoTextChanged(redoText()); } } else { if (macro) { m_macro_stack.last()->d->child_list.append(cmd); } else { m_command_list.append(cmd); if(checkUndoLimit()) { m_lastMergedIndex = m_index - m_strokesN; } setIndex(m_index + 1, false); } } return cmd; }
void KisSketchView::documentChanged() { d->doc = DocumentManager::instance()->document(); if (!d->doc) return; connect(d->doc, SIGNAL(modified(bool)), SIGNAL(modifiedChanged())); KisSketchPart *part = DocumentManager::instance()->part(); Q_ASSERT(part); QPointer<KisView2> view = qobject_cast<KisView2*>(part->createView(d->doc, QApplication::activeWindow())); d->view = view; d->view->setShowFloatingMessage(false); connect(d->view, SIGNAL(floatingMessageRequested(QString,QString)), this, SIGNAL(floatingMessageRequested(QString,QString))); d->view->canvasControllerWidget()->setGeometry(x(), y(), width(), height()); d->view->hide(); d->canvas = d->view->canvasBase(); d->undoStack = d->doc->undoStack(); d->undoAction = d->view->actionCollection()->action("edit_undo"); connect(d->undoAction, SIGNAL(changed()), this, SIGNAL(canUndoChanged())); d->redoAction = d->view->actionCollection()->action("edit_redo"); connect(d->redoAction, SIGNAL(changed()), this, SIGNAL(canRedoChanged())); KoToolManager::instance()->switchToolRequested( "KritaShape/KisToolBrush" ); d->canvasWidget = d->canvas->canvasWidget(); connect(d->doc->image(), SIGNAL(sigImageUpdated(QRect)), SLOT(imageUpdated(QRect))); connect(d->view->canvasControllerWidget()->proxyObject, SIGNAL(moveDocumentOffset(QPoint)), SLOT(documentOffsetMoved())); connect(d->view->zoomController(), SIGNAL(zoomChanged(KoZoomMode::Mode,qreal)), SLOT(zoomChanged())); connect(d->canvas, SIGNAL(updateCanvasRequested(QRect)), SLOT(imageUpdated(QRect))); connect(d->doc->image()->signalRouter(), SIGNAL(sigRemoveNodeAsync(KisNodeSP)), SLOT(removeNodeAsync(KisNodeSP))); connect(d->doc->image()->signalRouter(), SIGNAL(sigSizeChanged(QPointF,QPointF)), SIGNAL(imageSizeChanged())); if(scene()) { SketchDeclarativeView *v = qobject_cast<SketchDeclarativeView*>(scene()->views().at(0)); if (v) { v->setCanvasWidget(d->canvasWidget); v->setDrawCanvas(true); } } d->imageUpdated(d->canvas->image()->bounds()); static_cast<KoZoomHandler*>(d->canvas->viewConverter())->setResolution(d->doc->image()->xRes(), d->doc->image()->yRes()); d->view->zoomController()->setZoomMode(KoZoomMode::ZOOM_PAGE); d->view->canvasControllerWidget()->setScrollBarValue(QPoint(0, 0)); d->view->canvasControllerWidget()->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); d->view->canvasControllerWidget()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); geometryChanged(QRectF(x(), y(), width(), height()), QRectF()); d->loadedTimer->start(100); d->view->actionCollection()->action("zoom_to_100pct")->trigger(); d->resetDocumentPosition(); emit viewChanged(); }