Refactor missing packages dialog into model (MissingPackageList) and controller (InstallMissingPackagesDialog.qml)

Rename classes and files to have unified naming.

CURA-6990
This commit is contained in:
j.delarago 2022-06-01 16:50:53 +02:00
parent 5a3836b841
commit 0df21e6073
6 changed files with 273 additions and 1 deletions

View file

@ -9,6 +9,7 @@ from UM.Application import Application
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
from cura.Settings.GlobalStack import GlobalStack from cura.Settings.GlobalStack import GlobalStack
from plugins.Marketplace.InstallMissingPackagesDialog import InstallMissingPackageDialog
from .UpdatableMachinesModel import UpdatableMachinesModel from .UpdatableMachinesModel import UpdatableMachinesModel
import os import os
@ -60,6 +61,8 @@ class WorkspaceDialog(QObject):
self._is_printer_group = False self._is_printer_group = False
self._updatable_machines_model = UpdatableMachinesModel(self) self._updatable_machines_model = UpdatableMachinesModel(self)
self._missing_package_metadata: List[Dict[str, str]] = [] self._missing_package_metadata: List[Dict[str, str]] = []
self._plugin_registry: PluginRegistry = CuraApplication.getInstance().getPluginRegistry()
self._install_missing_package_dialog: Optional[QObject] = None
machineConflictChanged = pyqtSignal() machineConflictChanged = pyqtSignal()
qualityChangesConflictChanged = pyqtSignal() qualityChangesConflictChanged = pyqtSignal()
@ -284,6 +287,10 @@ class WorkspaceDialog(QObject):
def missingPackages(self): def missingPackages(self):
return self._missing_package_metadata return self._missing_package_metadata
@pyqtSlot()
def installMissingPackages(self):
self._install_missing_package_dialog = InstallMissingPackageDialog(self._missing_package_metadata)
self._install_missing_package_dialog.show()
def getResult(self) -> Dict[str, Optional[str]]: def getResult(self) -> Dict[str, Optional[str]]:
if "machine" in self._result and self.updatableMachinesModel.count <= 1: if "machine" in self._result and self.updatableMachinesModel.count <= 1:

View file

@ -469,7 +469,7 @@ UM.Dialog
{ {
visible: buttonWarning visible: buttonWarning
text: catalog.i18nc("@action:button", "Install missing Material") text: catalog.i18nc("@action:button", "Install missing Material")
onClicked: accept() onClicked: manager.installMissingPackages()
} }
] ]

View file

@ -0,0 +1,60 @@
import os
from PyQt6.QtCore import QObject, pyqtSignal, pyqtProperty
from typing import Optional, List, Dict, cast
from cura.CuraApplication import CuraApplication
from UM.PluginRegistry import PluginRegistry
from cura.CuraPackageManager import CuraPackageManager
from plugins.Marketplace.MissingPackageList import MissingPackageList
class InstallMissingPackageDialog(QObject):
"""Dialog used to display packages that need to be installed to load 3mf file materials"""
def __init__(self, packages_metadata: List[Dict[str, str]]):
"""Initialize
:param packages_metadata: List of dictionaries containing information about missing packages.
"""
super().__init__()
self._plugin_registry: PluginRegistry = CuraApplication.getInstance().getPluginRegistry()
self._package_manager: CuraPackageManager = cast(CuraPackageManager, CuraApplication.getInstance().getPackageManager())
self._package_manager.installedPackagesChanged.connect(self.checkIfRestartNeeded)
self._dialog: Optional[QObject] = None
self._restart_needed = False
self._package_metadata: List[Dict[str, str]] = packages_metadata
self._package_model = MissingPackageList()
self._package_model.setPackageIds(packages_metadata)
def show(self):
plugin_path = self._plugin_registry.getPluginPath("Marketplace")
if plugin_path is None:
plugin_path = os.path.dirname(__file__)
# create a QML component for the license dialog
license_dialog_component_path = os.path.join(plugin_path, "resources", "qml", "InstallMissingPackagesDialog.qml")
self._dialog = CuraApplication.getInstance().createQmlComponent(license_dialog_component_path, {"manager": self})
self._dialog.show()
def checkIfRestartNeeded(self) -> None:
if self._dialog is None:
return
if self._package_manager.hasPackagesToRemoveOrInstall:
self._restart_needed = True
else:
self._restart_needed = False
self.showRestartChanged.emit()
showRestartChanged = pyqtSignal()
@pyqtProperty(bool, notify=showRestartChanged)
def showRestartNotification(self) -> bool:
return self._restart_needed
@pyqtProperty(QObject)
def model(self):
return self._package_model

View file

@ -0,0 +1,32 @@
# Copyright (c) 2022 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional, TYPE_CHECKING, Dict, List
from .Constants import PACKAGES_URL
from .PackageModel import PackageModel
from .RemotePackageList import RemotePackageList
from PyQt6.QtCore import pyqtSignal, QObject, pyqtProperty, QCoreApplication
from UM.TaskManagement.HttpRequestManager import HttpRequestManager # To request the package list from the API.
from UM.i18n import i18nCatalog
if TYPE_CHECKING:
from PyQt6.QtCore import QObject, pyqtProperty, pyqtSignal
catalog = i18nCatalog("cura")
class MissingPackageList(RemotePackageList):
def __init__(self, parent: Optional["QObject"] = None) -> None:
super().__init__(parent)
self._package_metadata: List[Dict[str, str]] = []
# self.packageTypeFilter = None # This will be our new filter
self._package_type_filter = "material"
def setPackageIds(self, packages: List[Dict[str, str]]) -> None:
self._package_metadata = packages
search_string = ", ".join(map(lambda package: package["id"], packages))
# self.setSearchString(search_string)
self.setSearchString("ABS")

View file

@ -0,0 +1,158 @@
// Copyright (c) 2021 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.2
import UM 1.5 as UM
import Cura 1.6 as Cura
Window
{
id: marketplaceDialog
property variant catalog: UM.I18nCatalog { name: "cura" }
signal searchStringChanged(string new_search)
minimumWidth: UM.Theme.getSize("modal_window_minimum").width
minimumHeight: UM.Theme.getSize("modal_window_minimum").height
width: minimumWidth
height: minimumHeight
onVisibleChanged:
{
while(contextStack.depth > 1)
{
contextStack.pop(); //Do NOT use the StackView.Immediate transition here, since it causes the window to stay empty. Seemingly a Qt bug: https://bugreports.qt.io/browse/QTBUG-60670?
}
}
Connections
{
target: Cura.API.account
function onLoginStateChanged()
{
close();
}
}
title: catalog.i18nc("@title", "Install missing Materials")
modality: Qt.ApplicationModal
// Background color
Rectangle
{
anchors.fill: parent
color: UM.Theme.getColor("main_background")
}
//The Marketplace can have a page in front of everything with package details. The stack view controls its visibility.
StackView
{
id: contextStack
anchors.fill: parent
initialItem: packageBrowse
ColumnLayout
{
id: packageBrowse
spacing: UM.Theme.getSize("narrow_margin").height
// Page title.
Item
{
Layout.preferredWidth: parent.width
Layout.preferredHeight: childrenRect.height + UM.Theme.getSize("default_margin").height
UM.Label
{
id: pageTitle
anchors
{
left: parent.left
leftMargin: UM.Theme.getSize("default_margin").width
right: parent.right
rightMargin: UM.Theme.getSize("default_margin").width
bottom: parent.bottom
}
font: UM.Theme.getFont("large")
text: content.item ? content.item.pageTitle: catalog.i18nc("@title", "Loading...")
}
}
// Page contents.
Rectangle
{
Layout.preferredWidth: parent.width
Layout.fillHeight: true
color: UM.Theme.getColor("detail_background")
// Page contents.
Loader
{
id: content
anchors.fill: parent
anchors.margins: UM.Theme.getSize("default_margin").width
source: "MissingPackages.qml"
}
}
}
}
Rectangle
{
height: quitButton.height + 2 * UM.Theme.getSize("default_margin").width
color: UM.Theme.getColor("primary")
visible: manager.showRestartNotification
anchors
{
left: parent.left
right: parent.right
bottom: parent.bottom
}
RowLayout
{
anchors
{
left: parent.left
right: parent.right
verticalCenter: parent.verticalCenter
margins: UM.Theme.getSize("default_margin").width
}
spacing: UM.Theme.getSize("default_margin").width
UM.ColorImage
{
id: bannerIcon
source: UM.Theme.getIcon("Plugin")
color: UM.Theme.getColor("primary_button_text")
implicitWidth: UM.Theme.getSize("banner_icon_size").width
implicitHeight: UM.Theme.getSize("banner_icon_size").height
}
Text
{
color: UM.Theme.getColor("primary_button_text")
text: catalog.i18nc("@button", "In order to use the package you will need to restart Cura")
font: UM.Theme.getFont("default")
renderType: Text.NativeRendering
Layout.fillWidth: true
}
Cura.SecondaryButton
{
id: quitButton
text: catalog.i18nc("@info:button, %1 is the application name", "Quit %1").arg(CuraApplication.applicationDisplayName)
onClicked:
{
marketplaceDialog.hide();
CuraApplication.closeApplication();
}
}
}
}
}

View file

@ -0,0 +1,15 @@
// Copyright (c) 2021 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import UM 1.4 as UM
Packages
{
pageTitle: catalog.i18nc("@header", "Install Materials")
bannerVisible: false
showUpdateButton: false
showInstallButton: true
model: manager.model
}