summaryrefslogtreecommitdiffstats
path: root/Swift
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2016-11-11 11:28:53 (GMT)
committerTobias Markmann <tm@ayena.de>2016-11-11 13:50:52 (GMT)
commit97c87cf3e9b5e150152898e7907577c3ca3fdd86 (patch)
tree17c23b1a10537261e0d1e662493cc4ddf137026c /Swift
parent94ec9c25311f8d54519f045205d58526d885412a (diff)
downloadswift-97c87cf3e9b5e150152898e7907577c3ca3fdd86.zip
swift-97c87cf3e9b5e150152898e7907577c3ca3fdd86.tar.bz2
Add update channel configuration dialog to the about window
If software updates are enabled the about dialog will show the currently configured update channel and provides a link to a dialog to change the update channel. Test-Information: Builds on macOS 10.12.1, unit tests pass, and dialogs behave as expected. Did not test Sparkle updating. Change-Id: I05d5014f0d719ba9b2146c1e599db4f7fde80558
Diffstat (limited to 'Swift')
-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
12 files changed, 399 insertions, 13 deletions
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
@@ -20,10 +20,13 @@
#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
@@ -46,6 +49,19 @@ QtAboutWidget::QtAboutWidget() : QDialog() {
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));
}
@@ -89,6 +105,11 @@ 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);
@@ -108,4 +129,35 @@ void QtAboutWidget::openPlainTextWindow(const QString& path) {
}
}
+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
@@ -6,20 +6,33 @@
#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
@@ -442,7 +442,7 @@ void QtLoginWindow::handleCertficateChecked(bool checked) {
void QtLoginWindow::handleAbout() {
if (!aboutDialog_) {
- aboutDialog_ = new QtAboutWidget();
+ aboutDialog_ = new QtAboutWidget(settings_);
aboutDialog_->show();
}
else {
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
@@ -51,6 +51,7 @@
#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>
@@ -84,12 +85,6 @@
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()
@@ -141,6 +136,22 @@ void QtSwift::loadEmoticonsFile(const QString& fileName, std::map<std::string, s
}
}
+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);
@@ -285,10 +296,18 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa
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();
+ }
+ });
}
}
@@ -328,7 +347,7 @@ void QtSwift::handleAboutToQuit() {
}
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
@@ -67,6 +67,7 @@ namespace Swift {
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_;
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
@@ -6,6 +6,8 @@
#include <Swift/QtUI/QtUISettingConstants.h>
+#include <Swift/QtUI/SwiftUpdateFeeds.h>
+
namespace Swift {
const SettingsProvider::Setting<bool> QtUISettingConstants::COMPACT_ROSTER("compactRoster", false);
@@ -22,4 +24,6 @@ const SettingsProvider::Setting<std::string> QtUISettingConstants::SPELL_CHECKER
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
@@ -6,6 +6,8 @@
#pragma once
+#include <string>
+
#include <Swift/Controllers/Settings/SettingsProvider.h>
namespace Swift {
@@ -37,10 +39,15 @@ namespace Swift {
*/
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
@@ -199,6 +199,7 @@ sources = [
"QtURLValidator.cpp",
"QtResourceHelper.cpp",
"QtSpellCheckHighlighter.cpp",
+ "QtUpdateFeedSelectionDialog.cpp",
"Trellis/QtDynamicGridLayout.cpp",
"Trellis/QtDNDTabBar.cpp",
"Trellis/QtGridSelectionDialog.cpp"
@@ -299,6 +300,7 @@ 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")
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
+}
+
+}