diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index eb802cf6f8..b09371ae0d 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -215,6 +215,7 @@ class CuraApplication(QtApplication): self.setRequiredPlugins([ "CuraEngineBackend", + "UserAgreement", "SolidView", "LayerView", "STLReader", @@ -304,6 +305,8 @@ class CuraApplication(QtApplication): preferences.addPreference("view/invert_zoom", False) + self._need_to_show_user_agreement = not Preferences.getInstance().getValue("general/accepted_user_agreement") + for key in [ "dialog_load_path", # dialog_save_path is in LocalFileOutputDevicePlugin "dialog_profile_path", @@ -376,6 +379,14 @@ class CuraApplication(QtApplication): def _onEngineCreated(self): self._engine.addImageProvider("camera", CameraImageProvider.CameraImageProvider()) + @pyqtProperty(bool) + def needToShowUserAgreement(self): + return self._need_to_show_user_agreement + + + def setNeedToShowUserAgreement(self, set_value = True): + self._need_to_show_user_agreement = set_value + ## The "Quit" button click event handler. @pyqtSlot() def closeApplication(self): diff --git a/plugins/ChangeLogPlugin/ChangeLog.py b/plugins/ChangeLogPlugin/ChangeLog.py index 8d1e54f40c..a80779da50 100644 --- a/plugins/ChangeLogPlugin/ChangeLog.py +++ b/plugins/ChangeLogPlugin/ChangeLog.py @@ -8,7 +8,6 @@ from UM.Application import Application from UM.PluginRegistry import PluginRegistry from UM.Version import Version -from PyQt5.QtQuick import QQuickView from PyQt5.QtQml import QQmlComponent, QQmlContext from PyQt5.QtCore import QUrl, pyqtSlot, QObject diff --git a/plugins/UserAgreementPlugin/UserAgreement.py b/plugins/UserAgreementPlugin/UserAgreement.py new file mode 100644 index 0000000000..f472b6fb13 --- /dev/null +++ b/plugins/UserAgreementPlugin/UserAgreement.py @@ -0,0 +1,53 @@ +# Copyright (c) 2017 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from UM.Extension import Extension +from UM.Preferences import Preferences +from UM.Application import Application +from UM.PluginRegistry import PluginRegistry +from UM.Logger import Logger + +from cura.CuraApplication import CuraApplication + +from PyQt5.QtQml import QQmlComponent, QQmlContext +from PyQt5.QtCore import QUrl, QObject, pyqtSlot + +import os.path + +class UserAgreement(QObject, Extension): + def __init__(self, parent = None): + super(UserAgreement, self).__init__() + self._user_agreement_window = None + self._user_agreement_context = None + Application.getInstance().engineCreatedSignal.connect(self._onEngineCreated) + Preferences.getInstance().addPreference("general/accepted_user_agreement", False) + + def _onEngineCreated(self): + if not Preferences.getInstance().getValue("general/accepted_user_agreement"): + self.showUserAgreement() + + def showUserAgreement(self): + if not self._user_agreement_window: + self.createUserAgreementWindow() + + self._user_agreement_window.show() + + @pyqtSlot(bool) + def didAgree(self, userChoice): + if userChoice: + Logger.log("i", "User agreed to the user agreement") + Preferences.getInstance().setValue("general/accepted_user_agreement", True) + self._user_agreement_window.hide() + else: + Logger.log("i", "User did NOT agree to the user agreement") + Preferences.getInstance().setValue("general/accepted_user_agreement", False) + CuraApplication.getInstance().quit() + CuraApplication.getInstance().setNeedToShowUserAgreement(False) + + def createUserAgreementWindow(self): + path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "UserAgreement.qml")) + + component = QQmlComponent(Application.getInstance()._engine, path) + self._user_agreement_context = QQmlContext(Application.getInstance()._engine.rootContext()) + self._user_agreement_context.setContextProperty("manager", self) + self._user_agreement_window = component.create(self._user_agreement_context) diff --git a/plugins/UserAgreementPlugin/UserAgreement.qml b/plugins/UserAgreementPlugin/UserAgreement.qml new file mode 100644 index 0000000000..52d35a4f44 --- /dev/null +++ b/plugins/UserAgreementPlugin/UserAgreement.qml @@ -0,0 +1,64 @@ +// Copyright (c) 2017 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.4 + +import UM 1.3 as UM + +UM.Dialog +{ + id: baseDialog + minimumWidth: Math.floor(UM.Theme.getSize("modal_window_minimum").width * 0.75) + minimumHeight: Math.floor(UM.Theme.getSize("modal_window_minimum").height * 0.5) + width: minimumWidth + height: minimumHeight + title: catalog.i18nc("@title:window", "User Agreement") + + TextArea + { + anchors.top: parent.top + width: parent.width + anchors.bottom: buttonRow.top + text: '
PLEASE READ THIS DISCLAIMER CAREFULLY.
+EXCEPT WHEN OTHERWISE STATED IN WRITING, ULTIMAKER PROVIDES ANY ULTIMAKER SOFTWARE OR THIRD PARTY SOFTWARE “AS IS” WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF ULTIMAKER SOFTWARE IS WITH YOU.
+UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, IN NO EVENT WILL ULTIMAKER BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE ANY ULTIMAKER SOFTWARE OR THIRD PARTY SOFTWARE.
+ ' + readOnly: true; + textFormat: TextEdit.RichText + } + + Item + { + id: buttonRow + anchors.bottom: parent.bottom + width: parent.width + anchors.bottomMargin: UM.Theme.getSize("default_margin").height + + UM.I18nCatalog { id: catalog; name:"cura" } + + Button + { + anchors.right: parent.right + text: catalog.i18nc("@action:button", "I understand and agree") + onClicked: { + manager.didAgree(true) + } + } + + Button + { + anchors.left: parent.left + text: catalog.i18nc("@action:button", "I don't agree") + onClicked: { + manager.didAgree(false) + } + } + + } + + onClosing: { + manager.didAgree(false) + } +} diff --git a/plugins/UserAgreementPlugin/__init__.py b/plugins/UserAgreementPlugin/__init__.py new file mode 100644 index 0000000000..88cb151f9e --- /dev/null +++ b/plugins/UserAgreementPlugin/__init__.py @@ -0,0 +1,10 @@ +# Copyright (c) 2017 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from . import UserAgreement + +def getMetaData(): + return {} + +def register(app): + return {"extension": UserAgreement.UserAgreement()} diff --git a/plugins/UserAgreementPlugin/plugin.json b/plugins/UserAgreementPlugin/plugin.json new file mode 100644 index 0000000000..aa5dbb1258 --- /dev/null +++ b/plugins/UserAgreementPlugin/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "UserAgreement", + "author": "Ultimaker B.V.", + "version": "1.0.0", + "description": "Ask the user once if he/she agrees with our license", + "api": 4, + "i18n-catalog": "cura" +} diff --git a/resources/i18n/cura.pot b/resources/i18n/cura.pot index fb4b9ed0d6..99ccd7a459 100644 --- a/resources/i18n/cura.pot +++ b/resources/i18n/cura.pot @@ -18,6 +18,21 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" +#Manually added for plugins/UserAgreementPlugin/UserAgreement.qml +msgctxt "@title:window" +msgid "User Agreement" +msgstr "" + +#Manually added for plugins/UserAgreementPlugin/UserAgreement.qml +msgctxt "@action:button" +msgid "I understand and agree" +msgstr "" + +#Manually added for plugins/UserAgreementPlugin/UserAgreement.qml +msgctxt "@action:button" +msgid "I don't agree" +msgstr "" + #: Manually added for plugins/UM3NetworkPrinting/PrinterInfoBlock.qml msgctxt "@label:status" msgid "Print aborted" diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index cb0211f29f..2fd19a8a03 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -894,6 +894,11 @@ UM.MainWindow if(!base.visible) { base.visible = true; + } + + // check later if the user agreement dialog has been closed + if (CuraApplication.needToShowUserAgreement) + { restart(); } else if(Cura.MachineManager.activeMachineId == null || Cura.MachineManager.activeMachineId == "")