summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/Controllers/MainController.cpp')
-rw-r--r--Swift/Controllers/MainController.cpp186
1 files changed, 135 insertions, 51 deletions
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 9a35cc1..364dd57 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2011 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
@@ -14,14 +14,13 @@
#include <stdlib.h>
#include <Swiften/Base/format.h>
+#include <Swiften/Base/Algorithm.h>
#include <Swift/Controllers/Intl.h>
#include <Swift/Controllers/UIInterfaces/UIFactory.h>
#include "Swiften/Network/TimerFactory.h"
#include "Swift/Controllers/BuildVersion.h"
-#include "Swift/Controllers/StoragesFactory.h"
#include "Swiften/Client/Storages.h"
#include "Swiften/VCards/VCardManager.h"
-#include "Swift/Controllers/Chat/MUCSearchController.h"
#include "Swift/Controllers/Chat/UserSearchController.h"
#include "Swift/Controllers/Chat/ChatsManager.h"
#include "Swift/Controllers/XMPPEvents/EventController.h"
@@ -38,9 +37,11 @@
#include "Swift/Controllers/SystemTray.h"
#include "Swift/Controllers/SystemTrayController.h"
#include "Swift/Controllers/XMLConsoleController.h"
+#include "Swift/Controllers/FileTransferListController.h"
#include "Swift/Controllers/UIEvents/UIEventStream.h"
#include "Swift/Controllers/PresenceNotifier.h"
#include "Swift/Controllers/EventNotifier.h"
+#include "Swift/Controllers/Storages/StoragesFactory.h"
#include "SwifTools/Dock/Dock.h"
#include "SwifTools/Notifier/TogglableNotifier.h"
#include "Swiften/Base/foreach.h"
@@ -60,11 +61,17 @@
#include "Swift/Controllers/UIEvents/RequestChatUIEvent.h"
#include "Swift/Controllers/UIEvents/ToggleNotificationsUIEvent.h"
#include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h"
-#include "Swift/Controllers/CertificateStorageFactory.h"
-#include "Swift/Controllers/CertificateStorageTrustChecker.h"
+#include "Swift/Controllers/Storages/CertificateStorageFactory.h"
+#include "Swift/Controllers/Storages/CertificateStorageTrustChecker.h"
#include "Swiften/Network/NetworkFactories.h"
#include <Swift/Controllers/ProfileController.h>
#include <Swift/Controllers/ContactEditController.h>
+#include <Swift/Controllers/XMPPURIController.h>
+#include "Swift/Controllers/AdHocManager.h"
+#include <SwifTools/Idle/IdleDetector.h>
+#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
+#include <Swiften/FileTransfer/FileTransferManager.h>
+#include <Swiften/Client/ClientXMLTracer.h>
namespace Swift {
@@ -84,16 +91,22 @@ MainController::MainController(
CertificateStorageFactory* certificateStorageFactory,
Dock* dock,
Notifier* notifier,
- bool useDelayForLatency) :
+ URIHandler* uriHandler,
+ IdleDetector* idleDetector,
+ bool useDelayForLatency,
+ bool eagleMode) :
eventLoop_(eventLoop),
networkFactories_(networkFactories),
uiFactory_(uiFactories),
- idleDetector_(&idleQuerier_, networkFactories_->getTimerFactory(), 100),
storagesFactory_(storagesFactory),
certificateStorageFactory_(certificateStorageFactory),
settings_(settings),
+ uriHandler_(uriHandler),
+ idleDetector_(idleDetector),
loginWindow_(NULL) ,
- useDelayForLatency_(useDelayForLatency) {
+ useDelayForLatency_(useDelayForLatency),
+ eagleMode_(eagleMode),
+ ftOverview_(NULL) {
storages_ = NULL;
certificateStorage_ = NULL;
statusTracker_ = NULL;
@@ -121,33 +134,43 @@ MainController::MainController(
loginWindow_ = uiFactory_->createLoginWindow(uiEventStream_);
soundEventController_ = new SoundEventController(eventController_, soundPlayer, settings, uiEventStream_);
+ xmppURIController_ = new XMPPURIController(uriHandler_, uiEventStream_);
+
std::string selectedLoginJID = settings_->getStringSetting("lastLoginJID");
bool loginAutomatically = settings_->getBoolSetting("loginAutomatically", false);
std::string cachedPassword;
std::string cachedCertificate;
- foreach (std::string profile, settings->getAvailableProfiles()) {
- ProfileSettingsProvider profileSettings(profile, settings);
- std::string password = profileSettings.getStringSetting("pass");
- std::string certificate = profileSettings.getStringSetting("certificate");
- std::string jid = profileSettings.getStringSetting("jid");
- loginWindow_->addAvailableAccount(jid, password, certificate);
- if (jid == selectedLoginJID) {
- cachedPassword = password;
- cachedCertificate = certificate;
+ if (!eagleMode_) {
+ foreach (std::string profile, settings->getAvailableProfiles()) {
+ ProfileSettingsProvider profileSettings(profile, settings);
+ std::string password = eagleMode ? "" : profileSettings.getStringSetting("pass");
+ std::string certificate = profileSettings.getStringSetting("certificate");
+ std::string jid = profileSettings.getStringSetting("jid");
+ loginWindow_->addAvailableAccount(jid, password, certificate);
+ if (jid == selectedLoginJID) {
+ cachedPassword = password;
+ cachedCertificate = certificate;
+ }
}
+ loginWindow_->selectUser(selectedLoginJID);
+ loginWindow_->setLoginAutomatically(loginAutomatically);
+ } else {
+ loginWindow_->setRememberingAllowed(false);
}
- loginWindow_->selectUser(selectedLoginJID);
- loginWindow_->setLoginAutomatically(loginAutomatically);
+
+
loginWindow_->onLoginRequest.connect(boost::bind(&MainController::handleLoginRequest, this, _1, _2, _3, _4, _5));
loginWindow_->onPurgeSavedLoginRequest.connect(boost::bind(&MainController::handlePurgeSavedLoginRequest, this, _1));
loginWindow_->onCancelLoginRequest.connect(boost::bind(&MainController::handleCancelLoginRequest, this));
loginWindow_->onQuitRequest.connect(boost::bind(&MainController::handleQuitRequest, this));
- idleDetector_.setIdleTimeSeconds(600);
- idleDetector_.onIdleChanged.connect(boost::bind(&MainController::handleInputIdleChanged, this, _1));
+ idleDetector_->setIdleTimeSeconds(600);
+ idleDetector_->onIdleChanged.connect(boost::bind(&MainController::handleInputIdleChanged, this, _1));
xmlConsoleController_ = new XMLConsoleController(uiEventStream_, uiFactory_);
+ fileTransferListController_ = new FileTransferListController(uiEventStream_, uiFactory_);
+
uiEventStream_->onUIEvent.connect(boost::bind(&MainController::handleUIEvent, this, _1));
bool enabled = settings_->getBoolSetting(SHOW_NOTIFICATIONS, true);
uiEventStream_->send(boost::shared_ptr<ToggleNotificationsUIEvent>(new ToggleNotificationsUIEvent(enabled)));
@@ -161,12 +184,16 @@ MainController::MainController(
}
MainController::~MainController() {
+ idleDetector_->onIdleChanged.disconnect(boost::bind(&MainController::handleInputIdleChanged, this, _1));
+
+ purgeCachedCredentials();
//setManagersOffline();
eventController_->disconnectAll();
resetClient();
-
+ delete fileTransferListController_;
delete xmlConsoleController_;
+ delete xmppURIController_;
delete soundEventController_;
delete systemTrayController_;
delete eventController_;
@@ -174,7 +201,12 @@ MainController::~MainController() {
delete uiEventStream_;
}
+void MainController::purgeCachedCredentials() {
+ safeClear(password_);
+}
+
void MainController::resetClient() {
+ purgeCachedCredentials();
resetCurrentError();
resetPendingReconnects();
vCardPhotoHash_.clear();
@@ -186,6 +218,8 @@ void MainController::resetClient() {
eventWindowController_ = NULL;
delete chatsManager_;
chatsManager_ = NULL;
+ delete ftOverview_;
+ ftOverview_ = NULL;
delete rosterController_;
rosterController_ = NULL;
delete eventNotifier_;
@@ -234,20 +268,30 @@ void MainController::resetCurrentError() {
void MainController::handleConnected() {
boundJID_ = client_->getJID();
- loginWindow_->setIsLoggingIn(false);
resetCurrentError();
resetPendingReconnects();
+
+ if (eagleMode_) {
+ purgeCachedCredentials();
+ }
+
bool freshLogin = rosterController_ == NULL;
myStatusLooksOnline_ = true;
if (freshLogin) {
profileController_ = new ProfileController(client_->getVCardManager(), uiFactory_, uiEventStream_);
- rosterController_ = new RosterController(jid_, client_->getRoster(), client_->getAvatarManager(), uiFactory_, client_->getNickManager(), client_->getNickResolver(), client_->getPresenceOracle(), client_->getSubscriptionManager(), eventController_, uiEventStream_, client_->getIQRouter(), settings_);
+ srand(time(NULL));
+ int randomPort = 10000 + rand() % 10000;
+ client_->getFileTransferManager()->startListeningOnPort(randomPort);
+ ftOverview_ = new FileTransferOverview(client_->getFileTransferManager());
+ fileTransferListController_->setFileTransferOverview(ftOverview_);
+ rosterController_ = new RosterController(jid_, client_->getRoster(), client_->getAvatarManager(), uiFactory_, client_->getNickManager(), client_->getNickResolver(), client_->getPresenceOracle(), client_->getSubscriptionManager(), eventController_, uiEventStream_, client_->getIQRouter(), settings_, client_->getEntityCapsProvider(), ftOverview_);
rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2));
rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this));
contactEditController_ = new ContactEditController(rosterController_, uiFactory_, uiEventStream_);
- chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, settings_);
+ chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_, ftOverview_);
+
client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1));
chatsManager_->setAvatarManager(client_->getAvatarManager());
@@ -259,17 +303,25 @@ void MainController::handleConnected() {
discoInfo.addIdentity(DiscoInfo::Identity(CLIENT_NAME, "client", "pc"));
discoInfo.addFeature(DiscoInfo::ChatStatesFeature);
discoInfo.addFeature(DiscoInfo::SecurityLabelsFeature);
+ discoInfo.addFeature(DiscoInfo::MessageCorrectionFeature);
+#ifdef SWIFT_EXPERIMENTAL_FT
+ discoInfo.addFeature(DiscoInfo::JingleFeature);
+ discoInfo.addFeature(DiscoInfo::JingleFTFeature);
+ discoInfo.addFeature(DiscoInfo::JingleTransportsIBBFeature);
+ discoInfo.addFeature(DiscoInfo::JingleTransportsS5BFeature);
+#endif
client_->getDiscoManager()->setCapsNode(CLIENT_NODE);
client_->getDiscoManager()->setDiscoInfo(discoInfo);
-
userSearchControllerChat_ = new UserSearchController(UserSearchController::StartChat, jid_, uiEventStream_, uiFactory_, client_->getIQRouter(), rosterController_);
userSearchControllerAdd_ = new UserSearchController(UserSearchController::AddContact, jid_, uiEventStream_, uiFactory_, client_->getIQRouter(), rosterController_);
+ adHocManager_ = new AdHocManager(boundJID_, uiFactory_, client_->getIQRouter(), uiEventStream_, rosterController_->getWindow());
}
-
+ loginWindow_->setIsLoggingIn(false);
+
client_->requestRoster();
- GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(JID(), client_->getIQRouter());
+ GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(boundJID_.toBare(), client_->getIQRouter());
discoInfoRequest->onResponse.connect(boost::bind(&MainController::handleServerDiscoInfoResponse, this, _1, _2));
discoInfoRequest->send();
@@ -356,19 +408,27 @@ void MainController::handleInputIdleChanged(bool idle) {
}
void MainController::handleLoginRequest(const std::string &username, const std::string &password, const std::string& certificateFile, bool remember, bool loginAutomatically) {
- loginWindow_->setMessage("");
- loginWindow_->setIsLoggingIn(true);
- profileSettings_ = new ProfileSettingsProvider(username, settings_);
- profileSettings_->storeString("jid", username);
- profileSettings_->storeString("certificate", certificateFile);
- profileSettings_->storeString("pass", (remember || loginAutomatically) ? password : "");
- settings_->storeString("lastLoginJID", username);
- settings_->storeBool("loginAutomatically", loginAutomatically);
- loginWindow_->addAvailableAccount(profileSettings_->getStringSetting("jid"), profileSettings_->getStringSetting("pass"), profileSettings_->getStringSetting("certificate"));
jid_ = JID(username);
- password_ = password;
- certificateFile_ = certificateFile;
- performLoginFromCachedCredentials();
+ if (!jid_.isValid() || jid_.getNode().empty()) {
+ loginWindow_->setMessage(QT_TRANSLATE_NOOP("", "User address invalid. User address should be of the form 'alice@wonderland.lit'"));
+ loginWindow_->setIsLoggingIn(false);
+ } else {
+ loginWindow_->setMessage("");
+ loginWindow_->setIsLoggingIn(true);
+ profileSettings_ = new ProfileSettingsProvider(username, settings_);
+ if (!eagleMode_) {
+ profileSettings_->storeString("jid", username);
+ profileSettings_->storeString("certificate", certificateFile);
+ profileSettings_->storeString("pass", (remember || loginAutomatically) ? password : "");
+ settings_->storeString("lastLoginJID", username);
+ settings_->storeBool("loginAutomatically", loginAutomatically);
+ loginWindow_->addAvailableAccount(profileSettings_->getStringSetting("jid"), profileSettings_->getStringSetting("pass"), profileSettings_->getStringSetting("certificate"));
+ }
+
+ password_ = password;
+ certificateFile_ = certificateFile;
+ performLoginFromCachedCredentials();
+ }
}
void MainController::handlePurgeSavedLoginRequest(const std::string& username) {
@@ -377,6 +437,10 @@ void MainController::handlePurgeSavedLoginRequest(const std::string& username) {
}
void MainController::performLoginFromCachedCredentials() {
+ if (eagleMode_ && password_.empty()) {
+ /* Then we can't try to login again. */
+ return;
+ }
/* If we logged in with a bare JID, and we have a full bound JID, re-login with the
* bound JID to try and keep dynamically assigned resources */
JID clientJID = jid_;
@@ -392,7 +456,7 @@ void MainController::performLoginFromCachedCredentials() {
certificateStorage_ = certificateStorageFactory_->createCertificateStorage(jid_.toBare());
certificateTrustChecker_ = new CertificateStorageTrustChecker(certificateStorage_);
- client_ = boost::make_shared<Swift::Client>(clientJID, password_, networkFactories_, storages_);
+ client_ = boost::make_shared<Swift::Client>(clientJID, createSafeByteArray(password_.c_str()), networkFactories_, storages_);
clientInitialized_ = true;
client_->setCertificateTrustChecker(certificateTrustChecker_);
client_->onDataRead.connect(boost::bind(&XMLConsoleController::handleDataRead, xmlConsoleController_, _1));
@@ -422,11 +486,16 @@ void MainController::performLoginFromCachedCredentials() {
if (rosterController_) {
rosterController_->getWindow()->setConnecting();
}
-
- client_->connect();
+ ClientOptions clientOptions;
+ clientOptions.forgetPassword = eagleMode_;
+ clientOptions.useTLS = eagleMode_ ? ClientOptions::RequireTLS : ClientOptions::UseTLSWhenAvailable;
+ client_->connect(clientOptions);
}
void MainController::handleDisconnected(const boost::optional<ClientError>& error) {
+ if (eagleMode_) {
+ purgeCachedCredentials();
+ }
if (quitRequested_) {
resetClient();
loginWindow_->quit();
@@ -483,19 +552,27 @@ void MainController::handleDisconnected(const boost::optional<ClientError>& erro
else if (!rosterController_) { //hasn't been logged in yet
signOut();
loginWindow_->setMessage(message);
+ loginWindow_->setIsLoggingIn(false);
} else {
logout();
- setReconnectTimer();
- if (lastDisconnectError_) {
- message = str(format(QT_TRANSLATE_NOOP("", "Reconnect to %1% failed: %2%. Will retry in %3% seconds.")) % jid_.getDomain() % message % boost::lexical_cast<std::string>(timeBeforeNextReconnect_));
- lastDisconnectError_->conclude();
+ if (eagleMode_) {
+ message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%. To reconnect, Sign Out and provide your password again.")) % jid_.getDomain() % message);
} else {
- message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%.")) % jid_.getDomain() % message);
+ setReconnectTimer();
+ if (lastDisconnectError_) {
+ message = str(format(QT_TRANSLATE_NOOP("", "Reconnect to %1% failed: %2%. Will retry in %3% seconds.")) % jid_.getDomain() % message % boost::lexical_cast<std::string>(timeBeforeNextReconnect_));
+ lastDisconnectError_->conclude();
+ } else {
+ message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%.")) % jid_.getDomain() % message);
+ }
+ lastDisconnectError_ = boost::shared_ptr<ErrorEvent>(new ErrorEvent(JID(jid_.getDomain()), message));
+ eventController_->handleIncomingEvent(lastDisconnectError_);
}
- lastDisconnectError_ = boost::shared_ptr<ErrorEvent>(new ErrorEvent(JID(jid_.getDomain()), message));
- eventController_->handleIncomingEvent(lastDisconnectError_);
}
}
+ else if (!rosterController_) { //hasn't been logged in yet
+ loginWindow_->setIsLoggingIn(false);
+ }
}
void MainController::setReconnectTimer() {
@@ -517,6 +594,9 @@ void MainController::handleCancelLoginRequest() {
}
void MainController::signOut() {
+ if (eagleMode_) {
+ purgeCachedCredentials();
+ }
eventController_->clear();
logout();
loginWindow_->loggedOut();
@@ -524,6 +604,9 @@ void MainController::signOut() {
}
void MainController::logout() {
+ if (eagleMode_) {
+ purgeCachedCredentials();
+ }
systemTrayController_->setMyStatusType(StatusShow::None);
if (clientInitialized_ /*&& client_->isAvailable()*/) {
client_->disconnect();
@@ -554,11 +637,12 @@ void MainController::setManagersOffline() {
void MainController::handleServerDiscoInfoResponse(boost::shared_ptr<DiscoInfo> info, ErrorPayload::ref error) {
if (!error) {
chatsManager_->setServerDiscoInfo(info);
+ adHocManager_->setServerDiscoInfo(info);
}
}
void MainController::handleVCardReceived(const JID& jid, VCard::ref vCard) {
- if (!jid.equals(jid_, JID::WithoutResource) || !vCard || vCard->getPhoto().isEmpty()) {
+ if (!jid.equals(jid_, JID::WithoutResource) || !vCard || vCard->getPhoto().empty()) {
return;
}
std::string hash = Hexify::hexify(SHA1::getHash(vCard->getPhoto()));