Added the capability to create project specific virtual environments.

Sat, 05 Dec 2020 17:18:17 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 05 Dec 2020 17:18:17 +0100
changeset 52
caddf9f36f9f
parent 51
428c2bec2e8f
child 53
a314fbcb6b71

Added the capability to create project specific virtual environments.

ChangeLog file | annotate | diff | comparison | revisions
PKGLIST file | annotate | diff | comparison | revisions
PluginFlask.e4p file | annotate | diff | comparison | revisions
PluginProjectFlask.zip file | annotate | diff | comparison | revisions
ProjectFlask/Documentation/source/Plugin_Project_Flask.ProjectFlask.FlaskConfigDialog.html file | annotate | diff | comparison | revisions
ProjectFlask/Documentation/source/Plugin_Project_Flask.ProjectFlask.FlaskVirtualenvConfigurationDialog.html file | annotate | diff | comparison | revisions
ProjectFlask/Documentation/source/Plugin_Project_Flask.ProjectFlask.Project.html file | annotate | diff | comparison | revisions
ProjectFlask/Documentation/source/index-Plugin_Project_Flask.ProjectFlask.html file | annotate | diff | comparison | revisions
ProjectFlask/FlaskConfigDialog.py file | annotate | diff | comparison | revisions
ProjectFlask/FlaskVirtualenvConfigurationDialog.py file | annotate | diff | comparison | revisions
ProjectFlask/FlaskVirtualenvConfigurationDialog.ui file | annotate | diff | comparison | revisions
ProjectFlask/Project.py file | annotate | diff | comparison | revisions
ProjectFlask/i18n/flask_de.qm file | annotate | diff | comparison | revisions
ProjectFlask/i18n/flask_de.ts file | annotate | diff | comparison | revisions
ProjectFlask/i18n/flask_empty.ts file | annotate | diff | comparison | revisions
ProjectFlask/i18n/flask_en.ts file | annotate | diff | comparison | revisions
ProjectFlask/i18n/flask_es.ts file | annotate | diff | comparison | revisions
ProjectFlask/i18n/flask_ru.ts file | annotate | diff | comparison | revisions
--- a/ChangeLog	Wed Dec 02 20:04:05 2020 +0100
+++ b/ChangeLog	Sat Dec 05 17:18:17 2020 +0100
@@ -1,5 +1,10 @@
 ChangeLog
 ---------
+Version 1.2.0
+- bug fixes
+- added capability to configure project specific flask settings
+- added capability to create project specific virtual environments
+
 Version 1.1.0
 - bug fixes
 - added Spanish translations
--- a/PKGLIST	Wed Dec 02 20:04:05 2020 +0100
+++ b/PKGLIST	Sat Dec 05 17:18:17 2020 +0100
@@ -24,6 +24,8 @@
 ProjectFlask/FlaskBabelExtension/__init__.py
 ProjectFlask/FlaskCommandDialog.py
 ProjectFlask/FlaskCommandDialog.ui
+ProjectFlask/FlaskConfigDialog.py
+ProjectFlask/FlaskConfigDialog.ui
 ProjectFlask/FlaskMigrateExtension/FlaskMigrateDetector.py
 ProjectFlask/FlaskMigrateExtension/MigrateConfigDialog.py
 ProjectFlask/FlaskMigrateExtension/MigrateConfigDialog.ui
@@ -31,6 +33,8 @@
 ProjectFlask/FlaskMigrateExtension/MigrateSummaryDialog.py
 ProjectFlask/FlaskMigrateExtension/MigrateSummaryDialog.ui
 ProjectFlask/FlaskMigrateExtension/__init__.py
+ProjectFlask/FlaskVirtualenvConfigurationDialog.py
+ProjectFlask/FlaskVirtualenvConfigurationDialog.ui
 ProjectFlask/FormSelectionDialog.py
 ProjectFlask/FormSelectionDialog.ui
 ProjectFlask/Project.py
--- a/PluginFlask.e4p	Wed Dec 02 20:04:05 2020 +0100
+++ b/PluginFlask.e4p	Sat Dec 05 17:18:17 2020 +0100
@@ -30,6 +30,7 @@
     <Source>ProjectFlask/FlaskMigrateExtension/MigrateProjectExtension.py</Source>
     <Source>ProjectFlask/FlaskMigrateExtension/MigrateSummaryDialog.py</Source>
     <Source>ProjectFlask/FlaskMigrateExtension/__init__.py</Source>
+    <Source>ProjectFlask/FlaskVirtualenvConfigurationDialog.py</Source>
     <Source>ProjectFlask/FormSelectionDialog.py</Source>
     <Source>ProjectFlask/Project.py</Source>
     <Source>ProjectFlask/RoutesDialog.py</Source>
@@ -45,6 +46,7 @@
     <Form>ProjectFlask/FlaskConfigDialog.ui</Form>
     <Form>ProjectFlask/FlaskMigrateExtension/MigrateConfigDialog.ui</Form>
     <Form>ProjectFlask/FlaskMigrateExtension/MigrateSummaryDialog.ui</Form>
+    <Form>ProjectFlask/FlaskVirtualenvConfigurationDialog.ui</Form>
     <Form>ProjectFlask/FormSelectionDialog.ui</Form>
     <Form>ProjectFlask/RoutesDialog.ui</Form>
     <Form>ProjectFlask/RunServerDialog.ui</Form>
Binary file PluginProjectFlask.zip has changed
--- a/ProjectFlask/Documentation/source/Plugin_Project_Flask.ProjectFlask.FlaskConfigDialog.html	Wed Dec 02 20:04:05 2020 +0100
+++ b/ProjectFlask/Documentation/source/Plugin_Project_Flask.ProjectFlask.FlaskConfigDialog.html	Sat Dec 05 17:18:17 2020 +0100
@@ -73,6 +73,10 @@
 <td>Constructor</td>
 </tr>
 <tr>
+<td><a href="#FlaskConfigDialog.__installFlask">__installFlask</a></td>
+<td>Private method to install flask into the newly created environment.</td>
+</tr>
+<tr>
 <td><a href="#FlaskConfigDialog.getConfiguration">getConfiguration</a></td>
 <td>Public method to get the entered configuration data.</td>
 </tr>
@@ -89,7 +93,7 @@
 
 <a NAME="FlaskConfigDialog.__init__" ID="FlaskConfigDialog.__init__"></a>
 <h4>FlaskConfigDialog (Constructor)</h4>
-<b>FlaskConfigDialog</b>(<i>configuration, parent=None</i>)
+<b>FlaskConfigDialog</b>(<i>configuration, project, parent=None</i>)
 
 <p>
         Constructor
@@ -100,11 +104,29 @@
 <dd>
 current project specific configuration
 </dd>
+<dt><i>project</i> (Project)</dt>
+<dd>
+reference to the flask project object
+</dd>
 <dt><i>parent</i> (QWidget)</dt>
 <dd>
 reference to the parent widget
 </dd>
 </dl>
+<a NAME="FlaskConfigDialog.__installFlask" ID="FlaskConfigDialog.__installFlask"></a>
+<h4>FlaskConfigDialog.__installFlask</h4>
+<b>__installFlask</b>(<i>venvDir</i>)
+
+<p>
+        Private method to install flask into the newly created environment.
+</p>
+<dl>
+
+<dt><i>venvtDir</i> (str)</dt>
+<dd>
+directory containing the virtual environment
+</dd>
+</dl>
 <a NAME="FlaskConfigDialog.getConfiguration" ID="FlaskConfigDialog.getConfiguration"></a>
 <h4>FlaskConfigDialog.getConfiguration</h4>
 <b>getConfiguration</b>(<i></i>)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ProjectFlask/Documentation/source/Plugin_Project_Flask.ProjectFlask.FlaskVirtualenvConfigurationDialog.html	Sat Dec 05 17:18:17 2020 +0100
@@ -0,0 +1,219 @@
+<!DOCTYPE html>
+<html><head>
+<title>Plugin_Project_Flask.ProjectFlask.FlaskVirtualenvConfigurationDialog</title>
+<meta charset="UTF-8">
+<style>
+body {
+    background: #EDECE6;
+    margin: 0em 1em 10em 1em;
+    color: black;
+}
+
+h1 { color: white; background: #85774A; }
+h2 { color: white; background: #85774A; }
+h3 { color: white; background: #9D936E; }
+h4 { color: white; background: #9D936E; }
+    
+a { color: #BA6D36; }
+
+</style>
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>Plugin_Project_Flask.ProjectFlask.FlaskVirtualenvConfigurationDialog</h1>
+
+<p>
+Module implementing a dialog to configure a project specific virtual
+environment.
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+
+<tr>
+<td><a href="#FlaskVirtualenvConfigurationDialog">FlaskVirtualenvConfigurationDialog</a></td>
+<td>Class implementing a dialog to configure a project specific virtual environment.</td>
+</tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<hr />
+<hr />
+<a NAME="FlaskVirtualenvConfigurationDialog" ID="FlaskVirtualenvConfigurationDialog"></a>
+<h2>FlaskVirtualenvConfigurationDialog</h2>
+
+<p>
+    Class implementing a dialog to configure a project specific virtual
+    environment.
+</p>
+<p>
+    Note: This dialog is a simplified variant of the one found in the eric
+    package.
+</p>
+<h3>Derived from</h3>
+QDialog, Ui_FlaskVirtualenvConfigurationDialog
+<h3>Class Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Class Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#FlaskVirtualenvConfigurationDialog.__init__">FlaskVirtualenvConfigurationDialog</a></td>
+<td>Constructor</td>
+</tr>
+<tr>
+<td><a href="#FlaskVirtualenvConfigurationDialog.__generateTargetDir">__generateTargetDir</a></td>
+<td>Private method to generate a valid target directory path.</td>
+</tr>
+<tr>
+<td><a href="#FlaskVirtualenvConfigurationDialog.__updateOK">__updateOK</a></td>
+<td>Private method to update the enabled status of the OK button.</td>
+</tr>
+<tr>
+<td><a href="#FlaskVirtualenvConfigurationDialog.getData">getData</a></td>
+<td>Public method to retrieve the dialog data.</td>
+</tr>
+<tr>
+<td><a href="#FlaskVirtualenvConfigurationDialog.on_nameEdit_textChanged">on_nameEdit_textChanged</a></td>
+<td>Private slot handling a change of the virtual environment name.</td>
+</tr>
+<tr>
+<td><a href="#FlaskVirtualenvConfigurationDialog.on_targetDirectoryPicker_textChanged">on_targetDirectoryPicker_textChanged</a></td>
+<td>Private slot handling a change of the target directory.</td>
+</tr>
+</table>
+<h3>Static Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+
+<a NAME="FlaskVirtualenvConfigurationDialog.__init__" ID="FlaskVirtualenvConfigurationDialog.__init__"></a>
+<h4>FlaskVirtualenvConfigurationDialog (Constructor)</h4>
+<b>FlaskVirtualenvConfigurationDialog</b>(<i>projectPath, projectName, parent=None</i>)
+
+<p>
+        Constructor
+</p>
+<dl>
+
+<dt><i>projectPath</i> (str)</dt>
+<dd>
+directory path of the project
+</dd>
+<dt><i>projectName</i> (str)</dt>
+<dd>
+name of the project
+</dd>
+<dt><i>parent</i> (QWidget)</dt>
+<dd>
+reference to the parent widget
+</dd>
+</dl>
+<a NAME="FlaskVirtualenvConfigurationDialog.__generateTargetDir" ID="FlaskVirtualenvConfigurationDialog.__generateTargetDir"></a>
+<h4>FlaskVirtualenvConfigurationDialog.__generateTargetDir</h4>
+<b>__generateTargetDir</b>(<i></i>)
+
+<p>
+        Private method to generate a valid target directory path.
+</p>
+<dl>
+<dt>Returns:</dt>
+<dd>
+target directory path
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<a NAME="FlaskVirtualenvConfigurationDialog.__updateOK" ID="FlaskVirtualenvConfigurationDialog.__updateOK"></a>
+<h4>FlaskVirtualenvConfigurationDialog.__updateOK</h4>
+<b>__updateOK</b>(<i></i>)
+
+<p>
+        Private method to update the enabled status of the OK button.
+</p>
+<a NAME="FlaskVirtualenvConfigurationDialog.getData" ID="FlaskVirtualenvConfigurationDialog.getData"></a>
+<h4>FlaskVirtualenvConfigurationDialog.getData</h4>
+<b>getData</b>(<i></i>)
+
+<p>
+        Public method to retrieve the dialog data.
+</p>
+<p>
+        Note: This method returns a data structure compatible with the one
+        returned by the eric virtual environment configuration dialog.
+</p>
+<dl>
+<dt>Returns:</dt>
+<dd>
+dictionary containing the data for the environment to be
+            created. The keys for both variants are 'arguments' containing the
+            command line arguments, 'logicalName' containing the environment
+            name to be used with the virtual environment manager and 'envType'
+            containing the environment type (always pyvenv). The pyvenv
+            specific keys are 'openTarget' containg a flag to open the target
+            directory after creation (always False), 'createLog' containing a
+            flag to write a log file (always False), 'createScript' containing
+            a flag to write a script (always False), 'targetDirectory'
+            containing the target directory and 'pythonExe' containing the
+            Python interpreter to be used.
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+dict
+</dd>
+</dl>
+<a NAME="FlaskVirtualenvConfigurationDialog.on_nameEdit_textChanged" ID="FlaskVirtualenvConfigurationDialog.on_nameEdit_textChanged"></a>
+<h4>FlaskVirtualenvConfigurationDialog.on_nameEdit_textChanged</h4>
+<b>on_nameEdit_textChanged</b>(<i>txt</i>)
+
+<p>
+        Private slot handling a change of the virtual environment name.
+</p>
+<dl>
+
+<dt><i>txt</i> (str)</dt>
+<dd>
+name of the virtual environment
+</dd>
+</dl>
+<a NAME="FlaskVirtualenvConfigurationDialog.on_targetDirectoryPicker_textChanged" ID="FlaskVirtualenvConfigurationDialog.on_targetDirectoryPicker_textChanged"></a>
+<h4>FlaskVirtualenvConfigurationDialog.on_targetDirectoryPicker_textChanged</h4>
+<b>on_targetDirectoryPicker_textChanged</b>(<i>txt</i>)
+
+<p>
+        Private slot handling a change of the target directory.
+</p>
+<dl>
+
+<dt><i>txt</i> (str)</dt>
+<dd>
+target directory
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
--- a/ProjectFlask/Documentation/source/Plugin_Project_Flask.ProjectFlask.Project.html	Wed Dec 02 20:04:05 2020 +0100
+++ b/ProjectFlask/Documentation/source/Plugin_Project_Flask.ProjectFlask.Project.html	Sat Dec 05 17:18:17 2020 +0100
@@ -101,6 +101,14 @@
 <td>Private slot to start the Flask Web server.</td>
 </tr>
 <tr>
+<td><a href="#Project.__setDebugEnvironment">__setDebugEnvironment</a></td>
+<td>Private method to set the virtual environment as the selected debug environment.</td>
+</tr>
+<tr>
+<td><a href="#Project.__setIgnoreVirtualEnvironment">__setIgnoreVirtualEnvironment</a></td>
+<td>Private method to add an embedded project specific virtual environment to the list of ignore files/directories.</td>
+</tr>
+<tr>
 <td><a href="#Project.__shellProcessFinished">__shellProcessFinished</a></td>
 <td>Private slot connected to the finished signal.</td>
 </tr>
@@ -306,6 +314,22 @@
 flag indicating development mode
 </dd>
 </dl>
+<a NAME="Project.__setDebugEnvironment" ID="Project.__setDebugEnvironment"></a>
+<h4>Project.__setDebugEnvironment</h4>
+<b>__setDebugEnvironment</b>(<i></i>)
+
+<p>
+        Private method to set the virtual environment as the selected debug
+        environment.
+</p>
+<a NAME="Project.__setIgnoreVirtualEnvironment" ID="Project.__setIgnoreVirtualEnvironment"></a>
+<h4>Project.__setIgnoreVirtualEnvironment</h4>
+<b>__setIgnoreVirtualEnvironment</b>(<i></i>)
+
+<p>
+        Private method to add an embedded project specific virtual environment
+        to the list of ignore files/directories.
+</p>
 <a NAME="Project.__shellProcessFinished" ID="Project.__shellProcessFinished"></a>
 <h4>Project.__shellProcessFinished</h4>
 <b>__shellProcessFinished</b>(<i></i>)
@@ -425,7 +449,7 @@
 </dl>
 <a NAME="Project.getFullCommand" ID="Project.getFullCommand"></a>
 <h4>Project.getFullCommand</h4>
-<b>getFullCommand</b>(<i>command</i>)
+<b>getFullCommand</b>(<i>command, virtualEnvPath=None</i>)
 
 <p>
         Public method to get the full command for a given command name.
@@ -436,6 +460,10 @@
 <dd>
 command name
 </dd>
+<dt><i>virtualEnvPath</i> (str)</dt>
+<dd>
+path of the virtual environment
+</dd>
 </dl>
 <dl>
 <dt>Returns:</dt>
--- a/ProjectFlask/Documentation/source/index-Plugin_Project_Flask.ProjectFlask.html	Wed Dec 02 20:04:05 2020 +0100
+++ b/ProjectFlask/Documentation/source/index-Plugin_Project_Flask.ProjectFlask.html	Sat Dec 05 17:18:17 2020 +0100
@@ -58,6 +58,10 @@
 <td>Module implementing a dialog to configure project specific flask settings.</td>
 </tr>
 <tr>
+<td><a href="Plugin_Project_Flask.ProjectFlask.FlaskVirtualenvConfigurationDialog.html">FlaskVirtualenvConfigurationDialog</a></td>
+<td>Module implementing a dialog to configure a project specific virtual environment.</td>
+</tr>
+<tr>
 <td><a href="Plugin_Project_Flask.ProjectFlask.FormSelectionDialog.html">FormSelectionDialog</a></td>
 <td>Module implementing a dialog to select the template type.</td>
 </tr>
--- a/ProjectFlask/FlaskConfigDialog.py	Wed Dec 02 20:04:05 2020 +0100
+++ b/ProjectFlask/FlaskConfigDialog.py	Sat Dec 05 17:18:17 2020 +0100
@@ -15,18 +15,21 @@
 from .Ui_FlaskConfigDialog import Ui_FlaskConfigDialog
 
 import UI.PixmapCache
+import Preferences
 
 
 class FlaskConfigDialog(QDialog, Ui_FlaskConfigDialog):
     """
     Class implementing a dialog to configure project specific flask settings.
     """
-    def __init__(self, configuration, parent=None):
+    def __init__(self, configuration, project, parent=None):
         """
         Constructor
         
         @param configuration current project specific configuration
         @type dict
+        @param project reference to the flask project object
+        @type Project
         @param parent reference to the parent widget
         @type QWidget
         """
@@ -36,6 +39,8 @@
         self.newEnvironmentButton.setIcon(
             UI.PixmapCache.getIcon("virtualenvConfig"))
         
+        self.__project = project
+        
         self.__virtualEnvManager = e5App().getObject("VirtualEnvManager")
         
         self.virtualEnvironmentComboBox.addItem("")
@@ -87,31 +92,25 @@
         """
         Private slot to open a dialog for adding a new virtual environment.
         """
-##        self.__virtualEnvManager.createVirtualEnv()
-        from VirtualEnv.VirtualenvConfigurationDialog import (
-            VirtualenvConfigurationDialog
+        from .FlaskVirtualenvConfigurationDialog import (
+            FlaskVirtualenvConfigurationDialog
         )
         
-        dlg = VirtualenvConfigurationDialog(self)
+        e5Project = e5App().getObject("Project")
+        dlg = FlaskVirtualenvConfigurationDialog(
+            e5Project.getProjectPath(),
+            e5Project.getProjectName(),
+            self)
         if dlg.exec() == QDialog.Accepted:
             resultDict = dlg.getData()
             
-            if resultDict["envType"] == "conda":
-                # conda environments are not suitable
-                return
-            else:
-                # now do the call
-                from VirtualEnv.VirtualenvExecDialog import (
-                    VirtualenvExecDialog
-                )
-                dia = VirtualenvExecDialog(
-                    resultDict, self.__virtualEnvManager, self)
-                dia.show()
-                dia.start(resultDict["arguments"])
-                dia.exec()
-            
-            # reload the list of environments
-            currentEnvName = self.virtualEnvironmentComboBox.currentText()
+            # now do the call
+            from VirtualEnv.VirtualenvExecDialog import VirtualenvExecDialog
+            dia = VirtualenvExecDialog(
+                resultDict, self.__virtualEnvManager, self)
+            dia.show()
+            dia.start(resultDict["arguments"])
+            dia.exec()
             
             self.virtualEnvironmentComboBox.clear()
             self.virtualEnvironmentComboBox.addItem("")
@@ -121,4 +120,28 @@
                 ))
             )
             
-            self.virtualEnvironmentComboBox.setCurrentText(currentEnvName)
+            self.virtualEnvironmentComboBox.setCurrentText(
+                resultDict["logicalName"])
+            
+            self.__installFlask(resultDict["targetDirectory"])
+    
+    def __installFlask(self, venvDir):
+        """
+        Private method to install flask into the newly created environment.
+        
+        @param venvtDir  directory containing the virtual environment
+        @type str
+        """
+        from PipInterface.PipDialog import PipDialog
+        
+        interpreter = self.__project.getFullCommand("python", venvDir)
+        if Preferences.getPip("PipSearchIndex"):
+            indexUrl = Preferences.getPip("PipSearchIndex") + "/simple"
+            args = ["-m", "pip", "install", "--index-url", indexUrl]
+        else:
+            args = ["-m", "pip", "install"]
+        args.append("flask")
+        dia = PipDialog(self.tr('Install Flask'), self)
+        res = dia.startProcess(interpreter, args)
+        if res:
+            dia.exec()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ProjectFlask/FlaskVirtualenvConfigurationDialog.py	Sat Dec 05 17:18:17 2020 +0100
@@ -0,0 +1,147 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2020 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog to configure a project specific virtual
+environment.
+"""
+
+import sys
+import os
+
+from PyQt5.QtCore import pyqtSlot
+from PyQt5.QtWidgets import QDialog, QDialogButtonBox
+
+from E5Gui.E5PathPicker import E5PathPickerModes
+
+from .Ui_FlaskVirtualenvConfigurationDialog import (
+    Ui_FlaskVirtualenvConfigurationDialog
+)
+
+import Utilities
+
+
+class FlaskVirtualenvConfigurationDialog(
+    QDialog, Ui_FlaskVirtualenvConfigurationDialog
+):
+    """
+    Class implementing a dialog to configure a project specific virtual
+    environment.
+    
+    Note: This dialog is a simplified variant of the one found in the eric
+    package.
+    """
+    def __init__(self, projectPath, projectName, parent=None):
+        """
+        Constructor
+        
+        @param projectPath directory path of the project
+        @type str
+        @param projectName name of the project
+        @type str
+        @param parent reference to the parent widget
+        @type QWidget
+        """
+        super(FlaskVirtualenvConfigurationDialog, self).__init__(parent)
+        self.setupUi(self)
+        
+        self.targetDirectoryPicker.setMode(E5PathPickerModes.DirectoryMode)
+        self.targetDirectoryPicker.setWindowTitle(
+            self.tr("Virtualenv Target Directory"))
+        self.targetDirectoryPicker.setDefaultDirectory(projectPath)
+        
+        self.pythonExecPicker.setMode(E5PathPickerModes.OpenFileMode)
+        self.pythonExecPicker.setWindowTitle(
+            self.tr("Python Interpreter"))
+        self.pythonExecPicker.setDefaultDirectory(
+            sys.executable.replace("w.exe", ".exe"))
+        
+        mandatoryStyleSheet = "QLineEdit {border: 2px solid;}"
+        self.targetDirectoryPicker.setStyleSheet(mandatoryStyleSheet)
+        self.nameEdit.setStyleSheet(mandatoryStyleSheet)
+        
+        # pre-populate some fields
+        self.nameEdit.setText("Project {0}".format(projectName))
+        self.targetDirectoryPicker.setText(os.path.join(projectPath, "venv"))
+        
+        msh = self.minimumSizeHint()
+        self.resize(max(self.width(), msh.width()), msh.height())
+    
+    def __updateOK(self):
+        """
+        Private method to update the enabled status of the OK button.
+        """
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(
+            bool(self.targetDirectoryPicker.text()) and
+            bool(self.nameEdit.text())
+        )
+    
+    @pyqtSlot(str)
+    def on_nameEdit_textChanged(self, txt):
+        """
+        Private slot handling a change of the virtual environment name.
+        
+        @param txt name of the virtual environment
+        @type str
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_targetDirectoryPicker_textChanged(self, txt):
+        """
+        Private slot handling a change of the target directory.
+        
+        @param txt target directory
+        @type str
+        """
+        self.__updateOK()
+    
+    def __generateTargetDir(self):
+        """
+        Private method to generate a valid target directory path.
+        
+        @return target directory path
+        @rtype str
+        """
+        targetDirectory = Utilities.toNativeSeparators(
+            self.targetDirectoryPicker.text())
+        if not os.path.isabs(targetDirectory):
+            targetDirectory = os.path.join(os.path.expanduser("~"),
+                                           targetDirectory)
+        return targetDirectory
+    
+    def getData(self):
+        """
+        Public method to retrieve the dialog data.
+        
+        Note: This method returns a data structure compatible with the one
+        returned by the eric virtual environment configuration dialog.
+        
+        @return dictionary containing the data for the environment to be
+            created. The keys for both variants are 'arguments' containing the
+            command line arguments, 'logicalName' containing the environment
+            name to be used with the virtual environment manager and 'envType'
+            containing the environment type (always pyvenv). The pyvenv
+            specific keys are 'openTarget' containg a flag to open the target
+            directory after creation (always False), 'createLog' containing a
+            flag to write a log file (always False), 'createScript' containing
+            a flag to write a script (always False), 'targetDirectory'
+            containing the target directory and 'pythonExe' containing the
+            Python interpreter to be used.
+        @rtype dict
+        """
+        resultDict = {
+            "arguments": [self.__generateTargetDir()],
+            "logicalName": self.nameEdit.text(),
+            "envType": "pyvenv",
+            "openTarget": False,
+            "createLog": False,
+            "createScript": False,
+            "targetDirectory": self.__generateTargetDir(),
+            "pythonExe": Utilities.toNativeSeparators(
+                self.pythonExecPicker.text()),
+        }
+        
+        return resultDict
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ProjectFlask/FlaskVirtualenvConfigurationDialog.ui	Sat Dec 05 17:18:17 2020 +0100
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FlaskVirtualenvConfigurationDialog</class>
+ <widget class="QDialog" name="FlaskVirtualenvConfigurationDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>700</width>
+    <height>126</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Virtual Environment Configuration</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QFormLayout" name="formLayout">
+     <item row="0" column="0">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Logical Name:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="E5ClearableLineEdit" name="nameEdit">
+       <property name="toolTip">
+        <string>Enter a unique name for the virtual environment</string>
+       </property>
+       <property name="placeholderText">
+        <string>Name for the virtual environment</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Target Directory:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="E5PathPicker" name="targetDirectoryPicker" native="true">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="focusPolicy">
+        <enum>Qt::WheelFocus</enum>
+       </property>
+       <property name="toolTip">
+        <string>Enter the target directory for the virtual environment</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="0">
+      <widget class="QLabel" name="label_5">
+       <property name="text">
+        <string>Python Executable:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1">
+      <widget class="E5PathPicker" name="pythonExecPicker" native="true">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="focusPolicy">
+        <enum>Qt::WheelFocus</enum>
+       </property>
+       <property name="toolTip">
+        <string>Enter the Python interpreter for the virtual environment</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>E5ClearableLineEdit</class>
+   <extends>QLineEdit</extends>
+   <header>E5Gui/E5LineEdit.h</header>
+  </customwidget>
+  <customwidget>
+   <class>E5PathPicker</class>
+   <extends>QWidget</extends>
+   <header>E5Gui/E5PathPicker.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>FlaskVirtualenvConfigurationDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>FlaskVirtualenvConfigurationDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- a/ProjectFlask/Project.py	Wed Dec 02 20:04:05 2020 +0100
+++ b/ProjectFlask/Project.py	Sat Dec 05 17:18:17 2020 +0100
@@ -298,6 +298,7 @@
                 "newForm", self.newForm, self.tr("New template..."))
             
             self.__determineCapabilities()
+            self.__setDebugEnvironment()
             
             self.__pybabelProject.projectOpenedHooks()
             
@@ -413,16 +414,18 @@
         """
         return self.getFullCommand("python")
     
-    def getFullCommand(self, command):
+    def getFullCommand(self, command, virtualEnvPath=None):
         """
         Public method to get the full command for a given command name.
         
         @param command command name
         @type str
+        @param virtualEnvPath path of the virtual environment
+        @type str
         @return full command
         @rtype str
         """
-        virtualEnv = self.getVirtualEnvironment()
+        virtualEnv = virtualEnvPath or self.getVirtualEnvironment()
         if isWindowsPlatform():
             fullCmds = [
                 os.path.join(virtualEnv, "Scripts", command + '.exe'),
@@ -720,10 +723,12 @@
         from .FlaskConfigDialog import FlaskConfigDialog
         
         config = self.getData("flask", "")
-        dlg = FlaskConfigDialog(config)
+        dlg = FlaskConfigDialog(config, self)
         if dlg.exec() == QDialog.Accepted:
             config = dlg.getConfiguration()
             self.setData("flask", "", config)
+            self.__setIgnoreVirtualEnvironment()
+            self.__setDebugEnvironment()
             
             self.__migrateProject.determineCapability()
             
@@ -731,6 +736,38 @@
             self.projectClosedHooks()
             self.projectOpenedHooks()
     
+    def __setIgnoreVirtualEnvironment(self):
+        """
+        Private method to add an embedded project specific virtual environment
+        to the list of ignore files/directories.
+        """
+        virtenvName = self.getData("flask", "virtual_environment_name")
+        if virtenvName:
+            virtenvPath = self.getVirtualEnvironment()
+            if self.__e5project.startswithProjectPath(virtenvPath):
+                relVirtenvPath = self.__e5project.getRelativeUniversalPath(
+                    virtenvPath)
+                if relVirtenvPath not in self.__e5project.pdata["FILETYPES"]:
+                    self.__e5project.pdata["FILETYPES"][relVirtenvPath] = (
+                        "__IGNORE__"
+                    )
+                    self.__e5project.setDirty(True)
+    
+    def __setDebugEnvironment(self):
+        """
+        Private method to set the virtual environment as the selected debug
+        environment.
+        """
+        language = self.__e5project.getProjectLanguage()
+        if language == "Python3":
+            # get project specific virtual environment name
+            venvName = self.getData("flask", "virtual_environment_name")
+            if not venvName:
+                venvName = self.__plugin.getPreferences(
+                    "VirtualEnvironmentNamePy3")
+            if venvName:
+                self.__e5project.debugProperties["VIRTUALENV"] = venvName
+    
     ##################################################################
     ## slot below implements documentation function
     ##################################################################
Binary file ProjectFlask/i18n/flask_de.qm has changed
--- a/ProjectFlask/i18n/flask_de.ts	Wed Dec 02 20:04:05 2020 +0100
+++ b/ProjectFlask/i18n/flask_de.ts	Sat Dec 05 17:18:17 2020 +0100
@@ -85,6 +85,11 @@
         <source>&apos;flask-migrate&apos; available</source>
         <translation>&apos;flask-migrate&apos; verfügbar</translation>
     </message>
+    <message>
+        <location filename="../FlaskConfigDialog.py" line="144"/>
+        <source>Install Flask</source>
+        <translation>Flask installieren</translation>
+    </message>
 </context>
 <context>
     <name>FlaskPage</name>
@@ -195,6 +200,59 @@
     </message>
 </context>
 <context>
+    <name>FlaskVirtualenvConfigurationDialog</name>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="14"/>
+        <source>Virtual Environment Configuration</source>
+        <translation>Konfiguration für Virtuelle Umgebung</translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="25"/>
+        <source>Logical Name:</source>
+        <translation>Logischer Name:</translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="32"/>
+        <source>Enter a unique name for the virtual environment</source>
+        <translation>Gib einen eindeutigen Namen für die virtuelle Umgebung ein</translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="35"/>
+        <source>Name for the virtual environment</source>
+        <translation>Name für die virtuelle Umgebung</translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="42"/>
+        <source>Target Directory:</source>
+        <translation>Zielverzeichnis:</translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="58"/>
+        <source>Enter the target directory for the virtual environment</source>
+        <translation>Gib das Zielverzeichnis für die virtuelle Umgebung ein</translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="65"/>
+        <source>Python Executable:</source>
+        <translation>Python Programm:</translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="81"/>
+        <source>Enter the Python interpreter for the virtual environment</source>
+        <translation>Gib den für die virtuelle Umgebung zu verwendenden Python Interpreter ein</translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.py" line="51"/>
+        <source>Virtualenv Target Directory</source>
+        <translation>Zielverzeichnis der virtullen Umgebung</translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.py" line="56"/>
+        <source>Python Interpreter</source>
+        <translation>Python Interpreter</translation>
+    </message>
+</context>
+<context>
     <name>FormSelectionDialog</name>
     <message>
         <location filename="../FormSelectionDialog.ui" line="14"/>
@@ -622,12 +680,12 @@
         <translation>Neues Template...</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="364"/>
+        <location filename="../Project.py" line="365"/>
         <source>New Form</source>
         <translation>Neues Formular</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="350"/>
+        <location filename="../Project.py" line="351"/>
         <source>The file already exists! Overwrite it?</source>
         <translation>Die Datei existiert bereits. Überschreiben?</translation>
     </message>
@@ -712,7 +770,7 @@
         <translation>&lt;b&gt;Dokumentation&lt;/b&gt;&lt;p&gt;Zeigt die Hilfeanzeige mit der Flask Dokumentation an.&lt;/p&gt;</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="527"/>
+        <location filename="../Project.py" line="530"/>
         <source>About Flask</source>
         <translation>Über Flask</translation>
     </message>
@@ -737,27 +795,27 @@
         <translation>&amp;Flask</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="331"/>
+        <location filename="../Project.py" line="332"/>
         <source>HTML Files (*.html);;HTML Files (*.htm);;All Files (*)</source>
         <translation>HTML Dateien (*.html);;HTML Dateien (*.htm);;Alle Dateien (*)</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="364"/>
+        <location filename="../Project.py" line="365"/>
         <source>&lt;p&gt;The new form file &lt;b&gt;{0}&lt;/b&gt; could not be created.&lt;/p&gt;&lt;p&gt;Problem: {1}&lt;/p&gt;</source>
         <translation>&lt;p&gt;Die neue Formulardatei &lt;b&gt;{0}&lt;/b&gt; konnte nicht erstellt werden.&lt;/p&gt;&lt;p&gt;Problem: {1}&lt;/p&gt;</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="600"/>
+        <location filename="../Project.py" line="603"/>
         <source>Prepare Environment</source>
         <translation>Umgebung vorbereiten</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="600"/>
+        <location filename="../Project.py" line="603"/>
         <source>The project has no configured main script (= Flask application). Aborting...</source>
         <translation>Das Projekt hat keine konfigurierte Hauptdatei (= Flask Anwendung). Abbruch...</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="527"/>
+        <location filename="../Project.py" line="530"/>
         <source>&lt;p&gt;Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications.&lt;/p&gt;&lt;p&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;Flask Version:&lt;/td&gt;&lt;td&gt;{0}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Werkzeug Version:&lt;/td&gt;&lt;td&gt;{1}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Python Version:&lt;/td&gt;&lt;td&gt;{2}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Flask URL:&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;{3}&quot;&gt;The Pallets Projects - Flask&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</source>
         <comment>Do not translate the program names.</comment>
         <translation>&lt;p&gt;Flask ist ein leichtgewichtiger WSGI Webapplikationsrahmen. Es wurde entwickelt, um den Start schnell und einfach zu machen und die Möglichkeit für komplexe Applikationen zu erlauben.&lt;/p&gt;&lt;p&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;Flask Version:&lt;/td&gt;&lt;td&gt;{0}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Werkzeug Version:&lt;/td&gt;&lt;td&gt;{1}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Python Version:&lt;/td&gt;&lt;td&gt;{2}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Flask URL:&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;{3}&quot;&gt;The Pallets Projects - Flask&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</translation>
--- a/ProjectFlask/i18n/flask_empty.ts	Wed Dec 02 20:04:05 2020 +0100
+++ b/ProjectFlask/i18n/flask_empty.ts	Sat Dec 05 17:18:17 2020 +0100
@@ -85,6 +85,11 @@
         <source>&apos;flask-migrate&apos; available</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <location filename="../FlaskConfigDialog.py" line="144"/>
+        <source>Install Flask</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>FlaskPage</name>
@@ -195,6 +200,59 @@
     </message>
 </context>
 <context>
+    <name>FlaskVirtualenvConfigurationDialog</name>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="14"/>
+        <source>Virtual Environment Configuration</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="25"/>
+        <source>Logical Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="32"/>
+        <source>Enter a unique name for the virtual environment</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="35"/>
+        <source>Name for the virtual environment</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="42"/>
+        <source>Target Directory:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="58"/>
+        <source>Enter the target directory for the virtual environment</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="65"/>
+        <source>Python Executable:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="81"/>
+        <source>Enter the Python interpreter for the virtual environment</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.py" line="51"/>
+        <source>Virtualenv Target Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.py" line="56"/>
+        <source>Python Interpreter</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
     <name>FormSelectionDialog</name>
     <message>
         <location filename="../FormSelectionDialog.ui" line="14"/>
@@ -693,7 +751,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../Project.py" line="527"/>
+        <location filename="../Project.py" line="530"/>
         <source>About Flask</source>
         <translation type="unfinished"></translation>
     </message>
@@ -723,37 +781,37 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../Project.py" line="331"/>
+        <location filename="../Project.py" line="332"/>
         <source>HTML Files (*.html);;HTML Files (*.htm);;All Files (*)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../Project.py" line="364"/>
+        <location filename="../Project.py" line="365"/>
         <source>New Form</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../Project.py" line="350"/>
+        <location filename="../Project.py" line="351"/>
         <source>The file already exists! Overwrite it?</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../Project.py" line="364"/>
+        <location filename="../Project.py" line="365"/>
         <source>&lt;p&gt;The new form file &lt;b&gt;{0}&lt;/b&gt; could not be created.&lt;/p&gt;&lt;p&gt;Problem: {1}&lt;/p&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../Project.py" line="600"/>
+        <location filename="../Project.py" line="603"/>
         <source>Prepare Environment</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../Project.py" line="600"/>
+        <location filename="../Project.py" line="603"/>
         <source>The project has no configured main script (= Flask application). Aborting...</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../Project.py" line="527"/>
+        <location filename="../Project.py" line="530"/>
         <source>&lt;p&gt;Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications.&lt;/p&gt;&lt;p&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;Flask Version:&lt;/td&gt;&lt;td&gt;{0}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Werkzeug Version:&lt;/td&gt;&lt;td&gt;{1}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Python Version:&lt;/td&gt;&lt;td&gt;{2}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Flask URL:&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;{3}&quot;&gt;The Pallets Projects - Flask&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</source>
         <comment>Do not translate the program names.</comment>
         <translation type="unfinished"></translation>
--- a/ProjectFlask/i18n/flask_en.ts	Wed Dec 02 20:04:05 2020 +0100
+++ b/ProjectFlask/i18n/flask_en.ts	Sat Dec 05 17:18:17 2020 +0100
@@ -85,6 +85,11 @@
         <source>&apos;flask-migrate&apos; available</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <location filename="../FlaskConfigDialog.py" line="144"/>
+        <source>Install Flask</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>FlaskPage</name>
@@ -195,6 +200,59 @@
     </message>
 </context>
 <context>
+    <name>FlaskVirtualenvConfigurationDialog</name>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="14"/>
+        <source>Virtual Environment Configuration</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="25"/>
+        <source>Logical Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="32"/>
+        <source>Enter a unique name for the virtual environment</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="35"/>
+        <source>Name for the virtual environment</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="42"/>
+        <source>Target Directory:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="58"/>
+        <source>Enter the target directory for the virtual environment</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="65"/>
+        <source>Python Executable:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="81"/>
+        <source>Enter the Python interpreter for the virtual environment</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.py" line="51"/>
+        <source>Virtualenv Target Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.py" line="56"/>
+        <source>Python Interpreter</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
     <name>FormSelectionDialog</name>
     <message>
         <location filename="../FormSelectionDialog.ui" line="14"/>
@@ -693,7 +751,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../Project.py" line="527"/>
+        <location filename="../Project.py" line="530"/>
         <source>About Flask</source>
         <translation type="unfinished"></translation>
     </message>
@@ -723,37 +781,37 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../Project.py" line="331"/>
+        <location filename="../Project.py" line="332"/>
         <source>HTML Files (*.html);;HTML Files (*.htm);;All Files (*)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../Project.py" line="364"/>
+        <location filename="../Project.py" line="365"/>
         <source>New Form</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../Project.py" line="350"/>
+        <location filename="../Project.py" line="351"/>
         <source>The file already exists! Overwrite it?</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../Project.py" line="364"/>
+        <location filename="../Project.py" line="365"/>
         <source>&lt;p&gt;The new form file &lt;b&gt;{0}&lt;/b&gt; could not be created.&lt;/p&gt;&lt;p&gt;Problem: {1}&lt;/p&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../Project.py" line="600"/>
+        <location filename="../Project.py" line="603"/>
         <source>Prepare Environment</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../Project.py" line="600"/>
+        <location filename="../Project.py" line="603"/>
         <source>The project has no configured main script (= Flask application). Aborting...</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../Project.py" line="527"/>
+        <location filename="../Project.py" line="530"/>
         <source>&lt;p&gt;Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications.&lt;/p&gt;&lt;p&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;Flask Version:&lt;/td&gt;&lt;td&gt;{0}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Werkzeug Version:&lt;/td&gt;&lt;td&gt;{1}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Python Version:&lt;/td&gt;&lt;td&gt;{2}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Flask URL:&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;{3}&quot;&gt;The Pallets Projects - Flask&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</source>
         <comment>Do not translate the program names.</comment>
         <translation type="unfinished"></translation>
--- a/ProjectFlask/i18n/flask_es.ts	Wed Dec 02 20:04:05 2020 +0100
+++ b/ProjectFlask/i18n/flask_es.ts	Sat Dec 05 17:18:17 2020 +0100
@@ -85,6 +85,11 @@
         <source>&apos;flask-migrate&apos; available</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <location filename="../FlaskConfigDialog.py" line="144"/>
+        <source>Install Flask</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>FlaskPage</name>
@@ -195,6 +200,59 @@
     </message>
 </context>
 <context>
+    <name>FlaskVirtualenvConfigurationDialog</name>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="14"/>
+        <source>Virtual Environment Configuration</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="25"/>
+        <source>Logical Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="32"/>
+        <source>Enter a unique name for the virtual environment</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="35"/>
+        <source>Name for the virtual environment</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="42"/>
+        <source>Target Directory:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="58"/>
+        <source>Enter the target directory for the virtual environment</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="65"/>
+        <source>Python Executable:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="81"/>
+        <source>Enter the Python interpreter for the virtual environment</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.py" line="51"/>
+        <source>Virtualenv Target Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.py" line="56"/>
+        <source>Python Interpreter</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
     <name>FormSelectionDialog</name>
     <message>
         <location filename="../FormSelectionDialog.ui" line="14"/>
@@ -697,7 +755,7 @@
         <translation>&lt;b&gt;Documentación&lt;/b&gt;&lt;p&gt;Muestra el visor de ayuda con la documentación de Flask.&lt;/p&gt;</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="527"/>
+        <location filename="../Project.py" line="530"/>
         <source>About Flask</source>
         <translation>Acerca de Flask</translation>
     </message>
@@ -727,37 +785,37 @@
         <translation>Nueva plantilla...</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="331"/>
+        <location filename="../Project.py" line="332"/>
         <source>HTML Files (*.html);;HTML Files (*.htm);;All Files (*)</source>
         <translation>Archivos HTML (*.html);;Archivos HTML (*.htm);;Todos los Archivos (*)</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="364"/>
+        <location filename="../Project.py" line="365"/>
         <source>New Form</source>
         <translation>Nuevo Formulario</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="350"/>
+        <location filename="../Project.py" line="351"/>
         <source>The file already exists! Overwrite it?</source>
         <translation>El archivo ya existe. ¿Sobreescribir?</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="364"/>
+        <location filename="../Project.py" line="365"/>
         <source>&lt;p&gt;The new form file &lt;b&gt;{0}&lt;/b&gt; could not be created.&lt;/p&gt;&lt;p&gt;Problem: {1}&lt;/p&gt;</source>
         <translation>&lt;p&gt;No se ha podido crear el nuevo archivo de formulario &lt;b&gt;{0}&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Problema: {1}&lt;/p&gt;</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="600"/>
+        <location filename="../Project.py" line="603"/>
         <source>Prepare Environment</source>
         <translation>Preparar Entorno</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="600"/>
+        <location filename="../Project.py" line="603"/>
         <source>The project has no configured main script (= Flask application). Aborting...</source>
         <translation>El proyecto no tiene configurado un script principal (= aplicación Flask). Abortando...</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="527"/>
+        <location filename="../Project.py" line="530"/>
         <source>&lt;p&gt;Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications.&lt;/p&gt;&lt;p&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;Flask Version:&lt;/td&gt;&lt;td&gt;{0}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Werkzeug Version:&lt;/td&gt;&lt;td&gt;{1}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Python Version:&lt;/td&gt;&lt;td&gt;{2}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Flask URL:&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;{3}&quot;&gt;The Pallets Projects - Flask&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</source>
         <comment>Do not translate the program names.</comment>
         <translation>&lt;p&gt;Flask es un framework ligero para aplicaciones web WSGI. Está diseñado para hacer fácil y rápida la puesta en marcha, con capacidad de escalado a aplicaciones más complejas.&lt;/p&gt;&lt;p&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;Versión de Flask:&lt;/td&gt;&lt;td&gt;{0}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Versión de Werkzeug:&lt;/td&gt;&lt;td&gt;{1}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Versión de Python:&lt;/td&gt;&lt;td&gt;{2}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;URL de Flask:&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;{3}&quot;&gt;The Pallets Projects - Flask&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</translation>
--- a/ProjectFlask/i18n/flask_ru.ts	Wed Dec 02 20:04:05 2020 +0100
+++ b/ProjectFlask/i18n/flask_ru.ts	Sat Dec 05 17:18:17 2020 +0100
@@ -85,6 +85,11 @@
         <source>&apos;flask-migrate&apos; available</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <location filename="../FlaskConfigDialog.py" line="144"/>
+        <source>Install Flask</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>FlaskPage</name>
@@ -195,6 +200,59 @@
     </message>
 </context>
 <context>
+    <name>FlaskVirtualenvConfigurationDialog</name>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="14"/>
+        <source>Virtual Environment Configuration</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="25"/>
+        <source>Logical Name:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="32"/>
+        <source>Enter a unique name for the virtual environment</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="35"/>
+        <source>Name for the virtual environment</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="42"/>
+        <source>Target Directory:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="58"/>
+        <source>Enter the target directory for the virtual environment</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="65"/>
+        <source>Python Executable:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.ui" line="81"/>
+        <source>Enter the Python interpreter for the virtual environment</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.py" line="51"/>
+        <source>Virtualenv Target Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../FlaskVirtualenvConfigurationDialog.py" line="56"/>
+        <source>Python Interpreter</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
     <name>FormSelectionDialog</name>
     <message>
         <location filename="../FormSelectionDialog.ui" line="14"/>
@@ -697,7 +755,7 @@
         <translation>&lt;b&gt;Документация&lt;/b&gt;&lt;p&gt;Отображает средство просмотра документации Flask.&lt;/p&gt;</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="527"/>
+        <location filename="../Project.py" line="530"/>
         <source>About Flask</source>
         <translation>О Flask</translation>
     </message>
@@ -727,37 +785,37 @@
         <translation>Новый шаблон...</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="331"/>
+        <location filename="../Project.py" line="332"/>
         <source>HTML Files (*.html);;HTML Files (*.htm);;All Files (*)</source>
         <translation>Файлы HTML (*.html);;Файлы HTML (*.htm);;Все файлы (*)</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="364"/>
+        <location filename="../Project.py" line="365"/>
         <source>New Form</source>
         <translation>Новая форма</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="350"/>
+        <location filename="../Project.py" line="351"/>
         <source>The file already exists! Overwrite it?</source>
         <translation>Файл уже существует! Переписать его?</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="364"/>
+        <location filename="../Project.py" line="365"/>
         <source>&lt;p&gt;The new form file &lt;b&gt;{0}&lt;/b&gt; could not be created.&lt;/p&gt;&lt;p&gt;Problem: {1}&lt;/p&gt;</source>
         <translation>&lt;p&gt;Не удалось создать файл новой формы &lt;b&gt;{0}&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Проблема: {1}&lt;/p&gt;</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="600"/>
+        <location filename="../Project.py" line="603"/>
         <source>Prepare Environment</source>
         <translation>Подготовить виртуальноео окружение</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="600"/>
+        <location filename="../Project.py" line="603"/>
         <source>The project has no configured main script (= Flask application). Aborting...</source>
         <translation>В проекте нет настроенного основного скрипта (= приложению Flask). Отмена...</translation>
     </message>
     <message>
-        <location filename="../Project.py" line="527"/>
+        <location filename="../Project.py" line="530"/>
         <source>&lt;p&gt;Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications.&lt;/p&gt;&lt;p&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;Flask Version:&lt;/td&gt;&lt;td&gt;{0}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Werkzeug Version:&lt;/td&gt;&lt;td&gt;{1}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Python Version:&lt;/td&gt;&lt;td&gt;{2}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Flask URL:&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;{3}&quot;&gt;The Pallets Projects - Flask&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</source>
         <comment>Do not translate the program names.</comment>
         <translation>&lt;p&gt;Flask - это легкий WSGI-фреймворк веб-приложений. Он разработан чтобы сделать начало работы быстрым и простым, с возможностью масштабирования до сложных приложений.&lt;/p&gt;&lt;p&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;Версия Flask:&lt;/td&gt;&lt;td&gt;{0}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Версия Werkzeug:&lt;/td&gt;&lt;td&gt;{1}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Версия Python:&lt;/td&gt;&lt;td&gt;{2}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;URL Flask:&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;{3}&quot;&gt;Проекты Pallets - Flask&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</translation>

eric ide

mercurial