diff options
-rw-r--r-- | SwifTools/AutoUpdater/AutoUpdater.h | 16 | ||||
-rw-r--r-- | SwifTools/AutoUpdater/SparkleAutoUpdater.h | 7 | ||||
-rw-r--r-- | SwifTools/AutoUpdater/SparkleAutoUpdater.mm | 30 | ||||
-rw-r--r-- | SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.h | 12 | ||||
-rw-r--r-- | SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.mm | 32 | ||||
-rw-r--r-- | Swift/QtUI/QtAboutWidget.cpp | 95 | ||||
-rw-r--r-- | Swift/QtUI/QtAboutWidget.h | 17 | ||||
-rw-r--r-- | Swift/QtUI/QtLoginWindow.cpp | 6 | ||||
-rw-r--r-- | Swift/QtUI/QtLoginWindow.h | 6 | ||||
-rw-r--r-- | Swift/QtUI/QtSwift.cpp | 49 | ||||
-rw-r--r-- | Swift/QtUI/QtSwift.h | 34 | ||||
-rw-r--r-- | Swift/QtUI/QtUIFactory.cpp | 6 | ||||
-rw-r--r-- | Swift/QtUI/QtUIFactory.h | 6 |
13 files changed, 222 insertions, 94 deletions
diff --git a/SwifTools/AutoUpdater/AutoUpdater.h b/SwifTools/AutoUpdater/AutoUpdater.h index 274bf50..a125229 100644 --- a/SwifTools/AutoUpdater/AutoUpdater.h +++ b/SwifTools/AutoUpdater/AutoUpdater.h @@ -1,30 +1,40 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once #include <string> #include <boost/signals2.hpp> namespace Swift { class AutoUpdater { public: + enum class State { + NotCheckedForUpdatesYet, + NoUpdateAvailable, + CheckingForUpdate, + ErrorCheckingForUpdate, + DownloadingUpdate, + RestartToInstallUpdate + }; + + public: virtual ~AutoUpdater(); virtual void setAppcastFeed(const std::string& appcastFeed) = 0; virtual void checkForUpdates() = 0; - virtual bool recommendRestartToUpdate() = 0; + virtual State getCurrentState() = 0; public: /** * Emit this signal if a new version of the software has been downloaded * and the user needs to be notified so they can quit the app and start * the newer version. */ - boost::signals2::signal<void()> onSuggestRestartToUserToUpdate; + boost::signals2::signal<void(State)> onUpdateStateChanged; }; } diff --git a/SwifTools/AutoUpdater/SparkleAutoUpdater.h b/SwifTools/AutoUpdater/SparkleAutoUpdater.h index dd22e73..48b75e5 100644 --- a/SwifTools/AutoUpdater/SparkleAutoUpdater.h +++ b/SwifTools/AutoUpdater/SparkleAutoUpdater.h @@ -1,34 +1,37 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once #include <memory> #include <string> #include <SwifTools/AutoUpdater/AutoUpdater.h> namespace Swift { /** * @brief The SparkleAutoUpdater class provides integration with Sparkle. * This enables automatic silent background updates. If using this in Qt you * need to emit a NSApplicationWillTerminateNotification before you quit * the application. */ class SparkleAutoUpdater : public AutoUpdater { public: SparkleAutoUpdater(const std::string& appcastFeed); ~SparkleAutoUpdater(); void setAppcastFeed(const std::string& appcastFeed); void checkForUpdates(); - bool recommendRestartToUpdate(); + State getCurrentState(); + + private: + void setCurrentState(State updatedState); private: class Private; const std::unique_ptr<Private> d; }; } diff --git a/SwifTools/AutoUpdater/SparkleAutoUpdater.mm b/SwifTools/AutoUpdater/SparkleAutoUpdater.mm index 0c296ee..4cf5837 100644 --- a/SwifTools/AutoUpdater/SparkleAutoUpdater.mm +++ b/SwifTools/AutoUpdater/SparkleAutoUpdater.mm @@ -1,62 +1,70 @@ /* - * Copyright (c) 2016 Isode Limited. + * Copyright (c) 2016-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <SwifTools/AutoUpdater/SparkleAutoUpdater.h> #include <Cocoa/Cocoa.h> #include <Sparkle/Sparkle.h> #include <SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.h> #include <SwifTools/Cocoa/CocoaUtil.h> namespace Swift { class SparkleAutoUpdater::Private { public: SUUpdater* updater; boost::intrusive_ptr<SparkleAutoUpdaterDelegate> delegate; - bool restartToUpdate = false; + State currentState = State::NotCheckedForUpdatesYet; }; SparkleAutoUpdater::SparkleAutoUpdater(const std::string& appcastFeed) : d(new Private()) { d->updater = [SUUpdater sharedUpdater]; [d->updater retain]; d->delegate = boost::intrusive_ptr<SparkleAutoUpdaterDelegate>([[SparkleAutoUpdaterDelegate alloc] init], false); - [d->delegate.get() setUpdateDownloadFinished: [&](){ - d->restartToUpdate = true; - onSuggestRestartToUserToUpdate(); + [d->delegate.get() setOnNewUpdateState: [&](AutoUpdater::State updatedState){ + setCurrentState(updatedState); }]; [d->updater setDelegate: d->delegate.get()]; [d->updater setAutomaticallyChecksForUpdates: true]; // Automatically check for an update after a day. [d->updater setUpdateCheckInterval: 86400]; [d->updater setAutomaticallyDownloadsUpdates: true]; - NSURL* nsurl = [NSURL URLWithString: std2NSString(appcastFeed)]; - [d->updater setFeedURL: nsurl]; + setAppcastFeed(appcastFeed); } SparkleAutoUpdater::~SparkleAutoUpdater() { [d->updater release]; } void SparkleAutoUpdater::setAppcastFeed(const std::string& appcastFeed) { NSURL* nsurl = [NSURL URLWithString: std2NSString(appcastFeed)]; [d->updater setFeedURL: nsurl]; } void SparkleAutoUpdater::checkForUpdates() { - [d->updater resetUpdateCycle]; - [d->updater checkForUpdatesInBackground]; + if (!(getCurrentState() == State::CheckingForUpdate || + getCurrentState() == State::DownloadingUpdate || + getCurrentState() == State::RestartToInstallUpdate)) { + setCurrentState(State::CheckingForUpdate); + [d->updater resetUpdateCycle]; + [d->updater checkForUpdatesInBackground]; + } +} + +void SparkleAutoUpdater::setCurrentState(AutoUpdater::State updatedState) { + d->currentState = updatedState; + onUpdateStateChanged(d->currentState); } -bool SparkleAutoUpdater::recommendRestartToUpdate() { - return d->restartToUpdate; +AutoUpdater::State SparkleAutoUpdater::getCurrentState() { + return d->currentState; } } diff --git a/SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.h b/SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.h index 8f408de..4aa236b 100644 --- a/SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.h +++ b/SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.h @@ -1,35 +1,37 @@ /* - * Copyright (c) 2016 Isode Limited. + * Copyright (c) 2016-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once #include <functional> #import <Cocoa/Cocoa.h> #import <Sparkle/Sparkle.h> -namespace Swift { - class SparkleAutoUpdater; -} +#include <SwifTools/AutoUpdater/AutoUpdater.h> @interface SparkleAutoUpdaterDelegate : NSObject<SUUpdaterDelegate> -@property (atomic) std::function< void ()> updateDownloadFinished; +@property (atomic) std::function< void (Swift::AutoUpdater::State)> onNewUpdateState; - (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast; - (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)update; - (id <SUVersionComparison>)versionComparatorForUpdater:(SUUpdater *)updater; - (void)updaterDidNotFindUpdate:(SUUpdater *)update; +- (void)updater:(SUUpdater *)updater willDownloadUpdate:(SUAppcastItem *)item withRequest:(NSMutableURLRequest *)request; + +- (void)updater:(SUUpdater *)updater failedToDownloadUpdate:(SUAppcastItem *)item error:(NSError *)error; + - (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update; - (void)updater:(SUUpdater *)updater willInstallUpdateOnQuit:(SUAppcastItem *)item immediateInstallationInvocation:(NSInvocation *)invocation; - (void)updater:(SUUpdater *)updater didAbortWithError:(NSError *)error; @end diff --git a/SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.mm b/SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.mm index 6e832ba..be58355 100644 --- a/SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.mm +++ b/SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.mm @@ -1,57 +1,79 @@ /* - * Copyright (c) 2016 Isode Limited. + * Copyright (c) 2016-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ -#import "SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.h" +#import <SwifTools/AutoUpdater/SparkleAutoUpdaterDelegate.h> #include <string> #include <Swiften/Base/Log.h> #include <SwifTools/Cocoa/CocoaUtil.h> using namespace Swift; @implementation SparkleAutoUpdaterDelegate -@synthesize updateDownloadFinished; +@synthesize onNewUpdateState; - (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast { (void)updater; (void)appcast; + onNewUpdateState(AutoUpdater::State::DownloadingUpdate); } - (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)update { (void)updater; (void)update; } - (id <SUVersionComparison>)versionComparatorForUpdater:(SUUpdater *)updater { (void)updater; return nil; } - (void)updaterDidNotFindUpdate:(SUUpdater *)updater { (void)updater; + onNewUpdateState(AutoUpdater::State::NoUpdateAvailable); +} + +- (void)updater:(SUUpdater *)updater willDownloadUpdate:(SUAppcastItem *)item withRequest:(NSMutableURLRequest *)request { + (void)updater; + (void)item; + (void)request; + onNewUpdateState(AutoUpdater::State::DownloadingUpdate); +} + +- (void)updater:(SUUpdater *)updater failedToDownloadUpdate:(SUAppcastItem *)item error:(NSError *)error { + (void)updater; + (void)item; + SWIFT_LOG(error) << ns2StdString([error localizedDescription]) << std::endl; + onNewUpdateState(AutoUpdater::State::ErrorCheckingForUpdate); } - (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update { (void)updater; (void)update; } - (void)updater:(SUUpdater *)updater willInstallUpdateOnQuit:(SUAppcastItem *)item immediateInstallationInvocation:(NSInvocation *)invocation { (void)updater; (void)item; (void)invocation; - updateDownloadFinished(); + onNewUpdateState(AutoUpdater::State::RestartToInstallUpdate); } - (void)updater:(SUUpdater *)updater didAbortWithError:(NSError *)error { (void)updater; - SWIFT_LOG(error) << ns2StdString([error localizedDescription]) << std::endl; + if ([error code] == SUNoUpdateError) { + onNewUpdateState(AutoUpdater::State::NoUpdateAvailable); + } + else { + SWIFT_LOG(error) << ns2StdString([error localizedDescription]) << std::endl; + onNewUpdateState(AutoUpdater::State::ErrorCheckingForUpdate); + } } @end diff --git a/Swift/QtUI/QtAboutWidget.cpp b/Swift/QtUI/QtAboutWidget.cpp index 9047525..3bc124a 100644 --- a/Swift/QtUI/QtAboutWidget.cpp +++ b/Swift/QtUI/QtAboutWidget.cpp @@ -1,93 +1,110 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swift/QtUI/QtAboutWidget.h> #include <QCoreApplication> #include <QFile> #include <QIcon> #include <QLabel> +#include <QProgressBar> #include <QPushButton> #include <QTextEdit> #include <QTextStream> #include <QVBoxLayout> #include <QtGlobal> #include <Swiften/Base/Log.h> #include <Swiften/Base/Platform.h> +#include <SwifTools/AutoUpdater/AutoUpdater.h> + #include <Swift/QtUI/QtSwiftUtil.h> #include <Swift/QtUI/QtUISettingConstants.h> #include <Swift/QtUI/QtUpdateFeedSelectionDialog.h> #include <Swift/QtUI/SwiftUpdateFeeds.h> namespace Swift { -QtAboutWidget::QtAboutWidget(SettingsProvider* settingsProvider) : QDialog(), settingsProvider_(settingsProvider) { +QtAboutWidget::QtAboutWidget(SettingsProvider* settingsProvider, AutoUpdater* autoUpdater) : QDialog(), settingsProvider_(settingsProvider), autoUpdater_(autoUpdater) { #ifndef Q_OS_MAC setWindowTitle(QString(tr("About %1")).arg("Swift")); #endif setWindowIcon(QIcon(":/logo-icon-16.png")); resize(180, 240); QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->setAlignment(Qt::AlignHCenter); setLayout(mainLayout); QLabel* iconLabel = new QLabel(this); iconLabel->setPixmap(QIcon(":/logo-shaded-text.256.png").pixmap(90, 90)); iconLabel->setAlignment(Qt::AlignHCenter); mainLayout->addWidget(iconLabel); QLabel* appNameLabel = new QLabel("<center><font size='+1'><b>" + QCoreApplication::applicationName() + "</b></font></center>", this); mainLayout->addWidget(appNameLabel); QLabel* versionLabel = new QLabel((QString("<center><font size='-1'>") + tr("Version %1") + "</font></center><center><font size='-1'><br/>" + QString(tr("Built with Qt %2")) + QString("<br/>") + QString(tr("Running with Qt %3")) + "</font></center>").arg(QCoreApplication::applicationVersion()).arg(QT_VERSION_STR).arg(qVersion())); versionLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard); mainLayout->addWidget(versionLabel); - settingsChangedConnection_ = settingsProvider_->onSettingChanged.connect([&](const std::string& path) { - if (path == QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL.getKey() || path == QtUISettingConstants::ENABLE_SOFTWARE_UPDATES.getKey()) { - updateUpdateInfoLabel(); - } - }); + if (autoUpdater_) { + settingsChangedConnection_ = settingsProvider_->onSettingChanged.connect([&](const std::string& path) { + if (path == QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL.getKey() || path == QtUISettingConstants::ENABLE_SOFTWARE_UPDATES.getKey()) { + updateUpdateInfo(); + } + }); + + autoUpdaterChangeConnection_ = autoUpdater_->onUpdateStateChanged.connect([&](AutoUpdater::State /*updatedState*/) { + updateUpdateInfo(); + }); + } + + updateChannelInfoLabel_ = new QLabel("", this); + updateChannelInfoLabel_->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse); + connect(updateChannelInfoLabel_, SIGNAL(linkActivated(const QString &)), this, SLOT(handleChangeUpdateChannelClicked())); + mainLayout->addWidget(updateChannelInfoLabel_); - updateInfoLabel_ = new QLabel("", this); - updateInfoLabel_->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse); - connect(updateInfoLabel_, SIGNAL(linkActivated(const QString &)), this, SLOT(handleChangeUpdateChannelClicked())); - mainLayout->addWidget(updateInfoLabel_); + updateStateInfoLabel_ = new QLabel("", this); + mainLayout->addWidget(updateStateInfoLabel_); - updateUpdateInfoLabel(); + updateProgressBar_ = new QProgressBar(this); + updateProgressBar_->setMinimum(0); + updateProgressBar_->setMaximum(0); + mainLayout->addWidget(updateProgressBar_); + + updateUpdateInfo(); if (QCoreApplication::translate("TRANSLATION_INFO", "TRANSLATION_AUTHOR") != "TRANSLATION_AUTHOR") { mainLayout->addWidget(new QLabel(QString("<center><font size='-1'>") + QString(tr("Using the English translation by\n%1")).arg(QCoreApplication::translate("TRANSLATION_INFO", "TRANSLATION_AUTHOR")).replace("\n", "<br/>") + "</font></center>", this)); } QCoreApplication::translate("TRANSLATION_INFO", "TRANSLATION_LICENSE", "This string contains the license under which this translation is licensed. We ask you to license the translation under the BSD license. Please read http://www.opensource.org/licenses/bsd-license.php, and if you agree to release your translation under this license, use the following (untranslated) text: 'This translation is licensed under the BSD License. See http://www.opensource.org/licenses/bsd-license.php'"); #if defined(SWIFTEN_PLATFORM_WINDOWS) || defined(SWIFTEN_PLATFORM_MACOSX) QPushButton* licenseButton = new QPushButton(tr("View License"), this); mainLayout->addWidget(licenseButton); connect(licenseButton, SIGNAL(clicked()), this, SLOT(handleLicenseClicked())); QPushButton* changelogButton = new QPushButton(tr("View Changes"), this); mainLayout->addWidget(changelogButton); connect(changelogButton, SIGNAL(clicked()), this, SLOT(handleChangelogClicked())); #else // Some Linux desktops have dialog window decorations without close window buttons. // This code adds a dedicated button to close the about window dialog. QHBoxLayout* buttonLayout = new QHBoxLayout(); mainLayout->addLayout(buttonLayout); QPushButton* licenseButton = new QPushButton(tr("View License"), this); buttonLayout->addWidget(licenseButton); connect(licenseButton, SIGNAL(clicked()), this, SLOT(handleLicenseClicked())); QPushButton* changelogButton = new QPushButton(tr("View Changes"), this); buttonLayout->addWidget(changelogButton); connect(changelogButton, SIGNAL(clicked()), this, SLOT(handleChangelogClicked())); buttonLayout->addItem(new QSpacerItem(20,20)); QPushButton* closeButton = new QPushButton(tr("Close"), this); @@ -102,62 +119,98 @@ void QtAboutWidget::handleLicenseClicked() { } void QtAboutWidget::handleChangelogClicked() { openPlainTextWindow(":/ChangeLog.md"); } void QtAboutWidget::handleChangeUpdateChannelClicked() { auto feedSelectionDialog = new QtUpdateFeedSelectionDialog(settingsProvider_); feedSelectionDialog->show(); } void QtAboutWidget::openPlainTextWindow(const QString& path) { QTextEdit* text = new QTextEdit(); text->setAttribute(Qt::WA_DeleteOnClose); text->setReadOnly(true); QFile file(path); if (file.open(QIODevice::ReadOnly)) { QTextStream in(&file); in.setCodec("UTF-8"); text->setPlainText(in.readAll()); file.close(); text->resize(500, 600); text->show(); text->activateWindow(); } else { SWIFT_LOG(error) << "Failed to open " << Q2PSTRING(path) << "." << std::endl; } } -void QtAboutWidget::updateUpdateInfoLabel() { +void QtAboutWidget::updateUpdateInfo() { + updateChannelInfoLabel_->hide(); + updateStateInfoLabel_->hide(); + updateProgressBar_->hide(); + // Currently auto updating is only supported on macOS. +#ifdef SWIFTEN_PLATFORM_MACOSX if (settingsProvider_->getSetting(QtUISettingConstants::ENABLE_SOFTWARE_UPDATES)) { if (!settingsProvider_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL).empty()) { QString updateFeedDescription; auto addUpdateFeedDialogLink = false; if (settingsProvider_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL) == UpdateFeeds::StableChannel) { updateFeedDescription = tr("You are receiving updates from the Stable update channel."); addUpdateFeedDialogLink = true; } else if (settingsProvider_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL) == UpdateFeeds::DevelopmentChannel) { updateFeedDescription = tr("You are receiving updates from the Development update channel."); addUpdateFeedDialogLink = true; } else if (settingsProvider_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL) == UpdateFeeds::TestingChannel) { updateFeedDescription = tr("You are receiving updates from the Testing update channel."); addUpdateFeedDialogLink = true; } auto updateFeedDialogLink = QString( addUpdateFeedDialogLink ? "<a href=\"#\">%1</a>" : "" ).arg(tr("Change the update channel.")); - updateInfoLabel_->setText(QString("<center><font size='-1'>%1<br/>%2</font></center>").arg(updateFeedDescription, updateFeedDialogLink)); - updateInfoLabel_->show(); - } - else { - updateInfoLabel_->hide(); + updateChannelInfoLabel_->setText(QString("<center><font size='-1'>%1<br/>%2</font></center>").arg(updateFeedDescription, updateFeedDialogLink)); + updateChannelInfoLabel_->show(); + + auto currentState = autoUpdater_->getCurrentState(); + auto currentStateStringPattern = QString("<center><font size='-1'>%1</font></center>"); + switch (currentState) { + case AutoUpdater::State::NotCheckedForUpdatesYet: + // Simply not showing any current state info. + break; + case AutoUpdater::State::CheckingForUpdate: + updateStateInfoLabel_->setText(currentStateStringPattern.arg(tr("Checking for updates…"))); + updateStateInfoLabel_->show(); + updateProgressBar_->show(); + break; + case AutoUpdater::State::ErrorCheckingForUpdate: + updateStateInfoLabel_->setText(currentStateStringPattern.arg(tr("Error checking for updates!"))); + updateStateInfoLabel_->show(); + break; + case AutoUpdater::State::NoUpdateAvailable: + updateStateInfoLabel_->setText(currentStateStringPattern.arg(tr("Swift is up to date."))); + updateStateInfoLabel_->show(); + break; + case AutoUpdater::State::DownloadingUpdate: + updateStateInfoLabel_->setText(currentStateStringPattern.arg(tr("Downloading update…"))); + updateStateInfoLabel_->show(); + updateProgressBar_->show(); + break; + case AutoUpdater::State::RestartToInstallUpdate: + updateStateInfoLabel_->setText(currentStateStringPattern.arg(tr("Update will be installed when you next restart Swift."))); + updateStateInfoLabel_->show(); + break; + } } } - else { - updateInfoLabel_->hide(); - } +#endif + setFixedSize(minimumSizeHint()); +} +void QtAboutWidget::showEvent(QShowEvent*) { + if (autoUpdater_) { + autoUpdater_->checkForUpdates(); + } } } diff --git a/Swift/QtUI/QtAboutWidget.h b/Swift/QtUI/QtAboutWidget.h index fb54c6e..b07c6b0 100644 --- a/Swift/QtUI/QtAboutWidget.h +++ b/Swift/QtUI/QtAboutWidget.h @@ -1,38 +1,47 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once #include <boost/signals2/connection.hpp> #include <QDialog> class QLabel; +class QProgressBar; namespace Swift { + class AutoUpdater; class SettingsProvider; class QtAboutWidget : public QDialog { Q_OBJECT public: - QtAboutWidget(SettingsProvider* settings); + QtAboutWidget(SettingsProvider* settings, AutoUpdater* autoUpdater); private slots: void handleLicenseClicked(); void handleChangelogClicked(); void handleChangeUpdateChannelClicked(); private: void openPlainTextWindow(const QString& path); - void updateUpdateInfoLabel(); + void updateUpdateInfo(); + + protected: + void showEvent(QShowEvent*); private: SettingsProvider* settingsProvider_; - QLabel* updateInfoLabel_ = nullptr; + AutoUpdater* autoUpdater_; + QLabel* updateChannelInfoLabel_ = nullptr; + QLabel* updateStateInfoLabel_ = nullptr; + QProgressBar* updateProgressBar_ = nullptr; boost::signals2::scoped_connection settingsChangedConnection_; + boost::signals2::scoped_connection autoUpdaterChangeConnection_; }; } diff --git a/Swift/QtUI/QtLoginWindow.cpp b/Swift/QtUI/QtLoginWindow.cpp index 865d8b5..654e921 100644 --- a/Swift/QtUI/QtLoginWindow.cpp +++ b/Swift/QtUI/QtLoginWindow.cpp @@ -1,86 +1,86 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swift/QtUI/QtLoginWindow.h> #include <algorithm> #include <cassert> #include <boost/bind.hpp> #include <memory> #include <QApplication> #include <QBoxLayout> #include <QCloseEvent> #include <QComboBox> #include <QCursor> #include <QDebug> #include <QDesktopWidget> #include <QFileDialog> #include <QHBoxLayout> #include <QKeyEvent> #include <QLabel> #include <QMenuBar> #include <QMessageBox> #include <QStatusBar> #include <QToolButton> #include <Swiften/Base/Platform.h> #include <Swiften/Base/Paths.h> #include <Swift/Controllers/SettingConstants.h> #include <Swift/Controllers/Settings/SettingsProvider.h> #include <Swift/Controllers/UIEvents/RequestFileTransferListUIEvent.h> #include <Swift/Controllers/UIEvents/RequestHighlightEditorUIEvent.h> #include <Swift/Controllers/UIEvents/RequestXMLConsoleUIEvent.h> #include <Swift/Controllers/UIEvents/UIEventStream.h> #include <Swift/QtUI/QtAboutWidget.h> #include <Swift/QtUI/QtConnectionSettingsWindow.h> #include <Swift/QtUI/QtMainWindow.h> #include <Swift/QtUI/QtSwiftUtil.h> #include <Swift/QtUI/QtUISettingConstants.h> #include <Swift/QtUI/QtUtilities.h> #ifdef HAVE_SCHANNEL #include "CAPICertificateSelector.h" #include <Swiften/TLS/CAPICertificate.h> #endif #include <Swiften/TLS/PKCS12Certificate.h> namespace Swift{ -QtLoginWindow::QtLoginWindow(UIEventStream* uiEventStream, SettingsProvider* settings, TimerFactory* timerFactory) : QMainWindow(), settings_(settings), timerFactory_(timerFactory) { +QtLoginWindow::QtLoginWindow(UIEventStream* uiEventStream, SettingsProvider* settings, TimerFactory* timerFactory, AutoUpdater* autoUpdater) : QMainWindow(), settings_(settings), timerFactory_(timerFactory), autoUpdater_(autoUpdater) { uiEventStream_ = uiEventStream; setWindowTitle("Swift"); #ifndef Q_OS_MAC #ifdef Q_OS_WIN32 setWindowIcon(QIcon(":/logo-icon-16-win.png")); #else setWindowIcon(QIcon(":/logo-icon-16.png")); #endif #endif QtUtilities::setX11Resource(this, "Main"); setAccessibleName(tr("Swift Login Window")); //setAccessibleDescription(tr("This window is used for providing credentials to log into your XMPP service")); resize(200, 500); setContentsMargins(0,0,0,0); QWidget *centralWidget = new QWidget(this); setCentralWidget(centralWidget); QBoxLayout *topLayout = new QBoxLayout(QBoxLayout::TopToBottom, centralWidget); stack_ = new QStackedWidget(centralWidget); topLayout->addWidget(stack_); topLayout->setMargin(0); loginWidgetWrapper_ = new QWidget(this); loginWidgetWrapper_->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, loginWidgetWrapper_); layout->addStretch(2); QLabel* logo = new QLabel(this); QIcon swiftWithTextLogo = QIcon(":/logo-shaded-text.png"); logo->setPixmap(swiftWithTextLogo.pixmap(QSize(192,192))); @@ -415,61 +415,61 @@ void QtLoginWindow::loginClicked() { } else { onCancelLoginRequest(); } } void QtLoginWindow::setLoginAutomatically(bool loginAutomatically) { loginAutomatically_->setChecked(loginAutomatically); } void QtLoginWindow::handleCertficateChecked(bool checked) { if (checked) { #ifdef HAVE_SCHANNEL certificateFile_ = P2QSTRING(selectCAPICertificate()); if (certificateFile_.isEmpty()) { certificateButton_->setChecked(false); } #else certificateFile_ = QFileDialog::getOpenFileName(this, tr("Select an authentication certificate"), QString(), tr("P12 files (*.cert *.p12 *.pfx);;All files (*.*)")); if (certificateFile_.isEmpty()) { certificateButton_->setChecked(false); } #endif } else { certificateFile_ = ""; } } void QtLoginWindow::handleAbout() { if (!aboutDialog_) { - aboutDialog_ = new QtAboutWidget(settings_); + aboutDialog_ = new QtAboutWidget(settings_, autoUpdater_); aboutDialog_->show(); } else { aboutDialog_->show(); aboutDialog_->raise(); aboutDialog_->activateWindow(); } } void QtLoginWindow::handleShowXMLConsole() { uiEventStream_->send(std::make_shared<RequestXMLConsoleUIEvent>()); } void QtLoginWindow::handleShowFileTransferOverview() { uiEventStream_->send(std::make_shared<RequestFileTransferListUIEvent>()); } void QtLoginWindow::handleShowHighlightEditor() { uiEventStream_->send(std::make_shared<RequestHighlightEditorUIEvent>()); } void QtLoginWindow::handleToggleSounds(bool enabled) { settings_->storeSetting(SettingConstants::PLAY_SOUNDS, enabled); } void QtLoginWindow::handleToggleNotifications(bool enabled) { settings_->storeSetting(SettingConstants::SHOW_NOTIFICATIONS, enabled); } void QtLoginWindow::handleQuit() { diff --git a/Swift/QtUI/QtLoginWindow.h b/Swift/QtUI/QtLoginWindow.h index c42d65d..674e1e3 100644 --- a/Swift/QtUI/QtLoginWindow.h +++ b/Swift/QtUI/QtLoginWindow.h @@ -1,71 +1,72 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once #include <QCheckBox> #include <QLineEdit> #include <QMainWindow> #include <QMenuBar> #include <QPointer> #include <QPushButton> #include <QStackedWidget> #include <Swift/Controllers/UIEvents/UIEventStream.h> #include <Swift/Controllers/UIInterfaces/LoginWindow.h> #include <Swift/Controllers/UIInterfaces/MainWindow.h> #include <Swift/QtUI/QtAboutWidget.h> class QLabel; class QToolButton; class QComboBox; namespace Swift { + class AutoUpdater; class SettingsProvider; class TimerFactory; class QtLoginWindow : public QMainWindow, public LoginWindow { Q_OBJECT public: struct QtMenus { QtMenus(QMenu* swiftMenu, QMenu* generalMenu) : swiftMenu(swiftMenu), generalMenu(generalMenu) {} QMenu* swiftMenu; QMenu* generalMenu; }; public: - QtLoginWindow(UIEventStream* uiEventStream, SettingsProvider* settings, TimerFactory* timerFactory); + QtLoginWindow(UIEventStream* uiEventStream, SettingsProvider* settings, TimerFactory* timerFactory, AutoUpdater* autoUpdater); void morphInto(MainWindow *mainWindow); virtual void loggedOut(); virtual void setShowNotificationToggle(bool); virtual void setMessage(const std::string& message); virtual void addAvailableAccount(const std::string& defaultJID, const std::string& defaultPassword, const std::string& defaultCertificate, const ClientOptions& options); virtual void removeAvailableAccount(const std::string& jid); virtual void setLoginAutomatically(bool loginAutomatically); virtual void setIsLoggingIn(bool loggingIn); void selectUser(const std::string& user); bool askUserToTrustCertificatePermanently(const std::string& message, const std::vector<Certificate::ref>& certificate); void hide(); QtMenus getMenus() const; virtual void quit(); signals: void geometryChanged(); private slots: void loginClicked(); void handleCertficateChecked(bool); void handleQuit(); void handleShowXMLConsole(); void handleShowFileTransferOverview(); void handleShowHighlightEditor(); void handleToggleSounds(bool enabled); void handleToggleNotifications(bool enabled); void handleAbout(); void bringToFront(); void toggleBringToFront(); @@ -82,32 +83,33 @@ namespace Swift { void setInitialMenus(); QWidget* loginWidgetWrapper_; QStringList usernames_; QStringList passwords_; QStringList certificateFiles_; std::vector<ClientOptions> options_; QComboBox* username_; QLineEdit* password_; QPushButton* loginButton_; /* If you add a widget here, change setLoggingIn as well.*/ QCheckBox* remember_; QCheckBox* loginAutomatically_; QStackedWidget* stack_; QLabel* message_; QString certificateFile_; QToolButton* certificateButton_; QMenuBar* menuBar_; QMenu* swiftMenu_; QMenu* generalMenu_; QMenu* viewMenu_ = nullptr; QAction* toggleSoundsAction_; QAction* toggleNotificationsAction_; UIEventStream* uiEventStream_; QPointer<QtAboutWidget> aboutDialog_; SettingsProvider* settings_; QAction* xmlConsoleAction_; QAction* fileTransferOverviewAction_; QAction* highlightEditorAction_; TimerFactory* timerFactory_; ClientOptions currentOptions_; + AutoUpdater* autoUpdater_; }; } diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp index ee21c4f..b61147d 100644 --- a/Swift/QtUI/QtSwift.cpp +++ b/Swift/QtUI/QtSwift.cpp @@ -242,113 +242,126 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa #elif defined(SWIFTEN_PLATFORM_WINDOWS) notifier_ = new WindowsNotifier(SWIFT_APPLICATION_NAME, applicationPathProvider_->getResourcePath("/images/logo-icon-32.png"), systemTray->getQSystemTrayIcon()); #elif defined(SWIFTEN_PLATFORM_LINUX) notifier_ = new FreeDesktopNotifier(SWIFT_APPLICATION_NAME); #elif defined(SWIFTEN_PLATFORM_MACOSX) notifier_ = new NotificationCenterNotifier(); #else notifier_ = new NullNotifier(); #endif #if defined(SWIFTEN_PLATFORM_MACOSX) dock_ = new MacOSXDock(&cocoaApplication_); #else dock_ = new NullDock(); #endif #if defined(SWIFTEN_PLATFORM_MACOSX) uriHandler_ = new QtURIHandler(); #elif defined(SWIFTEN_PLATFORM_WIN32) uriHandler_ = new NullURIHandler(); #else uriHandler_ = new QtDBUSURIHandler(); #endif statusCache_ = new StatusCache(applicationPathProvider_); if (splitter_) { splitter_->show(); } + PlatformAutoUpdaterFactory autoUpdaterFactory; + if (autoUpdaterFactory.isSupported() && settingsHierachy_->getSetting(QtUISettingConstants::ENABLE_SOFTWARE_UPDATES) + && !settingsHierachy_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL).empty()) { + autoUpdater_ = autoUpdaterFactory.createAutoUpdater(updateChannelToFeed(settingsHierachy_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL))); + autoUpdater_->checkForUpdates(); + autoUpdater_->onUpdateStateChanged.connect(boost::bind(&QtSwift::handleAutoUpdaterStateChanged, this, _1)); + + settingsHierachy_->onSettingChanged.connect([&](const std::string& path) { + if (path == QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL.getKey()) { + autoUpdater_->setAppcastFeed(updateChannelToFeed(settingsHierachy_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL))); + autoUpdater_->checkForUpdates(); + } + }); + } + 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(settingsHierachy_, qtSettings_, tabs_, splitter_, systemTrays_[i], chatWindowFactory_, networkFactories_.getTimerFactory(), statusCache_, startMinimized, !emoticons.empty(), enableAdHocCommandOnJID); + QtUIFactory* uiFactory = new QtUIFactory(settingsHierachy_, 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, settingsHierachy_, systemTrays_[i], soundPlayer_, storagesFactory_, certificateStorageFactory_, dock_, notifier_, uriHandler_, &idleDetector_, emoticons, options.count("latency-debug") > 0); mainControllers_.push_back(mainController); } connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(handleAboutToQuit())); - - PlatformAutoUpdaterFactory autoUpdaterFactory; - if (autoUpdaterFactory.isSupported() && settingsHierachy_->getSetting(QtUISettingConstants::ENABLE_SOFTWARE_UPDATES) - && !settingsHierachy_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL).empty()) { - autoUpdater_ = autoUpdaterFactory.createAutoUpdater(updateChannelToFeed(settingsHierachy_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL))); - autoUpdater_->checkForUpdates(); - autoUpdater_->onSuggestRestartToUserToUpdate.connect(boost::bind(&QtSwift::handleRecommendRestartToInstallUpdate, this)); - - settingsHierachy_->onSettingChanged.connect([&](const std::string& path) { - if (path == QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL.getKey()) { - autoUpdater_->setAppcastFeed(updateChannelToFeed(settingsHierachy_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL))); - autoUpdater_->checkForUpdates(); - } - }); - } } QtSwift::~QtSwift() { delete autoUpdater_; for (auto* factory : uiFactories_) { delete factory; } for (auto* controller : mainControllers_) { delete controller; } delete notifier_; for (auto* tray : systemTrays_) { delete tray; } delete tabs_; delete chatWindowFactory_; delete splitter_; delete settingsHierachy_; delete qtSettings_; delete xmlSettings_; delete statusCache_; delete uriHandler_; delete dock_; delete soundPlayer_; delete certificateStorageFactory_; delete storagesFactory_; delete applicationPathProvider_; } void QtSwift::handleAboutToQuit() { #if defined(SWIFTEN_PLATFORM_MACOSX) // This is required so Sparkle knows about the application shutting down // and can update the application in background. CocoaUIHelpers::sendCocoaApplicationWillTerminateNotification(); #endif } -void QtSwift::handleRecommendRestartToInstallUpdate() { - notifier_->showMessage(Notifier::SystemMessage, Q2PSTRING(tr("Swift Update Available")), Q2PSTRING(tr("Restart Swift to update to the new Swift version.")), "", [](){}); +void QtSwift::handleAutoUpdaterStateChanged(AutoUpdater::State updatedState) { + switch (updatedState) { + case AutoUpdater::State::NotCheckedForUpdatesYet: + break; + case AutoUpdater::State::CheckingForUpdate: + break; + case AutoUpdater::State::DownloadingUpdate: + break; + case AutoUpdater::State::ErrorCheckingForUpdate: + break; + case AutoUpdater::State::NoUpdateAvailable: + break; + case AutoUpdater::State::RestartToInstallUpdate: + notifier_->showMessage(Notifier::SystemMessage, Q2PSTRING(tr("Swift Update Available")), Q2PSTRING(tr("Restart Swift to update to the new Swift version.")), "", [](){}); + } } } diff --git a/Swift/QtUI/QtSwift.h b/Swift/QtUI/QtSwift.h index 3ad5714..a7dc3cf 100644 --- a/Swift/QtUI/QtSwift.h +++ b/Swift/QtUI/QtSwift.h @@ -1,101 +1,105 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once -#include <boost/program_options/variables_map.hpp> +#include <string> + #include <boost/program_options/options_description.hpp> +#include <boost/program_options/variables_map.hpp> -#include <Swiften/TLS/PlatformTLSFactories.h> +#include <Swiften/Base/Platform.h> +#include <Swiften/EventLoop/Qt/QtEventLoop.h> #include <Swiften/Network/BoostNetworkFactories.h> -#include <string> -#include "Swiften/Base/Platform.h" -#include "Swiften/EventLoop/Qt/QtEventLoop.h" -#include "QtSettingsProvider.h" +#include <Swiften/TLS/PlatformTLSFactories.h> + +#include <SwifTools/AutoUpdater/AutoUpdater.h> +#include <SwifTools/Idle/ActualIdleDetector.h> +#include <SwifTools/Idle/PlatformIdleQuerier.h> + +#include <Swift/QtUI/QtSettingsProvider.h> + #if defined(SWIFTEN_PLATFORM_MACOSX) -#include "SwifTools/Application/CocoaApplication.h" -#include "CocoaApplicationActivateHelper.h" +#include <SwifTools/Application/CocoaApplication.h> +#include <CocoaApplicationActivateHelper.h> #endif #if defined(SWIFTEN_PLATFORM_WINDOWS) -#include "WindowsNotifier.h" +#include <WindowsNotifier.h> #endif -#include "SwifTools/Idle/PlatformIdleQuerier.h" -#include "SwifTools/Idle/ActualIdleDetector.h" namespace po = boost::program_options; class QSplitter; namespace Swift { class QtUIFactory; class CertificateStorageFactory; class Dock; class Notifier; class StoragesFactory; - class AutoUpdater; class ApplicationPathProvider; class AvatarStorage; class CapsStorage; class MainController; class QtSystemTray; class QtChatTabsBase; class QtChatWindowFactory; class QtSoundPlayer; class QtMUCSearchWindowFactory; class QtUserSearchWindowFactory; class EventLoop; class URIHandler; class SettingsProviderHierachy; class XMLSettingsProvider; class StatusCache; class QtSingleWindow; class QtSwift : public QObject { Q_OBJECT public: QtSwift(const po::variables_map& options); static po::options_description getOptionsDescription(); ~QtSwift(); private slots: void handleAboutToQuit(); - void handleRecommendRestartToInstallUpdate(); + void handleAutoUpdaterStateChanged(AutoUpdater::State updatedState); 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); private: QtEventLoop clientMainThreadCaller_; PlatformTLSFactories tlsFactories_; BoostNetworkFactories networkFactories_; QtChatWindowFactory* chatWindowFactory_; std::vector<MainController*> mainControllers_; std::vector<QtSystemTray*> systemTrays_; std::vector<QtUIFactory*> uiFactories_; QtSettingsProvider* qtSettings_; XMLSettingsProvider* xmlSettings_; SettingsProviderHierachy* settingsHierachy_; QtSingleWindow* splitter_; QtSoundPlayer* soundPlayer_; Dock* dock_; URIHandler* uriHandler_; QtChatTabsBase* tabs_; ApplicationPathProvider* applicationPathProvider_; StoragesFactory* storagesFactory_; CertificateStorageFactory* certificateStorageFactory_; - AutoUpdater* autoUpdater_; + AutoUpdater* autoUpdater_ = nullptr; Notifier* notifier_; StatusCache* statusCache_; PlatformIdleQuerier idleQuerier_; ActualIdleDetector idleDetector_; #if defined(SWIFTEN_PLATFORM_MACOSX) CocoaApplication cocoaApplication_; CocoaApplicationActivateHelper cocoaApplicationActivateHelper_; #endif }; } diff --git a/Swift/QtUI/QtUIFactory.cpp b/Swift/QtUI/QtUIFactory.cpp index 9eed822..16952a0 100644 --- a/Swift/QtUI/QtUIFactory.cpp +++ b/Swift/QtUI/QtUIFactory.cpp @@ -1,120 +1,120 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #include <Swift/QtUI/QtUIFactory.h> #include <algorithm> #include <QSplitter> #include <Swiften/Whiteboard/WhiteboardSession.h> #include <Swift/Controllers/Settings/SettingsProviderHierachy.h> #include <Swift/QtUI/MUCSearch/QtMUCSearchWindow.h> #include <Swift/QtUI/QtAdHocCommandWindow.h> #include <Swift/QtUI/QtBlockListEditorWindow.h> #include <Swift/QtUI/QtChatTabs.h> #include <Swift/QtUI/QtChatTabsBase.h> #include <Swift/QtUI/QtChatWindow.h> #include <Swift/QtUI/QtChatWindowFactory.h> #include <Swift/QtUI/QtContactEditWindow.h> #include <Swift/QtUI/QtFileTransferListWidget.h> #include <Swift/QtUI/QtHighlightEditor.h> #include <Swift/QtUI/QtHistoryWindow.h> #include <Swift/QtUI/QtJoinMUCWindow.h> #include <Swift/QtUI/QtLoginWindow.h> #include <Swift/QtUI/QtMainWindow.h> #include <Swift/QtUI/QtProfileWindow.h> #include <Swift/QtUI/QtSettingsProvider.h> #include <Swift/QtUI/QtSingleWindow.h> #include <Swift/QtUI/QtSwiftUtil.h> #include <Swift/QtUI/QtSystemTray.h> #include <Swift/QtUI/QtUISettingConstants.h> #include <Swift/QtUI/QtXMLConsoleWidget.h> #include <Swift/QtUI/UserSearch/QtUserSearchWindow.h> #include <Swift/QtUI/Whiteboard/QtWhiteboardWindow.h> namespace Swift { -QtUIFactory::QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabsBase* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, bool startMinimized, bool emoticonsExist, bool enableAdHocCommandOnJID) : settings(settings), qtOnlySettings(qtOnlySettings), tabsBase(tabs), netbookSplitter(netbookSplitter), systemTray(systemTray), chatWindowFactory(chatWindowFactory), timerFactory_(timerFactory), lastMainWindow(nullptr), loginWindow(nullptr), statusCache(statusCache), startMinimized(startMinimized), emoticonsExist_(emoticonsExist), enableAdHocCommandOnJID_(enableAdHocCommandOnJID) { +QtUIFactory::QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabsBase* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, AutoUpdater* autoUpdater, bool startMinimized, bool emoticonsExist, bool enableAdHocCommandOnJID) : settings(settings), qtOnlySettings(qtOnlySettings), tabsBase(tabs), netbookSplitter(netbookSplitter), systemTray(systemTray), chatWindowFactory(chatWindowFactory), timerFactory_(timerFactory), lastMainWindow(nullptr), loginWindow(nullptr), statusCache(statusCache), autoUpdater(autoUpdater), startMinimized(startMinimized), emoticonsExist_(emoticonsExist), enableAdHocCommandOnJID_(enableAdHocCommandOnJID) { chatFontSize = settings->getSetting(QtUISettingConstants::CHATWINDOW_FONT_SIZE); historyFontSize_ = settings->getSetting(QtUISettingConstants::HISTORYWINDOW_FONT_SIZE); this->tabs = dynamic_cast<QtChatTabs*>(tabsBase); } XMLConsoleWidget* QtUIFactory::createXMLConsoleWidget() { QtXMLConsoleWidget* widget = new QtXMLConsoleWidget(); tabsBase->addTab(widget); showTabs(); widget->show(); return widget; } HistoryWindow* QtUIFactory::createHistoryWindow(UIEventStream* uiEventStream) { QtHistoryWindow* window = new QtHistoryWindow(settings, uiEventStream); tabsBase->addTab(window); showTabs(); connect(window, SIGNAL(fontResized(int)), this, SLOT(handleHistoryWindowFontResized(int))); window->handleFontResized(historyFontSize_); window->show(); return window; } void QtUIFactory::handleHistoryWindowFontResized(int size) { historyFontSize_ = size; settings->storeSetting(QtUISettingConstants::HISTORYWINDOW_FONT_SIZE, size); } FileTransferListWidget* QtUIFactory::createFileTransferListWidget() { QtFileTransferListWidget* widget = new QtFileTransferListWidget(); tabsBase->addTab(widget); showTabs(); widget->show(); return widget; } MainWindow* QtUIFactory::createMainWindow(UIEventStream* eventStream) { lastMainWindow = new QtMainWindow(settings, eventStream, loginWindow->getMenus(), statusCache, emoticonsExist_, enableAdHocCommandOnJID_); if (tabs) { tabs->setViewMenu(lastMainWindow->getMenus()[0]); } return lastMainWindow; } LoginWindow* QtUIFactory::createLoginWindow(UIEventStream* eventStream) { - loginWindow = new QtLoginWindow(eventStream, settings, timerFactory_); + loginWindow = new QtLoginWindow(eventStream, settings, timerFactory_, autoUpdater); if (netbookSplitter) { netbookSplitter->insertAtFront(loginWindow); } connect(systemTray, SIGNAL(clicked()), loginWindow, SLOT(toggleBringToFront())); #ifndef SWIFT_MOBILE QVariant loginWindowGeometryVariant = qtOnlySettings->getQSettings()->value("loginWindowGeometry"); if (loginWindowGeometryVariant.isValid()) { loginWindow->restoreGeometry(loginWindowGeometryVariant.toByteArray()); } connect(loginWindow, SIGNAL(geometryChanged()), this, SLOT(handleLoginWindowGeometryChanged())); if (startMinimized) loginWindow->hide(); #endif return loginWindow; } void QtUIFactory::handleLoginWindowGeometryChanged() { qtOnlySettings->getQSettings()->setValue("loginWindowGeometry", loginWindow->saveGeometry()); } EventWindow* QtUIFactory::createEventWindow() { return lastMainWindow->getEventWindow(); } ChatListWindow* QtUIFactory::createChatListWindow(UIEventStream*) { return lastMainWindow->getChatListWindow(); } MUCSearchWindow* QtUIFactory::createMUCSearchWindow() { return new QtMUCSearchWindow(); diff --git a/Swift/QtUI/QtUIFactory.h b/Swift/QtUI/QtUIFactory.h index ce3b533..18bf9fe 100644 --- a/Swift/QtUI/QtUIFactory.h +++ b/Swift/QtUI/QtUIFactory.h @@ -1,84 +1,86 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ #pragma once #include <vector> #include <QObject> #include <QPointer> #include <Swift/Controllers/UIInterfaces/UIFactory.h> class QSplitter; namespace Swift { + class AutoUpdater; class QtChatTabs; class QtChatTabsBase; class QtChatTheme; class QtChatWindow; class QtChatWindowFactory; class QtLoginWindow; class QtMainWindow; class QtSettingsProvider; class QtSingleWindow; class QtSystemTray; class SettingsProviderHierachy; class StatusCache; class TimerFactory; class WhiteboardSession; class QtUIFactory : public QObject, public UIFactory { Q_OBJECT public: - QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabsBase* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, bool startMinimized, bool emoticonsExist, bool enableAdHocCommandOnJID); + QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabsBase* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, AutoUpdater* autoUpdater, bool startMinimized, bool emoticonsExist, bool enableAdHocCommandOnJID); virtual XMLConsoleWidget* createXMLConsoleWidget(); virtual HistoryWindow* createHistoryWindow(UIEventStream*); virtual MainWindow* createMainWindow(UIEventStream* eventStream); virtual LoginWindow* createLoginWindow(UIEventStream* eventStream); virtual EventWindow* createEventWindow(); virtual ChatListWindow* createChatListWindow(UIEventStream*); virtual MUCSearchWindow* createMUCSearchWindow(); virtual ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream); virtual UserSearchWindow* createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream, const std::set<std::string>& groups); virtual JoinMUCWindow* createJoinMUCWindow(UIEventStream* uiEventStream); virtual ProfileWindow* createProfileWindow(); virtual ContactEditWindow* createContactEditWindow(); virtual FileTransferListWidget* createFileTransferListWidget(); virtual WhiteboardWindow* createWhiteboardWindow(std::shared_ptr<WhiteboardSession> whiteboardSession); virtual HighlightEditorWindow* createHighlightEditorWindow(); virtual BlockListEditorWidget* createBlockListEditorWidget(); virtual AdHocCommandWindow* createAdHocCommandWindow(std::shared_ptr<OutgoingAdHocCommandSession> command); private slots: void handleLoginWindowGeometryChanged(); void handleChatWindowFontResized(int); void handleHistoryWindowFontResized(int); private: void showTabs(); private: SettingsProviderHierachy* settings; QtSettingsProvider* qtOnlySettings; QtChatTabsBase* tabsBase; QtChatTabs* tabs; QtSingleWindow* netbookSplitter; QtSystemTray* systemTray; QtChatWindowFactory* chatWindowFactory; TimerFactory* timerFactory_; QtMainWindow* lastMainWindow; QtLoginWindow* loginWindow; StatusCache* statusCache; + AutoUpdater* autoUpdater; std::vector<QPointer<QtChatWindow> > chatWindows; bool startMinimized; int chatFontSize; int historyFontSize_; bool emoticonsExist_; bool enableAdHocCommandOnJID_; }; } |