aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/updateinfo
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@theqtcompany.com>2015-05-19 15:15:15 +0200
committerJarek Kobus <jaroslaw.kobus@theqtcompany.com>2015-06-16 11:12:12 +0000
commit13fcf5ad3c3705ae87556b2072889daa519ff1b3 (patch)
treef10166badfeec45a1b26b7a67aefc7cd9550bc65 /src/plugins/updateinfo
parent41ea69248cc6d49838c4c00072635ae9b1d4227a (diff)
Refactor UpdateInfo plugin
Change-Id: I63fc40b12e29204d9ecd4ed3fd33e7ad3171918d Reviewed-by: Eike Ziller <eike.ziller@theqtcompany.com>
Diffstat (limited to 'src/plugins/updateinfo')
-rw-r--r--src/plugins/updateinfo/settingspage.cpp125
-rw-r--r--src/plugins/updateinfo/settingspage.h10
-rw-r--r--src/plugins/updateinfo/settingspage.ui278
-rw-r--r--src/plugins/updateinfo/updateinfo.pro2
-rw-r--r--src/plugins/updateinfo/updateinfo.qbs2
-rw-r--r--src/plugins/updateinfo/updateinfobutton.cpp77
-rw-r--r--src/plugins/updateinfo/updateinfobutton.h52
-rw-r--r--src/plugins/updateinfo/updateinfoplugin.cpp336
-rw-r--r--src/plugins/updateinfo/updateinfoplugin.h57
9 files changed, 456 insertions, 483 deletions
diff --git a/src/plugins/updateinfo/settingspage.cpp b/src/plugins/updateinfo/settingspage.cpp
index 6565760dc0..291424fd41 100644
--- a/src/plugins/updateinfo/settingspage.cpp
+++ b/src/plugins/updateinfo/settingspage.cpp
@@ -29,21 +29,31 @@
****************************************************************************/
#include "settingspage.h"
-#include "updateinfoplugin.h"
#include <coreplugin/coreconstants.h>
+#include <utils/qtcassert.h>
+#include <utils/progressindicator.h>
+
+#include <QDate>
using namespace UpdateInfo;
using namespace UpdateInfo::Internal;
+namespace {
+
+static const char FILTER_OPTIONS_PAGE_ID[] = "Update";
+static const char FILTER_OPTIONS_PAGE[] = QT_TRANSLATE_NOOP("Update", "Update");
+
+}
+
SettingsPage::SettingsPage(UpdateInfoPlugin *plugin)
: m_widget(0)
, m_plugin(plugin)
{
- setId(Constants::FILTER_OPTIONS_PAGE);
+ setId(FILTER_OPTIONS_PAGE_ID);
setCategory(Core::Constants::SETTINGS_CATEGORY_CORE);
setCategoryIcon(QLatin1String(Core::Constants::SETTINGS_CATEGORY_CORE_ICON));
- setDisplayName(QCoreApplication::translate("Update", UpdateInfo::Constants::FILTER_OPTIONS_PAGE));
+ setDisplayName(QCoreApplication::translate("Update", FILTER_OPTIONS_PAGE));
setDisplayCategory(QCoreApplication::translate("Core", Core::Constants::SETTINGS_TR_CATEGORY_CORE));
}
@@ -52,17 +62,116 @@ QWidget *SettingsPage::widget()
if (!m_widget) {
m_widget = new QWidget;
m_ui.setupUi(m_widget);
- m_ui.m_timeTable->setItemText(m_ui.m_timeTable->currentIndex(), QTime(m_plugin->scheduledUpdateTime())
- .toString(QLatin1String("hh:mm")));
+ m_ui.m_checkIntervalComboBox->addItem(tr("Daily"), UpdateInfoPlugin::DailyCheck);
+ m_ui.m_checkIntervalComboBox->addItem(tr("Weekly"), UpdateInfoPlugin::WeeklyCheck);
+ m_ui.m_checkIntervalComboBox->addItem(tr("Monthly"), UpdateInfoPlugin::MonthlyCheck);
+ UpdateInfoPlugin::CheckUpdateInterval interval = m_plugin->checkUpdateInterval();
+ for (int i = 0; i < m_ui.m_checkIntervalComboBox->count(); i++) {
+ if (m_ui.m_checkIntervalComboBox->itemData(i).toInt() == interval) {
+ m_ui.m_checkIntervalComboBox->setCurrentIndex(i);
+ break;
+ }
+ }
+
+ m_ui.m_updatesGroupBox->setChecked(m_plugin->isAutomaticCheck());
+
+ updateLastCheckDate();
+ checkRunningChanged(m_plugin->isCheckForUpdatesRunning());
+
+ connect(m_ui.m_checkNowButton, &QPushButton::clicked,
+ m_plugin, &UpdateInfoPlugin::startCheckForUpdates);
+ connect(m_ui.m_checkIntervalComboBox,
+ static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+ this, &SettingsPage::updateNextCheckDate);
+ connect(m_plugin, &UpdateInfoPlugin::lastCheckDateChanged,
+ this, &SettingsPage::updateLastCheckDate);
+ connect(m_plugin, &UpdateInfoPlugin::checkForUpdatesRunningChanged,
+ this, &SettingsPage::checkRunningChanged);
+ connect(m_plugin, &UpdateInfoPlugin::newUpdatesAvailable,
+ this, &SettingsPage::newUpdatesAvailable);
}
return m_widget;
}
+UpdateInfoPlugin::CheckUpdateInterval SettingsPage::currentCheckInterval() const
+{
+ QTC_ASSERT(m_widget, return UpdateInfoPlugin::WeeklyCheck);
+
+ return static_cast<UpdateInfoPlugin::CheckUpdateInterval>
+ (m_ui.m_checkIntervalComboBox->itemData(m_ui.m_checkIntervalComboBox->currentIndex()).toInt());
+}
+
+void SettingsPage::newUpdatesAvailable(bool available)
+{
+ if (!m_widget)
+ return;
+
+ const QString message = available
+ ? tr("New updates are available.")
+ : tr("No new updates are available.");
+ m_ui.m_messageLabel->setText(message);
+}
+
+void SettingsPage::checkRunningChanged(bool running)
+{
+ if (!m_widget)
+ return;
+
+ m_ui.m_checkNowButton->setDisabled(running);
+
+ if (running) {
+ if (!m_progressIndicator) {
+ m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicator::Large);
+ m_progressIndicator->attachToWidget(m_widget);
+ }
+ m_progressIndicator->show();
+ } else {
+ if (m_progressIndicator) {
+ delete m_progressIndicator;
+ }
+ }
+
+ const QString message = running
+ ? tr("Checking for updates...") : QString();
+ m_ui.m_messageLabel->setText(message);
+}
+
+void SettingsPage::updateLastCheckDate()
+{
+ if (!m_widget)
+ return;
+
+ const QDate date = m_plugin->lastCheckDate();
+ QString lastCheckDateString;
+ if (date.isValid())
+ lastCheckDateString = date.toString();
+ else
+ lastCheckDateString = tr("Not checked yet");
+
+ m_ui.m_lastCheckDateLabel->setText(lastCheckDateString);
+
+ updateNextCheckDate();
+}
+
+void SettingsPage::updateNextCheckDate()
+{
+ if (!m_widget)
+ return;
+
+ QDate date = m_plugin->nextCheckDate(currentCheckInterval());
+ if (!date.isValid() || date < QDate::currentDate())
+ date = QDate::currentDate();
+
+ m_ui.m_nextCheckDateLabel->setText(date.toString());
+}
+
void SettingsPage::apply()
{
- m_plugin->setScheduledUpdateTime(QTime::fromString(m_ui.m_timeTable->currentText(),
- QLatin1String("hh:mm")));
- m_plugin->saveSettings();
+ if (!m_widget)
+ return;
+
+ m_plugin->setCheckUpdateInterval(currentCheckInterval());
+ m_plugin->setAutomaticCheck(m_ui.m_updatesGroupBox->isChecked());
}
void SettingsPage::finish()
diff --git a/src/plugins/updateinfo/settingspage.h b/src/plugins/updateinfo/settingspage.h
index 43bdd0b533..77cf685a89 100644
--- a/src/plugins/updateinfo/settingspage.h
+++ b/src/plugins/updateinfo/settingspage.h
@@ -32,11 +32,14 @@
#define SETTINGSPAGE_H
#include "ui_settingspage.h"
+#include "updateinfoplugin.h"
#include <coreplugin/dialogs/ioptionspage.h>
#include <QPointer>
+namespace Utils { class ProgressIndicator; }
+
namespace UpdateInfo {
namespace Internal {
@@ -54,7 +57,14 @@ public:
void finish();
private:
+ void newUpdatesAvailable(bool available);
+ void checkRunningChanged(bool running);
+ void updateLastCheckDate();
+ void updateNextCheckDate();
+ UpdateInfoPlugin::CheckUpdateInterval currentCheckInterval() const;
+
QPointer<QWidget> m_widget;
+ QPointer<Utils::ProgressIndicator> m_progressIndicator;
Ui::SettingsWidget m_ui;
UpdateInfoPlugin *m_plugin;
};
diff --git a/src/plugins/updateinfo/settingspage.ui b/src/plugins/updateinfo/settingspage.ui
index fee80c0e94..d34ef304e6 100644
--- a/src/plugins/updateinfo/settingspage.ui
+++ b/src/plugins/updateinfo/settingspage.ui
@@ -7,21 +7,34 @@
<x>0</x>
<y>0</y>
<width>482</width>
- <height>364</height>
+ <height>242</height>
</rect>
</property>
<property name="windowTitle">
<string>Configure Filters</string>
</property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QGroupBox" name="groupBox">
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0" colspan="4">
+ <widget class="QGroupBox" name="m_updatesGroupBox">
<property name="title">
- <string>Qt Creator Update Settings</string>
+ <string>Automatic Check for Updates</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QLabel" name="m_info">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Check interval basis:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="3">
+ <widget class="QLabel" name="m_infoLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
@@ -29,196 +42,107 @@
</sizepolicy>
</property>
<property name="text">
- <string>Qt Creator automatically runs a scheduled update check on a daily basis. If Qt Creator is not in use on the scheduled time or maintenance is behind schedule, the automatic update check will be run next time Qt Creator starts.</string>
+ <string>Qt Creator automatically runs a scheduled check for updates on a time interval basis. If Qt Creator is not in use on the scheduled date, the automatic check for updates will be performed next time Qt Creator starts.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
- <item>
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="m_checkIntervalComboBox">
+ <property name="currentIndex">
+ <number>-1</number>
</property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>20</width>
+ <width>171</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Run update check daily at:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="m_timeTable">
- <property name="currentIndex">
- <number>12</number>
- </property>
- <item>
- <property name="text">
- <string notr="true">00:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">01:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">02:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">03:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">04:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">05:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">06:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">07:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">08:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">09:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">10:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">11:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">12:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">13:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">14:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">15:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">16:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">17:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">18:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">19:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">20:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">21:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">22:00</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">23:00</string>
- </property>
- </item>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Next check date:</string>
</property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>253</height>
- </size>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="2">
+ <widget class="QLabel" name="m_nextCheckDateLabel">
+ <property name="text">
+ <string/>
</property>
- </spacer>
+ </widget>
</item>
</layout>
</widget>
</item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Last check date:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="m_lastCheckDateLabel">
+ <property name="text">
+ <string>Not checked yet</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>167</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="3">
+ <widget class="QPushButton" name="m_checkNowButton">
+ <property name="text">
+ <string>Check Now</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="4">
+ <widget class="QLabel" name="m_messageLabel">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="4">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>233</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
</layout>
</widget>
<resources/>
diff --git a/src/plugins/updateinfo/updateinfo.pro b/src/plugins/updateinfo/updateinfo.pro
index 7654a4f6c5..8a66ba3898 100644
--- a/src/plugins/updateinfo/updateinfo.pro
+++ b/src/plugins/updateinfo/updateinfo.pro
@@ -1,10 +1,8 @@
QT += network xml
HEADERS += updateinfoplugin.h \
- updateinfobutton.h \
settingspage.h
SOURCES += updateinfoplugin.cpp \
- updateinfobutton.cpp \
settingspage.cpp
FORMS += settingspage.ui
RESOURCES += updateinfo.qrc
diff --git a/src/plugins/updateinfo/updateinfo.qbs b/src/plugins/updateinfo/updateinfo.qbs
index 02161420e3..2a875c4d7f 100644
--- a/src/plugins/updateinfo/updateinfo.qbs
+++ b/src/plugins/updateinfo/updateinfo.qbs
@@ -14,8 +14,6 @@ QtcPlugin {
pluginJsonReplacements: ({"UPDATEINFO_EXPERIMENTAL_STR": (enable ? "false": "true")})
files: [
- "updateinfobutton.cpp",
- "updateinfobutton.h",
"updateinfoplugin.cpp",
"updateinfoplugin.h",
"settingspage.cpp",
diff --git a/src/plugins/updateinfo/updateinfobutton.cpp b/src/plugins/updateinfo/updateinfobutton.cpp
deleted file mode 100644
index e049626923..0000000000
--- a/src/plugins/updateinfo/updateinfobutton.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms and
-** conditions see http://www.qt.io/terms-conditions. For further information
-** use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#include "updateinfobutton.h"
-
-#include <coreplugin/coreconstants.h>
-#include <utils/stylehelper.h>
-
-#include <QIcon>
-#include <QPainter>
-
-
-namespace UpdateInfo {
-namespace Internal {
-
-UpdateInfoButton::UpdateInfoButton(QWidget *parent) :
- QAbstractButton(parent)
-{
- setIcon(QIcon(QLatin1String(":/updateinfo/images/update_available_logo.png")));
-}
-
-//copied from fancytoolbutton
-QSize UpdateInfoButton::minimumSizeHint() const
-{
- return QSize(8, 8);
-}
-
-//copied from fancytoolbutton
-QSize UpdateInfoButton::sizeHint() const
-{
- return iconSize().expandedTo(QSize(64, 38));
-}
-
-//copied from fancytoolbutton and removed unused things
-void UpdateInfoButton::paintEvent(QPaintEvent *event)
-{
- Q_UNUSED(event)
- QPainter painter(this);
-
- QRect iconRect(0, 0, Core::Constants::TARGET_ICON_SIZE, Core::Constants::TARGET_ICON_SIZE);
-
-
- iconRect.moveCenter(rect().center());
- Utils::StyleHelper::drawIconWithShadow(icon(), iconRect, &painter, isEnabled() ? QIcon::Normal : QIcon::Disabled);
-
-}
-
-
-} //Internal
-} //namespace UpdateInfo
diff --git a/src/plugins/updateinfo/updateinfobutton.h b/src/plugins/updateinfo/updateinfobutton.h
deleted file mode 100644
index d99827ee4b..0000000000
--- a/src/plugins/updateinfo/updateinfobutton.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms and
-** conditions see http://www.qt.io/terms-conditions. For further information
-** use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#ifndef UPDATEINFOBUTTON_H
-#define UPDATEINFOBUTTON_H
-
-#include <QAbstractButton>
-
-namespace UpdateInfo {
-namespace Internal {
-
-class UpdateInfoButton : public QAbstractButton
-{
- Q_OBJECT
-public:
- explicit UpdateInfoButton(QWidget *parent = 0);
- void paintEvent(QPaintEvent *event);
- QSize sizeHint() const;
- QSize minimumSizeHint() const;
-};
-
-} //namespace Internal
-} //namespace UpdateInfo
-
-#endif // UPDATEINFOBUTTON_H
diff --git a/src/plugins/updateinfo/updateinfoplugin.cpp b/src/plugins/updateinfo/updateinfoplugin.cpp
index 1def9167f4..b327d2eb2e 100644
--- a/src/plugins/updateinfo/updateinfoplugin.cpp
+++ b/src/plugins/updateinfo/updateinfoplugin.cpp
@@ -30,28 +30,34 @@
#include "settingspage.h"
#include "updateinfoplugin.h"
-#include "updateinfobutton.h"
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
-#include <coreplugin/progressmanager/progressmanager.h>
-#include <coreplugin/progressmanager/futureprogress.h>
#include <coreplugin/settingsdatabase.h>
+#include <coreplugin/shellcommand.h>
+#include <utils/fileutils.h>
-#include <qtconcurrentrun.h>
-
-#include <QBasicTimer>
+#include <QDate>
#include <QDomDocument>
#include <QFile>
-#include <QFutureWatcher>
+#include <QFileInfo>
#include <QMenu>
-#include <QProcess>
+#include <QMessageBox>
+#include <QMetaEnum>
+#include <QProcessEnvironment>
+#include <QTimer>
#include <QtPlugin>
namespace {
+ static const char UpdaterGroup[] = "Updater";
+ static const char MaintenanceToolKey[] = "MaintenanceTool";
+ static const char AutomaticCheckKey[] = "AutomaticCheck";
+ static const char CheckIntervalKey[] = "CheckUpdateInterval";
+ static const char LastCheckDateKey[] = "LastCheckDate";
static const quint32 OneMinute = 60000;
+ static const quint32 OneHour = 3600000;
}
using namespace Core;
@@ -63,47 +69,120 @@ class UpdateInfoPluginPrivate
{
public:
UpdateInfoPluginPrivate()
- : progressUpdateInfoButton(0),
- checkUpdateInfoWatcher(0),
- m_settingsPage(0)
- {
- }
+ { }
- QString updaterProgram;
- QString updaterRunUiArgument;
- QString updaterCheckOnlyArgument;
+ QString m_maintenanceTool;
+ ShellCommand *m_checkUpdatesCommand = 0;
+ QString m_collectedOutput;
+ QTimer *m_checkUpdatesTimer = 0;
- QFuture<QDomDocument> lastCheckUpdateInfoTask;
- QPointer<FutureProgress> updateInfoProgress;
- UpdateInfoButton *progressUpdateInfoButton;
- QFutureWatcher<QDomDocument> *checkUpdateInfoWatcher;
-
- QBasicTimer m_timer;
- QDate m_lastDayChecked;
- QTime m_scheduledUpdateTime;
- SettingsPage *m_settingsPage;
+ bool m_automaticCheck = true;
+ UpdateInfoPlugin::CheckUpdateInterval m_checkInterval = UpdateInfoPlugin::WeeklyCheck;
+ QDate m_lastCheckDate;
};
UpdateInfoPlugin::UpdateInfoPlugin()
: d(new UpdateInfoPluginPrivate)
{
+ d->m_checkUpdatesTimer = new QTimer(this);
+ d->m_checkUpdatesTimer->setTimerType(Qt::VeryCoarseTimer);
+ d->m_checkUpdatesTimer->setInterval(OneHour);
+ connect(d->m_checkUpdatesTimer, &QTimer::timeout,
+ this, &UpdateInfoPlugin::doAutoCheckForUpdates);
}
UpdateInfoPlugin::~UpdateInfoPlugin()
{
- d->lastCheckUpdateInfoTask.cancel();
- d->lastCheckUpdateInfoTask.waitForFinished();
+ stopCheckForUpdates();
+ if (!d->m_maintenanceTool.isEmpty())
+ saveSettings();
delete d;
}
+void UpdateInfoPlugin::startAutoCheckForUpdates()
+{
+ doAutoCheckForUpdates();
+
+ d->m_checkUpdatesTimer->start();
+}
+
+void UpdateInfoPlugin::stopAutoCheckForUpdates()
+{
+ d->m_checkUpdatesTimer->stop();
+}
+
+void UpdateInfoPlugin::doAutoCheckForUpdates()
+{
+ if (d->m_checkUpdatesCommand)
+ return; // update task is still running (might have been run manually just before)
+
+ if (nextCheckDate().isValid() && nextCheckDate() > QDate::currentDate())
+ return; // not a time for check yet
+
+ startCheckForUpdates();
+}
+
+void UpdateInfoPlugin::startCheckForUpdates()
+{
+ stopCheckForUpdates();
+
+ d->m_checkUpdatesCommand = new ShellCommand(QString(), QProcessEnvironment());
+ connect(d->m_checkUpdatesCommand, &ShellCommand::stdOutText, this, &UpdateInfoPlugin::collectCheckForUpdatesOutput);
+ connect(d->m_checkUpdatesCommand, &ShellCommand::finished, this, &UpdateInfoPlugin::checkForUpdatesFinished);
+ d->m_checkUpdatesCommand->addJob(Utils::FileName(QFileInfo(d->m_maintenanceTool)), QStringList(QLatin1String("--checkupdates")));
+ d->m_checkUpdatesCommand->execute();
+ emit checkForUpdatesRunningChanged(true);
+}
+
+void UpdateInfoPlugin::stopCheckForUpdates()
+{
+ if (!d->m_checkUpdatesCommand)
+ return;
+
+ d->m_collectedOutput = QString();
+ d->m_checkUpdatesCommand->disconnect();
+ d->m_checkUpdatesCommand->cancel();
+ d->m_checkUpdatesCommand = 0;
+ emit checkForUpdatesRunningChanged(false);
+}
+
+void UpdateInfoPlugin::collectCheckForUpdatesOutput(const QString &contents)
+{
+ d->m_collectedOutput += contents;
+}
+
+void UpdateInfoPlugin::checkForUpdatesFinished()
+{
+ setLastCheckDate(QDate::currentDate());
+
+ QDomDocument document;
+ document.setContent(d->m_collectedOutput);
+
+ stopCheckForUpdates();
+
+ if (!document.isNull() && document.firstChildElement().hasChildNodes()) {
+ emit newUpdatesAvailable(true);
+ if (QMessageBox::question(0, tr("Updater"),
+ tr("New updates are available. Do you want to start update?"))
+ == QMessageBox::Yes)
+ startUpdater();
+ } else {
+ emit newUpdatesAvailable(false);
+ }
+}
+
+bool UpdateInfoPlugin::isCheckForUpdatesRunning() const
+{
+ return d->m_checkUpdatesCommand;
+}
+
bool UpdateInfoPlugin::delayedInitialize()
{
- d->checkUpdateInfoWatcher = new QFutureWatcher<QDomDocument>(this);
- connect(d->checkUpdateInfoWatcher, SIGNAL(finished()), this, SLOT(parseUpdates()));
+ if (isAutomaticCheck())
+ QTimer::singleShot(OneMinute, this, &UpdateInfoPlugin::startAutoCheckForUpdates);
- d->m_timer.start(OneMinute, this);
return true;
}
@@ -114,167 +193,132 @@ void UpdateInfoPlugin::extensionsInitialized()
bool UpdateInfoPlugin::initialize(const QStringList & /* arguments */, QString *errorMessage)
{
loadSettings();
- if (d->updaterProgram.isEmpty()) {
+
+ if (d->m_maintenanceTool.isEmpty()) {
*errorMessage = tr("Could not determine location of maintenance tool. Please check "
"your installation if you did not enable this plugin manually.");
return false;
}
- if (!QFile::exists(d->updaterProgram)) {
- *errorMessage = tr("Could not find maintenance tool at \"%1\". Check your installation.")
- .arg(d->updaterProgram);
+ if (!QFileInfo(d->m_maintenanceTool).isExecutable()) {
+ *errorMessage = tr("The maintenance tool at \"%1\" is not an executable. Check your installation.")
+ .arg(d->m_maintenanceTool);
+ d->m_maintenanceTool = QString();
return false;
}
- d->m_settingsPage = new SettingsPage(this);
- addAutoReleasedObject(d->m_settingsPage);
+ connect(ICore::instance(), &ICore::saveSettingsRequested,
+ this, &UpdateInfoPlugin::saveSettings);
+
+ addAutoReleasedObject(new SettingsPage(this));
- ActionContainer *const container = ActionManager::actionContainer(Core::Constants::M_HELP);
- container->menu()->addAction(tr("Start Updater"), this, SLOT(startUpdaterUiApplication()));
+ QAction *checkForUpdatesAction = new QAction(tr("Check for Updates"), this);
+ Core::Command *checkForUpdatesCommand = Core::ActionManager::registerAction(checkForUpdatesAction, "Updates.CheckForUpdates");
+ connect(checkForUpdatesAction, &QAction::triggered, this, &UpdateInfoPlugin::startCheckForUpdates);
+ ActionContainer *const helpContainer = ActionManager::actionContainer(Core::Constants::M_HELP);
+ helpContainer->addAction(checkForUpdatesCommand, Constants::G_HELP_UPDATES);
return true;
}
-void UpdateInfoPlugin::loadSettings()
+void UpdateInfoPlugin::loadSettings() const
{
- QSettings *qs = ICore::settings();
- if (qs->contains(QLatin1String("Updater/Application"))) {
- settingsHelper(qs);
- qs->remove(QLatin1String("Updater"));
- saveSettings(); // update to the new settings location
- } else {
- settingsHelper(ICore::settingsDatabase());
+ QSettings *settings = ICore::settings();
+ const QString updaterKey = QLatin1String(UpdaterGroup) + QLatin1Char('/');
+ d->m_maintenanceTool = settings->value(updaterKey + QLatin1String(MaintenanceToolKey)).toString();
+ d->m_lastCheckDate = settings->value(updaterKey + QLatin1String(LastCheckDateKey), QDate()).toDate();
+ d->m_automaticCheck = settings->value(updaterKey + QLatin1String(AutomaticCheckKey), true).toBool();
+ const QString checkInterval = settings->value(updaterKey + QLatin1String(CheckIntervalKey)).toString();
+ const QMetaObject *mo = metaObject();
+ const QMetaEnum me = mo->enumerator(mo->indexOfEnumerator(CheckIntervalKey));
+ if (me.isValid()) {
+ bool ok = false;
+ const int newValue = me.keyToValue(checkInterval.toUtf8(), &ok);
+ if (ok)
+ d->m_checkInterval = static_cast<CheckUpdateInterval>(newValue);
}
}
void UpdateInfoPlugin::saveSettings()
{
- SettingsDatabase *settings = ICore::settingsDatabase();
- if (settings) {
- settings->beginTransaction();
- settings->beginGroup(QLatin1String("Updater"));
- settings->setValue(QLatin1String("Application"), d->updaterProgram);
- settings->setValue(QLatin1String("LastDayChecked"), d->m_lastDayChecked);
- settings->setValue(QLatin1String("RunUiArgument"), d->updaterRunUiArgument);
- settings->setValue(QLatin1String("CheckOnlyArgument"), d->updaterCheckOnlyArgument);
- settings->setValue(QLatin1String("ScheduledUpdateTime"), d->m_scheduledUpdateTime);
- settings->endGroup();
- settings->endTransaction();
- }
+ QSettings *settings = ICore::settings();
+ settings->beginGroup(QLatin1String(UpdaterGroup));
+ settings->setValue(QLatin1String(LastCheckDateKey), d->m_lastCheckDate);
+ settings->setValue(QLatin1String(AutomaticCheckKey), d->m_automaticCheck);
+ // Note: don't save MaintenanceToolKey on purpose! This setting may be set only by installer.
+ // If creator is run not from installed SDK, the setting can be manually created here:
+ // [CREATOR_INSTALLATION_LOCATION]/share/qtcreator/QtProject/QtCreator.ini or
+ // [CREATOR_INSTALLATION_LOCATION]/Qt Creator.app/Contents/Resources/QtProject/QtCreator.ini on OS X
+ const QMetaObject *mo = metaObject();
+ const QMetaEnum me = mo->enumerator(mo->indexOfEnumerator(CheckIntervalKey));
+ settings->setValue(QLatin1String(CheckIntervalKey), QLatin1String(me.valueToKey(d->m_checkInterval)));
+ settings->endGroup();
}
-QTime UpdateInfoPlugin::scheduledUpdateTime() const
+bool UpdateInfoPlugin::isAutomaticCheck() const
{
- return d->m_scheduledUpdateTime;
+ return d->m_automaticCheck;
}
-void UpdateInfoPlugin::setScheduledUpdateTime(const QTime &time)
+void UpdateInfoPlugin::setAutomaticCheck(bool on)
{
- d->m_scheduledUpdateTime = time;
-}
+ if (d->m_automaticCheck == on)
+ return;
-// -- protected
+ d->m_automaticCheck = on;
+ if (on)
+ startAutoCheckForUpdates();
+ else
+ stopAutoCheckForUpdates();
+}
-void UpdateInfoPlugin::timerEvent(QTimerEvent *event)
+UpdateInfoPlugin::CheckUpdateInterval UpdateInfoPlugin::checkUpdateInterval() const
{
- if (event->timerId() == d->m_timer.timerId()) {
- const QDate today = QDate::currentDate();
- if ((d->m_lastDayChecked == today) || (d->lastCheckUpdateInfoTask.isRunning()))
- return; // we checked already or the update task is still running
-
- bool check = false;
- if (d->m_lastDayChecked <= today.addDays(-2))
- check = true; // we haven't checked since some days, force check
-
- if (QTime::currentTime() > d->m_scheduledUpdateTime)
- check = true; // we are behind schedule, force check
-
- if (check) {
- d->lastCheckUpdateInfoTask = QtConcurrent::run(this, &UpdateInfoPlugin::update);
- d->checkUpdateInfoWatcher->setFuture(d->lastCheckUpdateInfoTask);
- }
- } else {
- // not triggered from our timer
- ExtensionSystem::IPlugin::timerEvent(event);
- }
+ return d->m_checkInterval;
}
-// -- private slots
-
-void UpdateInfoPlugin::parseUpdates()
+void UpdateInfoPlugin::setCheckUpdateInterval(UpdateInfoPlugin::CheckUpdateInterval interval)
{
- QDomDocument updatesDomDocument = d->checkUpdateInfoWatcher->result();
- if (updatesDomDocument.isNull() || !updatesDomDocument.firstChildElement().hasChildNodes())
+ if (d->m_checkInterval == interval)
return;
- // add the finished task to the progress manager
- d->updateInfoProgress
- = ProgressManager::addTask(d->lastCheckUpdateInfoTask, tr("Updates Available"),
- "Update.GetInfo", ProgressManager::KeepOnFinish);
- d->updateInfoProgress->setKeepOnFinish(FutureProgress::KeepOnFinish);
-
- d->progressUpdateInfoButton = new UpdateInfoButton();
- d->updateInfoProgress->setWidget(d->progressUpdateInfoButton);
- connect(d->progressUpdateInfoButton, SIGNAL(released()), this, SLOT(startUpdaterUiApplication()));
+ d->m_checkInterval = interval;
}
-void UpdateInfoPlugin::startUpdaterUiApplication()
+QDate UpdateInfoPlugin::lastCheckDate() const
{
- QProcess::startDetached(d->updaterProgram, QStringList() << d->updaterRunUiArgument);
- if (!d->updateInfoProgress.isNull()) //this is fading out the last update info
- d->updateInfoProgress->setKeepOnFinish(FutureProgress::HideOnFinish);
+ return d->m_lastCheckDate;
}
-// -- private
-
-QDomDocument UpdateInfoPlugin::update()
+void UpdateInfoPlugin::setLastCheckDate(const QDate &date)
{
- if (QThread::currentThread() == QCoreApplication::instance()->thread()) {
- qWarning() << Q_FUNC_INFO << " was not designed to run in main/ gui thread, it is using "
- "QProcess::waitForFinished()";
- }
-
- // start
- QProcess updater;
- updater.start(d->updaterProgram, QStringList() << d->updaterCheckOnlyArgument);
- while (updater.state() != QProcess::NotRunning) {
- if (!updater.waitForFinished(1000)
- && d->lastCheckUpdateInfoTask.isCanceled()) {
- updater.kill();
- updater.waitForFinished(-1);
- return QDomDocument();
- }
- }
-
- // process return value
- QDomDocument updates;
- if (updater.exitStatus() != QProcess::CrashExit) {
- d->m_timer.stop();
- updates.setContent(updater.readAllStandardOutput());
- saveSettings(); // force writing out the last update date
- } else {
- qWarning() << "Updater application crashed.";
- }
+ if (d->m_lastCheckDate == date)
+ return;
- d->m_lastDayChecked = QDate::currentDate();
- return updates;
+ d->m_lastCheckDate = date;
+ emit lastCheckDateChanged(date);
}
-template <typename T>
-void UpdateInfoPlugin::settingsHelper(T *settings)
+QDate UpdateInfoPlugin::nextCheckDate() const
{
- settings->beginGroup(QLatin1String("Updater"));
+ return nextCheckDate(d->m_checkInterval);
+}
- d->updaterProgram = settings->value(QLatin1String("Application")).toString();
- d->m_lastDayChecked = settings->value(QLatin1String("LastDayChecked"), QDate()).toDate();
- d->updaterRunUiArgument = settings->value(QLatin1String("RunUiArgument"),
- QLatin1String("--updater")).toString();
- d->updaterCheckOnlyArgument = settings->value(QLatin1String("CheckOnlyArgument"),
- QLatin1String("--checkupdates")).toString();
- d->m_scheduledUpdateTime = settings->value(QLatin1String("ScheduledUpdateTime"), QTime(12, 0))
- .toTime();
+QDate UpdateInfoPlugin::nextCheckDate(CheckUpdateInterval interval) const
+{
+ if (!d->m_lastCheckDate.isValid())
+ return QDate();
+
+ if (interval == DailyCheck)
+ return d->m_lastCheckDate.addDays(1);
+ if (interval == WeeklyCheck)
+ return d->m_lastCheckDate.addDays(7);
+ return d->m_lastCheckDate.addMonths(1);
+}
- settings->endGroup();
+void UpdateInfoPlugin::startUpdater()
+{
+ QProcess::startDetached(d->m_maintenanceTool, QStringList(QLatin1String("--updater")));
}
} //namespace Internal
diff --git a/src/plugins/updateinfo/updateinfoplugin.h b/src/plugins/updateinfo/updateinfoplugin.h
index 6f4c0576cf..69862e1be5 100644
--- a/src/plugins/updateinfo/updateinfoplugin.h
+++ b/src/plugins/updateinfo/updateinfoplugin.h
@@ -33,26 +33,28 @@
#include <extensionsystem/iplugin.h>
-#include <QTime>
-#include <QDomDocument>
+QT_BEGIN_NAMESPACE
+class QDate;
+QT_END_NAMESPACE
namespace UpdateInfo {
-namespace Constants {
- const char FILTER_OPTIONS_PAGE[] = QT_TRANSLATE_NOOP("Update", "Update");
-} // namespace Constants
-
namespace Internal {
-class SettingsPage;
class UpdateInfoPluginPrivate;
class UpdateInfoPlugin : public ExtensionSystem::IPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "UpdateInfo.json")
-
+ Q_ENUMS(CheckUpdateInterval)
public:
+ enum CheckUpdateInterval {
+ DailyCheck,
+ WeeklyCheck,
+ MonthlyCheck
+ };
+
UpdateInfoPlugin();
virtual ~UpdateInfoPlugin();
@@ -60,22 +62,39 @@ public:
void extensionsInitialized();
bool initialize(const QStringList &arguments, QString *errorMessage);
- void loadSettings();
- void saveSettings();
+ bool isAutomaticCheck() const;
+ void setAutomaticCheck(bool on);
+
+ CheckUpdateInterval checkUpdateInterval() const;
+ void setCheckUpdateInterval(CheckUpdateInterval interval);
- QTime scheduledUpdateTime() const;
- void setScheduledUpdateTime(const QTime &time);
+ QDate lastCheckDate() const;
+ QDate nextCheckDate() const;
+ QDate nextCheckDate(CheckUpdateInterval interval) const;
-protected:
- void timerEvent(QTimerEvent *event);
+ bool isCheckForUpdatesRunning() const;
+ void startCheckForUpdates();
-private slots:
- void parseUpdates();
- void startUpdaterUiApplication();
+signals:
+ void lastCheckDateChanged(const QDate &date);
+ void newUpdatesAvailable(bool available);
+ void checkForUpdatesRunningChanged(bool running);
private:
- QDomDocument update();
- template <typename T> void settingsHelper(T *settings);
+ void setLastCheckDate(const QDate &date);
+
+ void startAutoCheckForUpdates();
+ void stopAutoCheckForUpdates();
+ void doAutoCheckForUpdates();
+
+ void startUpdater();
+ void stopCheckForUpdates();
+
+ void collectCheckForUpdatesOutput(const QString &contents);
+ void checkForUpdatesFinished();
+
+ void loadSettings() const;
+ void saveSettings();
private:
UpdateInfoPluginPrivate *d;