summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swift/Controllers/MainController.cpp11
-rw-r--r--Swiften/Elements/Presence.h4
2 files changed, 12 insertions, 3 deletions
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 29d67b5..946b7d0 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -157,128 +157,133 @@ void MainController::handleConnected() {
discoResponder_ = new DiscoInfoResponder(client_);
discoResponder_->setDiscoInfo(discoInfo);
discoResponder_->setDiscoInfo(capsInfo_->getNode() + "#" + capsInfo_->getVersion(), discoInfo);
serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>(new DiscoInfo());
}
boost::shared_ptr<GetDiscoInfoRequest> discoInfoRequest(new GetDiscoInfoRequest(JID(), client_));
discoInfoRequest->onResponse.connect(boost::bind(&MainController::handleServerDiscoInfoResponse, this, _1, _2));
discoInfoRequest->send();
boost::shared_ptr<GetVCardRequest> vCardRequest(new GetVCardRequest(JID(), client_));
vCardRequest->onResponse.connect(boost::bind(&MainController::handleOwnVCardReceived, this, _1, _2));
vCardRequest->send();
//Send presence last to catch all the incoming presences.
boost::shared_ptr<Presence> initialPresence;
if (queuedPresence_.get() != NULL) {
initialPresence = queuedPresence_;
} else {
initialPresence = boost::shared_ptr<Presence>(new Presence());
}
initialPresence->addPayload(capsInfo_);
setManagersEnabled(true);
sendPresence(initialPresence);
}
void MainController::handleEventQueueLengthChange(int count) {
application_->getApplicationMessageDisplay()->setMessage(count == 0 ? "" : boost::lexical_cast<std::string>(count).c_str());
}
void MainController::reconnectAfterError() {
performLoginFromCachedCredentials();
sendPresence(queuedPresence_);
}
void MainController::handleChangeStatusRequest(StatusShow::Type show, const String &statusText) {
boost::shared_ptr<Presence> presence(new Presence());
if (show == StatusShow::None) {
// FIXME: This is wrong. None doesn't mean unavailable
presence->setType(Presence::Unavailable);
}
else {
presence->setShow(show);
}
presence->setStatus(statusText);
if (presence->getType() != Presence::Unavailable && !client_->isAvailable()) {
performLoginFromCachedCredentials();
queuedPresence_ = presence;
- } else {
+ }
+ else {
sendPresence(presence);
}
}
void MainController::sendPresence(boost::shared_ptr<Presence> presence) {
+ // Copy presence before adding extra information
+ lastSentPresence_ = presence->clone();
+
+ // Add information and send
if (!vCardPhotoHash_.isEmpty()) {
presence->addPayload(boost::shared_ptr<VCardUpdate>(new VCardUpdate(vCardPhotoHash_)));
}
presence->addPayload(capsInfo_);
- lastSentPresence_ = presence;
presenceSender_->sendPresence(presence);
if (presence->getType() == Presence::Unavailable) {
logout();
}
}
void MainController::handleInputIdleChanged(bool idle) {
if (!client_ || !client_->isAvailable()) {
return;
}
if (idle) {
preIdlePresence_ = lastSentPresence_;
boost::shared_ptr<Presence> presence(new Presence());
presence->setShow(StatusShow::Away);
presence->setStatus("Auto-away");
sendPresence(presence);
}
else {
if (client_) {
sendPresence(preIdlePresence_);
- } else {
+ }
+ else {
queuedPresence_ = preIdlePresence_;
}
}
}
void MainController::handleIncomingPresence(boost::shared_ptr<Presence> presence) {
//FIXME: subscribe, subscribed
rosterController_->handleIncomingPresence(presence);
}
void MainController::handleLoginRequest(const String &username, const String &password, const String& certificateFile, bool remember) {
loginWindow_->setMessage("");
ProfileSettingsProvider* profileSettings = new ProfileSettingsProvider(username, settings_);
profileSettings->storeString("jid", username);
profileSettings->storeString("certificate", certificateFile);
profileSettings->storeString("pass", remember ? password : "");
settings_->storeString("lastLoginJID", username);
loginWindow_->addAvailableAccount(profileSettings->getStringSetting("jid"), profileSettings->getStringSetting("pass"), profileSettings->getStringSetting("certificate"));
delete profileSettings;
jid_ = JID(username);
password_ = password;
certificateFile_ = certificateFile;
performLoginFromCachedCredentials();
}
void MainController::performLoginFromCachedCredentials() {
if (!client_) {
client_ = new Swift::Client(jid_, password_);
presenceSender_ = new PresenceSender(client_);
client_->onDataRead.connect(boost::bind(
&XMLConsoleController::handleDataRead, xmlConsoleController_, _1));
client_->onDataWritten.connect(boost::bind(
&XMLConsoleController::handleDataWritten, xmlConsoleController_, _1));
if (!certificateFile_.isEmpty()) {
client_->setCertificate(certificateFile_);
}
client_->onError.connect(boost::bind(&MainController::handleError, this, _1));
client_->onConnected.connect(boost::bind(&MainController::handleConnected, this));
}
client_->connect();
}
void MainController::handleError(const ClientError& error) {
String message;
switch(error.getType()) {
case ClientError::UnknownError: message = "Unknown Error"; break;
case ClientError::DomainNameResolveError: message = "Unable to find server"; break;
case ClientError::ConnectionError: message = "Error connecting to server"; break;
diff --git a/Swiften/Elements/Presence.h b/Swiften/Elements/Presence.h
index a1f15fa..f748e44 100644
--- a/Swiften/Elements/Presence.h
+++ b/Swiften/Elements/Presence.h
@@ -7,52 +7,56 @@
namespace Swift {
class Presence : public Stanza
{
public:
enum Type { Available, Error, Probe, Subscribe, Subscribed, Unavailable, Unsubscribe, Unsubscribed };
Presence() : type_(Available) /*, showType_(Online)*/ {}
Presence(const String& status) : type_(Available) {
setStatus(status);
}
Type getType() const { return type_; }
void setType(Type type) { type_ = type; }
StatusShow::Type getShow() const {
boost::shared_ptr<StatusShow> show(getPayload<StatusShow>());
if (show) {
return show->getType();
}
return type_ == Available ? StatusShow::Online : StatusShow::None;
}
void setShow(const StatusShow::Type &show) {
updatePayload(boost::shared_ptr<StatusShow>(new StatusShow(show)));
}
String getStatus() const {
boost::shared_ptr<Status> status(getPayload<Status>());
if (status) {
return status->getText();
}
return "";
}
void setStatus(const String& status) {
updatePayload(boost::shared_ptr<Status>(new Status(status)));
}
int getPriority() const {
boost::shared_ptr<Priority> priority(getPayload<Priority>());
return (priority ? priority->getPriority() : 0);
}
void setPriority(int priority) {
updatePayload(boost::shared_ptr<Priority>(new Priority(priority)));
}
+ boost::shared_ptr<Presence> clone() const {
+ return boost::shared_ptr<Presence>(new Presence(*this));
+ }
+
private:
Presence::Type type_;
};
}