Welcome to mirror list, hosted at ThFree Co, Russian Federation.

LicensePresenter.py « CloudSync « src « Toolbox « plugins - github.com/Ultimaker/Cura.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 778a36fbdea8aadabc5c36299f8dfe50b8bfd46e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import os
from collections import OrderedDict
from typing import Dict, Optional, List, Any

from PyQt5.QtCore import QObject, pyqtSlot

from UM.Logger import Logger
from UM.PackageManager import PackageManager
from UM.Signal import Signal
from cura.CuraApplication import CuraApplication
from UM.i18n import i18nCatalog

from .LicenseModel import LicenseModel


class LicensePresenter(QObject):
    """Presents licenses for a set of packages for the user to accept or reject.

    Call present() exactly once to show a licenseDialog for a set of packages
    Before presenting another set of licenses, create a new instance using resetCopy().

    licenseAnswers emits a list of Dicts containing answers when the user has made a choice for all provided packages.
    """

    def __init__(self, app: CuraApplication) -> None:
        super().__init__()
        self._presented = False
        """Whether present() has been called and state is expected to be initialized"""
        self._catalog = i18nCatalog("cura")
        self._dialog = None  # type: Optional[QObject]
        self._package_manager = app.getPackageManager()  # type: PackageManager
        # Emits List[Dict[str, [Any]] containing for example
        # [{ "package_id": "BarbarianPlugin", "package_path" : "/tmp/dg345as", "accepted" : True }]
        self.licenseAnswers = Signal()

        self._current_package_idx = 0
        self._package_models = []  # type: List[Dict]
        decline_button_text = self._catalog.i18nc("@button", "Decline and remove from account")
        self._license_model = LicenseModel(decline_button_text=decline_button_text)  # type: LicenseModel
        self._page_count = 0

        self._app = app

        self._compatibility_dialog_path = "resources/qml/dialogs/ToolboxLicenseDialog.qml"

    ## Show a license dialog for multiple packages where users can read a license and accept or decline them
    # \param plugin_path: Root directory of the Toolbox plugin
    # \param packages: Dict[package id, file path]
    def present(self, plugin_path: str, packages: Dict[str, Dict[str, str]]) -> None:
        if self._presented:
            Logger.error("{clazz} is single-use. Create a new {clazz} instead", clazz=self.__class__.__name__)
            return

        path = os.path.join(plugin_path, self._compatibility_dialog_path)

        self._initState(packages)

        if self._page_count == 0:
            self.licenseAnswers.emit(self._package_models)
            return

        if self._dialog is None:

            context_properties = {
                "catalog": self._catalog,
                "licenseModel": self._license_model,
                "handler": self
            }
            self._dialog = self._app.createQmlComponent(path, context_properties)
        self._presentCurrentPackage()
        self._presented = True

    def resetCopy(self) -> "LicensePresenter":
        """Clean up and return a new copy with the same settings such as app"""
        if self._dialog:
            self._dialog.close()
        self.licenseAnswers.disconnectAll()
        return LicensePresenter(self._app)

    @pyqtSlot()
    def onLicenseAccepted(self) -> None:
        self._package_models[self._current_package_idx]["accepted"] = True
        self._checkNextPage()

    @pyqtSlot()
    def onLicenseDeclined(self) -> None:
        self._package_models[self._current_package_idx]["accepted"] = False
        self._checkNextPage()

    def _initState(self, packages: Dict[str, Dict[str, Any]]) -> None:

        implicitly_accepted_count = 0

        for package_id, item in packages.items():
            item["package_id"] = package_id
            item["licence_content"] = self._package_manager.getPackageLicense(item["package_path"])
            if item["licence_content"] is None:
                # Implicitly accept when there is no license
                item["accepted"] = True
                implicitly_accepted_count = implicitly_accepted_count + 1
                self._package_models.append(item)
            else:
                item["accepted"] = None  #: None: no answer yet
                # When presenting the packages, we want to show packages which have a license first.
                # In fact, we don't want to show the others at all because they are implicitly accepted
                self._package_models.insert(0, item)
            CuraApplication.getInstance().processEvents()
        self._page_count = len(self._package_models) - implicitly_accepted_count
        self._license_model.setPageCount(self._page_count)


    def _presentCurrentPackage(self) -> None:
        package_model = self._package_models[self._current_package_idx]
        package_info = self._package_manager.getPackageInfo(package_model["package_path"])

        self._license_model.setCurrentPageIdx(self._current_package_idx)
        self._license_model.setPackageName(package_info["display_name"])
        self._license_model.setIconUrl(package_model["icon_url"])
        self._license_model.setLicenseText(package_model["licence_content"])
        if self._dialog:
            self._dialog.open()  # Does nothing if already open

    def _checkNextPage(self) -> None:
        if self._current_package_idx + 1 < self._page_count:
            self._current_package_idx += 1
            self._presentCurrentPackage()
        else:
            if self._dialog:
                self._dialog.close()
            self.licenseAnswers.emit(self._package_models)