--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/eric7/QtHelpInterface/QtHelpDocumentationSettings.py Mon Jan 09 11:22:56 2023 +0100 @@ -0,0 +1,215 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2021 - 2023 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a class to store the QtHelp documentation settings before +being applied to the help engine. +""" + +import collections +import contextlib +import copy + +from PyQt6.QtHelp import QCompressedHelpInfo + + +class QtHelpDocumentationSettings: + """ + Class implementing a temporary store for QtHelp documentation settings. + """ + + def __init__(self): + """ + Constructor + """ + self._namespaceToComponent = {} + self._componentToNamespace = collections.defaultdict(list) + + self._namespaceToVersion = {} + self._versionToNamespace = collections.defaultdict(list) + + self._namespaceToFilename = {} + self._filenameToNamespace = {} + + def addDocumentation(self, filename): + """ + Public method to a add a documentation file to the list. + + @param filename name of the documentation file to add + @type str + @return flag indicating success + @rtype bool + """ + info = QCompressedHelpInfo.fromCompressedHelpFile(filename) + + if info.isNull(): + return False + + namespace = info.namespaceName() + + if namespace in self._namespaceToFilename: + return False + + if filename in self._filenameToNamespace: + return False + + component = info.component() + version = info.version() + + self._namespaceToFilename[namespace] = filename + self._filenameToNamespace[filename] = namespace + + self._namespaceToComponent[namespace] = component + self._componentToNamespace[component].append(namespace) + + self._namespaceToVersion[namespace] = version + self._versionToNamespace[version].append(namespace) + + return True + + def removeDocumentation(self, namespace): + """ + Public method to remove the documentation of a given namespace. + + @param namespace name of the namespace + @type str + @return flag indicating success + @rtype bool + """ + if not namespace: + return False + + try: + filename = self._namespaceToFilename[namespace] + except KeyError: + return False + + component = self._namespaceToComponent[namespace] + version = self._namespaceToVersion[namespace] + + del self._namespaceToComponent[namespace] + del self._namespaceToVersion[namespace] + del self._namespaceToFilename[namespace] + with contextlib.suppress(KeyError): + del self._filenameToNamespace[filename] + self._componentToNamespace[component].remove(namespace) + if len(self._componentToNamespace[component]) == 0: + del self._componentToNamespace[component] + self._versionToNamespace[version].remove(namespace) + if len(self._versionToNamespace[version]) == 0: + del self._versionToNamespace[version] + + return True + + def namespace(self, filename): + """ + Public method to get the namespace defined by a QtHelp file. + + @param filename name of the QtHelp file + @type str + @return name of the namespace + @rtype str + """ + return self._filenameToNamespace[filename] + + def components(self): + """ + Public method to get the list of components. + + @return list of components + @rtype list of str + """ + return [k for k in self._componentToNamespace.keys()] + + def versions(self): + """ + Public method to get the list of versions. + + @return list of versions + @rtype list of QVersionNumber + """ + return [k for k in self._versionToNamespace.keys()] + + def namespaces(self): + """ + Public method to get the list of namespaces. + + @return list of namespaces + @rtype list of str + """ + return [k for k in self._namespaceToFilename.keys()] + + def namespaceToFilename(self): + """ + Public method to get the namespace to filename mapping. + + @return dictionary containing the namespace to filename mapping + @rtype dict + """ + return copy.deepcopy(self._namespaceToFilename) + + @staticmethod + def readSettings(helpEngine): + """ + Static method to read the QtHelp documentation configuration. + + @param helpEngine reference to the QtHelp engine + @type QHelpEngineCore + @return reference to the created QtHelpDocumentationSettings object + @rtype QtHelpDocumentationSettings + """ + filterEngine = helpEngine.filterEngine() + + docSettings = QtHelpDocumentationSettings() + docSettings._namespaceToComponent = filterEngine.namespaceToComponent() + docSettings._namespaceToVersion = filterEngine.namespaceToVersion() + + for namespace, component in docSettings._namespaceToComponent.items(): + filename = helpEngine.documentationFileName(namespace) + docSettings._namespaceToFilename[namespace] = filename + docSettings._filenameToNamespace[filename] = namespace + docSettings._componentToNamespace[component].append(namespace) + + for namespace, version in docSettings._namespaceToVersion.items(): + docSettings._versionToNamespace[version].append(namespace) + + return docSettings + + @staticmethod + def applySettings(helpEngine, settings): + """ + Static method to apply the changed QtHelp documentation configuration. + + @param helpEngine reference to the QtHelp engine + @type QHelpEngineCore + @param settings reference to the created QtHelpDocumentationSettings + object + @type QtHelpDocumentationSettings + @return flag indicating success + @rtype bool + """ + currentSettings = QtHelpDocumentationSettings.readSettings(helpEngine) + + docsToRemove = [ + name + for name in currentSettings._namespaceToFilename + if name not in settings._namespaceToFilename + ] + docsToAdd = [ + filename + for filename in settings._filenameToNamespace + if filename not in currentSettings._filenameToNamespace + ] + + changed = False + for namespace in docsToRemove: + helpEngine.unregisterDocumentation(namespace) + changed = True + + for filename in docsToAdd: + helpEngine.registerDocumentation(filename) + changed = True + + return changed