diff options
Diffstat (limited to 'plugins/Marketplace/Marketplace.py')
-rw-r--r-- | plugins/Marketplace/Marketplace.py | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/plugins/Marketplace/Marketplace.py b/plugins/Marketplace/Marketplace.py new file mode 100644 index 0000000000..2d98947572 --- /dev/null +++ b/plugins/Marketplace/Marketplace.py @@ -0,0 +1,114 @@ +# Copyright (c) 2022 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +import os.path +from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject +from typing import Optional, cast + +from cura.CuraApplication import CuraApplication # Creating QML objects and managing packages. + +from UM.Extension import Extension # We are implementing the main object of an extension here. +from UM.PluginRegistry import PluginRegistry # To find out where we are stored (the proper way). + +from .RemotePackageList import RemotePackageList # To register this type with QML. +from .LocalPackageList import LocalPackageList # To register this type with QML. + + +class Marketplace(Extension, QObject): + """ + The main managing object for the Marketplace plug-in. + """ + def __init__(self, parent: Optional[QObject] = None) -> None: + QObject.__init__(self, parent) + Extension.__init__(self) + self._window: Optional["QObject"] = None # If the window has been loaded yet, it'll be cached in here. + self._plugin_registry: Optional[PluginRegistry] = None + self._package_manager = CuraApplication.getInstance().getPackageManager() + + self._material_package_list: Optional[RemotePackageList] = None + self._plugin_package_list: Optional[RemotePackageList] = None + + # Not entirely the cleanest code, since the localPackage list also checks the server if there are updates + # Since that in turn will trigger notifications to be shown, we do need to construct it here and make sure + # that it checks for updates... + self._local_package_list = LocalPackageList(self) + self._local_package_list.checkForUpdates(self._package_manager.local_packages) + + self._package_manager.installedPackagesChanged.connect(self.checkIfRestartNeeded) + + self._tab_shown: int = 0 + self._restart_needed = False + + def getTabShown(self) -> int: + return self._tab_shown + + def setTabShown(self, tab_shown: int) -> None: + if tab_shown != self._tab_shown: + self._tab_shown = tab_shown + self.tabShownChanged.emit() + + tabShownChanged = pyqtSignal() + tabShown = pyqtProperty(int, fget=getTabShown, fset=setTabShown, notify=tabShownChanged) + + @pyqtProperty(QObject, constant=True) + def MaterialPackageList(self): + if self._material_package_list is None: + self._material_package_list = RemotePackageList() + self._material_package_list.packageTypeFilter = "material" + + return self._material_package_list + + @pyqtProperty(QObject, constant=True) + def PluginPackageList(self): + if self._plugin_package_list is None: + self._plugin_package_list = RemotePackageList() + self._plugin_package_list.packageTypeFilter = "plugin" + return self._plugin_package_list + + @pyqtProperty(QObject, constant=True) + def LocalPackageList(self): + return self._local_package_list + + @pyqtSlot() + def show(self) -> None: + """ + Opens the window of the Marketplace. + + If the window hadn't been loaded yet into Qt, it will be created lazily. + """ + if self._window is None: + self._plugin_registry = PluginRegistry.getInstance() + self._plugin_registry.pluginsEnabledOrDisabledChanged.connect(self.checkIfRestartNeeded) + plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId()) + if plugin_path is None: + plugin_path = os.path.dirname(__file__) + path = os.path.join(plugin_path, "resources", "qml", "Marketplace.qml") + self._window = CuraApplication.getInstance().createQmlComponent(path, {"manager": self}) + if self._window is None: # Still None? Failed to load the QML then. + return + if not self._window.isVisible(): + self.setTabShown(0) + self._window.show() + self._window.requestActivate() # Bring window into focus, if it was already open in the background. + + @pyqtSlot() + def setVisibleTabToMaterials(self) -> None: + """ + Set the tab shown to the remote materials one. + Not implemented in a more generic way because it needs the ability to be called with 'callExtensionMethod'. + """ + self.setTabShown(1) + + def checkIfRestartNeeded(self) -> None: + if self._package_manager.hasPackagesToRemoveOrInstall or \ + cast(PluginRegistry, self._plugin_registry).getCurrentSessionActivationChangedPlugins(): + self._restart_needed = True + else: + self._restart_needed = False + self.showRestartNotificationChanged.emit() + + showRestartNotificationChanged = pyqtSignal() + + @pyqtProperty(bool, notify=showRestartNotificationChanged) + def showRestartNotification(self) -> bool: + return self._restart_needed |