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
This commit is contained in:
Kostas Karmas 2020-08-04 16:33:11 +02:00
parent e5d3271698
commit 4e20c7dddc
4 changed files with 98 additions and 67 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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")
{
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", "new")
}
else
{
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