示例#1
0
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;
}
示例#2
0
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;
}
示例#4
0
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;
        }
    };
示例#6
0
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;
}
示例#7
0
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;
		}
	}
}