PluginExtensionProtobuf.py

Mon, 12 Dec 2022 16:55:43 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Mon, 12 Dec 2022 16:55:43 +0100
changeset 10
362689624e2d
parent 8
24fdd6e43cd7
child 12
8ddcd9d47bdf
permissions
-rw-r--r--

Moved the Protobuf class browser to this plugin.

# -*- coding: utf-8 -*-

# Copyright (c) 2022 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing a plugin to add support for Protobuf development.
"""

import os

from PyQt6.QtCore import QCoreApplication, QObject, QTranslator

from eric7 import Globals, Preferences
from eric7.EricWidgets import EricMessageBox
from eric7.EricWidgets.EricApplication import ericApp
from ExtensionProtobuf import protoclbr
from ExtensionProtobuf.ProjectProtocolsBrowser import ProjectProtocolsBrowser

# Start-Of-Header
name = "Protobuf and gRPC Extension Plugin"
author = "Detlev Offenbach <detlev@die-offenbachs.de>"
autoactivate = True
deactivateable = True
version = "10.1.0"
className = "ProtobufExtensionPlugin"
packageName = "ExtensionProtobuf"
shortDescription = "Support for the development of Protobuf and gRPC projects"
longDescription = (
    "This plugin adds support for the development of Protobuf and gRPC related"
    " projects."
)
needsRestart = False
pyqtApi = 2
# End-Of-Header

error = ""

protobufExtensionPluginObject = None


def exeDisplayDataList():
    """
    Module function to support the display of some executable info.

    @return list of dictionaries containing the data to query the presence of
        the executable
    @rtype list of dict
    """
    global protobufExtensionPluginObject

    # 1. Protobuf compiler
    if protobufExtensionPluginObject is None:
        protocData = {
            "programEntry": False,
            "header": QCoreApplication.translate(
                "ProtobufExtensionPlugin", "Protobuf Compiler"
            ),
            "text": QCoreApplication.translate(
                "ProtobufExtensionPlugin",
                "Protobuf and gRPC Support plugin is not activated",
            ),
            "version": QCoreApplication.translate(
                "ProtobufExtensionPlugin", "(inactive)"
            ),
        }
    else:
        exe = protobufExtensionPluginObject.getPreferences("protoc")
        if not exe:
            exe = "protoc.exe" if Globals.isWindowsPlatform() else "protoc"

        protocData = {
            "programEntry": True,
            "header": QCoreApplication.translate(
                "ProtobufExtensionPlugin", "Protobuf Compiler"
            ),
            "exe": exe,
            "versionCommand": "--version",
            "versionStartsWith": "libprotoc",
            "versionRe": "",
            "versionPosition": -1,
            "version": "",
            "versionCleanup": None,
            "exeModule": None,
        }

    # 2. grpc compiler
    if protobufExtensionPluginObject is None:
        grpcData = {
            "programEntry": False,
            "header": QCoreApplication.translate(
                "ProtobufExtensionPlugin", "gRPC Compiler"
            ),
            "text": QCoreApplication.translate(
                "ProtobufExtensionPlugin",
                "Protobuf and gRPC Support plugin is not activated",
            ),
            "version": QCoreApplication.translate(
                "ProtobufExtensionPlugin", "(inactive)"
            ),
        }
    else:
        env = protobufExtensionPluginObject.getPreferences("grpcPythonEnv")
        interpreter = (
            ericApp().getObject("VirtualEnvManager").getVirtualenvInterpreter(env)
        )
        if not interpreter:
            interpreter = Globals.getPythonExecutable()

        grpcData = {
            "programEntry": True,
            "header": QCoreApplication.translate(
                "ProtobufExtensionPlugin", "gRPC Compiler"
            ),
            "exe": interpreter,
            "versionCommand": "--version",
            "versionStartsWith": "libprotoc",
            "versionRe": "",
            "versionPosition": -1,
            "version": "",
            "versionCleanup": None,
            "exeModule": ["-m", "grpc_tools.protoc"],
        }

    return [protocData, grpcData]


def getConfigData():
    """
    Module function returning data as required by the configuration dialog.

    @return dictionary containing the relevant data
    @rtype dict
    """
    return {
        "protobufPage": [
            QCoreApplication.translate("ProtobufExtensionPlugin", "Protobuf and gRPC"),
            os.path.join("ExtensionProtobuf", "icons", "protobuf"),
            createProtobufPage,
            None,
            None,
        ],
    }


def createProtobufPage(configDlg):
    """
    Module function to create the Protobuf configuration page.

    @param configDlg reference to the configuration dialog
    @type ConfigurationWidget
    @return reference to the configuration page
    @rtype CorbaPage
    """
    from ExtensionProtobuf.ConfigurationPage.ProtobufPage import ProtobufPage

    # __IGNORE_WARNING_I102__

    global protobufExtensionPluginObject

    page = ProtobufPage(protobufExtensionPluginObject)
    return page


def prepareUninstall():
    """
    Module function to prepare for an un-installation.
    """
    Preferences.getSettings().remove(ProtobufExtensionPlugin.PreferencesKey)


class ProtobufExtensionPlugin(QObject):
    """
    Class implementing a plugin to add support for Protobuf development.
    """

    PreferencesKey = "Corba"

    def __init__(self, ui):
        """
        Constructor

        @param ui reference to the user interface object
        @type UI.UserInterface
        """
        super().__init__(ui)
        self.__ui = ui
        self.__initialize()

        self.__defaults = {
            "protoc": "",
            "grpcPythonEnv": "",
        }

        self.__translator = None
        self.__loadTranslator()

    def __initialize(self):
        """
        Private slot to (re)initialize the plugin.
        """
        global protobufExtensionPluginObject
        protobufExtensionPluginObject = None

        self.__browser = None

    def activate(self):
        """
        Public method to activate this plug-in.

        @return tuple of None and activation status
        @rtype bool
        """
        from eric7.QScintilla import Lexers
        from eric7.Utilities import ClassBrowsers

        global error, protobufExtensionPluginObject
        error = ""  # clear previous error

        if self.__ui.versionIsNewer("22.12"):
            protobufExtensionPluginObject = self

            self.__browser = ProjectProtocolsBrowser(self)

            Lexers.registerLexer(
                "Protocol Buffer",
                self.tr("Protocol Buffer (protobuf)"),
                "dummy.proto",
                self.getLexer,
                [self.tr("Protocol Buffer Files (*.proto)")],
                [self.tr("Protocol Buffer Files (*.proto)")],
                ["*.proto"],
                os.path.join("ExtensionProtobuf", "icons", "protobuf"),
            )

            ClassBrowsers.registerClassBrowser(
                "Protocol Buffer",
                protoclbr.readmodule_ex,
                protoclbr.scan,
                self.getFileIcon,
                [".proto"],
            )

            return None, True
        else:
            EricMessageBox.warning(
                self.__ui,
                self.tr("Protobuf and gRPC Extension"),
                self.tr(
                    "The Protobuf and gRPC extension cannot be activated because it"
                    " requires eric7 23.1 or newer."
                ),
            )
            error = self.tr(
                "The Protobuf and gRPC extension cannot be activated because it"
                " requires eric7 23.1 or newer."
            )

            return None, False

    def deactivate(self):
        """
        Public method to deactivate this plug-in.
        """
        from eric7.QScintilla import Lexers
        from eric7.Utilities import ClassBrowsers

        Lexers.unregisterLexer("Protocol Buffer")
        ClassBrowsers.registerClassBrowser("Protocol Buffer")

        self.__browser.deactivate()

        self.__initialize()

    def __loadTranslator(self):
        """
        Private method to load the translation file.
        """
        if self.__ui is not None:
            loc = self.__ui.getLocale()
            if loc and loc != "C":
                locale_dir = os.path.join(
                    os.path.dirname(__file__), "ExtensionProtobuf", "i18n"
                )
                translation = "protobuf_{0}".format(loc)
                translator = QTranslator(None)
                loaded = translator.load(translation, locale_dir)
                if loaded:
                    self.__translator = translator
                    ericApp().installTranslator(self.__translator)
                else:
                    print(
                        "Warning: translation file '{0}' could not be"
                        " loaded.".format(translation)
                    )
                    print("Using default.")

    def getPreferences(self, key):
        """
        Public method to retrieve the various settings values.

        @param key the key of the value to get
        @type str
        @return the requested setting value
        @rtype any
        """
        return Preferences.Prefs.settings.value(
            self.PreferencesKey + "/" + key, self.__defaults[key]
        )

    def setPreferences(self, key, value):
        """
        Public method to store the various settings values.

        @param key the key of the setting to be set
        @type str
        @param value the value to be set
        @type any
        """
        Preferences.Prefs.settings.setValue(self.PreferencesKey + "/" + key, value)

    def getLexer(self, parent=None):
        """
        Public method to instantiate a Pygments Protocol Buffer lexer object.

        @param parent reference to the parent object
        @type QObject
        @return reference to the instanciated lexer object
        @rtype QsciLexer
        """
        from eric7.QScintilla.Lexers.LexerPygments import LexerPygments

        lexer = LexerPygments(parent, name="Protocol Buffer")
        if lexer.canStyle():
            return lexer
        else:
            return None

    def getFileIcon(self, filename=""):
        """
        Public method to get the name of a file icon.

        @param filename file name (defaults to "")
        @type str (optional)
        @return name of a file icon
        @rtype str
        """
        return os.path.join("ExtensionProtobuf", "icons", "protobuf")


def installDependencies(pipInstall):
    """
    Function to install dependencies of this plug-in.

    @param pipInstall function to be called with a list of package names.
    @type function
    """
    try:
        import grpc_tools  # __IGNORE_WARNING__
    except ImportError:
        pipInstall(["protobuf", "grpcio", "grpcio-tools"])


#
# eflag: noqa = M801

eric ide

mercurial