def _createView(self):
        Logger.log("d", "Creating post processing plugin view.")

        ## Load all scripts in the scripts folder
        try:
            self.loadAllScripts(
                os.path.join(
                    PluginRegistry.getInstance().getPluginPath(
                        "PostProcessingPlugin"), "scripts"))
        except Exception as e:
            print(
                "Exception occured", e
            )  # TODO: Debug code (far to general catch. Remove this once done testing)

        path = QUrl.fromLocalFile(
            os.path.join(
                PluginRegistry.getInstance().getPluginPath(
                    "PostProcessingPlugin"), "PostProcessingPlugin.qml"))
        self._component = QQmlComponent(Application.getInstance()._engine,
                                        path)

        # We need access to engine (although technically we can't)
        self._context = QQmlContext(
            Application.getInstance()._engine.rootContext())
        self._context.setContextProperty("manager", self)
        self._view = self._component.create(self._context)
        Logger.log("d", "Post processing view created.")

        Application.getInstance().addAdditionalComponent(
            "saveButton",
            self._view.findChild(QObject, "postProcessingSaveAreaButton"))
    def _createAdditionalComponentsView(self):
        Logger.log(
            "d",
            "Creating additional ui components for OctoPrint-connected printers."
        )

        path = QUrl.fromLocalFile(
            os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         "OctoPrintComponents.qml"))
        self._additional_component = QQmlComponent(
            Application.getInstance()._engine, path)

        # We need access to engine (although technically we can't)
        self._additional_components_context = QQmlContext(
            Application.getInstance()._engine.rootContext())
        self._additional_components_context.setContextProperty("manager", self)

        self._additional_components_view = self._additional_component.create(
            self._additional_components_context)
        if not self._additional_components_view:
            Logger.log(
                "w",
                "Could not create additional components for OctoPrint-connected printers."
            )
            return

        Application.getInstance().addAdditionalComponent(
            "monitorButtons",
            self._additional_components_view.findChild(QObject,
                                                       "openOctoPrintButton"))
Esempio n. 3
0
 def createControlInterface(self):
     if self._control_view is None:
         path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("USBPrinting"), "ControlWindow.qml"))
         component = QQmlComponent(Application.getInstance()._engine, path)
         self._control_context = QQmlContext(Application.getInstance()._engine.rootContext())
         self._control_context.setContextProperty("manager", self)
         self._control_view = component.create(self._control_context)
    def _createAdditionalComponentsView(self):
        Logger.log(
            "d", "Creating additional ui components for Pause Backend plugin.")

        path = QUrl.fromLocalFile(
            os.path.join(
                PluginRegistry.getInstance().getPluginPath(
                    "PauseBackendPlugin"), "PauseBackend.qml"))
        self._additional_component = QQmlComponent(
            Application.getInstance()._engine, path)

        # We need access to engine (although technically we can't)
        self._additional_components_context = QQmlContext(
            Application.getInstance()._engine.rootContext())
        self._additional_components_context.setContextProperty("manager", self)

        self._additional_components_view = self._additional_component.create(
            self._additional_components_context)
        if not self._additional_components_view:
            Logger.log(
                "w",
                "Could not create additional components for Pause Backend plugin."
            )
            return

        Application.getInstance().addAdditionalComponent(
            "saveButton",
            self._additional_components_view.findChild(QObject,
                                                       "pauseResumeButton"))
Esempio n. 5
0
 def _createViewFromQML(self):
     path = QUrl.fromLocalFile(
         os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), self._qml_url))
     self._component = QQmlComponent(Application.getInstance()._engine, path)
     self._context = QQmlContext(Application.getInstance()._engine.rootContext())
     self._context.setContextProperty("manager", self)
     self._view = self._component.create(self._context)
Esempio n. 6
0
    def createQmlComponent(self, qml_file_path: str, context_properties: Dict[str, "QObject"] = None) -> Optional["QObject"]:
        """Create a QML component from a qml file.
        :param qml_file_path:: The absolute file path to the root qml file.
        :param context_properties:: Optional dictionary containing the properties that will be set on the context of the
        qml instance before creation.
        :return: None in case the creation failed (qml error), else it returns the qml instance.
        :note If the creation fails, this function will ensure any errors are logged to the logging service.
        """

        if self._qml_engine is None: # Protect in case the engine was not initialized yet
            return None
        path = QUrl.fromLocalFile(qml_file_path)
        component = QQmlComponent(self._qml_engine, path)
        result_context = QQmlContext(self._qml_engine.rootContext()) #type: ignore #MyPy doens't realise that self._qml_engine can't be None here.
        if context_properties is not None:
            for name, value in context_properties.items():
                result_context.setContextProperty(name, value)
        result = component.create(result_context)
        for err in component.errors():
            Logger.log("e", str(err.toString()))
        if result is None:
            return None

        # We need to store the context with the qml object, else the context gets garbage collected and the qml objects
        # no longer function correctly/application crashes.
        result.attached_context = result_context
        return result
Esempio n. 7
0
def run():
    directory = os.path.dirname(os.path.abspath(__file__))

    appIcon = QIcon()
    appIcon.addFile(os.path.join(directory, "python.png"), QSize(64, 64))
    app.setWindowIcon(appIcon)

    from . import registerQmlTypes

    registerQmlTypes()

    engine = QQmlApplicationEngine()
    context = QQmlContext(engine)

    mainQml = QUrl.fromLocalFile(os.path.join(directory, "Main.qml"))

    component = QQmlComponent(engine)
    component.loadUrl(mainQml)

    if component.isError():
        for error in component.errors():
            print("Error: ", error.toString())

    dialog = component.create(context)

    return app.exec_()
Esempio n. 8
0
    def _createAdditionalComponentsView(self):
        Logger.log("d", "Creating additional ui components for UM3.")
        path = QUrl.fromLocalFile(
            os.path.join(
                PluginRegistry.getInstance().getPluginPath(
                    "UM3NetworkPrinting"), "UM3InfoComponents.qml"))
        self.__additional_component = QQmlComponent(
            Application.getInstance()._engine, path)

        # We need access to engine (although technically we can't)
        self.__additional_components_context = QQmlContext(
            Application.getInstance()._engine.rootContext())
        self.__additional_components_context.setContextProperty(
            "manager", self)

        self.__additional_components_view = self.__additional_component.create(
            self.__additional_components_context)
        if not self.__additional_components_view:
            Logger.log("w", "Could not create ui components for UM3.")
            return

        Application.getInstance().addAdditionalComponent(
            "monitorButtons",
            self.__additional_components_view.findChild(
                QObject, "networkPrinterConnectButton"))
        Application.getInstance().addAdditionalComponent(
            "machinesDetailPane",
            self.__additional_components_view.findChild(
                QObject, "networkPrinterConnectionInfo"))
Esempio n. 9
0
    def __init__(self, app):
        super().__init__()
        self.app = app
        selection = libdice.dice.languages1(app, self, QUrl)
        self.languagerelevant()
        context = self.rootContext()
        self.scrollmodel = model2.PersonModel()
        context.setContextProperty("scrollmodel", self.scrollmodel)
        #self.libdice_strlist = [self.tr('lin'), self.tr('log'), self.tr('root'), self.tr('poly'), self.tr('exp'), self.tr('kombi'), self.tr('logistic'), self.tr('rand'), self.tr('gewicht'), self.tr('add'), self.tr('mul'), self.tr("Wuerfelwurf: "),self.tr(" (Wuerfelaugen ")]
        blub = [self.tr('test')]
        #print(str(blub[0]))
        #print(blub)
        #print(str(libdice.dice.randfkt2.values()))

        self.load(':/main.qml')

        langimg = self.rootObjects()[0].findChild(QObject, "langimg")
        # print("UrL: "+str(selection[1].fileName()))
        #langimg.setProperty("source",(":/"+selection[1].fileName()))
        langimg.setProperty("source", selection[1])
        #rado = self.rootObjects()[0].findChild(QObject, "radios")
        #rado.setProperty("onClicked", self.radu() )

        #layout = QVBoxLayout()
        #layout.addWidget(QPushButton('Top'))
        #layout.addWidget(QPushButton('Bottom'))
        context = QQmlContext(self.rootContext())
Esempio n. 10
0
    def _createCostView(self):
        path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("ElectricPrintCostCalculator"), "ElectricPrintCostCalculator.qml"))
        self._component = QQmlComponent(Application.getInstance()._engine, path)

        self._context = QQmlContext(Application.getInstance()._engine.rootContext())
        self._context.setContextProperty("manager", self)
        self._cost_view = self._component.create(self._context)
Esempio n. 11
0
    def createQmlComponent(
        self,
        qml_file_path: str,
        context_properties: Dict[str,
                                 "QObject"] = None) -> Optional["QObject"]:
        if self._qml_engine is None:  # Protect in case the engine was not initialized yet
            return None
        path = QUrl.fromLocalFile(qml_file_path)
        component = QQmlComponent(self._qml_engine, path)
        result_context = QQmlContext(
            self._qml_engine.rootContext()
        )  #type: ignore #MyPy doens't realise that self._qml_engine can't be None here.
        if context_properties is not None:
            for name, value in context_properties.items():
                result_context.setContextProperty(name, value)
        result = component.create(result_context)
        for err in component.errors():
            Logger.log("e", str(err.toString()))
        if result is None:
            return None

        # We need to store the context with the qml object, else the context gets garbage collected and the qml objects
        # no longer function correctly/application crashes.
        result.attached_context = result_context
        return result
Esempio n. 12
0
    def _createAdditionalComponentsView(self):
        Logger.log(
            "d",
            "Creating additional ui components for OctoPrint-connected printers."
        )

        path = QUrl.fromLocalFile(
            os.path.join(
                PluginRegistry.getInstance().getPluginPath(
                    "SculptoPrintPlugin"), "SculptoPrintPlugin.qml"))
        self._additional_component = QQmlComponent(
            Application.getInstance()._engine, path)

        # We need access to engine (although technically we can't)
        self._additional_components_context = QQmlContext(
            Application.getInstance()._engine.rootContext())
        self._additional_components_context.setContextProperty("manager", self)

        self._additional_components_view = self._additional_component.create(
            self._additional_components_context)
        if not self._additional_components_view:
            Logger.log(
                "w",
                "Could not create additional components for OctoPrint-connected printers."
            )
            return
Esempio n. 13
0
    def _createAdditionalComponentsView(self):
        Logger.log(
            "d",
            "Creating additional ui components for Repetier-Server - connected printers."
        )

        path = QUrl.fromLocalFile(
            os.path.join(
                PluginRegistry.getInstance().getPluginPath(
                    "RepetierServerPlugin"), "RepetierServerComponents.qml"))
        self._additional_component = QQmlComponent(
            Application.getInstance()._engine, path)

        # We need access to engine (although technically we can't)
        self._additional_components_context = QQmlContext(
            Application.getInstance()._engine.rootContext())
        self._additional_components_context.setContextProperty("manager", self)

        self._additional_components_view = self._additional_component.create(
            self._additional_components_context)
        if not self._additional_components_view:
            Logger.log(
                "w",
                "Could not create additional components for Repetier-Server - connected printers."
            )
            return

        Application.getInstance().addAdditionalComponent(
            "monitorButtons",
            self._additional_components_view.findChild(
                QObject, "openRepetierServerButton"))
    def requestWrite(self, node, fileName=None, *args, **kwargs):
        if self._stage != OutputStage.ready:
            raise OutputDeviceError.DeviceBusyError()

        if fileName:
            fileName = os.path.splitext(fileName)[0] + '.gcode'
        else:
            fileName = "%s.gcode" % Application.getInstance(
            ).getPrintInformation().jobName
        self._fileName = fileName

        path = QUrl.fromLocalFile(
            os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         'UploadFilename.qml'))
        self._component = QQmlComponent(Application.getInstance()._engine,
                                        path)
        Logger.log("d", "Errors:", self._component.errors())
        self._context = QQmlContext(
            Application.getInstance()._engine.rootContext())
        self._context.setContextProperty("manager", self)
        self._dialog = self._component.create(self._context)
        self._dialog.textChanged.connect(self.onFilenameChanged)
        self._dialog.accepted.connect(self.onFilenameAccepted)
        self._dialog.open()
        self._dialog.findChild(QObject, "nameField").setProperty(
            'text', self._fileName)
        self._dialog.findChild(QObject,
                               "nameField").select(0,
                                                   len(self._fileName) - 6)
        self._dialog.findChild(QObject, "nameField").setProperty('focus', True)
Esempio n. 15
0
 def _createViewFromQML(self):
     path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("3MFReader"), self._qml_url))
     self._component = QQmlComponent(Application.getInstance()._engine, path)
     self._context = QQmlContext(Application.getInstance()._engine.rootContext())
     self._context.setContextProperty("manager", self)
     self._view = self._component.create(self._context)
     if self._view is None:
         Logger.log("c", "QQmlComponent status %s", self._component.status())
         Logger.log("c", "QQmlComponent error string %s", self._component.errorString())
Esempio n. 16
0
    def _createConfigUI(self):
        if self._ui_view is None:
            path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("CuraSolidWorksPlugin"), "ExportSTLUI.qml"))
            component = QQmlComponent(Application.getInstance()._engine, path)
            self._ui_context = QQmlContext(Application.getInstance()._engine.rootContext())
            self._ui_context.setContextProperty("manager", self)
            self._ui_view = component.create(self._ui_context)

            self._ui_view.setFlags(self._ui_view.flags() & ~Qt.WindowCloseButtonHint & ~Qt.WindowMinimizeButtonHint & ~Qt.WindowMaximizeButtonHint)
Esempio n. 17
0
    def spawnFirmwareInterface(self, serial_port):
        if self._firmware_view is None:
            path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("USBPrinting"), "FirmwareUpdateWindow.qml"))
            component = QQmlComponent(Application.getInstance()._engine, path)

            self._firmware_context = QQmlContext(Application.getInstance()._engine.rootContext())
            self._firmware_context.setContextProperty("manager", self)
            self._firmware_view = component.create(self._firmware_context)

        self._firmware_view.show()
Esempio n. 18
0
 def createChangelogWindow(self):
     path = QUrl.fromLocalFile(
         os.path.join(
             PluginRegistry.getInstance().getPluginPath("ChangeLogPlugin"),
             "ChangeLog.qml"))
     component = QQmlComponent(Application.getInstance()._engine, path)
     self._changelog_context = QQmlContext(
         Application.getInstance()._engine.rootContext())
     self._changelog_context.setContextProperty("manager", self)
     self._changelog_window = component.create(self._changelog_context)
Esempio n. 19
0
    def _createView(self):
        ## Load all scripts in the scripts folder
        self.loadAllScripts(os.path.join(PluginRegistry.getInstance().getPluginPath("PostProcessingPlugin"), "scripts"))
        
        path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("PostProcessingPlugin"), "PostProcessingPlugin.qml"))
        self._component = QQmlComponent(Application.getInstance()._engine, path)

        self._context = QQmlContext(Application.getInstance()._engine.rootContext())
        self._context.setContextProperty("manager", self)
        self._view = self._component.create(self._context)
    def createUserAgreementWindow(self):
        path = QUrl.fromLocalFile(
            os.path.join(
                PluginRegistry.getInstance().getPluginPath(self.getPluginId()),
                "UserAgreement.qml"))

        component = QQmlComponent(Application.getInstance()._engine, path)
        self._user_agreement_context = QQmlContext(
            Application.getInstance()._engine.rootContext())
        self._user_agreement_context.setContextProperty("manager", self)
        self._user_agreement_window = component.create(
            self._user_agreement_context)
Esempio n. 21
0
    def _createConfigUI(self):
        if self._ui_view is None:
            Logger.log("d", "Creating ImageReader config UI")
            path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath("ImageReader"), "ConfigUI.qml"))
            component = QQmlComponent(Application.getInstance()._engine, path)
            self._ui_context = QQmlContext(Application.getInstance()._engine.rootContext())
            self._ui_context.setContextProperty("manager", self)
            self._ui_view = component.create(self._ui_context)

            self._ui_view.setFlags(self._ui_view.flags() & ~Qt.WindowCloseButtonHint & ~Qt.WindowMinimizeButtonHint & ~Qt.WindowMaximizeButtonHint);

            self._disable_size_callbacks = False
Esempio n. 22
0
    def _createDialogue(self):
        #Create a QML component from the Hello.qml file.
        qml_file = QUrl.fromLocalFile(
            os.path.join(
                PluginRegistry.getInstance().getPluginPath(self.getPluginId()),
                "SelectionInfo.qml"))
        component = QQmlComponent(Application.getInstance()._engine, qml_file)
        qml_context = QQmlContext(
            Application.getInstance()._engine.rootContext(
            ))  #List the QML component as subcomponent of the main window.

        return component.create(qml_context)
Esempio n. 23
0
    def _createDialog(self):
        Logger.log("d", "PluginBrowser")

        path = QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "PluginBrowser.qml"))
        self._qml_component = QQmlComponent(Application.getInstance()._engine, path)

        # We need access to engine (although technically we can't)
        self._qml_context = QQmlContext(Application.getInstance()._engine.rootContext())
        self._qml_context.setContextProperty("manager", self)
        self._dialog = self._qml_component.create(self._qml_context)
        if self._dialog is None:
            Logger.log("e", "QQmlComponent status %s", self._qml_component.status())
            Logger.log("e", "QQmlComponent errorString %s", self._qml_component.errorString())
Esempio n. 24
0
    def spawnPrintView(self):
        if self._print_view is None:
            path = QUrl.fromLocalFile(os.path.join(self._plugin_path, "PrintWindow.qml"))
            component = QQmlComponent(Application.getInstance()._engine, path)

            self._print_context = QQmlContext(Application.getInstance()._engine.rootContext())
            self._print_context.setContextProperty("OutputDevice", self)
            self._print_view = component.create(self._print_context)

            if component.isError():
                Logger.log("e", " Errors creating component: \n%s", "\n".join(
                    [e.toString() for e in component.errors()]))

        if self._print_view is not None:
            self._print_view.show()
Esempio n. 25
0
    def _createMonitorViewFromQML(self):
        path = QUrl.fromLocalFile(self._monitor_view_qml_path)

        # Because of garbage collection we need to keep this referenced by python.
        self._monitor_component = QQmlComponent(Application.getInstance()._engine, path)

        # Check if the context was already requested before (Printer output device might have multiple items in the future)
        if self._qml_context is None:
            self._qml_context = QQmlContext(Application.getInstance()._engine.rootContext())
            self._qml_context.setContextProperty("OutputDevice", self)

        self._monitor_item = self._monitor_component.create(self._qml_context)
        if self._monitor_item is None:
            Logger.log("e", "QQmlComponent status %s", self._monitor_component.status())
            Logger.log("e", "QQmlComponent error string %s", self._monitor_component.errorString())
Esempio n. 26
0
 def _createDialog(self, qml):
     path = QUrl.fromLocalFile(
         os.path.join(os.path.dirname(os.path.abspath(__file__)), qml))
     self._component = QQmlComponent(Application.getInstance()._engine,
                                     path)
     self._context = QQmlContext(
         Application.getInstance()._engine.rootContext())
     self._context.setContextProperty("manager", self)
     dialog = self._component.create(self._context)
     if dialog is None:
         Logger.log("e", "QQmlComponent status %s",
                    self._component.status())
         Logger.log("e", "QQmlComponent errorString %s",
                    self._component.errorString())
         raise RuntimeError(self._component.errorString())
     return dialog
Esempio n. 27
0
 def _createConfigUI(self):
     if self._ui_view is None:
         Logger.log('d', 'Creating SVGReader CDT UI')
         path = QUrl.fromLocalFile(
             os.path.join(
                 PluginRegistry.getInstance().getPluginPath('SVGReader'),
                 'CDTUI.qml'))
         component = QQmlComponent(Application.getInstance()._qml_engine,
                                   path)
         self._ui_context = QQmlContext(
             Application.getInstance()._qml_engine.rootContext())
         self._ui_context.setContextProperty('manager', self)
         self._ui_view = component.create(self._ui_context)
         self._ui_view.setFlags(self._ui_view.flags()
                                & ~(Qt.WindowCloseButtonHint)
                                & ~(Qt.WindowMinimizeButtonHint)
                                & ~(Qt.WindowMaximizeButtonHint))
         self._disable_size_callbacks = False
Esempio n. 28
0
    def _createDialog(self, dialog_qml, directory=None):
        if directory is None:
            directory = PluginRegistry.getInstance().getPluginPath(
                self.getPluginId())
        path = QUrl.fromLocalFile(os.path.join(directory, dialog_qml))
        self._qml_component = QQmlComponent(Application.getInstance()._engine,
                                            path)

        # We need access to engine (although technically we can't)
        self._qml_context = QQmlContext(
            Application.getInstance()._engine.rootContext())
        self._qml_context.setContextProperty("manager", self)
        dialog = self._qml_component.create(self._qml_context)
        if dialog is None:
            Logger.log("e", "QQmlComponent status %s",
                       self._qml_component.status())
            Logger.log("e", "QQmlComponent errorString %s",
                       self._qml_component.errorString())
        return dialog
Esempio n. 29
0
    def load(self, path, is_first_call = True):
        if path == self._path:
            return

        with open(os.path.join(path, "theme.json"), encoding = "utf-8") as f:
            Logger.log("d", "Loading theme file: %s", os.path.join(path, "theme.json"))
            data = json.load(f)

        # Iteratively load inherited themes
        try:
            theme_id = data["metadata"]["inherits"]
            self.load(Resources.getPath(Resources.Themes, theme_id), is_first_call = False)
        except FileNotFoundError:
            Logger.log("e", "Could not find inherited theme %s", theme_id)
        except KeyError:
            pass # No metadata or no inherits keyword in the theme.json file

        if "colors" in data:
            for name, color in data["colors"].items():
                c = QColor(color[0], color[1], color[2], color[3])
                self._colors[name] = c

        fontsdir = os.path.join(path, "fonts")
        if os.path.isdir(fontsdir):
            for file in os.listdir(fontsdir):
                if "ttf" in file:
                    QFontDatabase.addApplicationFont(os.path.join(fontsdir, file))

        if "fonts" in data:
            system_font_size = QCoreApplication.instance().font().pointSize()
            for name, font in data["fonts"].items():
                f = QFont()
                f.setFamily(font.get("family", QCoreApplication.instance().font().family()))

                if font.get("bold"):
                    f.setBold(font.get("bold", False))
                else:
                    f.setWeight(font.get("weight", 50))

                f.setLetterSpacing(QFont.AbsoluteSpacing, font.get("letterSpacing", 0))
                f.setItalic(font.get("italic", False))
                f.setPointSize(int(font.get("size", 1) * system_font_size))
                f.setCapitalization(QFont.AllUppercase if font.get("capitalize", False) else QFont.MixedCase)

                self._fonts[name] = f

        if "sizes" in data:
            for name, size in data["sizes"].items():
                s = QSizeF()
                s.setWidth(round(size[0] * self._em_width))
                s.setHeight(round(size[1] * self._em_height))

                self._sizes[name] = s

        iconsdir = os.path.join(path, "icons")
        if os.path.isdir(iconsdir):
            for icon in os.listdir(iconsdir):
                name = os.path.splitext(icon)[0]
                self._icons[name] = QUrl.fromLocalFile(os.path.join(iconsdir, icon))

        imagesdir = os.path.join(path, "images")
        if os.path.isdir(imagesdir):
            for image in os.listdir(imagesdir):
                name = os.path.splitext(image)[0]
                self._images[name] = QUrl.fromLocalFile(os.path.join(imagesdir, image))

        styles = os.path.join(path, "styles.qml")
        if os.path.isfile(styles):
            c = QQmlComponent(self._engine, styles)
            context = QQmlContext(self._engine, self._engine)
            context.setContextProperty("Theme", self)
            self._styles = c.create(context)

            if c.isError():
                for error in c.errors():
                    Logger.log("e", error.toString())

        Logger.log("d", "Loaded theme %s", path)
        self._path = path

        # only emit the theme loaded signal once after all the themes in the inheritance chain have been loaded
        if is_first_call:
            self.themeLoaded.emit()
Esempio n. 30
0
    def load(self, path: str, is_first_call: bool = True) -> None:
        if path == self._path:
            return

        theme_full_path = os.path.join(path, "theme.json")
        Logger.log(
            "d", "Loading theme file: {theme_full_path}".format(
                theme_full_path=theme_full_path))
        try:
            with open(theme_full_path, encoding="utf-8") as f:
                data = json.load(f)
        except EnvironmentError as e:
            Logger.error(
                "Unable to load theme file at {theme_full_path}: {err}".format(
                    theme_full_path=theme_full_path, err=e))
            return
        except UnicodeDecodeError:
            Logger.error(
                "Theme file at {theme_full_path} is corrupt (invalid UTF-8 bytes)."
                .format(theme_full_path=theme_full_path))
            return

        # Iteratively load inherited themes
        try:
            theme_id = data["metadata"]["inherits"]
            self.load(Resources.getPath(Resources.Themes, theme_id),
                      is_first_call=False)
        except FileNotFoundError:
            Logger.log("e", "Could not find inherited theme %s", theme_id)
        except KeyError:
            pass  # No metadata or no inherits keyword in the theme.json file

        if "colors" in data:
            for name, color in data["colors"].items():
                try:
                    c = QColor(color[0], color[1], color[2], color[3])
                except IndexError:  # Color doesn't have enough components.
                    Logger.log(
                        "w",
                        "Colour {name} doesn't have enough components. Need to have 4, but had {num_components}."
                        .format(name=name, num_components=len(color)))
                    continue  # Skip this one then.
                self._colors[name] = c

        fonts_dir = os.path.join(path, "fonts")
        if os.path.isdir(fonts_dir):
            for root, dirnames, filenames in os.walk(fonts_dir):
                for filename in filenames:
                    if filename.lower().endswith(".ttf"):
                        QFontDatabase.addApplicationFont(
                            os.path.join(root, filename))

        if "fonts" in data:
            system_font_size = QCoreApplication.instance().font().pointSize()
            for name, font in data["fonts"].items():
                q_font = QFont()
                q_font.setFamily(
                    font.get("family",
                             QCoreApplication.instance().font().family()))

                if font.get("bold"):
                    q_font.setBold(font.get("bold", False))
                else:
                    q_font.setWeight(font.get("weight", 50))

                q_font.setLetterSpacing(QFont.AbsoluteSpacing,
                                        font.get("letterSpacing", 0))
                q_font.setItalic(font.get("italic", False))
                q_font.setPointSize(int(
                    font.get("size", 1) * system_font_size))
                q_font.setCapitalization(QFont.AllUppercase if font.get(
                    "capitalize", False) else QFont.MixedCase)

                self._fonts[name] = q_font

        if "sizes" in data:
            for name, size in data["sizes"].items():
                s = QSizeF()
                s.setWidth(round(size[0] * self._em_width))
                s.setHeight(round(size[1] * self._em_height))

                self._sizes[name] = s

        iconsdir = os.path.join(path, "icons")
        if os.path.isdir(iconsdir):
            for icon in os.listdir(iconsdir):
                name = os.path.splitext(icon)[0]
                self._icons[name] = QUrl.fromLocalFile(
                    os.path.join(iconsdir, icon))

        imagesdir = os.path.join(path, "images")
        if os.path.isdir(imagesdir):
            for image in os.listdir(imagesdir):
                name = os.path.splitext(image)[0]
                self._images[name] = QUrl.fromLocalFile(
                    os.path.join(imagesdir, image))

        styles = os.path.join(path, "styles.qml")
        if os.path.isfile(styles):
            c = QQmlComponent(self._engine, styles)
            context = QQmlContext(self._engine, self._engine)
            context.setContextProperty("Theme", self)
            self._styles = c.create(context)

            if c.isError():
                for error in c.errors():
                    Logger.log("e", error.toString())

        Logger.log("d", "Loaded theme %s", path)
        self._path = path

        # only emit the theme loaded signal once after all the themes in the inheritance chain have been loaded
        if is_first_call:
            self.themeLoaded.emit()