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; }
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; }
bool UndoTransaction::commit() { if (!m_data) return false; TransactionData* data = static_cast<TransactionData*>(m_data.data()); UndoManager* UM = data->UM; int stackLevel = data->stackLevel; if (!UM->undoEnabled_) { cancel(); return false; } UndoObject *tmpu = UM->transactions_.at(stackLevel)->transactionObject; TransactionState *tmps = UM->transactions_.at(stackLevel)->transactionState; switch (m_data->m_status) { case Transaction::STATE_OPEN: // qDebug() << "UndoManager::commitTransaction" << data << data->transactionObject->getUName() << data->transactionState->getName() << stackLevel; m_data->m_status = Transaction::STATE_COMMITTED; // brutal for now: assert (stackLevel + 1 == signed(UM->transactions_.size())); if (stackLevel < signed(UM->transactions_.size())) { UM->transactions_.erase(UM->transactions_.begin() + stackLevel); } if (tmps->sizet() > 0) // are there any actions inside the committed transaction { if (tmps->getName().isEmpty()) tmps->useActionName(); UM->action(tmpu, tmps); } // if not just delete objects else { delete tmpu; tmpu = 0; delete tmps; tmps = 0; } return true; break; case STATE_WILLFAIL: return cancel(); break; default: // qDebug() << "UndoManager::commitTransaction ** already closed **"; // nothing break; } return false; }
void Client::onAnnounceState(void* sender, TransactionState& state, const TransactionState&) { TraceL << "On announce response: " << state << endl; auto transaction = reinterpret_cast<sockio::Transaction*>(sender); switch (state.id()) { case TransactionState::Success: try { json::Value data = transaction->response().json(); //[(unsigned)0]; _announceStatus = data["status"].asInt(); if (_announceStatus != 200) throw std::runtime_error(data["message"].asString()); _ourID = data["data"]["id"].asString(); //Address(); if (_ourID.empty()) throw std::runtime_error("Invalid announce response."); // Set our local peer data from the response or fail. onPresenceData(data["data"], true); // Notify the outside application of the response // status before we transition the client state. Announce.emit(this, _announceStatus); // Transition to Online state. onOnline(); // setState(this, sockio::ClientState::Online); // Broadcast a presence probe to our network. sendPresence(true); } catch (std::exception& exc) { // Set the error message and close the connection. setError("Announce failed: " + std::string(exc.what())); } break; case TransactionState::Failed: Announce.emit(this, _announceStatus); setError(state.message()); break; } }
void onTransactionStateChanged(void* sender, TransactionState& state, const TransactionState&) { Log("debug", this) << "Transaction State Changed: " << state.toString() << endl; SocketIO::Transaction* transaction = reinterpret_cast<SocketIO::Transaction*>(sender); switch (state.id()) { case TransactionState::Running: break; case TransactionState::Success: break; case TransactionState::Cancelled: break; case TransactionState::Failed: break; } };
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; } else if((*it)->isTransaction()) { TransactionState *ts = dynamic_cast<TransactionState*>(*it); if(ts->containsOnly(objectId)) { tmpRedoState = *it; redoActions_.erase(it); break; } } } } undoActions_.insert(undoActions_.begin(), tmpRedoState); // push to the undo actions tmpRedoState->redo(); } 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; } } }