VirtualEnv: started implementing a virtualenv manager.

Sat, 09 Jun 2018 17:19:37 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 09 Jun 2018 17:19:37 +0200
changeset 6337
c6af560e0039
parent 6336
a04ac8bd014b
child 6338
104ee21d765d

VirtualEnv: started implementing a virtualenv manager.

Documentation/Source/eric6.Plugins.UiExtensionPlugins.VirtualenvInterface.VirtualenvConfigurationDialog.html file | annotate | diff | comparison | revisions
Documentation/Source/eric6.Plugins.UiExtensionPlugins.VirtualenvInterface.VirtualenvExecDialog.html file | annotate | diff | comparison | revisions
Documentation/Source/index-eric6.Plugins.UiExtensionPlugins.VirtualenvInterface.html file | annotate | diff | comparison | revisions
Plugins/PluginVirtualenvInterface.py file | annotate | diff | comparison | revisions
Plugins/UiExtensionPlugins/VirtualenvInterface/VirtualenvConfigurationDialog.py file | annotate | diff | comparison | revisions
Plugins/UiExtensionPlugins/VirtualenvInterface/VirtualenvConfigurationDialog.ui file | annotate | diff | comparison | revisions
Plugins/UiExtensionPlugins/VirtualenvInterface/VirtualenvExecDialog.py file | annotate | diff | comparison | revisions
Plugins/UiExtensionPlugins/VirtualenvInterface/VirtualenvExecDialog.ui file | annotate | diff | comparison | revisions
Plugins/UiExtensionPlugins/VirtualenvInterface/__init__.py file | annotate | diff | comparison | revisions
UI/UserInterface.py file | annotate | diff | comparison | revisions
VirtualEnv/VirtualenvConfigurationDialog.py file | annotate | diff | comparison | revisions
VirtualEnv/VirtualenvConfigurationDialog.ui file | annotate | diff | comparison | revisions
VirtualEnv/VirtualenvExecDialog.py file | annotate | diff | comparison | revisions
VirtualEnv/VirtualenvExecDialog.ui file | annotate | diff | comparison | revisions
VirtualEnv/VirtualenvInterpreterSelectionDialog.py file | annotate | diff | comparison | revisions
VirtualEnv/VirtualenvInterpreterSelectionDialog.ui file | annotate | diff | comparison | revisions
VirtualEnv/VirtualenvManager.py file | annotate | diff | comparison | revisions
VirtualEnv/__init__.py file | annotate | diff | comparison | revisions
eric6.e4p file | annotate | diff | comparison | revisions
icons/default/virtualenv.png file | annotate | diff | comparison | revisions
--- a/Documentation/Source/eric6.Plugins.UiExtensionPlugins.VirtualenvInterface.VirtualenvConfigurationDialog.html	Sat Jun 09 12:09:21 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-<!DOCTYPE html>
-<html><head>
-<title>eric6.Plugins.UiExtensionPlugins.VirtualenvInterface.VirtualenvConfigurationDialog</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>eric6.Plugins.UiExtensionPlugins.VirtualenvInterface.VirtualenvConfigurationDialog</h1>
-<p>
-Module implementing a dialog to enter the parameters for the
-virtual environment.
-</p>
-<h3>Global Attributes</h3>
-<table>
-<tr><td>None</td></tr>
-</table>
-<h3>Classes</h3>
-<table>
-<tr>
-<td><a href="#VirtualenvConfigurationDialog">VirtualenvConfigurationDialog</a></td>
-<td>Class implementing a dialog to enter the parameters for the virtual environment.</td>
-</tr>
-</table>
-<h3>Functions</h3>
-<table>
-<tr><td>None</td></tr>
-</table>
-<hr /><hr />
-<a NAME="VirtualenvConfigurationDialog" ID="VirtualenvConfigurationDialog"></a>
-<h2>VirtualenvConfigurationDialog</h2>
-<p>
-    Class implementing a dialog to enter the parameters for the
-    virtual environment.
-</p>
-<h3>Derived from</h3>
-QDialog, Ui_VirtualenvConfigurationDialog
-<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="#VirtualenvConfigurationDialog.__init__">VirtualenvConfigurationDialog</a></td>
-<td>Constructor</td>
-</tr><tr>
-<td><a href="#VirtualenvConfigurationDialog.__generateArguments">__generateArguments</a></td>
-<td>Private method to generate the process arguments.</td>
-</tr><tr>
-<td><a href="#VirtualenvConfigurationDialog.__generateTargetDir">__generateTargetDir</a></td>
-<td>Private method to generate a valid target directory path.</td>
-</tr><tr>
-<td><a href="#VirtualenvConfigurationDialog.__setPyvenvVersion">__setPyvenvVersion</a></td>
-<td>Private method to determine the pyvenv version and set the respective label.</td>
-</tr><tr>
-<td><a href="#VirtualenvConfigurationDialog.__setVirtualenvVersion">__setVirtualenvVersion</a></td>
-<td>Private method to determine the virtualenv version and set the respective label.</td>
-</tr><tr>
-<td><a href="#VirtualenvConfigurationDialog.__updateOK">__updateOK</a></td>
-<td>Private method to update the enabled status of the OK button.</td>
-</tr><tr>
-<td><a href="#VirtualenvConfigurationDialog.__updateUi">__updateUi</a></td>
-<td>Private method to update the UI depending on the selected virtual environment creator (virtualenv or pyvenv).</td>
-</tr><tr>
-<td><a href="#VirtualenvConfigurationDialog.getData">getData</a></td>
-<td>Public method to retrieve the dialog data.</td>
-</tr><tr>
-<td><a href="#VirtualenvConfigurationDialog.on_extraSearchPathButton_clicked">on_extraSearchPathButton_clicked</a></td>
-<td>Private slot to select the extra search path via a directory selection dialog.</td>
-</tr><tr>
-<td><a href="#VirtualenvConfigurationDialog.on_pythonExecButton_clicked">on_pythonExecButton_clicked</a></td>
-<td>Private slot to select a Python interpreter via a file selection dialog.</td>
-</tr><tr>
-<td><a href="#VirtualenvConfigurationDialog.on_pythonExecEdit_textChanged">on_pythonExecEdit_textChanged</a></td>
-<td>Private slot to react to a change of the Python executable.</td>
-</tr><tr>
-<td><a href="#VirtualenvConfigurationDialog.on_pyvenvButton_toggled">on_pyvenvButton_toggled</a></td>
-<td>Private slot to react to the selection of 'pyvenv'.</td>
-</tr><tr>
-<td><a href="#VirtualenvConfigurationDialog.on_targetDirectoryButton_clicked">on_targetDirectoryButton_clicked</a></td>
-<td>Private slot to select the target directory via a directory selection dialog.</td>
-</tr><tr>
-<td><a href="#VirtualenvConfigurationDialog.on_targetDirectoryEdit_textChanged">on_targetDirectoryEdit_textChanged</a></td>
-<td>Private slot handling a change of the target directory.</td>
-</tr><tr>
-<td><a href="#VirtualenvConfigurationDialog.on_virtualenvButton_toggled">on_virtualenvButton_toggled</a></td>
-<td>Private slot to react to the selection of 'virtualenv'.</td>
-</tr>
-</table>
-<h3>Static Methods</h3>
-<table>
-<tr><td>None</td></tr>
-</table>
-<a NAME="VirtualenvConfigurationDialog.__init__" ID="VirtualenvConfigurationDialog.__init__"></a>
-<h4>VirtualenvConfigurationDialog (Constructor)</h4>
-<b>VirtualenvConfigurationDialog</b>(<i>parent=None</i>)
-<p>
-        Constructor
-</p><dl>
-<dt><i>parent</i></dt>
-<dd>
-reference to the parent widget (QWidget)
-</dd>
-</dl><a NAME="VirtualenvConfigurationDialog.__generateArguments" ID="VirtualenvConfigurationDialog.__generateArguments"></a>
-<h4>VirtualenvConfigurationDialog.__generateArguments</h4>
-<b>__generateArguments</b>(<i></i>)
-<p>
-        Private method to generate the process arguments.
-</p><dl>
-<dt>Returns:</dt>
-<dd>
-process arguments (list of string)
-</dd>
-</dl><a NAME="VirtualenvConfigurationDialog.__generateTargetDir" ID="VirtualenvConfigurationDialog.__generateTargetDir"></a>
-<h4>VirtualenvConfigurationDialog.__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 (string)
-</dd>
-</dl><a NAME="VirtualenvConfigurationDialog.__setPyvenvVersion" ID="VirtualenvConfigurationDialog.__setPyvenvVersion"></a>
-<h4>VirtualenvConfigurationDialog.__setPyvenvVersion</h4>
-<b>__setPyvenvVersion</b>(<i></i>)
-<p>
-        Private method to determine the pyvenv version and set the respective
-        label.
-</p><a NAME="VirtualenvConfigurationDialog.__setVirtualenvVersion" ID="VirtualenvConfigurationDialog.__setVirtualenvVersion"></a>
-<h4>VirtualenvConfigurationDialog.__setVirtualenvVersion</h4>
-<b>__setVirtualenvVersion</b>(<i></i>)
-<p>
-        Private method to determine the virtualenv version and set the
-        respective label.
-</p><a NAME="VirtualenvConfigurationDialog.__updateOK" ID="VirtualenvConfigurationDialog.__updateOK"></a>
-<h4>VirtualenvConfigurationDialog.__updateOK</h4>
-<b>__updateOK</b>(<i></i>)
-<p>
-        Private method to update the enabled status of the OK button.
-</p><a NAME="VirtualenvConfigurationDialog.__updateUi" ID="VirtualenvConfigurationDialog.__updateUi"></a>
-<h4>VirtualenvConfigurationDialog.__updateUi</h4>
-<b>__updateUi</b>(<i></i>)
-<p>
-        Private method to update the UI depending on the selected
-        virtual environment creator (virtualenv or pyvenv).
-</p><a NAME="VirtualenvConfigurationDialog.getData" ID="VirtualenvConfigurationDialog.getData"></a>
-<h4>VirtualenvConfigurationDialog.getData</h4>
-<b>getData</b>(<i></i>)
-<p>
-        Public method to retrieve the dialog data.
-</p><dl>
-<dt>Returns:</dt>
-<dd>
-tuple containing a flag indicating the pyvenv selection
-            (boolean), the process arguments (list of string), a flag
-            indicating to open the target directory after creation (boolean),
-            a flag indicating to write a log file (boolean), a flag indicating
-            to write a script (boolean), the name of the target directory
-            (string) and the name of the python interpreter to use (string)
-</dd>
-</dl><a NAME="VirtualenvConfigurationDialog.on_extraSearchPathButton_clicked" ID="VirtualenvConfigurationDialog.on_extraSearchPathButton_clicked"></a>
-<h4>VirtualenvConfigurationDialog.on_extraSearchPathButton_clicked</h4>
-<b>on_extraSearchPathButton_clicked</b>(<i></i>)
-<p>
-        Private slot to select the extra search path via a directory
-        selection dialog.
-</p><a NAME="VirtualenvConfigurationDialog.on_pythonExecButton_clicked" ID="VirtualenvConfigurationDialog.on_pythonExecButton_clicked"></a>
-<h4>VirtualenvConfigurationDialog.on_pythonExecButton_clicked</h4>
-<b>on_pythonExecButton_clicked</b>(<i></i>)
-<p>
-        Private slot to select a Python interpreter via a file selection
-        dialog.
-</p><a NAME="VirtualenvConfigurationDialog.on_pythonExecEdit_textChanged" ID="VirtualenvConfigurationDialog.on_pythonExecEdit_textChanged"></a>
-<h4>VirtualenvConfigurationDialog.on_pythonExecEdit_textChanged</h4>
-<b>on_pythonExecEdit_textChanged</b>(<i>txt</i>)
-<p>
-        Private slot to react to a change of the Python executable.
-</p><dl>
-<dt><i>txt</i></dt>
-<dd>
-contents of the line edit (string)
-</dd>
-</dl><a NAME="VirtualenvConfigurationDialog.on_pyvenvButton_toggled" ID="VirtualenvConfigurationDialog.on_pyvenvButton_toggled"></a>
-<h4>VirtualenvConfigurationDialog.on_pyvenvButton_toggled</h4>
-<b>on_pyvenvButton_toggled</b>(<i>checked</i>)
-<p>
-        Private slot to react to the selection of 'pyvenv'.
-</p><dl>
-<dt><i>checked</i></dt>
-<dd>
-state of the checkbox (boolean)
-</dd>
-</dl><a NAME="VirtualenvConfigurationDialog.on_targetDirectoryButton_clicked" ID="VirtualenvConfigurationDialog.on_targetDirectoryButton_clicked"></a>
-<h4>VirtualenvConfigurationDialog.on_targetDirectoryButton_clicked</h4>
-<b>on_targetDirectoryButton_clicked</b>(<i></i>)
-<p>
-        Private slot to select the target directory via a directory
-        selection dialog.
-</p><a NAME="VirtualenvConfigurationDialog.on_targetDirectoryEdit_textChanged" ID="VirtualenvConfigurationDialog.on_targetDirectoryEdit_textChanged"></a>
-<h4>VirtualenvConfigurationDialog.on_targetDirectoryEdit_textChanged</h4>
-<b>on_targetDirectoryEdit_textChanged</b>(<i>txt</i>)
-<p>
-        Private slot handling a change of the target directory.
-</p><dl>
-<dt><i>txt</i></dt>
-<dd>
-target directory (string)
-</dd>
-</dl><a NAME="VirtualenvConfigurationDialog.on_virtualenvButton_toggled" ID="VirtualenvConfigurationDialog.on_virtualenvButton_toggled"></a>
-<h4>VirtualenvConfigurationDialog.on_virtualenvButton_toggled</h4>
-<b>on_virtualenvButton_toggled</b>(<i>checked</i>)
-<p>
-        Private slot to react to the selection of 'virtualenv'.
-</p><dl>
-<dt><i>checked</i></dt>
-<dd>
-state of the checkbox (boolean)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-</body></html>
\ No newline at end of file
--- a/Documentation/Source/eric6.Plugins.UiExtensionPlugins.VirtualenvInterface.VirtualenvExecDialog.html	Sat Jun 09 12:09:21 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,226 +0,0 @@
-<!DOCTYPE html>
-<html><head>
-<title>eric6.Plugins.UiExtensionPlugins.VirtualenvInterface.VirtualenvExecDialog</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>eric6.Plugins.UiExtensionPlugins.VirtualenvInterface.VirtualenvExecDialog</h1>
-<p>
-Module implementing the virtualenv execution dialog.
-</p>
-<h3>Global Attributes</h3>
-<table>
-<tr><td>None</td></tr>
-</table>
-<h3>Classes</h3>
-<table>
-<tr>
-<td><a href="#VirtualenvExecDialog">VirtualenvExecDialog</a></td>
-<td>Class implementing the virtualenv execution dialog.</td>
-</tr>
-</table>
-<h3>Functions</h3>
-<table>
-<tr><td>None</td></tr>
-</table>
-<hr /><hr />
-<a NAME="VirtualenvExecDialog" ID="VirtualenvExecDialog"></a>
-<h2>VirtualenvExecDialog</h2>
-<p>
-    Class implementing the virtualenv execution dialog.
-</p><p>
-    This class starts a QProcess and displays a dialog that
-    shows the output of the virtualenv or pyvenv process.
-</p>
-<h3>Derived from</h3>
-QDialog, Ui_VirtualenvExecDialog
-<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="#VirtualenvExecDialog.__init__">VirtualenvExecDialog</a></td>
-<td>Constructor</td>
-</tr><tr>
-<td><a href="#VirtualenvExecDialog.__finish">__finish</a></td>
-<td>Private slot called when the process finished.</td>
-</tr><tr>
-<td><a href="#VirtualenvExecDialog.__logError">__logError</a></td>
-<td>Private method to log an error.</td>
-</tr><tr>
-<td><a href="#VirtualenvExecDialog.__logOutput">__logOutput</a></td>
-<td>Private method to log some output.</td>
-</tr><tr>
-<td><a href="#VirtualenvExecDialog.__nextAttempt">__nextAttempt</a></td>
-<td>Private method to start another attempt.</td>
-</tr><tr>
-<td><a href="#VirtualenvExecDialog.__readStderr">__readStderr</a></td>
-<td>Private slot to handle the readyReadStandardError signal.</td>
-</tr><tr>
-<td><a href="#VirtualenvExecDialog.__readStdout">__readStdout</a></td>
-<td>Private slot to handle the readyReadStandardOutput signal.</td>
-</tr><tr>
-<td><a href="#VirtualenvExecDialog.__writeLogFile">__writeLogFile</a></td>
-<td>Private method to write a log file to the virtualenv directory.</td>
-</tr><tr>
-<td><a href="#VirtualenvExecDialog.__writeScriptFile">__writeScriptFile</a></td>
-<td>Private method to write a script file to the virtualenv directory.</td>
-</tr><tr>
-<td><a href="#VirtualenvExecDialog.on_buttonBox_clicked">on_buttonBox_clicked</a></td>
-<td>Private slot called by a button of the button box clicked.</td>
-</tr><tr>
-<td><a href="#VirtualenvExecDialog.start">start</a></td>
-<td>Public slot to start the virtualenv command.</td>
-</tr>
-</table>
-<h3>Static Methods</h3>
-<table>
-<tr><td>None</td></tr>
-</table>
-<a NAME="VirtualenvExecDialog.__init__" ID="VirtualenvExecDialog.__init__"></a>
-<h4>VirtualenvExecDialog (Constructor)</h4>
-<b>VirtualenvExecDialog</b>(<i>pyvenv, targetDir, openTarget, createLog, createScript, interpreter, parent=None</i>)
-<p>
-        Constructor
-</p><dl>
-<dt><i>pyvenv</i></dt>
-<dd>
-flag indicating the use of 'pyvenv' (boolean)
-</dd><dt><i>targetDir</i></dt>
-<dd>
-name of the virtualenv directory (string)
-</dd><dt><i>openTarget</i></dt>
-<dd>
-flag indicating to open the virtualenv directory
-            in a file manager (boolean)
-</dd><dt><i>createLog</i></dt>
-<dd>
-flag indicating to create a log file of the
-            creation process (boolean)
-</dd><dt><i>createScript</i></dt>
-<dd>
-flag indicating to create a script to recreate
-            the virtual environment (boolean)
-</dd><dt><i>interpreter</i></dt>
-<dd>
-name of the python interpreter to use (string)
-</dd><dt><i>parent</i></dt>
-<dd>
-reference to the parent widget (QWidget)
-</dd>
-</dl><a NAME="VirtualenvExecDialog.__finish" ID="VirtualenvExecDialog.__finish"></a>
-<h4>VirtualenvExecDialog.__finish</h4>
-<b>__finish</b>(<i>exitCode, exitStatus, giveUp=False</i>)
-<p>
-        Private slot called when the process finished.
-</p><p>
-        It is called when the process finished or
-        the user pressed the button.
-</p><dl>
-<dt><i>exitCode</i></dt>
-<dd>
-exit code of the process (integer)
-</dd><dt><i>exitStatus</i></dt>
-<dd>
-exit status of the process (QProcess.ExitStatus)
-</dd><dt><i>giveUp=</i></dt>
-<dd>
-flag indicating to not start another attempt (boolean)
-</dd>
-</dl><a NAME="VirtualenvExecDialog.__logError" ID="VirtualenvExecDialog.__logError"></a>
-<h4>VirtualenvExecDialog.__logError</h4>
-<b>__logError</b>(<i>s</i>)
-<p>
-        Private method to log an error.
-</p><dl>
-<dt><i>s</i></dt>
-<dd>
-error string to log (string)
-</dd>
-</dl><a NAME="VirtualenvExecDialog.__logOutput" ID="VirtualenvExecDialog.__logOutput"></a>
-<h4>VirtualenvExecDialog.__logOutput</h4>
-<b>__logOutput</b>(<i>s</i>)
-<p>
-        Private method to log some output.
-</p><dl>
-<dt><i>s</i></dt>
-<dd>
-output sstring to log (string)
-</dd>
-</dl><a NAME="VirtualenvExecDialog.__nextAttempt" ID="VirtualenvExecDialog.__nextAttempt"></a>
-<h4>VirtualenvExecDialog.__nextAttempt</h4>
-<b>__nextAttempt</b>(<i></i>)
-<p>
-        Private method to start another attempt.
-</p><a NAME="VirtualenvExecDialog.__readStderr" ID="VirtualenvExecDialog.__readStderr"></a>
-<h4>VirtualenvExecDialog.__readStderr</h4>
-<b>__readStderr</b>(<i></i>)
-<p>
-        Private slot to handle the readyReadStandardError signal.
-</p><p>
-        It reads the error output of the process and inserts it into the
-        error pane.
-</p><a NAME="VirtualenvExecDialog.__readStdout" ID="VirtualenvExecDialog.__readStdout"></a>
-<h4>VirtualenvExecDialog.__readStdout</h4>
-<b>__readStdout</b>(<i></i>)
-<p>
-        Private slot to handle the readyReadStandardOutput signal.
-</p><p>
-        It reads the output of the process, formats it and inserts it into
-        the contents pane.
-</p><a NAME="VirtualenvExecDialog.__writeLogFile" ID="VirtualenvExecDialog.__writeLogFile"></a>
-<h4>VirtualenvExecDialog.__writeLogFile</h4>
-<b>__writeLogFile</b>(<i></i>)
-<p>
-        Private method to write a log file to the virtualenv directory.
-</p><a NAME="VirtualenvExecDialog.__writeScriptFile" ID="VirtualenvExecDialog.__writeScriptFile"></a>
-<h4>VirtualenvExecDialog.__writeScriptFile</h4>
-<b>__writeScriptFile</b>(<i></i>)
-<p>
-        Private method to write a script file to the virtualenv directory.
-</p><a NAME="VirtualenvExecDialog.on_buttonBox_clicked" ID="VirtualenvExecDialog.on_buttonBox_clicked"></a>
-<h4>VirtualenvExecDialog.on_buttonBox_clicked</h4>
-<b>on_buttonBox_clicked</b>(<i>button</i>)
-<p>
-        Private slot called by a button of the button box clicked.
-</p><dl>
-<dt><i>button</i></dt>
-<dd>
-button that was clicked (QAbstractButton)
-</dd>
-</dl><a NAME="VirtualenvExecDialog.start" ID="VirtualenvExecDialog.start"></a>
-<h4>VirtualenvExecDialog.start</h4>
-<b>start</b>(<i>arguments</i>)
-<p>
-        Public slot to start the virtualenv command.
-</p><dl>
-<dt><i>arguments</i></dt>
-<dd>
-commandline arguments for virtualenv/pyvenv program
-            (list of strings)
-</dd>
-</dl>
-<div align="right"><a href="#top">Up</a></div>
-<hr />
-</body></html>
\ No newline at end of file
--- a/Documentation/Source/index-eric6.Plugins.UiExtensionPlugins.VirtualenvInterface.html	Sat Jun 09 12:09:21 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-<!DOCTYPE html>
-<html><head>
-<title>eric6.Plugins.UiExtensionPlugins.VirtualenvInterface</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>
-<h1>eric6.Plugins.UiExtensionPlugins.VirtualenvInterface</h1>
-<p>
-Package implementing the virtualenv wizard dialogs and data.
-</p>
-
-
-<h3>Modules</h3>
-<table>
-<tr>
-<td><a href="eric6.Plugins.UiExtensionPlugins.VirtualenvInterface.VirtualenvConfigurationDialog.html">VirtualenvConfigurationDialog</a></td>
-<td>Module implementing a dialog to enter the parameters for the virtual environment.</td>
-</tr><tr>
-<td><a href="eric6.Plugins.UiExtensionPlugins.VirtualenvInterface.VirtualenvExecDialog.html">VirtualenvExecDialog</a></td>
-<td>Module implementing the virtualenv execution dialog.</td>
-</tr>
-</table>
-</body></html>
\ No newline at end of file
--- a/Plugins/PluginVirtualenvInterface.py	Sat Jun 09 12:09:21 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2014 - 2018 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing the virtualenv interface plug-in.
-"""
-
-from __future__ import unicode_literals
-
-from PyQt5.QtCore import QObject
-from PyQt5.QtWidgets import QDialog
-
-from E5Gui.E5Application import e5App
-from E5Gui.E5Action import E5Action
-
-import UI.Info
-
-# Start-of-Header
-name = "virtualenv Configurator Plug-in"
-author = "Detlev Offenbach <detlev@die-offenbachs.de>"
-autoactivate = True
-deactivateable = True
-version = UI.Info.VersionOnly
-className = "VirtualenvInterfacePlugin"
-packageName = "__core__"
-shortDescription = "Configurator for Python virtual environments."
-longDescription = \
-    """This plug-in implements a configuration interface to create Python""" \
-    """ virtual environments using 'virtualenv' or 'pyvenv."""
-needsRestart = False
-pyqtApi = 2
-python2Compatible = True
-# End-of-Header
-
-error = ""
-
-
-class VirtualenvInterfacePlugin(QObject):
-    """
-    Class implementing the virtualenv wizard plug-in.
-    """
-    def __init__(self, ui):
-        """
-        Constructor
-        
-        @param ui reference to the user interface object (UI.UserInterface)
-        """
-        super(VirtualenvInterfacePlugin, self).__init__(ui)
-        self.__ui = ui
-        self.__action = None
-        
-        self.__initAction()
-    
-    def activate(self):
-        """
-        Public method to activate this plug-in.
-        
-        @return tuple of None and activation status (boolean)
-        """
-        e5App().getObject("ToolbarManager").addAction(self.__action, "Tools")
-        
-        menu = self.__ui.getMenu("extras")
-        menu.addAction(self.__action)
-
-        return None, True
-    
-    def deactivate(self):
-        """
-        Public method to deactivate this plug-in.
-        """
-        e5App().getObject("ToolbarManager").removeAction(self.__action)
-        
-        menu = self.__ui.getMenu("extras")
-        menu.removeAction(self.__action)
-    
-    def __initAction(self):
-        """
-        Private method to initialize the action.
-        """
-        self.__action = E5Action(
-            self.tr('Virtualenv Configurator'),
-            self.tr('&Virtualenv Configurator...'),
-            0, 0, self,
-            'virtualenv_configurator')
-        self.__action.setStatusTip(self.tr('Virtualenv Configurator'))
-        self.__action.setWhatsThis(self.tr(
-            """<b>Virtualenv Configurator</b>"""
-            """<p>This opens a dialog for entering all the parameters"""
-            """ needed to create a Python virtual environment using"""
-            """ virtualenv or pyvenv.</p>"""
-        ))
-        self.__action.triggered.connect(self.__handle)
-    
-    def __handle(self):
-        """
-        Private method to handle the creation of a virtual environment.
-        """
-        from UiExtensionPlugins.VirtualenvInterface\
-            .VirtualenvConfigurationDialog import VirtualenvConfigurationDialog
-        
-        dlg = VirtualenvConfigurationDialog()
-        if dlg.exec_() == QDialog.Accepted:
-            (pyvenv, args, openTarget, createLog, createScript, targetDir,
-             interpreter) = dlg.getData()
-            
-            # now do the call
-            from UiExtensionPlugins.VirtualenvInterface.VirtualenvExecDialog \
-                import VirtualenvExecDialog
-            dia = VirtualenvExecDialog(pyvenv, targetDir, openTarget,
-                                       createLog, createScript, interpreter)
-            dia.show()
-            dia.start(args)
-            dia.exec_()
-
-#
-# eflag: noqa = M801
--- a/Plugins/UiExtensionPlugins/VirtualenvInterface/VirtualenvConfigurationDialog.py	Sat Jun 09 12:09:21 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,397 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2014 - 2018 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing a dialog to enter the parameters for the
-virtual environment.
-"""
-
-from __future__ import unicode_literals
-try:
-    str = unicode
-except NameError:
-    pass
-
-import os
-import sys
-import re
-
-from PyQt5.QtCore import pyqtSlot, QProcess, QTimer
-from PyQt5.QtWidgets import QDialog, QDialogButtonBox
-
-from E5Gui.E5Completers import E5DirCompleter, E5FileCompleter
-from E5Gui import E5FileDialog
-
-from .Ui_VirtualenvConfigurationDialog import Ui_VirtualenvConfigurationDialog
-
-import Preferences
-import Utilities
-import UI.PixmapCache
-
-
-class VirtualenvConfigurationDialog(QDialog, Ui_VirtualenvConfigurationDialog):
-    """
-    Class implementing a dialog to enter the parameters for the
-    virtual environment.
-    """
-    def __init__(self, parent=None):
-        """
-        Constructor
-        
-        @param parent reference to the parent widget (QWidget)
-        """
-        super(VirtualenvConfigurationDialog, self).__init__(parent)
-        self.setupUi(self)
-        
-        self.targetDirectoryButton.setIcon(UI.PixmapCache.getIcon("open.png"))
-        self.extraSearchPathButton.setIcon(UI.PixmapCache.getIcon("open.png"))
-        self.pythonExecButton.setIcon(UI.PixmapCache.getIcon("open.png"))
-        
-        self.__targetDirectoryCompleter = \
-            E5DirCompleter(self.targetDirectoryEdit)
-        self.__extraSearchPathCompleter = \
-            E5DirCompleter(self.extraSearchPathEdit)
-        self.__pythonExecCompleter = E5FileCompleter(self.pythonExecEdit)
-        
-        self.__versionRe = re.compile(r""".*?(\d+\.\d+\.\d+).*""")
-        
-        self.__virtualenvFound = False
-        self.__pyvenvFound = False
-        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
-        
-        self.__mandatoryStyleSheet = "QLineEdit {border: 2px solid;}"
-        self.targetDirectoryEdit.setStyleSheet(self.__mandatoryStyleSheet)
-        
-        self.__setVirtualenvVersion()
-        self.__setPyvenvVersion()
-        if self.__virtualenvFound:
-            self.virtualenvButton.setChecked(True)
-        elif self.__pyvenvFound:
-            self.pyvenvButton.setChecked(True)
-        
-        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(
-            (self.__virtualenvFound or self.__pyvenvFound) and
-            bool(self.targetDirectoryEdit.text())
-        )
-    
-    def __updateUi(self):
-        """
-        Private method to update the UI depending on the selected
-        virtual environment creator (virtualenv or pyvenv).
-        """
-        enable = self.virtualenvButton.isChecked()
-        self.extraSearchPathLabel.setEnabled(enable)
-        self.extraSearchPathEdit.setEnabled(enable)
-        self.extraSearchPathButton.setEnabled(enable)
-        self.promptPrefixLabel.setEnabled(enable)
-        self.promptPrefixEdit.setEnabled(enable)
-        self.verbosityLabel.setEnabled(enable)
-        self.verbositySpinBox.setEnabled(enable)
-        self.versionLabel.setEnabled(enable)
-        self.versionComboBox.setEnabled(enable)
-        self.unzipCheckBox.setEnabled(enable)
-        self.noSetuptoolsCheckBox.setEnabled(enable)
-        self.symlinkCheckBox.setEnabled(not enable)
-        self.upgradeCheckBox.setEnabled(not enable)
-    
-    @pyqtSlot()
-    def on_targetDirectoryButton_clicked(self):
-        """
-        Private slot to select the target directory via a directory
-        selection dialog.
-        """
-        target = self.targetDirectoryEdit.text()
-        if not target:
-            target = Utilities.getHomeDir()
-        target = Utilities.fromNativeSeparators(target)
-        target = E5FileDialog.getExistingDirectory(
-            self,
-            self.tr("Virtualenv Target Directory"),
-            target,
-            E5FileDialog.Options(E5FileDialog.ShowDirsOnly))
-        if target:
-            self.targetDirectoryEdit.setText(
-                Utilities.toNativeSeparators(target))
-    
-    @pyqtSlot(str)
-    def on_targetDirectoryEdit_textChanged(self, txt):
-        """
-        Private slot handling a change of the target directory.
-        
-        @param txt target directory (string)
-        """
-        self.__updateOK()
-    
-    @pyqtSlot()
-    def on_extraSearchPathButton_clicked(self):
-        """
-        Private slot to select the extra search path via a directory
-        selection dialog.
-        """
-        extraSearchPath = self.extraSearchPathEdit.text()
-        if not extraSearchPath:
-            extraSearchPath = Utilities.getHomeDir()
-        extraSearchPath = Utilities.fromNativeSeparators(extraSearchPath)
-        extraSearchPath = E5FileDialog.getExistingDirectory(
-            self,
-            self.tr("Extra Search Path for setuptools/pip"),
-            extraSearchPath,
-            E5FileDialog.Options(E5FileDialog.ShowDirsOnly))
-        if extraSearchPath:
-            self.extraSearchPathEdit.setText(
-                Utilities.toNativeSeparators(extraSearchPath))
-    
-    @pyqtSlot()
-    def on_pythonExecButton_clicked(self):
-        """
-        Private slot to select a Python interpreter via a file selection
-        dialog.
-        """
-        pythonExec = self.pythonExecEdit.text()
-        if not pythonExec:
-            pythonExec = sys.executable.replace("w.exe", ".exe")
-        pythonExec = Utilities.fromNativeSeparators(pythonExec)
-        pythonExec = E5FileDialog.getOpenFileName(
-            self,
-            self.tr("Python Interpreter"),
-            pythonExec,
-            "")
-        if pythonExec:
-            self.pythonExecEdit.setText(
-                Utilities.toNativeSeparators(pythonExec))
-    
-    @pyqtSlot(str)
-    def on_pythonExecEdit_textChanged(self, txt):
-        """
-        Private slot to react to a change of the Python executable.
-        
-        @param txt contents of the line edit (string)
-        """
-        self.__setVirtualenvVersion()
-        self.__setPyvenvVersion()
-        self.__updateOK()
-    
-    @pyqtSlot(bool)
-    def on_virtualenvButton_toggled(self, checked):
-        """
-        Private slot to react to the selection of 'virtualenv'.
-        
-        @param checked state of the checkbox (boolean)
-        """
-        self.__updateUi()
-    
-    @pyqtSlot(bool)
-    def on_pyvenvButton_toggled(self, checked):
-        """
-        Private slot to react to the selection of 'pyvenv'.
-        
-        @param checked state of the checkbox (boolean)
-        """
-        self.__updateUi()
-    
-    def __setVirtualenvVersion(self):
-        """
-        Private method to determine the virtualenv version and set the
-        respective label.
-        """
-        calls = [
-            (sys.executable.replace("w.exe", ".exe"),
-             ["-m", "virtualenv", "--version"]),
-            ("virtualenv", ["--version"]),
-        ]
-        if self.pythonExecEdit.text():
-            calls.append((self.pythonExecEdit.text(),
-                          ["-m", "virtualenv", "--version"]))
-        
-        proc = QProcess()
-        for prog, args in calls:
-            proc.start(prog, args)
-            
-            if not proc.waitForStarted(5000):
-                # try next entry
-                continue
-            
-            if not proc.waitForFinished(5000):
-                # process hangs, kill it
-                QTimer.singleShot(2000, proc.kill)
-                proc.waitForFinished(3000)
-                version = self.tr('<virtualenv did not finish within 5s.>')
-                self.__virtualenvFound = False
-                break
-            
-            if proc.exitCode() != 0:
-                # returned with error code, try next
-                continue
-            
-            output = str(proc.readAllStandardOutput(),
-                         Preferences.getSystem("IOEncoding"),
-                         'replace').strip()
-            match = re.match(self.__versionRe, output)
-            if match:
-                self.__virtualenvFound = True
-                version = match.group(1)
-                break
-        else:
-            self.__virtualenvFound = False
-            version = self.tr('<No suitable virtualenv found.>')
-        
-        self.virtualenvButton.setText(self.tr(
-            "virtualenv Version: {0}".format(version)))
-        self.virtualenvButton.setEnabled(self.__virtualenvFound)
-        if not self.__virtualenvFound:
-            self.virtualenvButton.setChecked(False)
-    
-    def __setPyvenvVersion(self):
-        """
-        Private method to determine the pyvenv version and set the respective
-        label.
-        """
-        calls = []
-        if self.pythonExecEdit.text():
-            calls.append((self.pythonExecEdit.text(),
-                          ["-m", "venv"]))
-        calls.extend([
-            (sys.executable.replace("w.exe", ".exe"),
-             ["-m", "venv"]),
-            ("python3", ["-m", "venv"]),
-            ("python", ["-m", "venv"]),
-        ])
-        
-        proc = QProcess()
-        for prog, args in calls:
-            proc.start(prog, args)
-            
-            if not proc.waitForStarted(5000):
-                # try next entry
-                continue
-            
-            if not proc.waitForFinished(5000):
-                # process hangs, kill it
-                QTimer.singleShot(2000, proc.kill)
-                proc.waitForFinished(3000)
-                version = self.tr('<pyvenv did not finish within 5s.>')
-                self.__pyvenvFound = False
-                break
-            
-            if proc.exitCode() not in [0, 2]:
-                # returned with error code, try next
-                continue
-            
-            proc.start(prog, ["--version"])
-            proc.waitForFinished(5000)
-            output = str(proc.readAllStandardOutput(),
-                         Preferences.getSystem("IOEncoding"),
-                         'replace').strip()
-            match = re.match(self.__versionRe, output)
-            if match:
-                self.__pyvenvFound = True
-                version = match.group(1)
-                break
-        else:
-            self.__pyvenvFound = False
-            version = self.tr('<No suitable pyvenv found.>')
-        
-        self.pyvenvButton.setText(self.tr(
-            "pyvenv Version: {0}".format(version)))
-        self.pyvenvButton.setEnabled(self.__pyvenvFound)
-        if not self.__pyvenvFound:
-            self.pyvenvButton.setChecked(False)
-    
-    def __generateTargetDir(self):
-        """
-        Private method to generate a valid target directory path.
-        
-        @return target directory path (string)
-        """
-        targetDirectory = Utilities.toNativeSeparators(
-            self.targetDirectoryEdit.text())
-        if not os.path.isabs(targetDirectory):
-            targetDirectory = os.path.join(os.path.expanduser("~"),
-                                           targetDirectory)
-        return targetDirectory
-    
-    def __generateArguments(self):
-        """
-        Private method to generate the process arguments.
-        
-        @return process arguments (list of string)
-        """
-        args = []
-        if self.virtualenvButton.isChecked():
-            if self.extraSearchPathEdit.text():
-                args.append("--extra-search-dir={0}".format(
-                    Utilities.toNativeSeparators(
-                        self.extraSearchPathEdit.text())))
-            if self.promptPrefixEdit.text():
-                args.append("--prompt={0}".format(
-                    self.promptPrefixEdit.text().replace(" ", "_")))
-            if self.pythonExecEdit.text():
-                args.append("--python={0}".format(
-                    Utilities.toNativeSeparators(self.pythonExecEdit.text())))
-            elif self.versionComboBox.currentText():
-                args.append("--python=python{0}".format(
-                    self.versionComboBox.currentText()))
-            if self.verbositySpinBox.value() == 1:
-                args.append("--verbose")
-            elif self.verbositySpinBox.value() == -1:
-                args.append("--quiet")
-            if self.clearCheckBox.isChecked():
-                args.append("--clear")
-            if self.systemCheckBox.isChecked():
-                args.append("--system-site-packages")
-            if self.unzipCheckBox.isChecked():
-                args.append("--unzip-setuptools")
-            if self.noSetuptoolsCheckBox.isChecked():
-                args.append("--no-setuptools")
-            if self.noPipCcheckBox.isChecked():
-                args.append("--no-pip")
-            if self.copyCheckBox.isChecked():
-                args.append("--always-copy")
-        elif self.pyvenvButton.isChecked():
-            if self.clearCheckBox.isChecked():
-                args.append("--clear")
-            if self.systemCheckBox.isChecked():
-                args.append("--system-site-packages")
-            if self.noPipCcheckBox.isChecked():
-                args.append("--without-pip")
-            if self.copyCheckBox.isChecked():
-                args.append("--copies")
-            if self.symlinkCheckBox.isChecked():
-                args.append("--symlinks")
-            if self.upgradeCheckBox.isChecked():
-                args.append("--upgrade")
-        targetDirectory = self.__generateTargetDir()
-        args.append(targetDirectory)
-        return args
-
-    def getData(self):
-        """
-        Public method to retrieve the dialog data.
-        
-        @return tuple containing a flag indicating the pyvenv selection
-            (boolean), the process arguments (list of string), a flag
-            indicating to open the target directory after creation (boolean),
-            a flag indicating to write a log file (boolean), a flag indicating
-            to write a script (boolean), the name of the target directory
-            (string) and the name of the python interpreter to use (string)
-        """
-        args = self.__generateArguments()
-        targetDirectory = self.__generateTargetDir()
-        return (
-            self.pyvenvButton.isChecked(),
-            args,
-            self.openCheckBox.isChecked(),
-            self.logCheckBox.isChecked(),
-            self.scriptCheckBox.isChecked(),
-            targetDirectory,
-            Utilities.toNativeSeparators(self.pythonExecEdit.text()),
-        )
--- a/Plugins/UiExtensionPlugins/VirtualenvInterface/VirtualenvConfigurationDialog.ui	Sat Jun 09 12:09:21 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,482 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>VirtualenvConfigurationDialog</class>
- <widget class="QDialog" name="VirtualenvConfigurationDialog">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>700</width>
-    <height>590</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Virtualenv Configuration</string>
-  </property>
-  <property name="sizeGripEnabled">
-   <bool>true</bool>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <item>
-    <widget class="QGroupBox" name="groupBox_3">
-     <property name="title">
-      <string>Environment Creator</string>
-     </property>
-     <layout class="QGridLayout" name="gridLayout_3">
-      <item row="0" column="0">
-       <widget class="QRadioButton" name="virtualenvButton">
-        <property name="font">
-         <font>
-          <weight>75</weight>
-          <bold>true</bold>
-         </font>
-        </property>
-        <property name="toolTip">
-         <string>Select to use 'virtualenv'</string>
-        </property>
-        <property name="text">
-         <string notr="true">0.0</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <spacer name="horizontalSpacer_2">
-        <property name="orientation">
-         <enum>Qt::Horizontal</enum>
-        </property>
-        <property name="sizeHint" stdset="0">
-         <size>
-          <width>40</width>
-          <height>20</height>
-         </size>
-        </property>
-       </spacer>
-      </item>
-      <item row="1" column="0">
-       <widget class="QRadioButton" name="pyvenvButton">
-        <property name="font">
-         <font>
-          <weight>75</weight>
-          <bold>true</bold>
-         </font>
-        </property>
-        <property name="toolTip">
-         <string>Select to use 'pyvenv'</string>
-        </property>
-        <property name="text">
-         <string notr="true">0.0</string>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QGroupBox" name="groupBox">
-     <property name="title">
-      <string>Paths</string>
-     </property>
-     <layout class="QGridLayout" name="gridLayout">
-      <item row="0" column="0">
-       <widget class="QLabel" name="label">
-        <property name="text">
-         <string>Target Directory:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <widget class="E5ClearableLineEdit" name="targetDirectoryEdit">
-        <property name="toolTip">
-         <string>Enter the target directory for the virtual environment</string>
-        </property>
-        <property name="placeholderText">
-         <string>Target directory for the virtual environment</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="2">
-       <widget class="QToolButton" name="targetDirectoryButton">
-        <property name="toolTip">
-         <string>Select the target directory via a directory selection dialog</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="0">
-       <widget class="QLabel" name="extraSearchPathLabel">
-        <property name="text">
-         <string>Extra Search Path:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
-       <widget class="E5ClearableLineEdit" name="extraSearchPathEdit">
-        <property name="toolTip">
-         <string>Enter the extra search path to look for setuptools/pip</string>
-        </property>
-        <property name="placeholderText">
-         <string>Extra search path to look for setuptools/pip</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="2">
-       <widget class="QToolButton" name="extraSearchPathButton">
-        <property name="toolTip">
-         <string>Select the extra search path to look for setuptools/pip via a directory selection dialog</string>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="0">
-       <widget class="QLabel" name="promptPrefixLabel">
-        <property name="text">
-         <string>Prompt Prefix:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="1">
-       <widget class="E5ClearableLineEdit" name="promptPrefixEdit">
-        <property name="toolTip">
-         <string>Enter the prompt prefix for the virtual environment</string>
-        </property>
-        <property name="placeholderText">
-         <string>Prompt prefix for the virtual environment</string>
-        </property>
-       </widget>
-      </item>
-      <item row="3" column="0">
-       <widget class="QLabel" name="label_5">
-        <property name="text">
-         <string>Python Executable:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="3" column="1">
-       <widget class="E5ClearableLineEdit" name="pythonExecEdit">
-        <property name="toolTip">
-         <string>Enter the Python interpreter for the virtual environment</string>
-        </property>
-        <property name="placeholderText">
-         <string>Python interpreter for the virtual environment</string>
-        </property>
-       </widget>
-      </item>
-      <item row="3" column="2">
-       <widget class="QToolButton" name="pythonExecButton">
-        <property name="toolTip">
-         <string>Select the Python interpreter via a file selection dialog</string>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QGroupBox" name="groupBox_2">
-     <property name="title">
-      <string>Options</string>
-     </property>
-     <layout class="QGridLayout" name="gridLayout_2">
-      <item row="0" column="0">
-       <layout class="QHBoxLayout" name="horizontalLayout_3">
-        <item>
-         <widget class="QLabel" name="verbosityLabel">
-          <property name="text">
-           <string>Verbosity:</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QSpinBox" name="verbositySpinBox">
-          <property name="toolTip">
-           <string>Select the verbosity (-1: quiet, 0: normal, 1: verbose)</string>
-          </property>
-          <property name="alignment">
-           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-          </property>
-          <property name="minimum">
-           <number>-1</number>
-          </property>
-          <property name="maximum">
-           <number>1</number>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <spacer name="horizontalSpacer_3">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-       </layout>
-      </item>
-      <item row="0" column="1">
-       <layout class="QHBoxLayout" name="horizontalLayout">
-        <item>
-         <widget class="QLabel" name="versionLabel">
-          <property name="text">
-           <string>Python Version:</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QComboBox" name="versionComboBox">
-          <property name="toolTip">
-           <string>Select the Python version (empty for current)</string>
-          </property>
-          <item>
-           <property name="text">
-            <string notr="true"/>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string notr="true">2.6</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string notr="true">2.7</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string notr="true">3.4</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string notr="true">3.5</string>
-           </property>
-          </item>
-          <item>
-           <property name="text">
-            <string notr="true">3.6</string>
-           </property>
-          </item>
-         </widget>
-        </item>
-        <item>
-         <spacer name="horizontalSpacer">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-       </layout>
-      </item>
-      <item row="1" column="0">
-       <widget class="QCheckBox" name="systemCheckBox">
-        <property name="toolTip">
-         <string>Select to give the virtualenv access to the global site-packages</string>
-        </property>
-        <property name="text">
-         <string>System-wide Python Packages</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
-       <widget class="QCheckBox" name="unzipCheckBox">
-        <property name="toolTip">
-         <string>Select to unzip setuptools when installing it</string>
-        </property>
-        <property name="text">
-         <string>Unzip Setuptool to virtualenv</string>
-        </property>
-        <property name="checked">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="0">
-       <widget class="QCheckBox" name="noSetuptoolsCheckBox">
-        <property name="toolTip">
-         <string>Select to not install setuptools (or pip) in the new virtualenv</string>
-        </property>
-        <property name="text">
-         <string>Don't install 'setuptool' (or pip) in the virtualenv</string>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="1">
-       <widget class="QCheckBox" name="noPipCcheckBox">
-        <property name="toolTip">
-         <string>Select to not install pip in the new virtualenv</string>
-        </property>
-        <property name="text">
-         <string>Don't install 'pip' in the virtualenv</string>
-        </property>
-       </widget>
-      </item>
-      <item row="3" column="0">
-       <widget class="QCheckBox" name="clearCheckBox">
-        <property name="toolTip">
-         <string>Select to clear the target first</string>
-        </property>
-        <property name="text">
-         <string>Clear out the target directory</string>
-        </property>
-       </widget>
-      </item>
-      <item row="3" column="1">
-       <widget class="QCheckBox" name="copyCheckBox">
-        <property name="toolTip">
-         <string>Select to always copy files rather than symlinking</string>
-        </property>
-        <property name="text">
-         <string>Always copy files</string>
-        </property>
-       </widget>
-      </item>
-      <item row="4" column="0">
-       <widget class="QCheckBox" name="symlinkCheckBox">
-        <property name="toolTip">
-         <string>Select to use symlinks instead of copies</string>
-        </property>
-        <property name="text">
-         <string>Use Symbolic Links</string>
-        </property>
-       </widget>
-      </item>
-      <item row="4" column="1">
-       <widget class="QCheckBox" name="upgradeCheckBox">
-        <property name="toolTip">
-         <string>Select to upgrade a virtual environment</string>
-        </property>
-        <property name="text">
-         <string>Upgrade</string>
-        </property>
-       </widget>
-      </item>
-      <item row="5" column="0">
-       <widget class="QCheckBox" name="logCheckBox">
-        <property name="toolTip">
-         <string>Select to generate a log file in the target directory</string>
-        </property>
-        <property name="text">
-         <string>Save a log file in the target directory after creation</string>
-        </property>
-        <property name="checked">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-      <item row="5" column="1">
-       <widget class="QCheckBox" name="scriptCheckBox">
-        <property name="toolTip">
-         <string>Select to write a shell script/batch file to regenerate the virtualenv</string>
-        </property>
-        <property name="text">
-         <string>Save virtualenv generation script</string>
-        </property>
-        <property name="checked">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-      <item row="6" column="0">
-       <widget class="QCheckBox" name="openCheckBox">
-        <property name="toolTip">
-         <string>Open the newly created virtualenv in a file manager window</string>
-        </property>
-        <property name="text">
-         <string>Open target directory after creation</string>
-        </property>
-        <property name="checked">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </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>
- </customwidgets>
- <tabstops>
-  <tabstop>virtualenvButton</tabstop>
-  <tabstop>pyvenvButton</tabstop>
-  <tabstop>targetDirectoryEdit</tabstop>
-  <tabstop>targetDirectoryButton</tabstop>
-  <tabstop>extraSearchPathEdit</tabstop>
-  <tabstop>extraSearchPathButton</tabstop>
-  <tabstop>promptPrefixEdit</tabstop>
-  <tabstop>pythonExecEdit</tabstop>
-  <tabstop>pythonExecButton</tabstop>
-  <tabstop>verbositySpinBox</tabstop>
-  <tabstop>versionComboBox</tabstop>
-  <tabstop>systemCheckBox</tabstop>
-  <tabstop>unzipCheckBox</tabstop>
-  <tabstop>noSetuptoolsCheckBox</tabstop>
-  <tabstop>noPipCcheckBox</tabstop>
-  <tabstop>clearCheckBox</tabstop>
-  <tabstop>copyCheckBox</tabstop>
-  <tabstop>symlinkCheckBox</tabstop>
-  <tabstop>upgradeCheckBox</tabstop>
-  <tabstop>logCheckBox</tabstop>
-  <tabstop>scriptCheckBox</tabstop>
-  <tabstop>openCheckBox</tabstop>
- </tabstops>
- <resources/>
- <connections>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>accepted()</signal>
-   <receiver>VirtualenvConfigurationDialog</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>VirtualenvConfigurationDialog</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/Plugins/UiExtensionPlugins/VirtualenvInterface/VirtualenvExecDialog.py	Sat Jun 09 12:09:21 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,306 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2014 - 2018 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing the virtualenv execution dialog.
-"""
-
-from __future__ import unicode_literals
-try:
-    str = unicode
-except NameError:
-    pass
-
-import sys
-import os
-
-from PyQt5.QtCore import QProcess, QTimer, QUrl
-from PyQt5.QtGui import QDesktopServices
-from PyQt5.QtWidgets import QDialog, QDialogButtonBox
-
-from .Ui_VirtualenvExecDialog import Ui_VirtualenvExecDialog
-
-import Preferences
-from Globals import isWindowsPlatform
-
-
-class VirtualenvExecDialog(QDialog, Ui_VirtualenvExecDialog):
-    """
-    Class implementing the virtualenv execution dialog.
-    
-    This class starts a QProcess and displays a dialog that
-    shows the output of the virtualenv or pyvenv process.
-    """
-    def __init__(self, pyvenv, targetDir, openTarget, createLog, createScript,
-                 interpreter, parent=None):
-        """
-        Constructor
-        
-        @param pyvenv flag indicating the use of 'pyvenv' (boolean)
-        @param targetDir name of the virtualenv directory (string)
-        @param openTarget flag indicating to open the virtualenv directory
-            in a file manager (boolean)
-        @param createLog flag indicating to create a log file of the
-            creation process (boolean)
-        @param createScript flag indicating to create a script to recreate
-            the virtual environment (boolean)
-        @param interpreter name of the python interpreter to use (string)
-        @param parent reference to the parent widget (QWidget)
-        """
-        super(VirtualenvExecDialog, self).__init__(parent)
-        self.setupUi(self)
-        
-        self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
-        self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)
-        
-        self.__pyvenv = pyvenv
-        self.__targetDir = targetDir
-        self.__openTarget = openTarget
-        self.__createLog = createLog
-        self.__createScript = createScript
-        
-        self.process = None
-        self.__cmd = ""
-        
-        if pyvenv:
-            self.__calls = []
-            if interpreter:
-                self.__calls.append((interpreter, ["-m", "venv"]))
-            self.__calls.extend([
-                (sys.executable.replace("w.exe", ".exe"),
-                 ["-m", "venv"]),
-                ("python3", ["-m", "venv"]),
-                ("python", ["-m", "venv"]),
-            ])
-        else:
-            self.__calls = [
-                (sys.executable.replace("w.exe", ".exe"),
-                 ["-m", "virtualenv"]),
-                ("virtualenv", []),
-            ]
-        self.__callIndex = 0
-        self.__callArgs = []
-    
-    def start(self, arguments):
-        """
-        Public slot to start the virtualenv command.
-        
-        @param arguments commandline arguments for virtualenv/pyvenv program
-            (list of strings)
-        """
-        if self.__callIndex == 0:
-            # first attempt, add a given python interpreter and do
-            # some other setup
-            self.errorGroup.hide()
-            self.contents.clear()
-            self.errors.clear()
-            
-            self.process = QProcess()
-            self.process.readyReadStandardOutput.connect(self.__readStdout)
-            self.process.readyReadStandardError.connect(self.__readStderr)
-            self.process.finished.connect(self.__finish)
-            
-            if not self.__pyvenv:
-                for arg in arguments:
-                    if arg.startswith("--python="):
-                        prog = arg.replace("--python=", "")
-                        self.__calls.insert(
-                            0, (prog, ["-m", "virtualenv"]))
-                        break
-            self.__callArgs = arguments
-        
-        prog, args = self.__calls[self.__callIndex]
-        args.extend(self.__callArgs)
-        self.__cmd = "{0} {1}".format(prog, " ".join(args))
-        self.__logOutput(self.tr("Executing: {0}\n").format(
-            self.__cmd))
-        self.process.start(prog, args)
-        procStarted = self.process.waitForStarted(5000)
-        if not procStarted:
-            self.__logOutput(self.tr("Failed\n\n"))
-            self.__nextAttempt()
-    
-    def on_buttonBox_clicked(self, button):
-        """
-        Private slot called by a button of the button box clicked.
-        
-        @param button button that was clicked (QAbstractButton)
-        """
-        if button == self.buttonBox.button(QDialogButtonBox.Close):
-            self.accept()
-        elif button == self.buttonBox.button(QDialogButtonBox.Cancel):
-            self.__finish()
-    
-    def __finish(self, exitCode, exitStatus, giveUp=False):
-        """
-        Private slot called when the process finished.
-        
-        It is called when the process finished or
-        the user pressed the button.
-        
-        @param exitCode exit code of the process (integer)
-        @param exitStatus exit status of the process (QProcess.ExitStatus)
-        @keyparam giveUp flag indicating to not start another attempt (boolean)
-        """
-        if self.process is not None and \
-           self.process.state() != QProcess.NotRunning:
-            self.process.terminate()
-            QTimer.singleShot(2000, self.process.kill)
-            self.process.waitForFinished(3000)
-        
-        self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
-        self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
-        self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
-        
-        if not giveUp:
-            if exitCode != 0:
-                self.__logOutput(self.tr("Failed\n\n"))
-                if len(self.errors.toPlainText().splitlines()) == 1:
-                    self.errors.clear()
-                    self.errorGroup.hide()
-                    self.__nextAttempt()
-                    return
-            
-            self.process = None
-            
-            if self.__pyvenv:
-                self.__logOutput(self.tr('\npyvenv finished.\n'))
-            else:
-                self.__logOutput(self.tr('\nvirtualenv finished.\n'))
-            
-            if os.path.exists(self.__targetDir):
-                if self.__createScript:
-                    self.__writeScriptFile()
-                
-                if self.__createLog:
-                    self.__writeLogFile()
-                
-                if self.__openTarget:
-                    QDesktopServices.openUrl(QUrl.fromLocalFile(
-                        self.__targetDir))
-    
-    def __nextAttempt(self):
-        """
-        Private method to start another attempt.
-        """
-        self.__callIndex += 1
-        if self.__callIndex < len(self.__calls):
-            self.start(self.__callArgs)
-        else:
-            if self.__pyvenv:
-                self.__logError(
-                    self.tr('No suitable pyvenv program could be'
-                            ' started.\n'))
-            else:
-                self.__logError(
-                    self.tr('No suitable virtualenv program could be'
-                            ' started.\n'))
-            self.__cmd = ""
-            self.__finish(0, 0, giveUp=True)
-    
-    def __readStdout(self):
-        """
-        Private slot to handle the readyReadStandardOutput signal.
-        
-        It reads the output of the process, formats it and inserts it into
-        the contents pane.
-        """
-        self.process.setReadChannel(QProcess.StandardOutput)
-        
-        while self.process.canReadLine():
-            s = str(self.process.readLine(),
-                    Preferences.getSystem("IOEncoding"),
-                    'replace')
-            self.__logOutput(s)
-    
-    def __readStderr(self):
-        """
-        Private slot to handle the readyReadStandardError signal.
-        
-        It reads the error output of the process and inserts it into the
-        error pane.
-        """
-        self.process.setReadChannel(QProcess.StandardError)
-        
-        while self.process.canReadLine():
-            s = str(self.process.readLine(),
-                    Preferences.getSystem("IOEncoding"),
-                    'replace')
-            self.__logError(s)
-    
-    def __logOutput(self, s):
-        """
-        Private method to log some output.
-        
-        @param s output sstring to log (string)
-        """
-        self.contents.insertPlainText(s)
-        self.contents.ensureCursorVisible()
-    
-    def __logError(self, s):
-        """
-        Private method to log an error.
-        
-        @param s error string to log (string)
-        """
-        self.errorGroup.show()
-        self.errors.insertPlainText(s)
-        self.errors.ensureCursorVisible()
-    
-    def __writeLogFile(self):
-        """
-        Private method to write a log file to the virtualenv directory.
-        """
-        outtxt = self.contents.toPlainText()
-        if self.__pyvenv:
-            logFile = os.path.join(self.__targetDir, "pyvenv.log")
-        else:
-            logFile = os.path.join(self.__targetDir, "virtualenv.log")
-        self.__logOutput(self.tr("\nWriting log file '{0}'.\n")
-                         .format(logFile))
-        
-        try:
-            f = open(logFile, "w", encoding="utf-8")
-            f.write(self.tr("Output:\n"))
-            f.write(outtxt)
-            errtxt = self.errors.toPlainText()
-            if errtxt:
-                f.write("\n")
-                f.write(self.tr("Errors:\n"))
-                f.write(errtxt)
-            f.close()
-        except (IOError, OSError) as err:
-            self.__logError(
-                self.tr("""The logfile '{0}' could not be written.\n"""
-                        """Reason: {1}\n""").format(logFile, str(err)))
-        self.__logOutput(self.tr("Done.\n"))
-    
-    def __writeScriptFile(self):
-        """
-        Private method to write a script file to the virtualenv directory.
-        """
-        if self.__pyvenv:
-            basename = "create_pyvenv"
-        else:
-            basename = "create_virtualenv"
-        if isWindowsPlatform():
-            script = os.path.join(self.__targetDir, basename + ".bat")
-            txt = self.__cmd
-        else:
-            script = os.path.join(self.__targetDir, basename + ".sh")
-            txt = "#!/usr/bin/env sh\n\n" + self.__cmd
-        
-        self.__logOutput(self.tr("\nWriting script file '{0}'.\n")
-                         .format(script))
-        
-        try:
-            f = open(script, "w", encoding="utf-8")
-            f.write(txt)
-            f.close()
-        except (IOError, OSError) as err:
-            self.__logError(
-                self.tr("""The script file '{0}' could not be written.\n"""
-                        """Reason: {1}\n""").format(script, str(err)))
-        self.__logOutput(self.tr("Done.\n"))
--- a/Plugins/UiExtensionPlugins/VirtualenvInterface/VirtualenvExecDialog.ui	Sat Jun 09 12:09:21 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>VirtualenvExecDialog</class>
- <widget class="QDialog" name="VirtualenvExecDialog">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>750</width>
-    <height>600</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Virtualenv Creation</string>
-  </property>
-  <property name="sizeGripEnabled">
-   <bool>true</bool>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout_3">
-   <item>
-    <widget class="QGroupBox" name="messagesGroup">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-       <horstretch>0</horstretch>
-       <verstretch>3</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="title">
-      <string>Messages</string>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout">
-      <item>
-       <widget class="QTextBrowser" name="contents">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-          <horstretch>0</horstretch>
-          <verstretch>3</verstretch>
-         </sizepolicy>
-        </property>
-        <property name="whatsThis">
-         <string>&lt;b&gt;virtualenv Execution&lt;/b&gt;
-&lt;p&gt;This shows the output of the virtualenv command.&lt;/p&gt;</string>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QGroupBox" name="errorGroup">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-       <horstretch>0</horstretch>
-       <verstretch>1</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="title">
-      <string>Errors</string>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout_2">
-      <item>
-       <widget class="QTextBrowser" name="errors">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-          <horstretch>0</horstretch>
-          <verstretch>1</verstretch>
-         </sizepolicy>
-        </property>
-        <property name="whatsThis">
-         <string>&lt;b&gt;virtualenv Execution&lt;/b&gt;
-&lt;p&gt;This shows the errors of the virtualenv command.&lt;/p&gt;</string>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Close</set>
-     </property>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <layoutdefault spacing="6" margin="11"/>
- <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
- <tabstops>
-  <tabstop>contents</tabstop>
-  <tabstop>errors</tabstop>
-  <tabstop>buttonBox</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
--- a/Plugins/UiExtensionPlugins/VirtualenvInterface/__init__.py	Sat Jun 09 12:09:21 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2014 - 2018 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Package implementing the virtualenv wizard dialogs and data.
-"""
--- a/UI/UserInterface.py	Sat Jun 09 12:09:21 2018 +0200
+++ b/UI/UserInterface.py	Sat Jun 09 17:19:37 2018 +0200
@@ -546,6 +546,9 @@
             QDesktopServices.setUrlHandler("http", self.handleUrl)
             QDesktopServices.setUrlHandler("https", self.handleUrl)
         
+        from VirtualEnv.VirtualenvManager import VirtualenvManager
+        self.virtualenvManager = VirtualenvManager(self)
+        
         # register all relevant objects
         splash.showMessage(self.tr("Registering Objects..."))
         e5App().registerObject("UserInterface", self)
@@ -568,6 +571,7 @@
         e5App().registerObject("Symbols", self.symbolsViewer)
         e5App().registerObject("Numbers", self.numbersViewer)
         e5App().registerObject("DocuViewer", self.codeDocumentationViewer)
+        e5App().registerObject("VirtualEnvManager", self.virtualenvManager)
         
         # list of web addresses serving the versions file
         self.__httpAlternatives = Preferences.getUI("VersionsUrls6")
@@ -2414,6 +2418,24 @@
         self.pluginRepoAct.triggered.connect(self.showPluginsAvailable)
         self.actions.append(self.pluginRepoAct)
         
+        self.virtualenvConfigAct = E5Action(
+            self.tr('Virtualenv Configurator'),
+            UI.PixmapCache.getIcon("virtualenv.png"),
+            self.tr('&Virtualenv Configurator...'),
+            0, 0, self,
+            'virtualenv_configurator')
+        self.virtualenvConfigAct.setStatusTip(self.tr(
+            'Virtualenv Configurator'))
+        self.virtualenvConfigAct.setWhatsThis(self.tr(
+            """<b>Virtualenv Configurator</b>"""
+            """<p>This opens a dialog for entering all the parameters"""
+            """ needed to create a Python virtual environment using"""
+            """ virtualenv or pyvenv.</p>"""
+        ))
+        self.virtualenvConfigAct.triggered.connect(
+            self.virtualenvManager.createVirtualEnv)
+        self.actions.append(self.virtualenvConfigAct)
+        
         # initialize viewmanager actions
         self.viewmanager.initActions()
         
@@ -2671,6 +2693,8 @@
         self.wizardsMenuAct.setEnabled(False)
         self.__menus["macros"] = self.viewmanager.initMacroMenu()
         self.__menus["extras"].addMenu(self.__menus["macros"])
+        self.__menus["extras"].addSeparator()
+        self.__menus["extras"].addAction(self.virtualenvConfigAct)
         self.toolGroupsMenu = QMenu(self.tr("Select Tool Group"), self)
         self.toolGroupsMenu.aboutToShow.connect(self.__showToolGroupsMenu)
         self.toolGroupsMenu.triggered.connect(self.__toolGroupSelected)
@@ -2870,6 +2894,8 @@
         toolstb.addAction(self.hexEditorAct)
         toolstb.addAction(self.iconEditorAct)
         toolstb.addAction(self.snapshotAct)
+        toolstb.addSeparator()
+        toolstb.addAction(self.virtualenvConfigAct)
         if self.webBrowserAct:
             toolstb.addSeparator()
             toolstb.addAction(self.webBrowserAct)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/VirtualEnv/VirtualenvConfigurationDialog.py	Sat Jun 09 17:19:37 2018 +0200
@@ -0,0 +1,355 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2014 - 2018 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog to enter the parameters for the
+virtual environment.
+"""
+
+from __future__ import unicode_literals
+try:
+    str = unicode
+except NameError:
+    pass
+
+import os
+import sys
+import re
+
+from PyQt5.QtCore import pyqtSlot, QProcess, QTimer
+from PyQt5.QtWidgets import QDialog, QDialogButtonBox
+
+from E5Gui.E5PathPicker import E5PathPickerModes
+
+from .Ui_VirtualenvConfigurationDialog import Ui_VirtualenvConfigurationDialog
+
+import Preferences
+import Utilities
+
+
+class VirtualenvConfigurationDialog(QDialog, Ui_VirtualenvConfigurationDialog):
+    """
+    Class implementing a dialog to enter the parameters for the
+    virtual environment.
+    """
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget
+        @type QWidget
+        """
+        super(VirtualenvConfigurationDialog, self).__init__(parent)
+        self.setupUi(self)
+        
+        self.targetDirectoryPicker.setMode(E5PathPickerModes.DirectoryMode)
+        self.targetDirectoryPicker.setWindowTitle(
+            self.tr("Virtualenv Target Directory"))
+        self.targetDirectoryPicker.setDefaultDirectory(Utilities.getHomeDir())
+        
+        self.extraSearchPathPicker.setMode(E5PathPickerModes.DirectoryMode)
+        self.extraSearchPathPicker.setWindowTitle(
+            self.tr("Extra Search Path for setuptools/pip"))
+        self.extraSearchPathPicker.setDefaultDirectory(Utilities.getHomeDir())
+        
+        self.pythonExecPicker.setMode(E5PathPickerModes.OpenFileMode)
+        self.pythonExecPicker.setWindowTitle(
+            self.tr("Python Interpreter"))
+        self.pythonExecPicker.setDefaultDirectory(
+            sys.executable.replace("w.exe", ".exe"))
+        
+        self.__versionRe = re.compile(r""".*?(\d+\.\d+\.\d+).*""")
+        
+        self.__virtualenvFound = False
+        self.__pyvenvFound = False
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
+        
+        self.__mandatoryStyleSheet = "QLineEdit {border: 2px solid;}"
+        self.targetDirectoryPicker.setStyleSheet(self.__mandatoryStyleSheet)
+        self.nameEdit.setStyleSheet(self.__mandatoryStyleSheet)
+        
+        self.__setVirtualenvVersion()
+        self.__setPyvenvVersion()
+        if self.__virtualenvFound:
+            self.virtualenvButton.setChecked(True)
+        elif self.__pyvenvFound:
+            self.pyvenvButton.setChecked(True)
+        
+        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(
+            (self.__virtualenvFound or self.__pyvenvFound) and
+            bool(self.targetDirectoryPicker.text() and
+            bool(self.nameEdit.text()))
+        )
+    
+    def __updateUi(self):
+        """
+        Private method to update the UI depending on the selected
+        virtual environment creator (virtualenv or pyvenv).
+        """
+        enable = self.virtualenvButton.isChecked()
+        self.extraSearchPathLabel.setEnabled(enable)
+        self.extraSearchPathPicker.setEnabled(enable)
+        self.promptPrefixLabel.setEnabled(enable)
+        self.promptPrefixEdit.setEnabled(enable)
+        self.verbosityLabel.setEnabled(enable)
+        self.verbositySpinBox.setEnabled(enable)
+        self.versionLabel.setEnabled(enable)
+        self.versionComboBox.setEnabled(enable)
+        self.unzipCheckBox.setEnabled(enable)
+        self.noSetuptoolsCheckBox.setEnabled(enable)
+        self.symlinkCheckBox.setEnabled(not enable)
+        self.upgradeCheckBox.setEnabled(not enable)
+    
+    @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()
+    
+    @pyqtSlot(str)
+    def on_pythonExecPicker_textChanged(self, txt):
+        """
+        Private slot to react to a change of the Python executable.
+        
+        @param txt contents of the picker's line edit
+        @type str
+        """
+        self.__setVirtualenvVersion()
+        self.__setPyvenvVersion()
+        self.__updateOK()
+    
+    @pyqtSlot(bool)
+    def on_virtualenvButton_toggled(self, checked):
+        """
+        Private slot to react to the selection of 'virtualenv'.
+        
+        @param checked state of the checkbox
+        @type bool
+        """
+        self.__updateUi()
+    
+    @pyqtSlot(bool)
+    def on_pyvenvButton_toggled(self, checked):
+        """
+        Private slot to react to the selection of 'pyvenv'.
+        
+        @param checked state of the checkbox
+        @type bool
+        """
+        self.__updateUi()
+    
+    def __setVirtualenvVersion(self):
+        """
+        Private method to determine the virtualenv version and set the
+        respective label.
+        """
+        calls = [
+            (sys.executable.replace("w.exe", ".exe"),
+             ["-m", "virtualenv", "--version"]),
+            ("virtualenv", ["--version"]),
+        ]
+        if self.pythonExecPicker.text():
+            calls.append((self.pythonExecPicker.text(),
+                          ["-m", "virtualenv", "--version"]))
+        
+        proc = QProcess()
+        for prog, args in calls:
+            proc.start(prog, args)
+            
+            if not proc.waitForStarted(5000):
+                # try next entry
+                continue
+            
+            if not proc.waitForFinished(5000):
+                # process hangs, kill it
+                QTimer.singleShot(2000, proc.kill)
+                proc.waitForFinished(3000)
+                version = self.tr('<virtualenv did not finish within 5s.>')
+                self.__virtualenvFound = False
+                break
+            
+            if proc.exitCode() != 0:
+                # returned with error code, try next
+                continue
+            
+            output = str(proc.readAllStandardOutput(),
+                         Preferences.getSystem("IOEncoding"),
+                         'replace').strip()
+            match = re.match(self.__versionRe, output)
+            if match:
+                self.__virtualenvFound = True
+                version = match.group(1)
+                break
+        else:
+            self.__virtualenvFound = False
+            version = self.tr('<No suitable virtualenv found.>')
+        
+        self.virtualenvButton.setText(self.tr(
+            "virtualenv Version: {0}".format(version)))
+        self.virtualenvButton.setEnabled(self.__virtualenvFound)
+        if not self.__virtualenvFound:
+            self.virtualenvButton.setChecked(False)
+    
+    def __setPyvenvVersion(self):
+        """
+        Private method to determine the pyvenv version and set the respective
+        label.
+        """
+        calls = []
+        if self.pythonExecPicker.text():
+            calls.append((self.pythonExecPicker.text(),
+                          ["-m", "venv"]))
+        calls.extend([
+            (sys.executable.replace("w.exe", ".exe"),
+             ["-m", "venv"]),
+            ("python3", ["-m", "venv"]),
+            ("python", ["-m", "venv"]),
+        ])
+        
+        proc = QProcess()
+        for prog, args in calls:
+            proc.start(prog, args)
+            
+            if not proc.waitForStarted(5000):
+                # try next entry
+                continue
+            
+            if not proc.waitForFinished(5000):
+                # process hangs, kill it
+                QTimer.singleShot(2000, proc.kill)
+                proc.waitForFinished(3000)
+                version = self.tr('<pyvenv did not finish within 5s.>')
+                self.__pyvenvFound = False
+                break
+            
+            if proc.exitCode() not in [0, 2]:
+                # returned with error code, try next
+                continue
+            
+            proc.start(prog, ["--version"])
+            proc.waitForFinished(5000)
+            output = str(proc.readAllStandardOutput(),
+                         Preferences.getSystem("IOEncoding"),
+                         'replace').strip()
+            match = re.match(self.__versionRe, output)
+            if match:
+                self.__pyvenvFound = True
+                version = match.group(1)
+                break
+        else:
+            self.__pyvenvFound = False
+            version = self.tr('<No suitable pyvenv found.>')
+        
+        self.pyvenvButton.setText(self.tr(
+            "pyvenv Version: {0}".format(version)))
+        self.pyvenvButton.setEnabled(self.__pyvenvFound)
+        if not self.__pyvenvFound:
+            self.pyvenvButton.setChecked(False)
+    
+    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 __generateArguments(self):
+        """
+        Private method to generate the process arguments.
+        
+        @return process arguments
+        @rtype list of str
+        """
+        args = []
+        if self.virtualenvButton.isChecked():
+            if self.extraSearchPathPicker.text():
+                args.append("--extra-search-dir={0}".format(
+                    Utilities.toNativeSeparators(
+                        self.extraSearchPathPicker.text())))
+            if self.promptPrefixEdit.text():
+                args.append("--prompt={0}".format(
+                    self.promptPrefixEdit.text().replace(" ", "_")))
+            if self.pythonExecPicker.text():
+                args.append("--python={0}".format(
+                    Utilities.toNativeSeparators(
+                        self.pythonExecPicker.text())))
+            elif self.versionComboBox.currentText():
+                args.append("--python=python{0}".format(
+                    self.versionComboBox.currentText()))
+            if self.verbositySpinBox.value() == 1:
+                args.append("--verbose")
+            elif self.verbositySpinBox.value() == -1:
+                args.append("--quiet")
+            if self.clearCheckBox.isChecked():
+                args.append("--clear")
+            if self.systemCheckBox.isChecked():
+                args.append("--system-site-packages")
+            if self.unzipCheckBox.isChecked():
+                args.append("--unzip-setuptools")
+            if self.noSetuptoolsCheckBox.isChecked():
+                args.append("--no-setuptools")
+            if self.noPipCcheckBox.isChecked():
+                args.append("--no-pip")
+            if self.copyCheckBox.isChecked():
+                args.append("--always-copy")
+        elif self.pyvenvButton.isChecked():
+            if self.clearCheckBox.isChecked():
+                args.append("--clear")
+            if self.systemCheckBox.isChecked():
+                args.append("--system-site-packages")
+            if self.noPipCcheckBox.isChecked():
+                args.append("--without-pip")
+            if self.copyCheckBox.isChecked():
+                args.append("--copies")
+            if self.symlinkCheckBox.isChecked():
+                args.append("--symlinks")
+            if self.upgradeCheckBox.isChecked():
+                args.append("--upgrade")
+        targetDirectory = self.__generateTargetDir()
+        args.append(targetDirectory)
+        return args
+
+    def getData(self):
+        """
+        Public method to retrieve the dialog data.
+        
+        @return tuple containing a flag indicating the pyvenv selection, the
+            process arguments, a name for the virtual environment, a flag
+            indicating to open the target directory after creation, a flag
+            indicating to write a log file, a flag indicating to write a
+            script, the name of the target directory and the name of the
+            Python interpreter to use
+        @rtype tuple of (bool, list of str, str, bool, bool, bool, str, str)
+        """
+        args = self.__generateArguments()
+        targetDirectory = self.__generateTargetDir()
+        return (
+            self.pyvenvButton.isChecked(),
+            args,
+            self.nameEdit.text(),
+            self.openCheckBox.isChecked(),
+            self.logCheckBox.isChecked(),
+            self.scriptCheckBox.isChecked(),
+            targetDirectory,
+            Utilities.toNativeSeparators(self.pythonExecPicker.text()),
+        )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/VirtualEnv/VirtualenvConfigurationDialog.ui	Sat Jun 09 17:19:37 2018 +0200
@@ -0,0 +1,506 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>VirtualenvConfigurationDialog</class>
+ <widget class="QDialog" name="VirtualenvConfigurationDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>700</width>
+    <height>592</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Virtualenv Configuration</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QGroupBox" name="groupBox_3">
+     <property name="title">
+      <string>Environment Creator</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_3">
+      <item row="0" column="0">
+       <widget class="QRadioButton" name="virtualenvButton">
+        <property name="font">
+         <font>
+          <weight>75</weight>
+          <bold>true</bold>
+         </font>
+        </property>
+        <property name="toolTip">
+         <string>Select to use 'virtualenv'</string>
+        </property>
+        <property name="text">
+         <string notr="true">0.0</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <spacer name="horizontalSpacer_2">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item row="1" column="0">
+       <widget class="QRadioButton" name="pyvenvButton">
+        <property name="font">
+         <font>
+          <weight>75</weight>
+          <bold>true</bold>
+         </font>
+        </property>
+        <property name="toolTip">
+         <string>Select to use 'pyvenv'</string>
+        </property>
+        <property name="text">
+         <string notr="true">0.0</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Logical Name:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="E5ClearableLineEdit" name="nameEdit">
+       <property name="toolTip">
+        <string>Enter a name for the virtual environment</string>
+       </property>
+       <property name="placeholderText">
+        <string>Name for the virtual environment</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
+      <string>Paths</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="0" column="0">
+       <widget class="QLabel" name="label">
+        <property name="text">
+         <string>Target Directory:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" 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="1" column="0">
+       <widget class="QLabel" name="extraSearchPathLabel">
+        <property name="text">
+         <string>Extra Search Path:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="E5PathPicker" name="extraSearchPathPicker" 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 extra search path to look for setuptools/pip</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0">
+       <widget class="QLabel" name="promptPrefixLabel">
+        <property name="text">
+         <string>Prompt Prefix:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="E5ClearableLineEdit" name="promptPrefixEdit">
+        <property name="toolTip">
+         <string>Enter the prompt prefix for the virtual environment</string>
+        </property>
+        <property name="placeholderText">
+         <string>Prompt prefix for the virtual environment</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="0">
+       <widget class="QLabel" name="label_5">
+        <property name="text">
+         <string>Python Executable:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" 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>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox_2">
+     <property name="title">
+      <string>Options</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_2">
+      <item row="0" column="0">
+       <layout class="QHBoxLayout" name="horizontalLayout_3">
+        <item>
+         <widget class="QLabel" name="verbosityLabel">
+          <property name="text">
+           <string>Verbosity:</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QSpinBox" name="verbositySpinBox">
+          <property name="toolTip">
+           <string>Select the verbosity (-1: quiet, 0: normal, 1: verbose)</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+          <property name="minimum">
+           <number>-1</number>
+          </property>
+          <property name="maximum">
+           <number>1</number>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_3">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+      <item row="0" column="1">
+       <layout class="QHBoxLayout" name="horizontalLayout">
+        <item>
+         <widget class="QLabel" name="versionLabel">
+          <property name="text">
+           <string>Python Version:</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QComboBox" name="versionComboBox">
+          <property name="toolTip">
+           <string>Select the Python version (empty for current)</string>
+          </property>
+          <item>
+           <property name="text">
+            <string notr="true"/>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string notr="true">2.6</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string notr="true">2.7</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string notr="true">3.4</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string notr="true">3.5</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string notr="true">3.6</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>3.7</string>
+           </property>
+          </item>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+      <item row="1" column="0">
+       <widget class="QCheckBox" name="systemCheckBox">
+        <property name="toolTip">
+         <string>Select to give the virtualenv access to the global site-packages</string>
+        </property>
+        <property name="text">
+         <string>System-wide Python Packages</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QCheckBox" name="unzipCheckBox">
+        <property name="toolTip">
+         <string>Select to unzip setuptools when installing it</string>
+        </property>
+        <property name="text">
+         <string>Unzip Setuptool to virtualenv</string>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0">
+       <widget class="QCheckBox" name="noSetuptoolsCheckBox">
+        <property name="toolTip">
+         <string>Select to not install setuptools (or pip) in the new virtualenv</string>
+        </property>
+        <property name="text">
+         <string>Don't install 'setuptool' (or pip) in the virtualenv</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QCheckBox" name="noPipCcheckBox">
+        <property name="toolTip">
+         <string>Select to not install pip in the new virtualenv</string>
+        </property>
+        <property name="text">
+         <string>Don't install 'pip' in the virtualenv</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="0">
+       <widget class="QCheckBox" name="clearCheckBox">
+        <property name="toolTip">
+         <string>Select to clear the target first</string>
+        </property>
+        <property name="text">
+         <string>Clear out the target directory</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="1">
+       <widget class="QCheckBox" name="copyCheckBox">
+        <property name="toolTip">
+         <string>Select to always copy files rather than symlinking</string>
+        </property>
+        <property name="text">
+         <string>Always copy files</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="0">
+       <widget class="QCheckBox" name="symlinkCheckBox">
+        <property name="toolTip">
+         <string>Select to use symlinks instead of copies</string>
+        </property>
+        <property name="text">
+         <string>Use Symbolic Links</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="1">
+       <widget class="QCheckBox" name="upgradeCheckBox">
+        <property name="toolTip">
+         <string>Select to upgrade a virtual environment</string>
+        </property>
+        <property name="text">
+         <string>Upgrade</string>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="0">
+       <widget class="QCheckBox" name="logCheckBox">
+        <property name="toolTip">
+         <string>Select to generate a log file in the target directory</string>
+        </property>
+        <property name="text">
+         <string>Save a log file in the target directory after creation</string>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="1">
+       <widget class="QCheckBox" name="scriptCheckBox">
+        <property name="toolTip">
+         <string>Select to write a shell script/batch file to regenerate the virtualenv</string>
+        </property>
+        <property name="text">
+         <string>Save virtualenv generation script</string>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="6" column="0">
+       <widget class="QCheckBox" name="openCheckBox">
+        <property name="toolTip">
+         <string>Open the newly created virtualenv in a file manager window</string>
+        </property>
+        <property name="text">
+         <string>Open target directory after creation</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </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>
+ <tabstops>
+  <tabstop>virtualenvButton</tabstop>
+  <tabstop>pyvenvButton</tabstop>
+  <tabstop>nameEdit</tabstop>
+  <tabstop>targetDirectoryPicker</tabstop>
+  <tabstop>extraSearchPathPicker</tabstop>
+  <tabstop>promptPrefixEdit</tabstop>
+  <tabstop>pythonExecPicker</tabstop>
+  <tabstop>verbositySpinBox</tabstop>
+  <tabstop>versionComboBox</tabstop>
+  <tabstop>systemCheckBox</tabstop>
+  <tabstop>unzipCheckBox</tabstop>
+  <tabstop>noSetuptoolsCheckBox</tabstop>
+  <tabstop>noPipCcheckBox</tabstop>
+  <tabstop>clearCheckBox</tabstop>
+  <tabstop>copyCheckBox</tabstop>
+  <tabstop>symlinkCheckBox</tabstop>
+  <tabstop>upgradeCheckBox</tabstop>
+  <tabstop>logCheckBox</tabstop>
+  <tabstop>scriptCheckBox</tabstop>
+  <tabstop>openCheckBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>VirtualenvConfigurationDialog</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>VirtualenvConfigurationDialog</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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/VirtualEnv/VirtualenvExecDialog.py	Sat Jun 09 17:19:37 2018 +0200
@@ -0,0 +1,322 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2014 - 2018 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the virtualenv execution dialog.
+"""
+
+from __future__ import unicode_literals
+try:
+    str = unicode
+except NameError:
+    pass
+
+import sys
+import os
+
+from PyQt5.QtCore import QProcess, QTimer, QUrl
+from PyQt5.QtGui import QDesktopServices
+from PyQt5.QtWidgets import QDialog, QDialogButtonBox
+
+from .Ui_VirtualenvExecDialog import Ui_VirtualenvExecDialog
+
+import Preferences
+from Globals import isWindowsPlatform
+
+
+class VirtualenvExecDialog(QDialog, Ui_VirtualenvExecDialog):
+    """
+    Class implementing the virtualenv execution dialog.
+    
+    This class starts a QProcess and displays a dialog that
+    shows the output of the virtualenv or pyvenv process.
+    """
+    def __init__(self, pyvenv, targetDir, venvName, openTarget, createLog,
+                 createScript, interpreter, venvManager, parent=None):
+        """
+        Constructor
+        
+        @param pyvenv flag indicating the use of 'pyvenv'
+        @type bool
+        @param targetDir name of the virtualenv directory
+        @type str
+        @param venvName logical name for the virtual environment
+        @type str
+        @param openTarget flag indicating to open the virtualenv directory
+            in a file manager
+        @type bool
+        @param createLog flag indicating to create a log file of the
+            creation process
+        @type bool
+        @param createScript flag indicating to create a script to recreate
+            the virtual environment
+        @type bool
+        @param interpreter name of the python interpreter to use
+        @type str
+        @param venvManager reference to the virtual environment manager
+        @type VirtualenvManager
+        @param parent reference to the parent widget
+        @type QWidget
+        """
+        super(VirtualenvExecDialog, self).__init__(parent)
+        self.setupUi(self)
+        
+        self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
+        self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)
+        
+        self.__pyvenv = pyvenv
+        self.__targetDir = targetDir
+        self.__openTarget = openTarget
+        self.__createLog = createLog
+        self.__createScript = createScript
+        self.__venvName = venvName
+        self.__venvManager = venvManager
+        
+        self.__process = None
+        self.__cmd = ""
+        
+        if pyvenv:
+            self.__calls = []
+            if interpreter:
+                self.__calls.append((interpreter, ["-m", "venv"]))
+            self.__calls.extend([
+                (sys.executable.replace("w.exe", ".exe"),
+                 ["-m", "venv"]),
+                ("python3", ["-m", "venv"]),
+                ("python", ["-m", "venv"]),
+            ])
+        else:
+            self.__calls = [
+                (sys.executable.replace("w.exe", ".exe"),
+                 ["-m", "virtualenv"]),
+                ("virtualenv", []),
+            ]
+        self.__callIndex = 0
+        self.__callArgs = []
+    
+    def start(self, arguments):
+        """
+        Public slot to start the virtualenv command.
+        
+        @param arguments commandline arguments for virtualenv/pyvenv program
+            (list of strings)
+        """
+        if self.__callIndex == 0:
+            # first attempt, add a given python interpreter and do
+            # some other setup
+            self.errorGroup.hide()
+            self.contents.clear()
+            self.errors.clear()
+            
+            self.__process = QProcess()
+            self.__process.readyReadStandardOutput.connect(self.__readStdout)
+            self.__process.readyReadStandardError.connect(self.__readStderr)
+            self.__process.finished.connect(self.__finish)
+            
+            if not self.__pyvenv:
+                for arg in arguments:
+                    if arg.startswith("--python="):
+                        prog = arg.replace("--python=", "")
+                        self.__calls.insert(
+                            0, (prog, ["-m", "virtualenv"]))
+                        break
+            self.__callArgs = arguments
+        
+        prog, args = self.__calls[self.__callIndex]
+        args.extend(self.__callArgs)
+        self.__cmd = "{0} {1}".format(prog, " ".join(args))
+        self.__logOutput(self.tr("Executing: {0}\n").format(
+            self.__cmd))
+        self.__process.start(prog, args)
+        procStarted = self.__process.waitForStarted(5000)
+        if not procStarted:
+            self.__logOutput(self.tr("Failed\n\n"))
+            self.__nextAttempt()
+    
+    def on_buttonBox_clicked(self, button):
+        """
+        Private slot called by a button of the button box clicked.
+        
+        @param button button that was clicked (QAbstractButton)
+        """
+        if button == self.buttonBox.button(QDialogButtonBox.Close):
+            self.accept()
+        elif button == self.buttonBox.button(QDialogButtonBox.Cancel):
+            self.__finish()
+    
+    def __finish(self, exitCode, exitStatus, giveUp=False):
+        """
+        Private slot called when the process finished.
+        
+        It is called when the process finished or
+        the user pressed the button.
+        
+        @param exitCode exit code of the process (integer)
+        @param exitStatus exit status of the process (QProcess.ExitStatus)
+        @keyparam giveUp flag indicating to not start another attempt (boolean)
+        """
+        if self.__process is not None and \
+           self.__process.state() != QProcess.NotRunning:
+            self.__process.terminate()
+            QTimer.singleShot(2000, self.__process.kill)
+            self.__process.waitForFinished(3000)
+        
+        self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
+        self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
+        self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
+        
+        if not giveUp:
+            if exitCode != 0:
+                self.__logOutput(self.tr("Failed\n\n"))
+                if len(self.errors.toPlainText().splitlines()) == 1:
+                    self.errors.clear()
+                    self.errorGroup.hide()
+                    self.__nextAttempt()
+                    return
+            
+            self.__process = None
+            
+            if self.__pyvenv:
+                self.__logOutput(self.tr('\npyvenv finished.\n'))
+            else:
+                self.__logOutput(self.tr('\nvirtualenv finished.\n'))
+            
+            if os.path.exists(self.__targetDir):
+                if self.__createScript:
+                    self.__writeScriptFile()
+                
+                if self.__createLog:
+                    self.__writeLogFile()
+                
+                if self.__openTarget:
+                    QDesktopServices.openUrl(QUrl.fromLocalFile(
+                        self.__targetDir))
+                
+                self.__venvManager.addVirtualEnv(self.__venvName,
+                                                 self.__targetDir)
+    
+    def __nextAttempt(self):
+        """
+        Private method to start another attempt.
+        """
+        self.__callIndex += 1
+        if self.__callIndex < len(self.__calls):
+            self.start(self.__callArgs)
+        else:
+            if self.__pyvenv:
+                self.__logError(
+                    self.tr('No suitable pyvenv program could be'
+                            ' started.\n'))
+            else:
+                self.__logError(
+                    self.tr('No suitable virtualenv program could be'
+                            ' started.\n'))
+            self.__cmd = ""
+            self.__finish(0, 0, giveUp=True)
+    
+    def __readStdout(self):
+        """
+        Private slot to handle the readyReadStandardOutput signal.
+        
+        It reads the output of the process, formats it and inserts it into
+        the contents pane.
+        """
+        self.__process.setReadChannel(QProcess.StandardOutput)
+        
+        while self.__process.canReadLine():
+            s = str(self.__process.readLine(),
+                    Preferences.getSystem("IOEncoding"),
+                    'replace')
+            self.__logOutput(s)
+    
+    def __readStderr(self):
+        """
+        Private slot to handle the readyReadStandardError signal.
+        
+        It reads the error output of the process and inserts it into the
+        error pane.
+        """
+        self.__process.setReadChannel(QProcess.StandardError)
+        
+        while self.__process.canReadLine():
+            s = str(self.__process.readLine(),
+                    Preferences.getSystem("IOEncoding"),
+                    'replace')
+            self.__logError(s)
+    
+    def __logOutput(self, s):
+        """
+        Private method to log some output.
+        
+        @param s output sstring to log (string)
+        """
+        self.contents.insertPlainText(s)
+        self.contents.ensureCursorVisible()
+    
+    def __logError(self, s):
+        """
+        Private method to log an error.
+        
+        @param s error string to log (string)
+        """
+        self.errorGroup.show()
+        self.errors.insertPlainText(s)
+        self.errors.ensureCursorVisible()
+    
+    def __writeLogFile(self):
+        """
+        Private method to write a log file to the virtualenv directory.
+        """
+        outtxt = self.contents.toPlainText()
+        if self.__pyvenv:
+            logFile = os.path.join(self.__targetDir, "pyvenv.log")
+        else:
+            logFile = os.path.join(self.__targetDir, "virtualenv.log")
+        self.__logOutput(self.tr("\nWriting log file '{0}'.\n")
+                         .format(logFile))
+        
+        try:
+            f = open(logFile, "w", encoding="utf-8")
+            f.write(self.tr("Output:\n"))
+            f.write(outtxt)
+            errtxt = self.errors.toPlainText()
+            if errtxt:
+                f.write("\n")
+                f.write(self.tr("Errors:\n"))
+                f.write(errtxt)
+            f.close()
+        except (IOError, OSError) as err:
+            self.__logError(
+                self.tr("""The logfile '{0}' could not be written.\n"""
+                        """Reason: {1}\n""").format(logFile, str(err)))
+        self.__logOutput(self.tr("Done.\n"))
+    
+    def __writeScriptFile(self):
+        """
+        Private method to write a script file to the virtualenv directory.
+        """
+        if self.__pyvenv:
+            basename = "create_pyvenv"
+        else:
+            basename = "create_virtualenv"
+        if isWindowsPlatform():
+            script = os.path.join(self.__targetDir, basename + ".bat")
+            txt = self.__cmd
+        else:
+            script = os.path.join(self.__targetDir, basename + ".sh")
+            txt = "#!/usr/bin/env sh\n\n" + self.__cmd
+        
+        self.__logOutput(self.tr("\nWriting script file '{0}'.\n")
+                         .format(script))
+        
+        try:
+            f = open(script, "w", encoding="utf-8")
+            f.write(txt)
+            f.close()
+        except (IOError, OSError) as err:
+            self.__logError(
+                self.tr("""The script file '{0}' could not be written.\n"""
+                        """Reason: {1}\n""").format(script, str(err)))
+        self.__logOutput(self.tr("Done.\n"))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/VirtualEnv/VirtualenvExecDialog.ui	Sat Jun 09 17:19:37 2018 +0200
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>VirtualenvExecDialog</class>
+ <widget class="QDialog" name="VirtualenvExecDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>750</width>
+    <height>600</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Virtualenv Creation</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_3">
+   <item>
+    <widget class="QGroupBox" name="messagesGroup">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+       <horstretch>0</horstretch>
+       <verstretch>3</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="title">
+      <string>Messages</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout">
+      <item>
+       <widget class="QTextBrowser" name="contents">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+          <horstretch>0</horstretch>
+          <verstretch>3</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="whatsThis">
+         <string>&lt;b&gt;virtualenv Execution&lt;/b&gt;
+&lt;p&gt;This shows the output of the virtualenv command.&lt;/p&gt;</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="errorGroup">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+       <horstretch>0</horstretch>
+       <verstretch>1</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="title">
+      <string>Errors</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_2">
+      <item>
+       <widget class="QTextBrowser" name="errors">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+          <horstretch>0</horstretch>
+          <verstretch>1</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="whatsThis">
+         <string>&lt;b&gt;virtualenv Execution&lt;/b&gt;
+&lt;p&gt;This shows the errors of the virtualenv command.&lt;/p&gt;</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Close</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
+ <tabstops>
+  <tabstop>contents</tabstop>
+  <tabstop>errors</tabstop>
+  <tabstop>buttonBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/VirtualEnv/VirtualenvInterpreterSelectionDialog.py	Sat Jun 09 17:19:37 2018 +0200
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2018 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog to enter the interpreter for a virtual
+environment.
+"""
+
+from __future__ import unicode_literals
+
+import os
+
+from PyQt5.QtCore import pyqtSlot
+from PyQt5.QtWidgets import QDialog, QDialogButtonBox
+
+from E5Gui.E5PathPicker import E5PathPickerModes
+
+from .Ui_VirtualenvInterpreterSelectionDialog import \
+    Ui_VirtualenvInterpreterSelectionDialog
+
+
+class VirtualenvInterpreterSelectionDialog(
+        QDialog, Ui_VirtualenvInterpreterSelectionDialog):
+    """
+    Class implementing a dialog to enter the interpreter for a virtual
+    environment.
+    """
+    def __init__(self, venvName, venvDirectory, parent=None):
+        """
+        Constructor
+        
+        @param venvName name for the virtual environment
+        @type str
+        @param venvDirectory directory of the virtual environment
+        @type str
+        @param parent reference to the parent widget
+        @type QWidget
+        """
+        super(VirtualenvInterpreterSelectionDialog, self).__init__(parent)
+        self.setupUi(self)
+        
+        self.pythonExecPicker.setMode(E5PathPickerModes.OpenFileMode)
+        self.pythonExecPicker.setWindowTitle(
+            self.tr("Python Interpreter"))
+        
+        self.nameEdit.setText(venvName)
+        self.pythonExecPicker.setText(venvDirectory)
+    
+    def __updateOK(self):
+        """
+        Private method to update the enabled status of the OK button.
+        """
+        interpreterPath = self.pythonExecPicker.text()
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(
+            bool(interpreterPath) and
+            os.path.isfile(interpreterPath) and
+            os.access(interpreterPath, os.X_OK)
+        )
+    
+    @pyqtSlot(str)
+    def on_pythonExecPicker_textChanged(self, txt):
+        """
+        Private slot to handle changes of the entered Python interpreter path.
+        
+        @param txt entered Python interpreter path
+        @type str
+        """
+        self.__updateOK()
+    
+    def getData(self):
+        """
+        Public method to get the entered data.
+        
+        @return path of the selected Python interpreter
+        @rtype str
+        """
+        return self.pythonExecPicker.text()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/VirtualEnv/VirtualenvInterpreterSelectionDialog.ui	Sat Jun 09 17:19:37 2018 +0200
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>VirtualenvInterpreterSelectionDialog</class>
+ <widget class="QDialog" name="VirtualenvInterpreterSelectionDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>550</width>
+    <height>118</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Add Virtual Environment</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Name:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="nameEdit">
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Enter interpreter for virtual environment:</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <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>
+   <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>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>VirtualenvInterpreterSelectionDialog</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>VirtualenvInterpreterSelectionDialog</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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/VirtualEnv/VirtualenvManager.py	Sat Jun 09 17:19:37 2018 +0200
@@ -0,0 +1,138 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2018 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a class to manage Python virtual environments.
+"""
+
+from __future__ import unicode_literals
+
+import os
+import sys
+import shutil
+
+from PyQt5.QtCore import pyqtSlot, QObject
+from PyQt5.QtWidgets import QDialog
+
+from E5Gui import E5MessageBox
+
+import Preferences
+
+
+class VirtualenvManager(QObject):
+    """
+    Class implementing an object to manage Python virtual environments.
+    """
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent object
+        @type QWidget
+        """
+        super(VirtualenvManager, self).__init__(parent)
+        
+        self.__ui = parent
+        
+        self.__virtualEnvironments = {}
+        self.__virtualEnvironmentInterpreters = {}
+        environments = Preferences.toDict(Preferences.Prefs.settings.value(
+            "PyVenv/Environments", {}))
+        interpreters = Preferences.toDict(Preferences.Prefs.settings.value(
+            "PyVenv/Interpreters", {}))
+        for venvName, venvExe in interpreters.items():
+            # remove all environments, that don't exist anymore
+            if os.access(venvExe, os.X_OK):
+                self.__virtualEnvironmentInterpreters[venvName] = venvExe
+                self.__virtualEnvironments[venvName] = environments[venvName]
+        
+        defaultPy = sys.executable.replace("w.exe", ".exe")
+        if defaultPy not in self.__virtualEnvironmentInterpreters.values():
+            self.__virtualEnvironmentInterpreters["<default>"] = defaultPy
+            self.__virtualEnvironments["<default>"] = ""
+        
+        self.__updateSettings()
+    
+    def __updateSettings(self):
+        """
+        Private slot to save the virtual environments.
+        """
+        Preferences.Prefs.settings.setValue(
+            "PyVenv/Environments", self.__virtualEnvironments)
+        Preferences.Prefs.settings.setValue(
+            "PyVenv/Interpreters", self.__virtualEnvironmentInterpreters)
+    
+    @pyqtSlot()
+    def createVirtualEnv(self):
+        """
+        Public slot to create a new virtual environment.
+        """
+        from .VirtualenvConfigurationDialog import \
+            VirtualenvConfigurationDialog
+        
+        dlg = VirtualenvConfigurationDialog()
+        if dlg.exec_() == QDialog.Accepted:
+            (pyvenv, args, name, openTarget, createLog, createScript,
+             targetDir, interpreter) = dlg.getData()
+            
+            # now do the call
+            from .VirtualenvExecDialog import VirtualenvExecDialog
+            dia = VirtualenvExecDialog(pyvenv, targetDir, name, openTarget,
+                                       createLog, createScript, interpreter,
+                                       self)
+            dia.show()
+            dia.start(args)
+            dia.exec_()
+    
+    def addVirtualEnv(self, venvName, venvDirectory):
+        """
+        Public method to add a virtual environment.
+        
+        @param venvName logical name for the virtual environment
+        @type str
+        @param venvDirectory directory of the virtual envoronment
+        @type str
+        """
+        if venvName in self.__virtualEnvironments:
+            ok = E5MessageBox.yesNo(
+                None,
+                self.tr("Add Virtual Environment"),
+                self.tr("""A virtual environment named <b>{0}</b> exists"""
+                        """ already. Shall it be replaced?""")
+                .format(venvName),
+                icon=E5MessageBox.Warning)
+            if not ok:
+                return
+        
+        from .VirtualenvInterpreterSelectionDialog import \
+            VirtualenvInterpreterSelectionDialog
+        dlg = VirtualenvInterpreterSelectionDialog(venvName, venvDirectory)
+        if dlg.exec_() == QDialog.Accepted:
+            venvExe = dlg.getData()
+            self.__virtualEnvironmentInterpreters[venvName] = venvExe
+            self.__virtualEnvironments[venvName] = venvDirectory
+            
+            self.__updateSettings()
+    
+    def deleteVirtualEnv(self, venvName):
+        """
+        Public method to delete a virtual environment from disk.
+        
+        @param venvName logical name for the virtual environment
+        @type str
+        """
+        if venvName in self.__virtualEnvironments:
+            ok = E5MessageBox.yesNo(
+                None,
+                self.tr("Delete Virtual Environment"),
+                self.tr("""Do you really want to delete the virtual"""
+                        """ environment <b>{0}</b>?<br>Path: {1}""")
+                .format(venvName, self.__virtualEnvironments[venvName]))
+            if ok:
+                shutil.rmtree(self.__virtualEnvironments[venvName], True)
+                del self.__virtualEnvironments[venvName]
+                del self.__virtualEnvironmentInterpreters[venvName]
+                
+                self.__updateSettings()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/VirtualEnv/__init__.py	Sat Jun 09 17:19:37 2018 +0200
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2018 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Package implementing virtualenv related functionality.
+"""
--- a/eric6.e4p	Sat Jun 09 12:09:21 2018 +0200
+++ b/eric6.e4p	Sat Jun 09 17:19:37 2018 +0200
@@ -515,7 +515,6 @@
     <Source>Plugins/PluginVcsMercurial.py</Source>
     <Source>Plugins/PluginVcsPySvn.py</Source>
     <Source>Plugins/PluginVcsSubversion.py</Source>
-    <Source>Plugins/PluginVirtualenvInterface.py</Source>
     <Source>Plugins/PluginVmListspace.py</Source>
     <Source>Plugins/PluginVmTabview.py</Source>
     <Source>Plugins/PluginWizardDotDesktop.py</Source>
@@ -559,9 +558,6 @@
     <Source>Plugins/UiExtensionPlugins/Translator/TranslatorRequest.py</Source>
     <Source>Plugins/UiExtensionPlugins/Translator/TranslatorWidget.py</Source>
     <Source>Plugins/UiExtensionPlugins/Translator/__init__.py</Source>
-    <Source>Plugins/UiExtensionPlugins/VirtualenvInterface/VirtualenvConfigurationDialog.py</Source>
-    <Source>Plugins/UiExtensionPlugins/VirtualenvInterface/VirtualenvExecDialog.py</Source>
-    <Source>Plugins/UiExtensionPlugins/VirtualenvInterface/__init__.py</Source>
     <Source>Plugins/UiExtensionPlugins/__init__.py</Source>
     <Source>Plugins/VcsPlugins/__init__.py</Source>
     <Source>Plugins/VcsPlugins/vcsGit/Config.py</Source>
@@ -1400,6 +1396,11 @@
     <Source>ViewManager/BookmarkedFilesDialog.py</Source>
     <Source>ViewManager/ViewManager.py</Source>
     <Source>ViewManager/__init__.py</Source>
+    <Source>VirtualEnv/VirtualenvConfigurationDialog.py</Source>
+    <Source>VirtualEnv/VirtualenvExecDialog.py</Source>
+    <Source>VirtualEnv/VirtualenvInterpreterSelectionDialog.py</Source>
+    <Source>VirtualEnv/VirtualenvManager.py</Source>
+    <Source>VirtualEnv/__init__.py</Source>
     <Source>WebBrowser/AdBlock/AdBlockDialog.py</Source>
     <Source>WebBrowser/AdBlock/AdBlockExceptionsDialog.py</Source>
     <Source>WebBrowser/AdBlock/AdBlockIcon.py</Source>
@@ -1810,8 +1811,6 @@
     <Form>Plugins/UiExtensionPlugins/PipInterface/PipSelectionDialog.ui</Form>
     <Form>Plugins/UiExtensionPlugins/Translator/ConfigurationPage/TranslatorPage.ui</Form>
     <Form>Plugins/UiExtensionPlugins/Translator/TranslatorWidget.ui</Form>
-    <Form>Plugins/UiExtensionPlugins/VirtualenvInterface/VirtualenvConfigurationDialog.ui</Form>
-    <Form>Plugins/UiExtensionPlugins/VirtualenvInterface/VirtualenvExecDialog.ui</Form>
     <Form>Plugins/VcsPlugins/vcsGit/ConfigurationPage/GitPage.ui</Form>
     <Form>Plugins/VcsPlugins/vcsGit/GitAddRemoteDialog.ui</Form>
     <Form>Plugins/VcsPlugins/vcsGit/GitApplyBundleDataDialog.ui</Form>
@@ -2110,6 +2109,9 @@
     <Form>VCS/CommandOptionsDialog.ui</Form>
     <Form>VCS/RepositoryInfoDialog.ui</Form>
     <Form>ViewManager/BookmarkedFilesDialog.ui</Form>
+    <Form>VirtualEnv/VirtualenvConfigurationDialog.ui</Form>
+    <Form>VirtualEnv/VirtualenvExecDialog.ui</Form>
+    <Form>VirtualEnv/VirtualenvInterpreterSelectionDialog.ui</Form>
     <Form>WebBrowser/AdBlock/AdBlockDialog.ui</Form>
     <Form>WebBrowser/AdBlock/AdBlockExceptionsDialog.ui</Form>
     <Form>WebBrowser/Bookmarks/AddBookmarkDialog.ui</Form>
Binary file icons/default/virtualenv.png has changed

eric ide

mercurial