PluginProjectPyramid.py

Sat, 26 Nov 2022 18:02:26 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 26 Nov 2022 18:02:26 +0100
branch
eric7
changeset 162
c044d1dd8116
parent 160
41b23683d5a1
child 164
277a93891db9
permissions
-rw-r--r--

Adapted to the project browser changes as of eric 22.12.

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

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

"""
Module implementing the Pyramid project plugin.
"""

import os
import glob
import fnmatch

from PyQt6.QtCore import QCoreApplication, QObject, QTranslator

from eric7 import Preferences
from eric7.EricWidgets.EricApplication import ericApp
from eric7.Globals import isWindowsPlatform, isMacPlatform

from ProjectPyramid.Project import Project

# Start-of-Header
name = "Pyramid Project Plugin"
author = "Detlev Offenbach <detlev@die-offenbachs.de>"
autoactivate = True
deactivateable = True
version = "10.2.0"
className = "ProjectPyramidPlugin"
packageName = "ProjectPyramid"
shortDescription = "Project support for Pyramid projects."
longDescription = """This plugin implements project support for Pyramid projects."""
needsRestart = False
pyqtApi = 2
# End-of-Header

error = ""

pyramidPluginObject = None


def createPyramidPage(configDlg):
    """
    Module function to create the Pyramid configuration page.

    @param configDlg reference to the configuration dialog
    @type ConfigurationWidget
    @return reference to the configuration page
    @rtype PyramidPage
    """
    global pyramidPluginObject
    from ProjectPyramid.ConfigurationPage.PyramidPage import PyramidPage

    return PyramidPage(pyramidPluginObject)


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

    @return dictionary containing the relevant data
    @rtype dict
    """
    usesDarkPalette = ericApp().usesDarkPalette()
    iconSuffix = "dark" if usesDarkPalette else "light"

    return {
        "pyramidPage": [
            QCoreApplication.translate("ProjectPyramidPlugin", "Pyramid"),
            os.path.join("ProjectPyramid", "icons", "pyramid-{0}".format(iconSuffix)),
            createPyramidPage,
            None,
            None,
        ],
    }


def apiFiles(language):
    """
    Module function to return the API files made available by this plugin.

    @param language language to get APIs for
    @type str
    @return list of API filenames
    @rtype list of str
    """
    if language == "Python3":
        apisDir = os.path.join(os.path.dirname(__file__), "ProjectPyramid", "APIs")
        return glob.glob(os.path.join(apisDir, "*.api"))
    else:
        return []


def prepareUninstall():
    """
    Module function to prepare for an uninstallation.
    """
    try:
        Preferences.removeProjectBrowsers(ProjectPyramidPlugin.PreferencesKey)
    except AttributeError:
        # backward compatibility for eric7 < 22.12
        Preferences.removeProjectBrowserFlags(ProjectPyramidPlugin.PreferencesKey)
    Preferences.Prefs.settings.remove(ProjectPyramidPlugin.PreferencesKey)


class ProjectPyramidPlugin(QObject):
    """
    Class implementing the Pyramid project plugin.
    """

    PreferencesKey = "Pyramid"

    lexerAssociations = {
        "*.mako": "Pygments|HTML+Mako",
        "*.pt": "Pygments|HTML+Genshi",
        "*.txt": "Pygments|Genshi",
        "*.html": "Pygments|HTML+Genshi",
        "*.htm": "Pygments|HTML+Genshi",
    }

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

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

        self.__defaults = {
            "VirtualEnvironmentNamePy3": "",
            "Python3ConsoleType": "python",
            "PyramidDocUrl": "http://docs.pylonsproject.org/projects/"
            "pyramid/en/latest/index.html",
            "TranslationsEditor": "",
            "UseExternalBrowser": False,
        }
        if isWindowsPlatform():
            self.__defaults["ConsoleCommand"] = "cmd.exe /c"
        elif isMacPlatform():
            self.__defaults["ConsoleCommand"] = "xterm -e"
        else:
            self.__defaults["ConsoleCommand"] = "konsole -e"

        self.__translator = None
        self.__loadTranslator()

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

        self.__mainMenu = None
        self.__mainAct = None
        self.__separatorAct = None

        self.__ericProject = ericApp().getObject("Project")

        self.__supportedVariants = []

    def activate(self):
        """
        Public method to activate this plugin.

        @return tuple of None and activation status
        @rtype (None, bool)
        """
        global pyramidPluginObject
        pyramidPluginObject = self

        usesDarkPalette = ericApp().usesDarkPalette()
        iconSuffix = "dark" if usesDarkPalette else "light"

        self.__object = Project(self, iconSuffix, self.__ui)
        self.__object.initActions()
        ericApp().registerPluginObject("ProjectPyramid", self.__object)

        self.__mainMenu = self.__object.initMenu()

        self.__supportedVariants = self.__object.supportedPythonVariants()

        if self.__supportedVariants:
            self.__ericProject.registerProjectType(
                "Pyramid",
                self.tr("Pyramid"),
                self.fileTypesCallback,
                lexerAssociationCallback=self.lexerAssociationCallback,
                binaryTranslationsCallback=self.binaryTranslationsCallback,
                progLanguages=self.__supportedVariants[:],
            )

        try:
            # backward compatibility for eric7 < 22.12
            from eric7.Project.ProjectBrowser import (
                SourcesBrowserFlag,
                FormsBrowserFlag,
                TranslationsBrowserFlag,
                OthersBrowserFlag,
            )

            Preferences.setProjectBrowserFlagsDefault(
                "Pyramid",
                SourcesBrowserFlag
                | FormsBrowserFlag
                | TranslationsBrowserFlag
                | OthersBrowserFlag,
            )
        except ImportError:
            Preferences.setProjectBrowsersDefault(
                "Pyramid",
                ("sources", "forms", "translations", "others"),
            )

        if self.__ericProject.isOpen():
            self.__projectOpened()
            self.__object.projectOpenedHooks()

        ericApp().getObject("Project").projectOpened.connect(self.__projectOpened)
        ericApp().getObject("Project").projectClosed.connect(self.__projectClosed)
        ericApp().getObject("Project").newProject.connect(self.__projectOpened)

        ericApp().getObject("Project").projectOpenedHooks.connect(
            self.__object.projectOpenedHooks
        )
        ericApp().getObject("Project").projectClosedHooks.connect(
            self.__object.projectClosedHooks
        )
        ericApp().getObject("Project").newProjectHooks.connect(
            self.__object.projectOpenedHooks
        )

        return None, True

    def deactivate(self):
        """
        Public method to deactivate this plugin.
        """
        ericApp().unregisterPluginObject("ProjectPyramid")

        ericApp().getObject("Project").projectOpened.disconnect(self.__projectOpened)
        ericApp().getObject("Project").projectClosed.disconnect(self.__projectClosed)
        ericApp().getObject("Project").newProject.disconnect(self.__projectOpened)

        ericApp().getObject("Project").projectOpenedHooks.disconnect(
            self.__object.projectOpenedHooks
        )
        ericApp().getObject("Project").projectClosedHooks.disconnect(
            self.__object.projectClosedHooks
        )
        ericApp().getObject("Project").newProjectHooks.disconnect(
            self.__object.projectOpenedHooks
        )

        self.__ericProject.unregisterProjectType("Pyramid")

        self.__object.projectClosedHooks()
        self.__projectClosed()

        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__), "ProjectPyramid", "i18n"
                )
                translation = "pyramid_{0}".format(loc)
                translator = QTranslator(None)
                loaded = translator.load(translation, locale_dir)
                if loaded:
                    self.__translator = translator
                    ericApp().installTranslator(self.__translator)
                else:
                    print(  # __IGNORE_WARNING__
                        "Warning: translation file '{0}' could not be loaded.".format(
                            translation
                        )
                    )
                    print("Using default.")  # __IGNORE_WARNING__

    def __projectOpened(self):
        """
        Private slot to handle the projectOpened signal.
        """
        if self.__ericProject.getProjectType() == "Pyramid":
            projectToolsMenu = self.__ui.getMenu("project_tools")
            insertBeforeAct = projectToolsMenu.actions()[0]
            self.__mainAct = projectToolsMenu.insertMenu(
                insertBeforeAct, self.__mainMenu
            )
            self.__separatorAct = projectToolsMenu.insertSeparator(insertBeforeAct)

    def __projectClosed(self):
        """
        Private slot to handle the projectClosed signal.
        """
        if self.__mainAct is not None:
            projectToolsMenu = self.__ui.getMenu("project_tools")
            projectToolsMenu.removeAction(self.__separatorAct)
            projectToolsMenu.removeAction(self.__mainAct)
            self.__mainAct = None
            self.__separatorAct = None
            self.__object.projectClosed()

    def fileTypesCallback(self):
        """
        Public method get the filetype associations of the Pyramid project
        type.

        @return dictionary with file type associations
        @rtype dict
        """
        if self.__ericProject.getProjectType() == "Pyramid":
            return {
                "*.mako": "FORMS",
                "*.mak": "FORMS",
                "*.pt": "FORMS",
                "*.html": "FORMS",
                "*.htm": "FORMS",
                "*.js": "SOURCES",
                "*.pot": "TRANSLATIONS",
                "*.po": "TRANSLATIONS",
                "*.mo": "TRANSLATIONS",
            }
        else:
            return {}

    def lexerAssociationCallback(self, filename):
        """
        Public method to get the lexer association of the Pyramid project type
        for a file.

        @param filename name of the file
        @type str
        @return name of the lexer (Pygments lexers are prefixed with
            'Pygments|')
        @rtype str
        """
        for pattern, language in self.lexerAssociations.items():
            if fnmatch.fnmatch(filename, pattern):
                return language

        return ""

    def binaryTranslationsCallback(self, filename):
        """
        Public method to determine the filename of a compiled translation file
        given the translation source file.

        @param filename name of the translation source file
        @type str
        @return name of the binary translation file
        @rtype str
        """
        if filename.endswith(".po"):
            return filename.replace(".po", ".mo")

        return filename

    def getDefaultPreference(self, key):
        """
        Public method to get the default value for a setting.

        @param key key of the value to get
        @type str
        @return value of the requested setting
        @rtype Any
        """
        return self.__defaults[key]

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

        @param key key of the value to get
        @type str
        @return value of the requested setting
        @rtype Any
        """
        if key in ["UseExternalBrowser"]:
            return Preferences.toBool(
                Preferences.Prefs.settings.value(
                    self.PreferencesKey + "/" + key, self.__defaults[key]
                )
            )
        else:
            return Preferences.Prefs.settings.value(
                self.PreferencesKey + "/" + key, self.__defaults[key]
            )

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

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

        if key in ["VirtualEnvironmentNamePy3"]:
            self.__reregisterProjectType()
        elif key == "TranslationsEditor" and self.__object:
            self.__object.registerOpenHook()

    def __reregisterProjectType(self):
        """
        Private method to re-register the project type.
        """
        supportedVariants = self.__object.supportedPythonVariants()
        if supportedVariants != self.__supportedVariants:
            # step 1: unregister
            self.__ericProject.unregisterProjectType("Pyramid")

            # step 2: register again with new language settings
            self.__supportedVariants = supportedVariants
            if self.__supportedVariants:
                self.__ericProject.registerProjectType(
                    "Pyramid",
                    self.tr("Pyramid"),
                    self.fileTypesCallback,
                    lexerAssociationCallback=self.lexerAssociationCallback,
                    binaryTranslationsCallback=self.binaryTranslationsCallback,
                    progLanguages=self.__supportedVariants[:],
                )

    def getMenu(self, name):
        """
        Public method to get a reference to the requested menu.

        @param name name of the menu
        @type str
        @return reference to the menu or None, if no menu with the given
            name exists
        @rtype QMenu
        """
        if self.__object is not None:
            return self.__object.getMenu(name)
        else:
            return None

    def getMenuNames(self):
        """
        Public method to get the names of all menus.

        @return menu names
        @rtype list of str
        """
        if self.__object is not None:
            return list(self.__menus.keys())
        else:
            return []


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 cookiecutter  # __IGNORE_WARNING__
    except ImportError:
        pipInstall(["cookiecutter"])

eric ide

mercurial