Browse Source

Rework the open project dialog to contain only 1 dropdown

With the caveat that the qtQuickControls had to be updated to 2.3, due to a qt bug in 1.x that did
not update the dropdown popup list according to the ListModel.
This leads to a different look in the dropdowns and in the buttons of the open project dialog,
compaired to the rest of the application.

CURA-7609
Kostas Karmas 4 years ago
parent
commit
4e20c7dddc

+ 5 - 5
plugins/3MFReader/ThreeMFWorkspaceReader.py

@@ -227,7 +227,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
         # Read definition containers
         #
         machine_definition_id = None
-        updatable_machine_names = []
+        updatable_machines = []
         machine_definition_container_count = 0
         extruder_definition_container_count = 0
         definition_container_files = [name for name in cura_file_names if name.endswith(self._definition_container_suffix)]
@@ -246,7 +246,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
                 machine_definition_id = container_id
                 machine_definition_containers = self._container_registry.findDefinitionContainers(id = machine_definition_id)
                 if machine_definition_containers:
-                    updatable_machine_names = [machine.name for machine in self._container_registry.findContainerStacks(type = "machine") if machine.definition == machine_definition_containers[0]]
+                    updatable_machines = [machine for machine in self._container_registry.findContainerStacks(type = "machine") if machine.definition == machine_definition_containers[0]]
                 machine_type = definition_container["name"]
                 variant_type_name = definition_container.get("variants_name", variant_type_name)
 
@@ -403,7 +403,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
                     machine_conflict = True
                     break
 
-        if updatable_machine_names and not containers_found_dict["machine"]:
+        if updatable_machines and not containers_found_dict["machine"]:
             containers_found_dict["machine"] = True
 
         # Get quality type
@@ -572,7 +572,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
         self._dialog.setNumSettingsOverriddenByQualityChanges(num_settings_overridden_by_quality_changes)
         self._dialog.setNumUserSettings(num_user_settings)
         self._dialog.setActiveMode(active_mode)
-        self._dialog.setUpdatableMachineNames(updatable_machine_names)
+        self._dialog.setUpdatableMachinesModel(updatable_machines)
         self._dialog.setMachineName(machine_name)
         self._dialog.setMaterialLabels(material_labels)
         self._dialog.setMachineType(machine_type)
@@ -654,7 +654,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
         application.expandedCategoriesChanged.emit()  # Notify the GUI of the change
 
         # If there are no machines of the same type, create a new machine.
-        if self._resolve_strategies["machine"] != "override" or not self._dialog.updatableMachineNames:
+        if self._resolve_strategies["machine"] != "override" or self._dialog.updatableMachinesModel.count <= 1:
             # We need to create a new machine
             machine_name = self._container_registry.uniqueName(self._machine_info.name)
 

+ 43 - 0
plugins/3MFReader/UpdatableMachinesModel.py

@@ -0,0 +1,43 @@
+# Copyright (c) 2020 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Dict, List
+
+from PyQt5.QtCore import Qt
+
+from UM.Qt.ListModel import ListModel
+from cura.Settings.GlobalStack import GlobalStack
+
+create_new_list_item = {
+    "id":   "new",
+    "name": "Create new",
+    "displayName": "Create new",
+    "type": "default_option"  # to make sure we are not mixing the "Create new" option with a printer with id "new"
+}  # type: Dict[str, str]
+
+
+class UpdatableMachinesModel(ListModel):
+    """Model that holds cura packages.
+
+    By setting the filter property the instances held by this model can be changed.
+    """
+
+    def __init__(self, parent = None) -> None:
+        super().__init__(parent)
+
+        self.addRoleName(Qt.UserRole + 1, "id")
+        self.addRoleName(Qt.UserRole + 2, "name")
+        self.addRoleName(Qt.UserRole + 3, "displayName")
+        self.addRoleName(Qt.UserRole + 4, "type")  # Either "default_option" or "machine"
+
+    def update(self, machines: List[GlobalStack]) -> None:
+        items = [create_new_list_item]  # type: List[Dict[str, str]]
+
+        for machine in sorted(machines, key = lambda printer: printer.name):
+            items.append({
+                "id":   machine.id,
+                "name": machine.name,
+                "displayName": "Update " + machine.name,
+                "type": "machine"
+            })
+        self.setItems(items)

+ 14 - 17
plugins/3MFReader/WorkspaceDialog.py

@@ -1,6 +1,6 @@
-# Copyright (c) 2016 Ultimaker B.V.
+# Copyright (c) 2020 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
-from typing import List, Optional, Dict
+from typing import List, Optional, Dict, cast
 
 from PyQt5.QtCore import pyqtSignal, QObject, pyqtProperty, QCoreApplication
 from UM.FlameProfiler import pyqtSlot
@@ -8,6 +8,8 @@ from UM.PluginRegistry import PluginRegistry
 from UM.Application import Application
 from UM.i18n import i18nCatalog
 from UM.Settings.ContainerRegistry import ContainerRegistry
+from cura.Settings.GlobalStack import GlobalStack
+from .UpdatableMachinesModel import UpdatableMachinesModel
 
 import os
 import threading
@@ -50,13 +52,13 @@ class WorkspaceDialog(QObject):
         self._quality_type = ""
         self._intent_name = ""
         self._machine_name = ""
-        self._updatable_machines = []
         self._machine_type = ""
         self._variant_type = ""
         self._material_labels = []
         self._extruders = []
         self._objects_on_plate = False
         self._is_printer_group = False
+        self._updatable_machines_model = UpdatableMachinesModel(self)
 
     machineConflictChanged = pyqtSignal()
     qualityChangesConflictChanged = pyqtSignal()
@@ -69,7 +71,7 @@ class WorkspaceDialog(QObject):
     qualityTypeChanged = pyqtSignal()
     intentNameChanged = pyqtSignal()
     machineNameChanged = pyqtSignal()
-    updatableMachineNamesChanged = pyqtSignal()
+    updatableMachinesChanged = pyqtSignal()
     materialLabelsChanged = pyqtSignal()
     objectsOnPlateChanged = pyqtSignal()
     numUserSettingsChanged = pyqtSignal()
@@ -149,18 +151,13 @@ class WorkspaceDialog(QObject):
             self._machine_name = machine_name
             self.machineNameChanged.emit()
 
-    @pyqtProperty("QVariantList", notify = updatableMachineNamesChanged)
-    def updatableMachineNames(self) -> List[str]:
-        return self._updatable_machines
+    @pyqtProperty(QObject, notify = updatableMachinesChanged)
+    def updatableMachinesModel(self) -> UpdatableMachinesModel:
+        return cast(UpdatableMachinesModel, self._updatable_machines_model)
 
-    def setUpdatableMachineNames(self, updatable_machines: List[str]) -> None:
-        if self._updatable_machines != updatable_machines:
-            self._updatable_machines = sorted(updatable_machines)
-            self.updatableMachineNamesChanged.emit()
-
-    @pyqtProperty(int, notify = updatableMachineNamesChanged)
-    def updatableMachineNamesCount(self) -> int:
-        return len(self._updatable_machines)
+    def setUpdatableMachinesModel(self, updatable_machines: List[GlobalStack]) -> None:
+        self._updatable_machines_model.update(updatable_machines)
+        self.updatableMachinesChanged.emit()
 
     @pyqtProperty(str, notify=qualityTypeChanged)
     def qualityType(self) -> str:
@@ -245,7 +242,7 @@ class WorkspaceDialog(QObject):
         return self._has_material_conflict
 
     @pyqtSlot(str, str)
-    def setResolveStrategy(self, key: str, strategy: str) -> None:
+    def setResolveStrategy(self, key: str, strategy: Optional[str]) -> None:
         if key in self._result:
             self._result[key] = strategy
 
@@ -278,7 +275,7 @@ class WorkspaceDialog(QObject):
             self.qualityChangesConflictChanged.emit()
 
     def getResult(self) -> Dict[str, Optional[str]]:
-        if "machine" in self._result and not self._updatable_machines:
+        if "machine" in self._result and self.updatableMachinesModel.count <= 1:
             self._result["machine"] = None
         if "quality_changes" in self._result and not self._has_quality_changes_conflict:
             self._result["quality_changes"] = None

+ 36 - 45
plugins/3MFReader/WorkspaceDialog.qml

@@ -2,7 +2,7 @@
 // Cura is released under the terms of the LGPLv3 or higher.
 
 import QtQuick 2.10
-import QtQuick.Controls 1.4
+import QtQuick.Controls 2.3
 import QtQuick.Layouts 1.3
 import QtQuick.Window 2.2
 
@@ -21,7 +21,6 @@ UM.Dialog
     property int comboboxHeight: 15 * screenScaleFactor
     property int spacerHeight: 10 * screenScaleFactor
     property int doubleSpacerHeight: 20 * screenScaleFactor
-    property string machineResolveStrategyCurrentKey: "override"
 
     onClosing: manager.notifyClosed()
     onVisibleChanged:
@@ -106,25 +105,50 @@ UM.Dialog
                     id: machineResolveStrategyTooltip
                     width: (parent.width / 3) | 0
                     height: visible ? comboboxHeight : 0
-                    visible: manager.updatableMachineNamesCount != 0
+                    visible: base.visible && machineResolveComboBox.model.count > 1
                     text: catalog.i18nc("@info:tooltip", "How should the conflict in the machine be resolved?")
                     ComboBox
                     {
                         id: machineResolveComboBox
-                        model: ListModel
+                        model: manager.updatableMachinesModel
+                        visible: machineResolveStrategyTooltip.visible
+                        textRole: "displayName"
+                        width: parent.width
+                        onCurrentIndexChanged:
                         {
-                            Component.onCompleted:
+                            if (model.getItem(currentIndex).id == "new"
+                                && model.getItem(currentIndex).type == "default_option")
+                            {
+                                manager.setResolveStrategy("machine", "new")
+                            }
+                            else
                             {
-                                append({"key": "override", "label": catalog.i18nc("@action:ComboBox option", "Update existing...")});
-                                append({"key": "new", "label": catalog.i18nc("@action:ComboBox option", "Create new printer")});
+                                manager.setResolveStrategy("machine", "override")
+                                manager.setMachineToOverride(model.getItem(currentIndex).id)
                             }
                         }
-                        textRole: "label"
-                        width: parent.width
-                        onActivated:
+
+                        onVisibleChanged:
                         {
-                            machineResolveStrategyCurrentKey = resolveStrategiesModel.get(index).key
-                            manager.setResolveStrategy("machine", resolveStrategiesModel.get(index).key)
+                            if (!visible) {return}
+
+                            currentIndex = 0
+                            // If the project printer exists in Cura, set it as the default dropdown menu option.
+                            // No need to check object 0, which is the "Create new" option
+                            for (var i = 1; i < model.count; i++)
+                            {
+                                if (model.getItem(i).name == manager.machineName)
+                                {
+                                    currentIndex = i
+                                    break
+                                }
+                            }
+                            // The project printer does not exist in Cura. If there is at least one printer of the same
+                            // type, select the first one, else set the index to "Create new"
+                            if (currentIndex == 0 && model.count > 1)
+                            {
+                                currentIndex = 1
+                            }
                         }
                     }
                 }
@@ -159,39 +183,6 @@ UM.Dialog
                     text: manager.machineName
                     width: (parent.width / 3) | 0
                 }
-                UM.TooltipArea
-                {
-                    id: machineResolveTooltip
-                    width: (parent.width / 3) | 0
-                    height: visible ? comboboxHeight : 0
-                    visible: base.visible && manager.updatableMachineNamesCount != 0 && machineResolveStrategyCurrentKey == "override"
-                    text: catalog.i18nc("@info:tooltip", "Which machine of the same type should be overriden?")
-                    ComboBox
-                    {
-                        id: selectMachineComboBox
-                        model: manager.updatableMachineNames
-                        width: parent.width
-                        onCurrentIndexChanged:
-                        {
-                            manager.setMachineToOverride(model[currentIndex])
-                        }
-                        onVisibleChanged:
-                        {
-                            if (!visible) {return}
-
-                            currentIndex = 0
-                            for (var i = 0; i < count; i++)
-                            {
-                                if (model[i] == manager.machineName)
-                                {
-                                    currentIndex = i
-                                    break
-                                }
-                            }
-
-                        }
-                    }
-                }
             }
 
             Item // Spacer