summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--SwifTools/AutoUpdater/AutoUpdater.h3
-rw-r--r--SwifTools/AutoUpdater/SparkleAutoUpdater.h3
-rw-r--r--SwifTools/AutoUpdater/SparkleAutoUpdater.mm9
-rw-r--r--Swift/QtUI/QtAboutWidget.cpp54
-rw-r--r--Swift/QtUI/QtAboutWidget.h15
-rw-r--r--Swift/QtUI/QtLoginWindow.cpp2
-rw-r--r--Swift/QtUI/QtSwift.cpp37
-rw-r--r--Swift/QtUI/QtSwift.h1
-rw-r--r--Swift/QtUI/QtUISettingConstants.cpp4
-rw-r--r--Swift/QtUI/QtUISettingConstants.h9
-rw-r--r--Swift/QtUI/QtUpdateFeedSelectionDialog.cpp83
-rw-r--r--Swift/QtUI/QtUpdateFeedSelectionDialog.h30
-rw-r--r--Swift/QtUI/QtUpdateFeedSelectionDialog.ui146
-rw-r--r--Swift/QtUI/SConscript2
-rw-r--r--Swift/QtUI/SwiftUpdateFeeds.h29
15 files changed, 411 insertions, 16 deletions
diff --git a/SwifTools/AutoUpdater/AutoUpdater.h b/SwifTools/AutoUpdater/AutoUpdater.h
index ed53e11..274bf50 100644
--- a/SwifTools/AutoUpdater/AutoUpdater.h
+++ b/SwifTools/AutoUpdater/AutoUpdater.h
@@ -1,27 +1,30 @@
/*
* Copyright (c) 2010-2016 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:
virtual ~AutoUpdater();
+ virtual void setAppcastFeed(const std::string& appcastFeed) = 0;
virtual void checkForUpdates() = 0;
virtual bool recommendRestartToUpdate() = 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;
};
}
diff --git a/SwifTools/AutoUpdater/SparkleAutoUpdater.h b/SwifTools/AutoUpdater/SparkleAutoUpdater.h
index 41a25f0..dd22e73 100644
--- a/SwifTools/AutoUpdater/SparkleAutoUpdater.h
+++ b/SwifTools/AutoUpdater/SparkleAutoUpdater.h
@@ -1,33 +1,34 @@
/*
* Copyright (c) 2010-2016 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& url);
+ SparkleAutoUpdater(const std::string& appcastFeed);
~SparkleAutoUpdater();
+ void setAppcastFeed(const std::string& appcastFeed);
void checkForUpdates();
bool recommendRestartToUpdate();
private:
class Private;
const std::unique_ptr<Private> d;
};
}
diff --git a/SwifTools/AutoUpdater/SparkleAutoUpdater.mm b/SwifTools/AutoUpdater/SparkleAutoUpdater.mm
index 6b27ba7..ed5f094 100644
--- a/SwifTools/AutoUpdater/SparkleAutoUpdater.mm
+++ b/SwifTools/AutoUpdater/SparkleAutoUpdater.mm
@@ -1,57 +1,62 @@
/*
* Copyright (c) 2016 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;
};
-SparkleAutoUpdater::SparkleAutoUpdater(const std::string& url) : d(new Private()) {
+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->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(url)];
+ NSURL* nsurl = [NSURL URLWithString: std2NSString(appcastFeed)];
[d->updater setFeedURL: nsurl];
}
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]; // This is useful for testing to force a check ot start.
[d->updater checkForUpdatesInBackground];
}
bool SparkleAutoUpdater::recommendRestartToUpdate() {
return d->restartToUpdate;
}
}
diff --git a/Swift/QtUI/QtAboutWidget.cpp b/Swift/QtUI/QtAboutWidget.cpp
index d90e35a..9047525 100644
--- a/Swift/QtUI/QtAboutWidget.cpp
+++ b/Swift/QtUI/QtAboutWidget.cpp
@@ -1,111 +1,163 @@
/*
* Copyright (c) 2010-2016 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 <QPushButton>
#include <QTextEdit>
#include <QTextStream>
#include <QVBoxLayout>
#include <QtGlobal>
#include <Swiften/Base/Log.h>
#include <Swiften/Base/Platform.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() : QDialog() {
+QtAboutWidget::QtAboutWidget(SettingsProvider* settingsProvider) : QDialog(), settingsProvider_(settingsProvider) {
#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();
+ }
+ });
+
+ updateInfoLabel_ = new QLabel("", this);
+ updateInfoLabel_->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse);
+ connect(updateInfoLabel_, SIGNAL(linkActivated(const QString &)), this, SLOT(handleChangeUpdateChannelClicked()));
+ mainLayout->addWidget(updateInfoLabel_);
+
+ updateUpdateInfoLabel();
+
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);
buttonLayout->addWidget(closeButton);
connect(closeButton, SIGNAL(clicked()), this, SLOT(accept()));
#endif
setFixedSize(minimumSizeHint());
}
void QtAboutWidget::handleLicenseClicked() {
openPlainTextWindow(":/COPYING");
}
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() {
+ 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();
+ }
+ }
+ else {
+ updateInfoLabel_->hide();
+ }
+
+}
+
}
diff --git a/Swift/QtUI/QtAboutWidget.h b/Swift/QtUI/QtAboutWidget.h
index c8b0356..fb54c6e 100644
--- a/Swift/QtUI/QtAboutWidget.h
+++ b/Swift/QtUI/QtAboutWidget.h
@@ -1,25 +1,38 @@
/*
* Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <boost/signals2/connection.hpp>
+
#include <QDialog>
+class QLabel;
+
namespace Swift {
+ class SettingsProvider;
+
class QtAboutWidget : public QDialog {
Q_OBJECT
public:
- QtAboutWidget();
+ QtAboutWidget(SettingsProvider* settings);
private slots:
void handleLicenseClicked();
void handleChangelogClicked();
+ void handleChangeUpdateChannelClicked();
private:
void openPlainTextWindow(const QString& path);
+ void updateUpdateInfoLabel();
+
+ private:
+ SettingsProvider* settingsProvider_;
+ QLabel* updateInfoLabel_ = nullptr;
+ boost::signals2::scoped_connection settingsChangedConnection_;
};
}
diff --git a/Swift/QtUI/QtLoginWindow.cpp b/Swift/QtUI/QtLoginWindow.cpp
index 6e9510d..d91f694 100644
--- a/Swift/QtUI/QtLoginWindow.cpp
+++ b/Swift/QtUI/QtLoginWindow.cpp
@@ -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();
+ aboutDialog_ = new QtAboutWidget(settings_);
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/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp
index 3aff999..3f6ce8e 100644
--- a/Swift/QtUI/QtSwift.cpp
+++ b/Swift/QtUI/QtSwift.cpp
@@ -24,150 +24,161 @@
#include <Swiften/Base/Platform.h>
#include <Swiften/Client/Client.h>
#include <Swiften/Elements/Presence.h>
#include <Swiften/TLS/TLSContextFactory.h>
#include <SwifTools/Application/PlatformApplicationPathProvider.h>
#include <SwifTools/AutoUpdater/AutoUpdater.h>
#include <SwifTools/AutoUpdater/PlatformAutoUpdaterFactory.h>
#include <Swift/Controllers/ApplicationInfo.h>
#include <Swift/Controllers/BuildVersion.h>
#include <Swift/Controllers/MainController.h>
#include <Swift/Controllers/SettingConstants.h>
#include <Swift/Controllers/Settings/SettingsProviderHierachy.h>
#include <Swift/Controllers/Settings/XMLSettingsProvider.h>
#include <Swift/Controllers/StatusCache.h>
#include <Swift/Controllers/Storages/CertificateFileStorageFactory.h>
#include <Swift/Controllers/Storages/FileStoragesFactory.h>
#include <Swift/QtUI/QtChatTabs.h>
#include <Swift/QtUI/QtChatTabsBase.h>
#include <Swift/QtUI/QtChatTabsShortcutOnlySubstitute.h>
#include <Swift/QtUI/QtChatWindowFactory.h>
#include <Swift/QtUI/QtLoginWindow.h>
#include <Swift/QtUI/QtSingleWindow.h>
#include <Swift/QtUI/QtSoundPlayer.h>
#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/QtSystemTray.h>
#include <Swift/QtUI/QtUIFactory.h>
#include <Swift/QtUI/QtUISettingConstants.h>
+#include <Swift/QtUI/SwiftUpdateFeeds.h>
#if defined(SWIFTEN_PLATFORM_WINDOWS)
#include <Swift/QtUI/WindowsNotifier.h>
#elif defined(HAVE_GROWL)
#include <SwifTools/Notifier/GrowlNotifier.h>
#elif defined(SWIFTEN_PLATFORM_LINUX)
#include <Swift/QtUI/FreeDesktopNotifier.h>
#elif defined(SWIFTEN_PLATFORM_MACOSX)
#include <SwifTools/Notifier/NotificationCenterNotifier.h>
#else
#include <SwifTools/Notifier/NullNotifier.h>
#endif
#if defined(SWIFTEN_PLATFORM_MACOSX)
#include <SwifTools/Dock/MacOSXDock.h>
#else
#include <SwifTools/Dock/NullDock.h>
#endif
#if defined(SWIFTEN_PLATFORM_MACOSX)
#include <Swift/QtUI/QtURIHandler.h>
#elif defined(SWIFTEN_PLATFORM_WIN32)
#include <SwifTools/URIHandler/NullURIHandler.h>
#else
#include <Swift/QtUI/QtDBUSURIHandler.h>
#endif
#if defined(SWIFTEN_PLATFORM_MACOSX)
#include <Swift/QtUI/CocoaUIHelpers.h>
#endif
namespace Swift{
-#if defined(SWIFTEN_PLATFORM_MACOSX)
-#define SWIFT_APPCAST_URL "https://swift.im/appcast/swift-mac-dev.xml"
-#else
-#define SWIFT_APPCAST_URL ""
-#endif
-
po::options_description QtSwift::getOptionsDescription() {
po::options_description result("Options");
result.add_options()
("debug", "Turn on debug logging")
("help", "Show this help message")
("version", "Show version information")
("netbook-mode", "Use netbook mode display (unsupported)")
("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 JID's.")
#if QT_VERSION >= 0x040800
("language", po::value<std::string>(), "Use a specific language, instead of the system-wide one")
#endif
;
return result;
}
XMLSettingsProvider* QtSwift::loadSettingsFile(const QString& fileName) {
QFile configFile(fileName);
if (configFile.exists() && configFile.open(QIODevice::ReadOnly)) {
QString xmlString;
while (!configFile.atEnd()) {
QByteArray line = configFile.readLine();
xmlString += line + "\n";
}
return new XMLSettingsProvider(Q2PSTRING(xmlString));
}
return new XMLSettingsProvider("");
}
void QtSwift::loadEmoticonsFile(const QString& fileName, std::map<std::string, std::string>& emoticons) {
QFile file(fileName);
if (file.exists() && file.open(QIODevice::ReadOnly)) {
while (!file.atEnd()) {
QString line = file.readLine();
line.replace("\n", "");
line.replace("\r", "");
QStringList tokens = line.split(" ");
if (tokens.size() == 2) {
QString emoticonFile = tokens[1];
if (!emoticonFile.startsWith(":/") && !emoticonFile.startsWith("qrc:/")) {
emoticonFile = "file://" + emoticonFile;
}
emoticons[Q2PSTRING(tokens[0])] = Q2PSTRING(emoticonFile);
}
}
}
}
+const std::string& QtSwift::updateChannelToFeed(const std::string& channel) {
+ static const std::string invalidChannel;
+ if (channel == UpdateFeeds::StableChannel) {
+ return UpdateFeeds::StableAppcastFeed;
+ }
+ else if (channel == UpdateFeeds::TestingChannel) {
+ return UpdateFeeds::TestingAppcastFeed;
+ }
+ else if (channel == UpdateFeeds::DevelopmentChannel) {
+ return UpdateFeeds::DevelopmentAppcastFeed;
+ }
+ else {
+ return invalidChannel;
+ }
+}
+
QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMainThreadCaller_), autoUpdater_(nullptr), idleDetector_(&idleQuerier_, networkFactories_.getTimerFactory(), 1000) {
QCoreApplication::setApplicationName(SWIFT_APPLICATION_NAME);
QCoreApplication::setOrganizationName(SWIFT_ORGANIZATION_NAME);
QCoreApplication::setOrganizationDomain(SWIFT_ORGANIZATION_DOMAIN);
QCoreApplication::setApplicationVersion(buildVersion);
qtSettings_ = new QtSettingsProvider();
xmlSettings_ = loadSettingsFile(P2QSTRING(pathToString(Paths::getExecutablePath() / "system-settings.xml")));
settingsHierachy_ = new SettingsProviderHierachy();
settingsHierachy_->addProviderToTopOfStack(xmlSettings_);
settingsHierachy_->addProviderToTopOfStack(qtSettings_);
networkFactories_.getTLSContextFactory()->setDisconnectOnCardRemoval(settingsHierachy_->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);
if (options.count("netbook-mode")) {
splitter_ = new QtSingleWindow(qtSettings_);
} else {
splitter_ = nullptr;
}
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;
@@ -258,77 +269,85 @@ 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(settingsHierachy_, qtSettings_, tabs_, splitter_, systemTrays_[i], chatWindowFactory_, networkFactories_.getTimerFactory(), statusCache_, 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)) {
- autoUpdater_ = autoUpdaterFactory.createAutoUpdater(SWIFT_APPCAST_URL);
+ 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 splitter_;
delete settingsHierachy_;
delete qtSettings_;
delete xmlSettings_;
delete statusCache_;
delete uriHandler_;
delete dock_;
delete soundPlayer_;
delete chatWindowFactory_;
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 now or later to update to the new Swift version")), "", [](){});
+ 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 64b79b8..3ad5714 100644
--- a/Swift/QtUI/QtSwift.h
+++ b/Swift/QtUI/QtSwift.h
@@ -40,60 +40,61 @@ namespace Swift {
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();
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_;
Notifier* notifier_;
StatusCache* statusCache_;
PlatformIdleQuerier idleQuerier_;
ActualIdleDetector idleDetector_;
#if defined(SWIFTEN_PLATFORM_MACOSX)
CocoaApplication cocoaApplication_;
CocoaApplicationActivateHelper cocoaApplicationActivateHelper_;
#endif
};
diff --git a/Swift/QtUI/QtUISettingConstants.cpp b/Swift/QtUI/QtUISettingConstants.cpp
index c81a234..24cc6dc 100644
--- a/Swift/QtUI/QtUISettingConstants.cpp
+++ b/Swift/QtUI/QtUISettingConstants.cpp
@@ -1,25 +1,29 @@
/*
* Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/QtUISettingConstants.h>
+#include <Swift/QtUI/SwiftUpdateFeeds.h>
+
namespace Swift {
const SettingsProvider::Setting<bool> QtUISettingConstants::COMPACT_ROSTER("compactRoster", false);
const SettingsProvider::Setting<std::string> QtUISettingConstants::CLICKTHROUGH_BANNER("clickthroughBanner", "");
const SettingsProvider::Setting<int> QtUISettingConstants::CURRENT_ROSTER_TAB("currentRosterTab", 0);
const SettingsProvider::Setting<bool> QtUISettingConstants::SHOW_NICK_IN_ROSTER_HEADER("showNickInRosterHeader", true);
const SettingsProvider::Setting<int> QtUISettingConstants::CHATWINDOW_FONT_SIZE("chatWindowFontSize", 0);
const SettingsProvider::Setting<int> QtUISettingConstants::HISTORYWINDOW_FONT_SIZE("historyWindowFontSize", 0);
const SettingsProvider::Setting<bool> QtUISettingConstants::SHOW_EMOTICONS("showEmoticons", true);
const SettingsProvider::Setting<bool> QtUISettingConstants::USE_PLAIN_CHATS("plainChats", false);
const SettingsProvider::Setting<bool> QtUISettingConstants::USE_SCREENREADER("screenreader", false);
const SettingsProvider::Setting<bool> QtUISettingConstants::SPELL_CHECKER("spellChecker", false);
const SettingsProvider::Setting<std::string> QtUISettingConstants::SPELL_CHECKER_LANGUAGE("spellCheckerLanguage", "en_US");
const SettingsProvider::Setting<std::string> QtUISettingConstants::TRELLIS_GRID_SIZE("trellisGridSize", "");
const SettingsProvider::Setting<std::string> QtUISettingConstants::TRELLIS_GRID_POSITIONS("trellisGridPositions", "");
const SettingsProvider::Setting<bool> QtUISettingConstants::ENABLE_SOFTWARE_UPDATES("enableSoftwareUpdates", true);
+const SettingsProvider::Setting<std::string> QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL("softwareUpdateChannel", UpdateFeeds::StableChannel);
+
}
diff --git a/Swift/QtUI/QtUISettingConstants.h b/Swift/QtUI/QtUISettingConstants.h
index 4616656..a569587 100644
--- a/Swift/QtUI/QtUISettingConstants.h
+++ b/Swift/QtUI/QtUISettingConstants.h
@@ -1,46 +1,53 @@
/*
* Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <string>
+
#include <Swift/Controllers/Settings/SettingsProvider.h>
namespace Swift {
class QtUISettingConstants {
public:
static const SettingsProvider::Setting<bool> COMPACT_ROSTER;
static const SettingsProvider::Setting<std::string> CLICKTHROUGH_BANNER;
static const SettingsProvider::Setting<int> CURRENT_ROSTER_TAB;
static const SettingsProvider::Setting<bool> SHOW_NICK_IN_ROSTER_HEADER;
static const SettingsProvider::Setting<int> CHATWINDOW_FONT_SIZE;
static const SettingsProvider::Setting<int> HISTORYWINDOW_FONT_SIZE;
static const SettingsProvider::Setting<bool> SHOW_EMOTICONS;
static const SettingsProvider::Setting<bool> USE_PLAIN_CHATS;
static const SettingsProvider::Setting<bool> USE_SCREENREADER;
static const SettingsProvider::Setting<bool> SPELL_CHECKER;
static const SettingsProvider::Setting<std::string> SPELL_CHECKER_LANGUAGE;
/**
* The #TRELLIS_GRID_SIZE setting specifies the dimensions of the grid used for the trellis
* layout.
*
* Its value is a Qt serialized representation.
*/
static const SettingsProvider::Setting<std::string> TRELLIS_GRID_SIZE;
/**
* The #TRELLIS_GRID_POSITIONS setting specifies where conversations to contacts or rooms go
* in the trellis grid.
*
* Its value is a Qt serialized representation.
*/
static const SettingsProvider::Setting<std::string> TRELLIS_GRID_POSITIONS;
/**
- * The #ENABLE_SOFTWARE_UPDATES settings specifies, whether Swift
+ * The #ENABLE_SOFTWARE_UPDATES setting specifies, whether Swift
* should automatically check for software updates in regular
* intervals and install them automatically.
*/
static const SettingsProvider::Setting<bool> ENABLE_SOFTWARE_UPDATES;
+ /**
+ * The #SOFTWARE_UPDATE_CHANNEL setting defines what update channel
+ * Swift uses to check for, and receive, updates.
+ */
+ static const SettingsProvider::Setting<std::string> SOFTWARE_UPDATE_CHANNEL;
};
}
diff --git a/Swift/QtUI/QtUpdateFeedSelectionDialog.cpp b/Swift/QtUI/QtUpdateFeedSelectionDialog.cpp
new file mode 100644
index 0000000..1f4058a
--- /dev/null
+++ b/Swift/QtUI/QtUpdateFeedSelectionDialog.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtUpdateFeedSelectionDialog.h>
+
+#include <QComboBox>
+
+#include <Swift/Controllers/Settings/SettingsProvider.h>
+
+#include <Swift/QtUI/QtUISettingConstants.h>
+#include <Swift/QtUI/SwiftUpdateFeeds.h>
+
+namespace Swift {
+
+QtUpdateFeedSelectionDialog::QtUpdateFeedSelectionDialog(SettingsProvider* settingsProvider) : QDialog(), settings_(settingsProvider) {
+ ui.setupUi(this);
+
+ connect(ui.currentChannelComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [&] (int newIndex) {
+ setDescriptionForIndex(newIndex);
+ });
+
+ auto updateChannel = settings_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL);
+ if (updateChannel == UpdateFeeds::StableChannel) {
+ ui.currentChannelComboBox->setCurrentIndex(0);
+ }
+ else if (updateChannel == UpdateFeeds::TestingChannel) {
+ ui.currentChannelComboBox->setCurrentIndex(1);
+ }
+ else if (updateChannel == UpdateFeeds::DevelopmentChannel) {
+ ui.currentChannelComboBox->setCurrentIndex(2);
+ }
+
+ connect(this, &QDialog::accepted, [&]() {
+ auto newUpdateChannel = std::string("");
+ switch (ui.currentChannelComboBox->currentIndex()) {
+ case 0:
+ newUpdateChannel = UpdateFeeds::StableChannel;
+ break;
+ case 1:
+ newUpdateChannel = UpdateFeeds::TestingChannel;
+ break;
+ case 2:
+ newUpdateChannel = UpdateFeeds::DevelopmentChannel;
+ break;
+ }
+ settings_->storeSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL, newUpdateChannel);
+ });
+
+ setAttribute(Qt::WA_DeleteOnClose);
+}
+
+void QtUpdateFeedSelectionDialog::setDescriptionForIndex(int index) {
+ switch (index) {
+ case 0:
+ ui.stableDescriptionLabel->show();
+ ui.testingDescriptionLabel->hide();
+ ui.developmentDescriptionLabel->hide();
+ break;
+ case 1:
+ ui.stableDescriptionLabel->hide();
+ ui.testingDescriptionLabel->show();
+ ui.developmentDescriptionLabel->hide();
+ break;
+ case 2:
+ ui.stableDescriptionLabel->hide();
+ ui.testingDescriptionLabel->hide();
+ ui.developmentDescriptionLabel->show();
+ break;
+ default:
+ ui.stableDescriptionLabel->hide();
+ ui.testingDescriptionLabel->hide();
+ ui.developmentDescriptionLabel->hide();
+ break;
+ }
+ setFixedSize(sizeHint());
+}
+
+
+
+}
diff --git a/Swift/QtUI/QtUpdateFeedSelectionDialog.h b/Swift/QtUI/QtUpdateFeedSelectionDialog.h
new file mode 100644
index 0000000..80b986f
--- /dev/null
+++ b/Swift/QtUI/QtUpdateFeedSelectionDialog.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <QDialog>
+
+#include <Swift/QtUI/ui_QtUpdateFeedSelectionDialog.h>
+
+namespace Swift {
+
+class SettingsProvider;
+
+class QtUpdateFeedSelectionDialog : public QDialog {
+ Q_OBJECT
+ public:
+ QtUpdateFeedSelectionDialog(SettingsProvider* settingsProvider);
+
+ private:
+ void setDescriptionForIndex(int index);
+
+ private:
+ Ui::QtUpdateFeedSelectionDialog ui;
+ SettingsProvider* settings_ = nullptr;
+};
+
+}
diff --git a/Swift/QtUI/QtUpdateFeedSelectionDialog.ui b/Swift/QtUI/QtUpdateFeedSelectionDialog.ui
new file mode 100644
index 0000000..4107f3a
--- /dev/null
+++ b/Swift/QtUI/QtUpdateFeedSelectionDialog.ui
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QtUpdateFeedSelectionDialog</class>
+ <widget class="QDialog" name="QtUpdateFeedSelectionDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>335</width>
+ <height>158</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Select Update Channel</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QComboBox" name="currentChannelComboBox">
+ <property name="currentText">
+ <string/>
+ </property>
+ <property name="currentIndex">
+ <number>-1</number>
+ </property>
+ <item>
+ <property name="text">
+ <string>Stable Channel</string>
+ </property>
+ <property name="icon">
+ <iconset theme=":/icons/delivery-success.svg"/>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Testing Channel</string>
+ </property>
+ <property name="icon">
+ <iconset theme=":/icons/delivery-warning.svg"/>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Development Channel</string>
+ </property>
+ <property name="icon">
+ <iconset theme=":/icons/delivery-warning.svg"/>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="stableDescriptionLabel">
+ <property name="text">
+ <string>This release channel includes our stable releases. They went throught internal QA testing and had previous RC releases to find critical bugs.</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignJustify|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::NoTextInteraction</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="testingDescriptionLabel">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>This release channel includes our stable releases, beta releases and release candidates. They should be free from obvious bugs and are released for wider testing to find more obscure bugs.</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignJustify|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="developmentDescriptionLabel">
+ <property name="text">
+ <string>This release channel includes our stable releases, beta releases, release candidates and development releases. The development releases are not thoroughly tested and might contained bugs.</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignJustify|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>QtUpdateFeedSelectionDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>QtUpdateFeedSelectionDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index fd47dd4..acfe7d0 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -172,60 +172,61 @@ sources = [
"MUCSearch/QtMUCSearchWindow.cpp",
"UserSearch/ContactListDelegate.cpp",
"UserSearch/ContactListModel.cpp",
"UserSearch/QtContactListWidget.cpp",
"UserSearch/QtSuggestingJIDInput.cpp",
"UserSearch/QtUserSearchFirstPage.cpp",
"UserSearch/QtUserSearchFirstMultiJIDPage.cpp",
"UserSearch/QtUserSearchFieldsPage.cpp",
"UserSearch/QtUserSearchResultsPage.cpp",
"UserSearch/QtUserSearchDetailsPage.cpp",
"UserSearch/QtUserSearchWindow.cpp",
"UserSearch/UserSearchModel.cpp",
"UserSearch/UserSearchDelegate.cpp",
"Whiteboard/FreehandLineItem.cpp",
"Whiteboard/GView.cpp",
"Whiteboard/TextDialog.cpp",
"Whiteboard/QtWhiteboardWindow.cpp",
"Whiteboard/ColorWidget.cpp",
"QtSubscriptionRequestWindow.cpp",
"QtRosterHeader.cpp",
"QtWebView.cpp",
"qrc_DefaultTheme.cc",
"qrc_Swift.cc",
"QtChatWindowJSBridge.cpp",
"QtMUCConfigurationWindow.cpp",
"QtAffiliationEditor.cpp",
"QtUISettingConstants.cpp",
"QtURLValidator.cpp",
"QtResourceHelper.cpp",
"QtSpellCheckHighlighter.cpp",
+ "QtUpdateFeedSelectionDialog.cpp",
"Trellis/QtDynamicGridLayout.cpp",
"Trellis/QtDNDTabBar.cpp",
"Trellis/QtGridSelectionDialog.cpp"
]
if env["PLATFORM"] == "win32" :
sources.extend(["qrc_SwiftWindows.cc"])
# QtVCardWidget
sources.extend([
"QtVCardWidget/QtCloseButton.cpp",
"QtVCardWidget/QtRemovableItemDelegate.cpp",
"QtVCardWidget/QtResizableLineEdit.cpp",
"QtVCardWidget/QtTagComboBox.cpp",
"QtVCardWidget/QtVCardHomeWork.cpp",
"QtVCardWidget/QtVCardAddressField.cpp",
"QtVCardWidget/QtVCardAddressLabelField.cpp",
"QtVCardWidget/QtVCardBirthdayField.cpp",
"QtVCardWidget/QtVCardDescriptionField.cpp",
"QtVCardWidget/QtVCardInternetEMailField.cpp",
"QtVCardWidget/QtVCardJIDField.cpp",
"QtVCardWidget/QtVCardOrganizationField.cpp",
"QtVCardWidget/QtVCardPhotoAndNameFields.cpp",
"QtVCardWidget/QtVCardRoleField.cpp",
"QtVCardWidget/QtVCardTelephoneField.cpp",
"QtVCardWidget/QtVCardTitleField.cpp",
"QtVCardWidget/QtVCardURLField.cpp",
"QtVCardWidget/QtVCardGeneralField.cpp",
"QtVCardWidget/QtVCardWidget.cpp"
])
@@ -272,60 +273,61 @@ if env["PLATFORM"] == "posix" :
if env["PLATFORM"] == "darwin" :
sources += ["CocoaApplicationActivateHelper.mm"]
sources += ["CocoaUIHelpers.mm"]
if env["PLATFORM"] == "darwin" or env["PLATFORM"] == "win32" :
swiftProgram = myenv.Program("Swift", sources)
else :
sources += ["QtCertificateViewerDialog.cpp"];
myenv.Uic4("QtCertificateViewerDialog.ui");
swiftProgram = myenv.Program("swift-im", sources)
if env["PLATFORM"] != "darwin" and env["PLATFORM"] != "win32" :
openURIProgram = myenv.Program("swift-open-uri", "swift-open-uri.cpp")
else :
openURIProgram = []
myenv.Uic4("MUCSearch/QtMUCSearchWindow.ui")
myenv.Uic4("UserSearch/QtUserSearchWizard.ui")
myenv.Uic4("UserSearch/QtUserSearchFirstPage.ui")
myenv.Uic4("UserSearch/QtUserSearchFirstMultiJIDPage.ui")
myenv.Uic4("UserSearch/QtUserSearchFieldsPage.ui")
myenv.Uic4("UserSearch/QtUserSearchResultsPage.ui")
myenv.Uic4("QtBookmarkDetailWindow.ui")
myenv.Uic4("QtAffiliationEditor.ui")
myenv.Uic4("QtJoinMUCWindow.ui")
myenv.Uic4("QtHistoryWindow.ui")
myenv.Uic4("QtConnectionSettings.ui")
myenv.Uic4("QtHighlightEditor.ui")
myenv.Uic4("QtBlockListEditorWindow.ui")
myenv.Uic4("QtSpellCheckerWindow.ui")
+myenv.Uic4("QtUpdateFeedSelectionDialog.ui")
myenv.Qrc("DefaultTheme.qrc")
myenv.Qrc("Swift.qrc")
if env["PLATFORM"] == "win32" :
myenv.Qrc("SwiftWindows.qrc")
# Resources
commonResources = {
"": ["#/Swift/resources/sounds"]
}
myenv["TEXTFILESUFFIX"] = ""
myenv.MyTextfile(target = "COPYING", source = [myenv.File("../../COPYING.gpl"), myenv.File("../../COPYING.thirdparty")], LINESEPARATOR = "\n\n========\n\n\n")
################################################################################
# Translation
################################################################################
# Collect available languages
translation_languages = []
for file in os.listdir(Dir("#/Swift/Translations").abspath) :
if file.startswith("swift_") and file.endswith(".ts") :
translation_languages.append(file[6:-3])
# Generate translation modules
translation_sources = [env.File("#/Swift/Translations/swift.ts").abspath]
translation_modules = []
for lang in translation_languages :
translation_resource = "#/Swift/resources/translations/swift_" + lang + ".qm"
translation_source = "#/Swift/Translations/swift_" + lang + ".ts"
diff --git a/Swift/QtUI/SwiftUpdateFeeds.h b/Swift/QtUI/SwiftUpdateFeeds.h
new file mode 100644
index 0000000..a6476f5
--- /dev/null
+++ b/Swift/QtUI/SwiftUpdateFeeds.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Base/Platform.h>
+
+namespace Swift {
+
+namespace UpdateFeeds {
+ const std::string StableChannel = "stable";
+ const std::string TestingChannel = "testing";
+ const std::string DevelopmentChannel = "development";
+
+#if defined(SWIFTEN_PLATFORM_MACOSX)
+ const std::string StableAppcastFeed = "https://swift.im/downloads/swift-stable-appcast-mac.xml";
+ const std::string TestingAppcastFeed = "https://swift.im/downloads/swift-testing-appcast-mac.xml";
+ const std::string DevelopmentAppcastFeed = "https://swift.im/downloads/swift-development-appcast-mac.xml";
+#else
+ const std::string StableAppcastFeed = "";
+ const std::string TestingAppcastFeed = "";
+ const std::string DevelopmentAppcastFeed = "";
+#endif
+}
+
+}