diff options
Diffstat (limited to 'Swiften/AdHoc')
-rw-r--r-- | Swiften/AdHoc/OutgoingAdHocCommandSession.cpp | 95 | ||||
-rw-r--r-- | Swiften/AdHoc/OutgoingAdHocCommandSession.h | 95 | ||||
-rw-r--r-- | Swiften/AdHoc/SConscript | 6 |
3 files changed, 196 insertions, 0 deletions
diff --git a/Swiften/AdHoc/OutgoingAdHocCommandSession.cpp b/Swiften/AdHoc/OutgoingAdHocCommandSession.cpp new file mode 100644 index 0000000..ecc6cd0 --- /dev/null +++ b/Swiften/AdHoc/OutgoingAdHocCommandSession.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2010-2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/AdHoc/OutgoingAdHocCommandSession.h> + +#include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp> + +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/Base/Algorithm.h> + +namespace Swift { +OutgoingAdHocCommandSession::OutgoingAdHocCommandSession(const JID& to, const std::string& commandNode, IQRouter* iqRouter) : to_(to), commandNode_(commandNode), iqRouter_(iqRouter), isMultiStage_(false) { + +} + +void OutgoingAdHocCommandSession::handleResponse(boost::shared_ptr<Command> payload, ErrorPayload::ref error) { + if (error) { + onError(error); + } else { + const std::vector<Command::Action>& actions = payload->getAvailableActions(); + actionStates_.clear(); + if (payload->getStatus() == Command::Executing ) { + actionStates_[Command::Cancel] = EnabledAndPresent; + actionStates_[Command::Complete] = Present; + if (std::find(actions.begin(), actions.end(), Command::Complete) != actions.end()) { + actionStates_[Command::Complete] = EnabledAndPresent; + } + + if (getIsMultiStage()) { + actionStates_[Command::Next] = Present; + actionStates_[Command::Prev] = Present; + } + + if (std::find(actions.begin(), actions.end(), Command::Next) != actions.end()) { + actionStates_[Command::Next] = EnabledAndPresent; + } + if (std::find(actions.begin(), actions.end(), Command::Prev) != actions.end()) { + actionStates_[Command::Prev] = EnabledAndPresent; + } + } + + sessionID_ = payload->getSessionID(); + if (std::find(actions.begin(), actions.end(), Command::Next) != actions.end() + || std::find(actions.begin(), actions.end(), Command::Prev) != actions.end()) { + isMultiStage_ = true; + } + onNextStageReceived(payload); + } +} + +bool OutgoingAdHocCommandSession::getIsMultiStage() const { + return isMultiStage_; +} + +void OutgoingAdHocCommandSession::start() { + boost::shared_ptr<GenericRequest<Command> > commandRequest = boost::make_shared< GenericRequest<Command> >(IQ::Set, to_, boost::make_shared<Command>(commandNode_), iqRouter_); + commandRequest->onResponse.connect(boost::bind(&OutgoingAdHocCommandSession::handleResponse, this, _1, _2)); + commandRequest->send(); +} + +void OutgoingAdHocCommandSession::cancel() { + if (!sessionID_.empty()) { + submitForm(Form::ref(), Command::Cancel); + } +} + +void OutgoingAdHocCommandSession::goBack() { + submitForm(Form::ref(), Command::Prev); +} + +void OutgoingAdHocCommandSession::complete(Form::ref form) { + submitForm(form, Command::Complete); +} + +void OutgoingAdHocCommandSession::goNext(Form::ref form) { + submitForm(form, Command::Next); +} + +void OutgoingAdHocCommandSession::submitForm(Form::ref form, Command::Action action) { + boost::shared_ptr<Command> command(boost::make_shared<Command>(commandNode_, sessionID_, action)); + command->setForm(form); + boost::shared_ptr<GenericRequest<Command> > commandRequest = boost::make_shared< GenericRequest<Command> >(IQ::Set, to_, command, iqRouter_); + commandRequest->onResponse.connect(boost::bind(&OutgoingAdHocCommandSession::handleResponse, this, _1, _2)); + commandRequest->send(); +} + +OutgoingAdHocCommandSession::ActionState OutgoingAdHocCommandSession::getActionState(Command::Action action) const { + return get(actionStates_, action, Absent); +} + +} diff --git a/Swiften/AdHoc/OutgoingAdHocCommandSession.h b/Swiften/AdHoc/OutgoingAdHocCommandSession.h new file mode 100644 index 0000000..a64eb4e --- /dev/null +++ b/Swiften/AdHoc/OutgoingAdHocCommandSession.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2010-2011 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> +#include <string> +#include <map> + +#include <Swiften/JID/JID.h> +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Elements/Command.h> +#include <Swiften/Elements/ErrorPayload.h> + +namespace Swift { + class IQRouter; + class MainWindow; + class UIEventStream; + + class OutgoingAdHocCommandSession { + public: + + /** + * Availability of action. + */ + enum ActionState { + Absent /** Action isn't applicable to this command. */ = 0, + Present /** Action is applicable to this command */= 1, + Enabled /** Action is applicable and currently available */ = 2, + EnabledAndPresent = 3}; + + OutgoingAdHocCommandSession(const JID& to, const std::string& commandNode, IQRouter* iqRouter); + /** + * Send initial request to the target. + */ + void start(); + /** + * Cancel command session with the target. + */ + void cancel(); + /** + * Return to the previous stage. + */ + void goBack(); + /** + * Send the form to complete the command. + * \param form Form for submission - if missing the command will be submitted with no form. + */ + void complete(Form::ref form); + /** + * Send the form to advance to the next stage of the command. + * \param form Form for submission - if missing the command will be submitted with no form. + */ + void goNext(Form::ref form); + + /** + * Is the form multi-stage? + */ + bool getIsMultiStage() const; + + /** + * Emitted when the form for the next stage is available. + */ + boost::signal<void (Command::ref)> onNextStageReceived; + + /** + * Emitted on error. + */ + boost::signal<void (ErrorPayload::ref)> onError; + + /** + * Get the state of a given action. + * This is useful for a UI to determine which buttons should be visible, + * and which enabled. + * Use for Next, Prev, Cancel and Complete only. + * If no actions are available, the command has completed. + */ + ActionState getActionState(Command::Action action) const; + + private: + void handleResponse(boost::shared_ptr<Command> payload, ErrorPayload::ref error); + void submitForm(Form::ref, Command::Action action); + + private: + JID to_; + std::string commandNode_; + IQRouter* iqRouter_; + bool isMultiStage_; + std::string sessionID_; + std::map<Command::Action, ActionState> actionStates_; + }; +} diff --git a/Swiften/AdHoc/SConscript b/Swiften/AdHoc/SConscript new file mode 100644 index 0000000..69c9083 --- /dev/null +++ b/Swiften/AdHoc/SConscript @@ -0,0 +1,6 @@ +Import("swiften_env") + +objects = swiften_env.SwiftenObject([ + "OutgoingAdHocCommandSession.cpp", + ]) +swiften_env.Append(SWIFTEN_OBJECTS = [objects]) |