diff options
author | Thanos Doukoudakis <thanos.doukoudakis@isode.com> | 2018-07-12 22:58:02 (GMT) |
---|---|---|
committer | Kevin Smith <kevin.smith@isode.com> | 2018-07-18 17:11:33 (GMT) |
commit | 0d5cd98d372c6b9235b55cd8d16e93647c9d017f (patch) | |
tree | 9f8ade0f540e35c49e1dd390bc3efe56de0b6b25 /Swift/QtUI | |
parent | 0d3c4298f0818cb377fcfc8409e89fe6327ab036 (diff) | |
download | swift-0d5cd98d372c6b9235b55cd8d16e93647c9d017f.zip swift-0d5cd98d372c6b9235b55cd8d16e93647c9d017f.tar.bz2 |
Add support for multiple accounts
Added support for multiple accounts and a list of servers where the
user can switch between the accounts. Future patches will make the list
widget to use server avatars with user status.
Upon startup the client will reconnect with all previous accounts. If
the user log outs with any of the accounts then it will not login
automatically for future sessions, the credential though will be
available to the user. Upon upgrading from previous versions, the client
will migrate the account that was previously marked to auto-login to the
new configuration and enable it. After the migration the autologin
setting will be set to false.
Some of the settings and command line arguments have been made obsolete
due to these changes and removed, including SSO support, which will be
re-introduced in a future patch.
Test-Information:
Tested the changes in Windows and Linux, tested adding and removing
accounts, and switching between them. Tested the new configuration for
accounts, the upgrade behaviour when an account is marked/not marked to
autojoin, and the migration to the new configuration. Verified that the
auto-login setting is set to false after the migration, and that the
migrated account can be disabled (currently only by signing out).
Change-Id: I63662f80e006112fde6f418f9743e2b420e81870
Diffstat (limited to 'Swift/QtUI')
-rw-r--r-- | Swift/QtUI/QtLoginWindow.h | 4 | ||||
-rw-r--r-- | Swift/QtUI/QtSingleWindow.cpp | 71 | ||||
-rw-r--r-- | Swift/QtUI/QtSingleWindow.h | 16 | ||||
-rw-r--r-- | Swift/QtUI/QtSwift.cpp | 190 | ||||
-rw-r--r-- | Swift/QtUI/QtSwift.h | 14 | ||||
-rw-r--r-- | Swift/QtUI/QtUIFactory.cpp | 13 | ||||
-rw-r--r-- | Swift/QtUI/QtUIFactory.h | 4 |
7 files changed, 235 insertions, 77 deletions
diff --git a/Swift/QtUI/QtLoginWindow.h b/Swift/QtUI/QtLoginWindow.h index 6920903..d3c2601 100644 --- a/Swift/QtUI/QtLoginWindow.h +++ b/Swift/QtUI/QtLoginWindow.h @@ -59,8 +59,10 @@ namespace Swift { signals: void geometryChanged(); - private slots: + public slots: void loginClicked(); + + private slots: void handleCertficateChecked(bool); void handleQuit(); void handleShowXMLConsole(); diff --git a/Swift/QtUI/QtSingleWindow.cpp b/Swift/QtUI/QtSingleWindow.cpp index d53f247..6881c4f 100644 --- a/Swift/QtUI/QtSingleWindow.cpp +++ b/Swift/QtUI/QtSingleWindow.cpp @@ -6,9 +6,13 @@ #include <Swift/QtUI/QtSingleWindow.h> +#include <QPushButton> +#include <QVBoxLayout> + #include <Swiften/Base/Platform.h> #include <Swift/QtUI/QtChatTabs.h> +#include <Swift/QtUI/QtLoginWindow.h> #include <Swift/QtUI/QtSettingsProvider.h> namespace Swift { @@ -24,6 +28,25 @@ QtSingleWindow::QtSingleWindow(QtSettingsProvider* settings) : QSplitter() { } connect(this, SIGNAL(splitterMoved(int, int)), this, SLOT(handleSplitterMoved(/*int, int*/))); setChildrenCollapsible(false); + + auto left = new QWidget(this); + list_ = new QListWidget(left); + auto addButton = new QPushButton("+", left); + QVBoxLayout* leftLayout = new QVBoxLayout(); + leftLayout->addWidget(list_); + leftLayout->addWidget(addButton); + left->setLayout(leftLayout); + QSplitter::addWidget(left); + loginWindows_ = new QStackedWidget(this); + QSplitter::addWidget(loginWindows_); + tabs_ = new QStackedWidget(this); + QSplitter::addWidget(tabs_); + restoreSplitters(); + setStretchFactor(0, 0); + setStretchFactor(1, 0); + setStretchFactor(2, 1); + connect(list_, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(handleListItemClicked(QListWidgetItem*))); + connect(addButton, SIGNAL(clicked()), this, SIGNAL(wantsToAddAccount())); #ifdef SWIFTEN_PLATFORM_MACOSX setHandleWidth(0); #endif @@ -33,14 +56,6 @@ QtSingleWindow::~QtSingleWindow() { } -void QtSingleWindow::addWidget(QWidget* widget) { - QtChatTabs* tabs = dynamic_cast<QtChatTabs*>(widget); - if (tabs) { - connect(tabs, SIGNAL(onTitleChanged(const QString&)), this, SLOT(handleTabsTitleChanged(const QString&))); - } - QSplitter::addWidget(widget); -} - void QtSingleWindow::handleTabsTitleChanged(const QString& title) { setWindowTitle(title); } @@ -55,25 +70,18 @@ void QtSingleWindow::handleSplitterMoved() { } void QtSingleWindow::restoreSplitters() { - QList<QVariant> variantValues = settings_->getQSettings()->value(SINGLE_WINDOW_SPLITS).toList(); - QList<int> intValues; - for (auto&& value : variantValues) { - intValues.append(value.toInt()); - } - setSizes(intValues); -} - -void QtSingleWindow::insertAtFront(QWidget* widget) { - insertWidget(0, widget); auto splitsVariant = settings_->getQSettings()->value(SINGLE_WINDOW_SPLITS); if (splitsVariant.isValid()) { - restoreSplitters(); + auto variantValues = splitsVariant.toList(); + QList<int> intValues; + for (auto&& value : variantValues) { + intValues.append(value.toInt()); + } + setSizes(intValues); } else { handleSplitterMoved(); } - setStretchFactor(0, 0); - setStretchFactor(1, 1); } void QtSingleWindow::handleGeometryChanged() { @@ -89,4 +97,25 @@ void QtSingleWindow::moveEvent(QMoveEvent*) { handleGeometryChanged(); } +void QtSingleWindow::addAccount(QtLoginWindow* loginWindow, QtChatTabs* tabs) { + if (!loginWindows_->count()) { + connect(tabs, SIGNAL(onTitleChanged(const QString&)), this, SLOT(handleTabsTitleChanged(const QString&))); + } + loginWindows_->addWidget(loginWindow); + tabs_->addWidget(tabs); + list_->addItem(QString("Account %1").arg(loginWindows_->count())); +} + +void QtSingleWindow::handleListItemClicked(QListWidgetItem* /*item*/) { + //FIXME: Should use a full model/view and do this properly (and render pretty things ourselves too) + auto currentTabs = tabs_->widget(tabs_->currentIndex()); + disconnect(currentTabs, SIGNAL(onTitleChanged(const QString&)), this, SLOT(handleTabsTitleChanged(const QString&))); + loginWindows_->setCurrentIndex(list_->currentRow()); + tabs_->setCurrentIndex(list_->currentRow()); + currentTabs = tabs_->widget(tabs_->currentIndex()); + connect(currentTabs, SIGNAL(onTitleChanged(const QString&)), this, SLOT(handleTabsTitleChanged(const QString&))); + //TODO change the title of the window. + handleTabsTitleChanged(QString("Swift")); +} + } diff --git a/Swift/QtUI/QtSingleWindow.h b/Swift/QtUI/QtSingleWindow.h index c6f22cf..9a7e475 100644 --- a/Swift/QtUI/QtSingleWindow.h +++ b/Swift/QtUI/QtSingleWindow.h @@ -6,9 +6,14 @@ #pragma once +#include <QListWidget> #include <QSplitter> +#include <QStackedWidget> + namespace Swift { + class QtChatTabs; + class QtLoginWindow; class QtSettingsProvider; class QtSingleWindow : public QSplitter { @@ -16,14 +21,18 @@ namespace Swift { public: QtSingleWindow(QtSettingsProvider* settings); virtual ~QtSingleWindow(); - void insertAtFront(QWidget* widget); - void addWidget(QWidget* widget); + void addAccount(QtLoginWindow* widget, QtChatTabs* tabs); + + signals: + void wantsToAddAccount(); + protected: void resizeEvent(QResizeEvent*); void moveEvent(QMoveEvent*); private slots: void handleSplitterMoved(); void handleTabsTitleChanged(const QString& title); + void handleListItemClicked(QListWidgetItem*); private: void handleGeometryChanged(); void restoreSplitters(); @@ -31,6 +40,9 @@ namespace Swift { private: QtSettingsProvider* settings_; + QListWidget* list_; + QStackedWidget* loginWindows_; + QStackedWidget* tabs_; }; } diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp index 89dfa01..28c7044 100644 --- a/Swift/QtUI/QtSwift.cpp +++ b/Swift/QtUI/QtSwift.cpp @@ -22,8 +22,10 @@ #include <Swiften/Base/Path.h> #include <Swiften/Base/Paths.h> #include <Swiften/Base/Platform.h> +#include <Swiften/Base/String.h> #include <Swiften/Client/Client.h> #include <Swiften/Elements/Presence.h> +#include <Swiften/StringCodecs/Base64.h> #include <Swiften/TLS/TLSContextFactory.h> #include <SwifTools/Application/PlatformApplicationPathProvider.h> @@ -92,8 +94,6 @@ po::options_description QtSwift::getOptionsDescription() { ("version", "Show version information") ("no-tabs", "Don't manage chat windows in tabs (unsupported)") ("latency-debug", "Use latency debugging (unsupported)") - ("multi-account", po::value<int>()->default_value(1), "Number of accounts to open windows for (unsupported)") - ("start-minimized", "Don't show the login/roster window at startup") ("enable-jid-adhocs", "Enable AdHoc commands to custom JIDs.") #if QT_VERSION >= 0x040800 ("language", po::value<std::string>(), "Use a specific language, instead of the system-wide one") @@ -167,19 +167,11 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa networkFactories_.getTLSContextFactory()->setDisconnectOnCardRemoval(settingsHierarchy_->getSetting(SettingConstants::DISCONNECT_ON_CARD_REMOVAL)); - std::map<std::string, std::string> emoticons; - loadEmoticonsFile(":/emoticons/emoticons.txt", emoticons); - loadEmoticonsFile(P2QSTRING(pathToString(Paths::getExecutablePath() / "emoticons.txt")), emoticons); + loadEmoticonsFile(":/emoticons/emoticons.txt", emoticons_); + loadEmoticonsFile(P2QSTRING(pathToString(Paths::getExecutablePath() / "emoticons.txt")), emoticons_); splitter_ = new QtSingleWindow(qtSettings_); - - int numberOfAccounts = 1; - try { - numberOfAccounts = options["multi-account"].as<int>(); - } catch (...) { - /* This seems to fail on a Mac when the .app is launched directly (the usual path).*/ - numberOfAccounts = 1; - } + connect(splitter_, SIGNAL(wantsToAddAccount()), this, SLOT(handleWantsToAddAccount())); if (options.count("debug")) { Log::setLogLevel(Swift::Log::debug); @@ -202,6 +194,8 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa SWIFT_LOG(error) << "Error while retrieving the specified log file name from the command line" << std::endl; } } + //TODO this old option can be purged + useDelayForLatency_ = options.count("latency-debug") > 0; // Load fonts std::vector<std::string> fontNames = { @@ -240,13 +234,10 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa #ifdef SWIFTEN_PLATFORM_WINDOWS QFont::insertSubstitution(QApplication::font().family(), "Segoe UI Emoji"); #endif - bool enableAdHocCommandOnJID = options.count("enable-jid-adhocs") > 0; - tabs_ = new QtChatTabs(settingsHierarchy_, true); - bool startMinimized = options.count("start-minimized") > 0; + enableAdHocCommandOnJID_ = options.count("enable-jid-adhocs") > 0; applicationPathProvider_ = new PlatformApplicationPathProvider(SWIFT_APPLICATION_NAME); storagesFactory_ = new FileStoragesFactory(applicationPathProvider_->getDataDir(), networkFactories_.getCryptoProvider()); certificateStorageFactory_ = new CertificateFileStorageFactory(applicationPathProvider_->getDataDir(), tlsFactories_.getCertificateFactory(), networkFactories_.getCryptoProvider()); - chatWindowFactory_ = new QtChatWindowFactory(splitter_, settingsHierarchy_, qtSettings_, tabs_, ":/themes/Default/", emoticons); soundPlayer_ = new QtSoundPlayer(applicationPathProvider_); // Ugly, because the dock depends on the tray, but the temporary @@ -298,32 +289,8 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa } }); } - - for (int i = 0; i < numberOfAccounts; i++) { - if (i > 0) { - // Don't add the first tray (see note above) - systemTrays_.push_back(new QtSystemTray()); - } - QtUIFactory* uiFactory = new QtUIFactory(settingsHierarchy_, qtSettings_, tabs_, splitter_, systemTrays_[i], chatWindowFactory_, networkFactories_.getTimerFactory(), statusCache_, autoUpdater_, startMinimized, !emoticons.empty(), enableAdHocCommandOnJID); - uiFactories_.push_back(uiFactory); - MainController* mainController = new MainController( - &clientMainThreadCaller_, - &networkFactories_, - uiFactory, - settingsHierarchy_, - systemTrays_[i], - soundPlayer_, - storagesFactory_, - certificateStorageFactory_, - dock_, - notifier_, - uriHandler_, - &idleDetector_, - emoticons, - options.count("latency-debug") > 0); - mainControllers_.push_back(mainController); - } - + migrateLastLoginAccount(); + restoreAccounts(); connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(handleAboutToQuit())); } @@ -339,8 +306,6 @@ QtSwift::~QtSwift() { for (auto* tray : systemTrays_) { delete tray; } - delete tabs_; - delete chatWindowFactory_; delete splitter_; delete settingsHierarchy_; delete qtSettings_; @@ -379,4 +344,139 @@ void QtSwift::handleAutoUpdaterStateChanged(AutoUpdater::State updatedState) { } } +void QtSwift::handleWantsToAddAccount() { + auto loginWindow = addAccount(); + if (!settingsHierarchy_->getSetting(SettingConstants::FORGET_PASSWORDS)) { + for (const auto& profile : settingsHierarchy_->getAvailableProfiles()) { + ProfileSettingsProvider profileSettings(profile, settingsHierarchy_); + if (profileSettings.getIntSetting("enabled", 0)) { + // No point showing accounts that're already logged in + continue; + } + const auto& password = profileSettings.getStringSetting("pass"); + const auto& certificate = profileSettings.getStringSetting("certificate"); + const auto& jid = profileSettings.getStringSetting("jid"); + const auto& clientOptions = parseClientOptions(profileSettings.getStringSetting("options")); + loginWindow->addAvailableAccount(jid, password, certificate, clientOptions); + } + } +} + +void QtSwift::restoreAccounts() { + if (!settingsHierarchy_->getSetting(SettingConstants::FORGET_PASSWORDS)) { + for (const auto& profile : settingsHierarchy_->getAvailableProfiles()) { + ProfileSettingsProvider profileSettings(profile, settingsHierarchy_); + if (!profileSettings.getIntSetting("enabled", 0)) { + continue; + } + const auto& jid = profileSettings.getStringSetting("jid"); + const auto& password = profileSettings.getStringSetting("pass"); + const auto& certificate = profileSettings.getStringSetting("certificate"); + const auto& clientOptions = parseClientOptions(profileSettings.getStringSetting("options")); + auto loginWindow = addAccount(); + loginWindow->addAvailableAccount(jid, password, certificate, clientOptions); + loginWindow->loginClicked(); + } + } +} + +void QtSwift::migrateLastLoginAccount() { + const SettingsProvider::Setting<bool> loginAutomatically = SettingsProvider::Setting<bool>("loginAutomatically", false); + if (settingsHierarchy_->getSetting(loginAutomatically)) { + auto selectedLoginJID = settingsHierarchy_->getSetting(SettingsProvider::Setting<std::string>("lastLoginJID", "")); + for (const auto& profile : settingsHierarchy_->getAvailableProfiles()) { + ProfileSettingsProvider profileSettings(profile, settingsHierarchy_); + if (profileSettings.getStringSetting("jid") == selectedLoginJID) { + profileSettings.storeInt("enabled", 1); + break; + } + } + settingsHierarchy_->storeSetting(loginAutomatically, false); + } +} + +QtLoginWindow* QtSwift::addAccount() { + if (uiFactories_.size() > 0) { + // Don't add the first tray (see note above) + systemTrays_.push_back(new QtSystemTray()); + } + auto tabs = new QtChatTabs(settingsHierarchy_, true); + QtUIFactory* uiFactory = new QtUIFactory(settingsHierarchy_, qtSettings_, tabs, splitter_, systemTrays_[systemTrays_.size() - 1], networkFactories_.getTimerFactory(), statusCache_, autoUpdater_, emoticons_, enableAdHocCommandOnJID_); + uiFactories_.push_back(uiFactory); + MainController* mainController = new MainController( + &clientMainThreadCaller_, + &networkFactories_, + uiFactory, + settingsHierarchy_, + systemTrays_[systemTrays_.size() - 1], + soundPlayer_, + storagesFactory_, + certificateStorageFactory_, + dock_, + notifier_, + uriHandler_, + &idleDetector_, + emoticons_, + useDelayForLatency_); + mainControllers_.push_back(mainController); + + //FIXME - mainController has already created the window, so we can pass null here and get the old one + auto loginWindow = uiFactory->createLoginWindow(nullptr); + + return dynamic_cast<QtLoginWindow*>(loginWindow); +} + +//FIXME: Switch all this to boost::serialise + +#define CHECK_PARSE_LENGTH if (i >= segments.size()) {return result;} +#define PARSE_INT_RAW(defaultValue) CHECK_PARSE_LENGTH intVal = defaultValue; try {intVal = boost::lexical_cast<int>(segments[i]);} catch(const boost::bad_lexical_cast&) {};i++; +#define PARSE_STRING_RAW CHECK_PARSE_LENGTH stringVal = byteArrayToString(Base64::decode(segments[i]));i++; + +#define PARSE_BOOL(option, defaultValue) PARSE_INT_RAW(defaultValue); result.option = (intVal == 1); +#define PARSE_INT(option, defaultValue) PARSE_INT_RAW(defaultValue); result.option = intVal; +#define PARSE_STRING(option) PARSE_STRING_RAW; result.option = stringVal; +#define PARSE_SAFE_STRING(option) PARSE_STRING_RAW; result.option = SafeString(createSafeByteArray(stringVal)); +#define PARSE_URL(option) {PARSE_STRING_RAW; result.option = URL::fromString(stringVal);} + + +ClientOptions QtSwift::parseClientOptions(const std::string& optionString) { + ClientOptions result; + size_t i = 0; + int intVal = 0; + std::string stringVal; + std::vector<std::string> segments = String::split(optionString, ','); + + PARSE_BOOL(useStreamCompression, 1); + PARSE_INT_RAW(-1); + switch (intVal) { + case 1: result.useTLS = ClientOptions::NeverUseTLS; break; + case 2: result.useTLS = ClientOptions::UseTLSWhenAvailable; break; + case 3: result.useTLS = ClientOptions::RequireTLS; break; + default:; + } + PARSE_BOOL(allowPLAINWithoutTLS, 0); + PARSE_BOOL(useStreamResumption, 0); + PARSE_BOOL(useAcks, 1); + PARSE_STRING(manualHostname); + PARSE_INT(manualPort, -1); + PARSE_INT_RAW(-1); + switch (intVal) { + case 1: result.proxyType = ClientOptions::NoProxy; break; + case 2: result.proxyType = ClientOptions::SystemConfiguredProxy; break; + case 3: result.proxyType = ClientOptions::SOCKS5Proxy; break; + case 4: result.proxyType = ClientOptions::HTTPConnectProxy; break; + } + PARSE_STRING(manualProxyHostname); + PARSE_INT(manualProxyPort, -1); + PARSE_URL(boshURL); + PARSE_URL(boshHTTPConnectProxyURL); + PARSE_SAFE_STRING(boshHTTPConnectProxyAuthID); + PARSE_SAFE_STRING(boshHTTPConnectProxyAuthPassword); + PARSE_BOOL(tlsOptions.schannelTLS1_0Workaround, false); + PARSE_BOOL(singleSignOn, false); + + return result; +} + + } diff --git a/Swift/QtUI/QtSwift.h b/Swift/QtUI/QtSwift.h index f35d2cc..d876cd8 100644 --- a/Swift/QtUI/QtSwift.h +++ b/Swift/QtUI/QtSwift.h @@ -6,12 +6,14 @@ #pragma once +#include <map> #include <string> #include <boost/program_options/options_description.hpp> #include <boost/program_options/variables_map.hpp> #include <Swiften/Base/Platform.h> +#include <Swiften/Client/ClientOptions.h> #include <Swiften/EventLoop/Qt/QtEventLoop.h> #include <Swiften/Network/BoostNetworkFactories.h> #include <Swiften/TLS/PlatformTLSFactories.h> @@ -68,11 +70,19 @@ namespace Swift { private slots: void handleAboutToQuit(); void handleAutoUpdaterStateChanged(AutoUpdater::State updatedState); + void handleWantsToAddAccount(); private: XMLSettingsProvider* loadSettingsFile(const QString& fileName); void loadEmoticonsFile(const QString& fileName, std::map<std::string, std::string>& emoticons); static const std::string& updateChannelToFeed(const std::string& channel); + QtLoginWindow* addAccount(); + ClientOptions parseClientOptions(const std::string& optionString); + void restoreAccounts(); + /** + * Upgrades the config from pre-multi-account to post-multi-account format (added in 5.0). + */ + void migrateLastLoginAccount(); private: QtEventLoop clientMainThreadCaller_; @@ -89,7 +99,6 @@ namespace Swift { QtSoundPlayer* soundPlayer_; Dock* dock_; URIHandler* uriHandler_; - QtChatTabs* tabs_; ApplicationPathProvider* applicationPathProvider_; StoragesFactory* storagesFactory_; CertificateStorageFactory* certificateStorageFactory_; @@ -98,6 +107,9 @@ namespace Swift { StatusCache* statusCache_; PlatformIdleQuerier idleQuerier_; ActualIdleDetector idleDetector_; + std::map<std::string, std::string> emoticons_; + bool enableAdHocCommandOnJID_ = false; + bool useDelayForLatency_; #if defined(SWIFTEN_PLATFORM_MACOSX) CocoaApplication cocoaApplication_; CocoaApplicationActivateHelper cocoaApplicationActivateHelper_; diff --git a/Swift/QtUI/QtUIFactory.cpp b/Swift/QtUI/QtUIFactory.cpp index 0b19f63..2762d68 100644 --- a/Swift/QtUI/QtUIFactory.cpp +++ b/Swift/QtUI/QtUIFactory.cpp @@ -40,7 +40,9 @@ namespace Swift { -QtUIFactory::QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, AutoUpdater* autoUpdater, bool startMinimized, bool emoticonsExist, bool enableAdHocCommandOnJID) : settings_(settings), qtOnlySettings_(qtOnlySettings), tabs_(tabs), netbookSplitter_(netbookSplitter), systemTray_(systemTray), chatWindowFactory_(chatWindowFactory), timerFactory_(timerFactory), lastMainWindow_(nullptr), loginWindow_(nullptr), statusCache_(statusCache), autoUpdater_(autoUpdater), startMinimized_(startMinimized), emoticonsExist_(emoticonsExist), enableAdHocCommandOnJID_(enableAdHocCommandOnJID) { +QtUIFactory::QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, TimerFactory* timerFactory, StatusCache* statusCache, AutoUpdater* autoUpdater, std::map<std::string, std::string>& emoticons, bool enableAdHocCommandOnJID) : settings_(settings), qtOnlySettings_(qtOnlySettings), tabs_(tabs), netbookSplitter_(netbookSplitter), systemTray_(systemTray), timerFactory_(timerFactory), lastMainWindow_(nullptr), loginWindow_(nullptr), statusCache_(statusCache), autoUpdater_(autoUpdater), emoticons_(emoticons), enableAdHocCommandOnJID_(enableAdHocCommandOnJID) { + emoticonsExist_ = !emoticons_.empty(); + chatWindowFactory_ = new QtChatWindowFactory(netbookSplitter_, settings, qtOnlySettings, tabs_, ":/themes/Default/", emoticons_); chatFontSize_ = settings_->getSetting(QtUISettingConstants::CHATWINDOW_FONT_SIZE); historyFontSize_ = settings_->getSetting(QtUISettingConstants::HISTORYWINDOW_FONT_SIZE); } @@ -50,6 +52,7 @@ QtUIFactory::~QtUIFactory() { for (auto chat : chatWindows_) { SWIFT_LOG_ASSERT(chat.isNull(), debug) << "QtUIFactory has active chat windows and has not been reset properly" << std::endl; } + delete chatWindowFactory_; } XMLConsoleWidget* QtUIFactory::createXMLConsoleWidget() { @@ -91,12 +94,12 @@ MainWindow* QtUIFactory::createMainWindow(Chattables& chattables, UIEventStream* } LoginWindow* QtUIFactory::createLoginWindow(UIEventStream* eventStream) { + if (loginWindow_) { + return loginWindow_; + } loginWindow_ = new QtLoginWindow(eventStream, settings_, timerFactory_, autoUpdater_); - netbookSplitter_->insertAtFront(loginWindow_); + netbookSplitter_->addAccount(loginWindow_, tabs_); connect(systemTray_, SIGNAL(clicked()), loginWindow_, SLOT(toggleBringToFront())); - if (startMinimized_) { - loginWindow_->hide(); - } return loginWindow_; } diff --git a/Swift/QtUI/QtUIFactory.h b/Swift/QtUI/QtUIFactory.h index 4013668..ad8dc1f 100644 --- a/Swift/QtUI/QtUIFactory.h +++ b/Swift/QtUI/QtUIFactory.h @@ -35,7 +35,7 @@ namespace Swift { class QtUIFactory : public QObject, public UIFactory { Q_OBJECT public: - QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, AutoUpdater* autoUpdater, bool startMinimized, bool emoticonsExist, bool enableAdHocCommandOnJID); + QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, TimerFactory* timerFactory, StatusCache* statusCache, AutoUpdater* autoUpdater, std::map<std::string, std::string>& emoticons, bool enableAdHocCommandOnJID); ~QtUIFactory(); virtual XMLConsoleWidget* createXMLConsoleWidget(); virtual HistoryWindow* createHistoryWindow(UIEventStream*); @@ -75,10 +75,10 @@ namespace Swift { StatusCache* statusCache_; AutoUpdater* autoUpdater_; std::vector<QPointer<QtChatWindow> > chatWindows_; - bool startMinimized_; int chatFontSize_; int historyFontSize_; bool emoticonsExist_; + std::map<std::string, std::string>& emoticons_; bool enableAdHocCommandOnJID_; }; } |