diff --git a/Orange/canvas/__main__.py b/Orange/canvas/__main__.py
index 194ba52d7c8..08ab034893d 100644
--- a/Orange/canvas/__main__.py
+++ b/Orange/canvas/__main__.py
@@ -7,6 +7,7 @@
import sys
import gc
import re
+import time
import logging
from logging.handlers import RotatingFileHandler
import optparse
@@ -19,7 +20,7 @@
from AnyQt.QtGui import QFont, QColor, QDesktopServices
from AnyQt.QtWidgets import QMessageBox
-from AnyQt.QtCore import Qt, QDir, QUrl, QSettings
+from AnyQt.QtCore import Qt, QDir, QUrl, QSettings, QThread, pyqtSignal
from Orange import canvas
from Orange.canvas.application.application import CanvasApplication
@@ -85,6 +86,82 @@ def make_sql_logger(level=logging.INFO):
sql_log.addHandler(handler)
+def show_survey():
+ # If run for the first time, open a browser tab with a survey
+ settings = QSettings()
+ show_survey = settings.value("startup/show-survey", True, type=bool)
+ if show_survey:
+ question = QMessageBox(
+ QMessageBox.Question,
+ 'Orange Survey',
+ 'We would like to know more about how our software is used.\n\n'
+ 'Would you care to fill our short 1-minute survey?',
+ QMessageBox.Yes | QMessageBox.No)
+ question.setDefaultButton(QMessageBox.Yes)
+ later = question.addButton('Ask again later', QMessageBox.NoRole)
+ question.setEscapeButton(later)
+
+ def handle_response(result):
+ if result == QMessageBox.Yes:
+ success = QDesktopServices.openUrl(
+ QUrl("https://orange.biolab.si/survey/short.html"))
+ settings.setValue("startup/show-survey", not success)
+ else:
+ settings.setValue("startup/show-survey", result != QMessageBox.No)
+
+ question.finished.connect(handle_response)
+ question.show()
+ return question
+
+
+def check_for_updates():
+ settings = QSettings()
+ check_updates = settings.value('startup/check-updates', True, type=bool)
+ last_check_time = settings.value('startup/last-update-check-time', 0, type=int)
+ ONE_DAY = 86400
+
+ if check_updates and time.time() - last_check_time > ONE_DAY:
+ settings.setValue('startup/last-update-check-time', int(time.time()))
+
+ from urllib.request import urlopen
+ from distutils.version import LooseVersion
+ from Orange.version import version as current
+
+ class GetLatestVersion(QThread):
+ resultReady = pyqtSignal(str)
+
+ def run(self):
+ try:
+ self.resultReady.emit(
+ urlopen('https://orange.biolab.si/version', timeout=10).read().decode())
+ except OSError:
+ log.exception('Failed to check for updates')
+
+ def compare_versions(latest):
+ if LooseVersion(latest) <= LooseVersion(current):
+ return
+ question = QMessageBox(
+ QMessageBox.Information,
+ 'Orange Update Available',
+ 'A newer version of Orange is available.
'
+ 'Current version: {}
'
+ 'Latest version: {}'.format(current, latest),
+ textFormat=Qt.RichText)
+ ok = question.addButton('Download Now', question.AcceptRole)
+ question.setDefaultButton(ok)
+ question.addButton('Remind Later', question.RejectRole)
+ question.finished.connect(
+ lambda:
+ question.clickedButton() == ok and
+ QDesktopServices.openUrl(QUrl("https://orange.biolab.si/download/")))
+ question.show()
+
+ thread = GetLatestVersion()
+ thread.resultReady.connect(compare_versions)
+ thread.start()
+ return thread
+
+
def main(argv=None):
if argv is None:
argv = sys.argv
@@ -328,29 +405,9 @@ def show_message(message):
open_requests[-1])
canvas_window.load_scheme(open_requests[-1].toLocalFile())
- # If run for the first time, open a browser tab with a survey
- show_survey = settings.value("startup/show-survey", True, type=bool)
- if show_survey:
- question = QMessageBox(
- QMessageBox.Question,
- 'Orange Survey',
- 'We would like to know more about how our software is used.\n\n'
- 'Would you care to fill our short 1-minute survey?',
- QMessageBox.Yes | QMessageBox.No)
- question.setDefaultButton(QMessageBox.Yes)
- later = question.addButton('Ask again later', QMessageBox.NoRole)
- question.setEscapeButton(later)
-
- def handle_response(result):
- if result == QMessageBox.Yes:
- success = QDesktopServices.openUrl(
- QUrl("http://orange.biolab.si/survey/short.html"));
- settings.setValue("startup/show-survey", not success)
- else:
- settings.setValue("startup/show-survey", result != QMessageBox.No)
-
- question.finished.connect(handle_response)
- question.show()
+ # local references prevent destruction
+ _ = show_survey()
+ __ = check_for_updates()
# Tee stdout and stderr into Output dock
log_view = canvas_window.log_view()
diff --git a/Orange/canvas/application/settings.py b/Orange/canvas/application/settings.py
index 12ed6b22ea2..1560d9fb893 100644
--- a/Orange/canvas/application/settings.py
+++ b/Orange/canvas/application/settings.py
@@ -303,13 +303,18 @@ def __setupUi(self):
objectName="show-splash-screen")
cb_welcome = QCheckBox(self.tr("Show welcome screen"), self,
- objectName="show-welcome-screen")
+ objectName="show-welcome-screen")
+
+ cb_updates = QCheckBox(self.tr("Check for updates"), self,
+ objectName="check-updates")
self.bind(cb_splash, "checked", "startup/show-splash-screen")
self.bind(cb_welcome, "checked", "startup/show-welcome-screen")
+ self.bind(cb_updates, "checked", "startup/check-updates")
startup.layout().addWidget(cb_splash)
startup.layout().addWidget(cb_welcome)
+ startup.layout().addWidget(cb_updates)
form.addRow(self.tr("On startup"), startup)
diff --git a/Orange/canvas/config.py b/Orange/canvas/config.py
index cd7ab145f30..5bbdfc498f5 100644
--- a/Orange/canvas/config.py
+++ b/Orange/canvas/config.py
@@ -55,6 +55,9 @@ def init():
("startup/show-welcome-screen", bool, True,
"Show Welcome screen at startup"),
+ ("startup/check-updates", bool, True,
+ "Check for updates"),
+
("stylesheet", str, "orange",
"QSS stylesheet to use"),