src/eric7/Project/PropertiesDialog.py

Wed, 13 Jul 2022 14:55:47 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Wed, 13 Jul 2022 14:55:47 +0200
branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9264
18a7312cfdb3
child 9323
6ae7193558ac
permissions
-rw-r--r--

Reformatted the source code using the 'Black' utility.

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

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

"""
Module implementing the project properties dialog.
"""

import contextlib
import os

import trove_classifiers

from PyQt6.QtCore import QDir, pyqtSlot
from PyQt6.QtWidgets import QDialog, QDialogButtonBox

from EricWidgets.EricApplication import ericApp
from EricWidgets.EricPathPicker import EricPathPickerModes

from .Ui_PropertiesDialog import Ui_PropertiesDialog

from QScintilla.DocstringGenerator import getSupportedDocstringTypes

from Testing.Interfaces import FrameworkNames

import Utilities
import Preferences
import UI.PixmapCache


class PropertiesDialog(QDialog, Ui_PropertiesDialog):
    """
    Class implementing the project properties dialog.
    """

    def __init__(self, project, new=True, parent=None, name=None):
        """
        Constructor

        @param project reference to the project object
        @param new flag indicating the generation of a new project
        @param parent parent widget of this dialog (QWidget)
        @param name name of this dialog (string)
        """
        super().__init__(parent)
        if name:
            self.setObjectName(name)
        self.setupUi(self)

        self.dirPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
        self.mainscriptPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)

        self.makeButton.setIcon(UI.PixmapCache.getIcon("makefile"))

        self.docstringStyleComboBox.addItem(self.tr("None"), "")
        for docstringType, docstringStyle in sorted(getSupportedDocstringTypes()):
            self.docstringStyleComboBox.addItem(docstringStyle, docstringType)

        self.project = project
        self.newProject = new
        self.transPropertiesDlg = None
        self.spellPropertiesDlg = None
        self.makePropertiesDlg = None

        patterns = []
        for pattern, filetype in self.project.pdata["FILETYPES"].items():
            if filetype == "SOURCES":
                patterns.append(pattern)
        filters = self.tr("Source Files ({0});;All Files (*)").format(
            " ".join(sorted(patterns))
        )
        self.mainscriptPicker.setFilters(filters)

        self.languageComboBox.addItems(project.getProgrammingLanguages())

        projectTypes = []
        for projectTypeItem in project.getProjectTypes().items():
            projectTypes.append((projectTypeItem[1], projectTypeItem[0]))
        self.projectTypeComboBox.clear()
        for projectType in sorted(projectTypes):
            self.projectTypeComboBox.addItem(projectType[0], projectType[1])

        ipath = Preferences.getMultiProject("Workspace") or Utilities.getHomeDir()
        self.__initPaths = [
            Utilities.fromNativeSeparators(ipath),
            Utilities.fromNativeSeparators(ipath) + "/",
        ]

        self.licenseComboBox.lineEdit().setClearButtonEnabled(True)
        self.__populateLicenseComboBox()

        if not new:
            name = os.path.splitext(self.project.pfile)[0]
            self.nameEdit.setText(os.path.basename(name))
            self.languageComboBox.setCurrentIndex(
                self.languageComboBox.findText(self.project.pdata["PROGLANGUAGE"])
            )
            self.mixedLanguageCheckBox.setChecked(self.project.pdata["MIXEDLANGUAGE"])
            curIndex = self.projectTypeComboBox.findData(
                self.project.pdata["PROJECTTYPE"]
            )
            if curIndex == -1:
                curIndex = self.projectTypeComboBox.findData("PyQt6")
            self.projectTypeComboBox.setCurrentIndex(curIndex)
            self.dirPicker.setText(self.project.ppath)
            self.versionEdit.setText(self.project.pdata["VERSION"])
            self.mainscriptPicker.setText(self.project.pdata["MAINSCRIPT"])
            self.authorEdit.setText(self.project.pdata["AUTHOR"])
            self.emailEdit.setText(self.project.pdata["EMAIL"])
            self.descriptionEdit.setPlainText(self.project.pdata["DESCRIPTION"])
            self.eolComboBox.setCurrentIndex(self.project.pdata["EOL"])
            self.vcsLabel.show()
            if self.project.vcs is not None:
                vcsSystemsDict = (
                    ericApp()
                    .getObject("PluginManager")
                    .getPluginDisplayStrings("version_control")
                )
                try:
                    vcsSystemDisplay = vcsSystemsDict[self.project.pdata["VCS"]]
                except KeyError:
                    vcsSystemDisplay = "None"
                self.vcsLabel.setText(
                    self.tr("The project is version controlled by <b>{0}</b>.").format(
                        vcsSystemDisplay
                    )
                )
                self.vcsInfoButton.show()
            else:
                self.vcsLabel.setText(self.tr("The project is not version controlled."))
                self.vcsInfoButton.hide()
            self.vcsCheckBox.hide()
            self.makeCheckBox.setChecked(
                self.project.pdata["MAKEPARAMS"]["MakeEnabled"]
            )
            cindex = self.docstringStyleComboBox.findData(
                self.project.pdata["DOCSTRING"]
            )
            self.docstringStyleComboBox.setCurrentIndex(cindex)
            with contextlib.suppress(KeyError):
                cindex = self.testingFrameworkComboBox.findData(
                    self.project.pdata["TESTING_FRAMEWORK"]
                )
                self.testingFrameworkComboBox.setCurrentIndex(cindex)
            with contextlib.suppress(KeyError):
                self.licenseComboBox.setCurrentText(self.project.pdata["LICENSE"])
        else:
            self.languageComboBox.setCurrentText("Python3")
            self.projectTypeComboBox.setCurrentIndex(
                self.projectTypeComboBox.findData("PyQt6")
            )
            self.dirPicker.setText(self.__initPaths[0])
            self.versionEdit.setText("0.1")
            self.vcsLabel.hide()
            self.vcsInfoButton.hide()
            if not self.project.vcsSoftwareAvailable():
                self.vcsCheckBox.hide()

        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
            bool(self.dirPicker.text())
            and self.dirPicker.text() not in self.__initPaths
        )

    def __populateLicenseComboBox(self):
        """
        Private method to populate the license selector with the list of trove
        license types.
        """
        self.licenseComboBox.addItem("")
        self.licenseComboBox.addItems(
            sorted(
                classifier.split("::")[-1].strip()
                for classifier in trove_classifiers.classifiers
                if classifier.startswith("License ::")
            )
        )

    @pyqtSlot(str)
    def on_languageComboBox_currentTextChanged(self, language):
        """
        Private slot handling the selection of a programming language.

        @param language text of the current item
        @type str
        """
        curProjectType = self.getProjectType()

        self.projectTypeComboBox.clear()
        for projectType in sorted(
            self.project.getProjectTypes(language).items(), key=lambda k: k[1]
        ):
            self.projectTypeComboBox.addItem(projectType[1], projectType[0])

        index = self.projectTypeComboBox.findData(curProjectType)
        if index == -1:
            index = 0
        self.projectTypeComboBox.setCurrentIndex(index)

        curTestingFramework = self.testingFrameworkComboBox.currentText()
        self.testingFrameworkComboBox.clear()
        self.testingFrameworkComboBox.addItem(self.tr("None"), "")
        with contextlib.suppress(KeyError):
            for framework in sorted(FrameworkNames[language]):
                self.testingFrameworkComboBox.addItem(framework, framework)
        self.testingFrameworkComboBox.setCurrentText(curTestingFramework)

    @pyqtSlot(str)
    def on_dirPicker_textChanged(self, txt):
        """
        Private slot to handle a change of the project directory.

        @param txt name of the project directory (string)
        """
        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
            bool(txt) and Utilities.fromNativeSeparators(txt) not in self.__initPaths
        )

    @pyqtSlot()
    def on_spellPropertiesButton_clicked(self):
        """
        Private slot to display the spelling properties dialog.
        """
        if self.spellPropertiesDlg is None:
            from .SpellingPropertiesDialog import SpellingPropertiesDialog

            self.spellPropertiesDlg = SpellingPropertiesDialog(
                self.project, self.newProject, self
            )
        res = self.spellPropertiesDlg.exec()
        if res == QDialog.DialogCode.Rejected:
            self.spellPropertiesDlg.initDialog()  # reset the dialogs contents

    @pyqtSlot()
    def on_transPropertiesButton_clicked(self):
        """
        Private slot to display the translations properties dialog.
        """
        if self.transPropertiesDlg is None:
            from .TranslationPropertiesDialog import TranslationPropertiesDialog

            self.transPropertiesDlg = TranslationPropertiesDialog(
                self.project, self.newProject, self
            )
        else:
            self.transPropertiesDlg.initFilters()
        res = self.transPropertiesDlg.exec()
        if res == QDialog.DialogCode.Rejected:
            self.transPropertiesDlg.initDialog()  # reset the dialogs contents

    @pyqtSlot()
    def on_makeButton_clicked(self):
        """
        Private slot to display the make properties dialog.
        """
        if self.makePropertiesDlg is None:
            from .MakePropertiesDialog import MakePropertiesDialog

            self.makePropertiesDlg = MakePropertiesDialog(
                self.project, self.newProject, self
            )
        res = self.makePropertiesDlg.exec()
        if res == QDialog.DialogCode.Rejected:
            self.makePropertiesDlg.initDialog()

    @pyqtSlot(str)
    def on_mainscriptPicker_pathSelected(self, script):
        """
        Private slot to check the selected main script name.

        @param script name of the main script
        @type str
        """
        if script:
            ppath = self.dirPicker.text()
            if ppath:
                ppath = QDir(ppath).absolutePath() + QDir.separator()
                script = script.replace(ppath, "")
            self.mainscriptPicker.setText(script)

    @pyqtSlot()
    def on_mainscriptPicker_aboutToShowPathPickerDialog(self):
        """
        Private slot to perform actions before the main script selection dialog
        is shown.
        """
        path = self.dirPicker.text()
        if not path:
            path = QDir.currentPath()
        self.mainscriptPicker.setDefaultDirectory(path)

    @pyqtSlot()
    def on_vcsInfoButton_clicked(self):
        """
        Private slot to display a vcs information dialog.
        """
        if self.project.vcs is None:
            return

        from VCS.RepositoryInfoDialog import VcsRepositoryInfoDialog

        info = self.project.vcs.vcsRepositoryInfos(self.project.ppath)
        dlg = VcsRepositoryInfoDialog(self, info)
        dlg.exec()

    def getProjectType(self):
        """
        Public method to get the selected project type.

        @return selected UI type (string)
        """
        return self.projectTypeComboBox.itemData(
            self.projectTypeComboBox.currentIndex()
        )

    def getPPath(self):
        """
        Public method to get the project path.

        @return data of the project directory edit (string)
        """
        return os.path.abspath(self.dirPicker.text())

    def storeData(self):
        """
        Public method to store the entered/modified data.
        """
        self.project.ppath = os.path.abspath(self.dirPicker.text())
        fn = self.nameEdit.text()
        if fn:
            self.project.name = fn
            fn = "{0}.epj".format(fn)
            self.project.pfile = os.path.join(self.project.ppath, fn)
        else:
            self.project.pfile = ""
        self.project.pdata["VERSION"] = self.versionEdit.text()
        fn = self.mainscriptPicker.text()
        if fn:
            fn = self.project.getRelativePath(fn)
            self.project.pdata["MAINSCRIPT"] = fn
            self.project.translationsRoot = os.path.splitext(fn)[0]
        else:
            self.project.pdata["MAINSCRIPT"] = ""
            self.project.translationsRoot = ""
        self.project.pdata["AUTHOR"] = self.authorEdit.text()
        self.project.pdata["EMAIL"] = self.emailEdit.text()
        self.project.pdata["DESCRIPTION"] = self.descriptionEdit.toPlainText()
        self.project.pdata["PROGLANGUAGE"] = self.languageComboBox.currentText()
        self.project.pdata["MIXEDLANGUAGE"] = self.mixedLanguageCheckBox.isChecked()
        projectType = self.getProjectType()
        if projectType is not None:
            self.project.pdata["PROJECTTYPE"] = projectType
        self.project.pdata["EOL"] = self.eolComboBox.currentIndex()

        self.project.vcsRequested = self.vcsCheckBox.isChecked()

        if self.spellPropertiesDlg is not None:
            self.spellPropertiesDlg.storeData()

        if self.transPropertiesDlg is not None:
            self.transPropertiesDlg.storeData()

        self.project.pdata["MAKEPARAMS"]["MakeEnabled"] = self.makeCheckBox.isChecked()
        if self.makePropertiesDlg is not None:
            self.makePropertiesDlg.storeData()

        self.project.pdata["DOCSTRING"] = self.docstringStyleComboBox.currentData()

        self.project.pdata[
            "TESTING_FRAMEWORK"
        ] = self.testingFrameworkComboBox.currentData()

        self.project.pdata["LICENSE"] = self.licenseComboBox.currentText()

eric ide

mercurial