diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 42a9ad67f6..31ea96d6df 100644 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -82,17 +82,23 @@ class ThreeMFWorkspaceReader(WorkspaceReader): if machine_conflict or quality_changes_conflict: # There is a conflict; User should choose to either update the existing data, add everything as new data or abort - self._resolve_strategies = {} + self._dialog.setMachineConflict(machine_conflict) + self._dialog.setQualityChangesConflict(quality_changes_conflict) self._dialog.show() self._dialog.waitForClose() - if self._dialog.getResult() == "cancel": + if self._dialog.getResult() == {}: return WorkspaceReader.PreReadResult.cancelled result = self._dialog.getResult() + # If there is no conflict, ignore the data. + print("beep", result) + if not machine_conflict: + result["machine"] = None + if not quality_changes_conflict: + result["quality_changes"] = None - if machine_conflict: - self._resolve_strategies["machine"] = result - if quality_changes_conflict: - self._resolve_strategies["quality_changes"] = result + + self._resolve_strategies = result + print("STRATEGY WAS", self._resolve_strategies) return WorkspaceReader.PreReadResult.accepted diff --git a/plugins/3MFReader/WorkspaceDialog.py b/plugins/3MFReader/WorkspaceDialog.py index ae1280b4bd..c90561e52d 100644 --- a/plugins/3MFReader/WorkspaceDialog.py +++ b/plugins/3MFReader/WorkspaceDialog.py @@ -1,7 +1,8 @@ -from PyQt5.QtCore import Qt, QUrl, pyqtSignal, pyqtSlot, QObject +from PyQt5.QtCore import Qt, QUrl, pyqtSignal, pyqtSlot, QObject, pyqtProperty from PyQt5.QtQml import QQmlComponent, QQmlContext from UM.PluginRegistry import PluginRegistry from UM.Application import Application +from UM.Logger import Logger import os import threading @@ -16,10 +17,36 @@ class WorkspaceDialog(QObject): self._view = None self._qml_url = "WorkspaceDialog.qml" self._lock = threading.Lock() - self._result = None # What option did the user pick? + self._default_strategy = "override" + self._result = {"machine": self._default_strategy, "quality_changes": self._default_strategy} self._visible = False self.showDialogSignal.connect(self.__show) + self._has_quality_changes_conflict = False + self._has_machine_conflict = False + + machineConflictChanged = pyqtSignal() + qualityChangesConflictChanged = pyqtSignal() + + @pyqtProperty(bool, notify = machineConflictChanged) + def machineConflict(self): + return self._has_machine_conflict + + @pyqtProperty(bool, notify=qualityChangesConflictChanged) + def qualityChangesConflict(self): + return self._has_quality_changes_conflict + + @pyqtSlot(str, str) + def setResolveStrategy(self, key, strategy): + if key in self._result: + self._result[key] = strategy + + def setMachineConflict(self, machine_conflict): + self._has_machine_conflict = machine_conflict + + def setQualityChangesConflict(self, quality_changes_conflict): + self._has_quality_changes_conflict = quality_changes_conflict + def getResult(self): return self._result @@ -29,11 +56,15 @@ class WorkspaceDialog(QObject): self._context = QQmlContext(Application.getInstance()._engine.rootContext()) self._context.setContextProperty("manager", self) self._view = self._component.create(self._context) + if self._view is None: + Logger.log("e", "QQmlComponent status %s", self._component.status()) + Logger.log("e", "QQmlComponent errorString %s", self._component.errorString()) def show(self): # Emit signal so the right thread actually shows the view. self._lock.acquire() - self._result = None + # Reset the result + self._result = {"machine": self._default_strategy, "quality_changes": self._default_strategy} self._visible = True self.showDialogSignal.emit() @@ -41,7 +72,7 @@ class WorkspaceDialog(QObject): ## Used to notify the dialog so the lock can be released. def notifyClosed(self): if self._result is None: - self._result = "cancel" + self._result = {} self._lock.release() def hide(self): @@ -50,22 +81,15 @@ class WorkspaceDialog(QObject): self._view.hide() @pyqtSlot() - def onOverrideButtonClicked(self): + def onOkButtonClicked(self): self._view.hide() self.hide() - self._result = "override" - - @pyqtSlot() - def onNewButtonClicked(self): - self._view.hide() - self.hide() - self._result = "new" @pyqtSlot() def onCancelButtonClicked(self): self._view.hide() self.hide() - self._result = "cancel" + self._result = {} ## Block thread until the dialog is closed. def waitForClose(self): @@ -76,4 +100,5 @@ class WorkspaceDialog(QObject): def __show(self): if self._view is None: self._createViewFromQML() - self._view.show() + if self._view: + self._view.show() diff --git a/plugins/3MFReader/WorkspaceDialog.qml b/plugins/3MFReader/WorkspaceDialog.qml index 0c56dbcb6c..6014739c39 100644 --- a/plugins/3MFReader/WorkspaceDialog.qml +++ b/plugins/3MFReader/WorkspaceDialog.qml @@ -10,7 +10,7 @@ import UM 1.1 as UM UM.Dialog { - title: catalog.i18nc("@title:window", "Conflict") + title: catalog.i18nc("@title:window", "Import workspace conflict") width: 350 * Screen.devicePixelRatio; minimumWidth: 350 * Screen.devicePixelRatio; @@ -21,24 +21,114 @@ UM.Dialog maximumHeight: 250 * Screen.devicePixelRatio; onClosing: manager.notifyClosed() - + onVisibleChanged: + { + if(visible) + { + machineResolveComboBox.currentIndex = 0 + qualityChangesResolveComboBox.currentIndex = 0 + } + } Item { - UM.I18nCatalog { id: catalog; name: "cura"; } + anchors.fill: parent + + UM.I18nCatalog + { + id: catalog; + name: "cura"; + } + + ListModel + { + id: resolveStrategiesModel + // Instead of directly adding the list elements, we add them afterwards. + // This is because it's impossible to use setting function results to be bound to listElement properties directly. + // See http://stackoverflow.com/questions/7659442/listelement-fields-as-properties + Component.onCompleted: + { + append({"key": "override", "label": catalog.i18nc("@action:ComboBox option", "Override existing")}); + append({"key": "new", "label": catalog.i18nc("@action:ComboBox option", "Create new")}); + } + } + + Column + { + anchors.fill: parent + Label + { + id: infoLabel + width: parent.width + text: catalog.i18nc("@action:label", "Cura detected a number of conflicts while importing the workspace. How would you like to resolve these?") + wrapMode: Text.Wrap + height: 50 + } + UM.TooltipArea + { + id: machineResolveTooltip + width: parent.width + height: visible ? 25 : 0 + text: catalog.i18nc("@info:tooltip", "How should the conflict in the machine be resolved?") + visible: manager.machineConflict + Row + { + width: parent.width + height: childrenRect.height + Label + { + text: catalog.i18nc("@action:label","Machine") + width: 150 + } + + ComboBox + { + model: resolveStrategiesModel + textRole: "label" + id: machineResolveComboBox + onActivated: + { + manager.setResolveStrategy("machine", resolveStrategiesModel.get(index).key) + } + } + } + } + UM.TooltipArea + { + id: qualityChangesResolveTooltip + width: parent.width + height: visible ? 25 : 0 + text: catalog.i18nc("@info:tooltip", "How should the conflict in the profile be resolved?") + visible: manager.qualityChangesConflict + Row + { + width: parent.width + height: childrenRect.height + Label + { + text: catalog.i18nc("@action:label","Profile") + width: 150 + } + + ComboBox + { + model: resolveStrategiesModel + textRole: "label" + id: qualityChangesResolveComboBox + onActivated: + { + manager.setResolveStrategy("machine", resolveStrategiesModel.get(index).key) + } + } + } + } + } } rightButtons: [ Button { - id: override_button - text: catalog.i18nc("@action:button","Override"); - onClicked: { manager.onOverrideButtonClicked() } - enabled: true - }, - Button - { - id: create_new - text: catalog.i18nc("@action:button","Create new"); - onClicked: { manager.onNewButtonClicked() } + id: ok_button + text: catalog.i18nc("@action:button","OK"); + onClicked: { manager.onOkButtonClicked() } enabled: true }, Button