1# Copyright (c) 2018 Ultimaker B.V.
2# Uranium is released under the terms of the LGPLv3 or higher.
3
4import itertools
5import sys
6from typing import Iterable, Union, Optional
7
8from PyQt5.QtWidgets import QMessageBox
9
10from UM.i18n import i18nCatalog
11from UM.Message import Message
12from UM.Resources import Resources
13
14i18n_catalog = i18nCatalog("uranium")
15
16
17class ConfigurationErrorMessage(Message):
18    """This is a specialised message that shows errors in the configuration.
19
20    This class coalesces all errors in the configuration. Whenever there are new
21    errors the message gets updated (and shown if it was hidden).
22    """
23
24    def __init__(self, application, *args, **kwargs):
25        if ConfigurationErrorMessage.__instance is not None:
26            raise RuntimeError("Try to create singleton '%s' more than once" % self.__class__.__name__)
27        ConfigurationErrorMessage.__instance = self
28
29        super().__init__(*args, **kwargs)
30        self._application = application
31        self._faulty_containers = set()
32
33        self.addAction("reset", name = i18n_catalog.i18nc("@action:button", "Reset"), icon = None, description = "Reset your configuration to factory defaults.")
34        self.actionTriggered.connect(self._actionTriggered)
35
36    # Show more containers which we know are faulty.
37    def addFaultyContainers(self, faulty_containers: Union[Iterable, str], *args):
38        initial_length = len(self._faulty_containers)
39        if isinstance(faulty_containers, str):
40            faulty_containers = [faulty_containers]
41        for container in itertools.chain(faulty_containers, args):
42            self._faulty_containers.add(container)
43
44        if initial_length != len(self._faulty_containers):
45            self.setText(i18n_catalog.i18nc("@info:status", "Your configuration seems to be corrupt. Something seems to be wrong with the following profiles:\n- {profiles}\n Would you like to reset to factory defaults? Reset will remove all your current printers and profiles.").format(profiles = "\n- ".join(self._faulty_containers)))
46            self.show()
47
48    def _actionTriggered(self, _, action_id):
49        if action_id == "reset":
50            result = QMessageBox.question(None, i18n_catalog.i18nc("@title:window", "Reset to factory"),
51                                          i18n_catalog.i18nc("@label",
52                                                        "Reset will remove all your current printers and profiles! Are you sure you want to reset?"))
53            if result == QMessageBox.Yes:
54                Resources.factoryReset()
55                sys.exit(1)
56
57    __instance = None   # type: ConfigurationErrorMessage
58
59    @classmethod
60    def getInstance(cls, *args, **kwargs) -> "ConfigurationErrorMessage":
61        return cls.__instance
62