Mon, 18 Feb 2019 19:17:04 +0100
Merged with default branch.
eric6.e4p | file | annotate | diff | comparison | revisions |
--- a/Documentation/Source/eric6.Plugins.UiExtensionPlugins.PipInterface.ConfigurationPage.PipPage.html Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric6.Plugins.UiExtensionPlugins.PipInterface.ConfigurationPage.PipPage</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.PipInterface.ConfigurationPage.PipPage</h1> -<p> -Package implementing the pip configuration page. -</p> -<h3>Global Attributes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Classes</h3> -<table> -<tr> -<td><a href="#PipPage">PipPage</a></td> -<td>Class implementing the pip configuration page.</td> -</tr> -</table> -<h3>Functions</h3> -<table> -<tr><td>None</td></tr> -</table> -<hr /><hr /> -<a NAME="PipPage" ID="PipPage"></a> -<h2>PipPage</h2> -<p> - Class implementing the pip configuration page. -</p> -<h3>Derived from</h3> -ConfigurationPageBase, Ui_PipPage -<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="#PipPage.__init__">PipPage</a></td> -<td>Constructor</td> -</tr><tr> -<td><a href="#PipPage.save">save</a></td> -<td>Public slot to save the pip configuration.</td> -</tr> -</table> -<h3>Static Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<a NAME="PipPage.__init__" ID="PipPage.__init__"></a> -<h4>PipPage (Constructor)</h4> -<b>PipPage</b>(<i>plugin</i>) -<p> - Constructor -</p><dl> -<dt><i>plugin</i> (PipInterfacePlugin)</dt> -<dd> -reference to the plugin object -</dd> -</dl><a NAME="PipPage.save" ID="PipPage.save"></a> -<h4>PipPage.save</h4> -<b>save</b>(<i></i>) -<p> - Public slot to save the pip configuration. -</p> -<div align="right"><a href="#top">Up</a></div> -<hr /> -</body></html> \ No newline at end of file
--- a/Documentation/Source/eric6.Plugins.UiExtensionPlugins.PipInterface.Pip.html Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,608 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric6.Plugins.UiExtensionPlugins.PipInterface.Pip</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.PipInterface.Pip</h1> -<p> -Package implementing the pip GUI logic. -</p> -<h3>Global Attributes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Classes</h3> -<table> -<tr> -<td><a href="#Pip">Pip</a></td> -<td>Class implementing the pip GUI logic.</td> -</tr> -</table> -<h3>Functions</h3> -<table> -<tr><td>None</td></tr> -</table> -<hr /><hr /> -<a NAME="Pip" ID="Pip"></a> -<h2>Pip</h2> -<p> - Class implementing the pip GUI logic. -</p> -<h3>Derived from</h3> -QObject -<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="#Pip.__init__">Pip</a></td> -<td>Constructor</td> -</tr><tr> -<td><a href="#Pip.__aboutToShowMenu">__aboutToShowMenu</a></td> -<td>Private slot to set the action enabled status.</td> -</tr><tr> -<td><a href="#Pip.__checkUpgradePyQt">__checkUpgradePyQt</a></td> -<td>Private method to check, if an upgrade of PyQt packages is attempted.</td> -</tr><tr> -<td><a href="#Pip.__editConfiguration">__editConfiguration</a></td> -<td>Private method to edit a configuration.</td> -</tr><tr> -<td><a href="#Pip.__editUserConfiguration">__editUserConfiguration</a></td> -<td>Private slot to edit the user configuration.</td> -</tr><tr> -<td><a href="#Pip.__editVirtualenvConfiguration">__editVirtualenvConfiguration</a></td> -<td>Private slot to edit the current virtualenv configuration.</td> -</tr><tr> -<td><a href="#Pip.__generateRequirements">__generateRequirements</a></td> -<td>Private slot to generate the contents for a requirements file.</td> -</tr><tr> -<td><a href="#Pip.__getUserConfig">__getUserConfig</a></td> -<td>Private method to get the name of the user configuration file.</td> -</tr><tr> -<td><a href="#Pip.__getVirtualenvConfig">__getVirtualenvConfig</a></td> -<td>Private method to get the name of the virtualenv configuration file.</td> -</tr><tr> -<td><a href="#Pip.__handleTearOffMenu">__handleTearOffMenu</a></td> -<td>Private slot to handle a change of the selected virtual environment.</td> -</tr><tr> -<td><a href="#Pip.__installLocalPackage">__installLocalPackage</a></td> -<td>Private slot to install a package available on local storage.</td> -</tr><tr> -<td><a href="#Pip.__installPackages">__installPackages</a></td> -<td>Private slot to install packages to be given by the user.</td> -</tr><tr> -<td><a href="#Pip.__installPip">__installPip</a></td> -<td>Private slot to install pip.</td> -</tr><tr> -<td><a href="#Pip.__installRequirements">__installRequirements</a></td> -<td>Private slot to install packages as given in a requirements file.</td> -</tr><tr> -<td><a href="#Pip.__listOutdatedPackages">__listOutdatedPackages</a></td> -<td>Private slot to list all installed, up-to-date packages.</td> -</tr><tr> -<td><a href="#Pip.__listPackages">__listPackages</a></td> -<td>Private slot to list all installed packages.</td> -</tr><tr> -<td><a href="#Pip.__listUptodatePackages">__listUptodatePackages</a></td> -<td>Private slot to list all installed, up-to-date packages.</td> -</tr><tr> -<td><a href="#Pip.__pipConfigure">__pipConfigure</a></td> -<td>Private slot to open the configuration page.</td> -</tr><tr> -<td><a href="#Pip.__repairPip">__repairPip</a></td> -<td>Private method to repair the pip installation.</td> -</tr><tr> -<td><a href="#Pip.__searchPyPI">__searchPyPI</a></td> -<td>Private slot to search the Python Package Index.</td> -</tr><tr> -<td><a href="#Pip.__selectPipVirtualenv">__selectPipVirtualenv</a></td> -<td>Private method to select the virtual environment to be used.</td> -</tr><tr> -<td><a href="#Pip.__uninstallPackages">__uninstallPackages</a></td> -<td>Private slot to uninstall packages to be given by the user.</td> -</tr><tr> -<td><a href="#Pip.__uninstallRequirements">__uninstallRequirements</a></td> -<td>Private slot to uninstall packages as given in a requirements file.</td> -</tr><tr> -<td><a href="#Pip.__upgradePackages">__upgradePackages</a></td> -<td>Private slot to upgrade packages to be given by the user.</td> -</tr><tr> -<td><a href="#Pip.getDefaultEnvironmentString">getDefaultEnvironmentString</a></td> -<td>Public method to get the string for the default environment.</td> -</tr><tr> -<td><a href="#Pip.getMenu">getMenu</a></td> -<td>Public method to get a reference to the requested menu.</td> -</tr><tr> -<td><a href="#Pip.getMenuNames">getMenuNames</a></td> -<td>Public method to get the names of all menus.</td> -</tr><tr> -<td><a href="#Pip.getProjectEnvironmentString">getProjectEnvironmentString</a></td> -<td>Public method to get the string for the project environment.</td> -</tr><tr> -<td><a href="#Pip.getVirtualenvInterpreter">getVirtualenvInterpreter</a></td> -<td>Public method to get the interpreter for a virtual environment.</td> -</tr><tr> -<td><a href="#Pip.getVirtualenvNames">getVirtualenvNames</a></td> -<td>Public method to get a sorted list of virtual environment names.</td> -</tr><tr> -<td><a href="#Pip.initActions">initActions</a></td> -<td>Public method to define the actions.</td> -</tr><tr> -<td><a href="#Pip.initMenu">initMenu</a></td> -<td>Public slot to initialize the menu.</td> -</tr><tr> -<td><a href="#Pip.installPackages">installPackages</a></td> -<td>Public method to install the given list of packages.</td> -</tr><tr> -<td><a href="#Pip.runProcess">runProcess</a></td> -<td>Public method to execute the current pip with the given arguments.</td> -</tr><tr> -<td><a href="#Pip.uninstallPackages">uninstallPackages</a></td> -<td>Public method to uninstall the given list of packages.</td> -</tr><tr> -<td><a href="#Pip.upgradePackages">upgradePackages</a></td> -<td>Public method to upgrade the given list of packages.</td> -</tr><tr> -<td><a href="#Pip.upgradePip">upgradePip</a></td> -<td>Public method to upgrade pip itself.</td> -</tr> -</table> -<h3>Static Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<a NAME="Pip.__init__" ID="Pip.__init__"></a> -<h4>Pip (Constructor)</h4> -<b>Pip</b>(<i>plugin, parent=None</i>) -<p> - Constructor -</p><dl> -<dt><i>plugin</i> (PipInterfacePlugin)</dt> -<dd> -reference to the plugin object -</dd><dt><i>parent</i> (QObject)</dt> -<dd> -parent -</dd> -</dl><a NAME="Pip.__aboutToShowMenu" ID="Pip.__aboutToShowMenu"></a> -<h4>Pip.__aboutToShowMenu</h4> -<b>__aboutToShowMenu</b>(<i></i>) -<p> - Private slot to set the action enabled status. -</p><a NAME="Pip.__checkUpgradePyQt" ID="Pip.__checkUpgradePyQt"></a> -<h4>Pip.__checkUpgradePyQt</h4> -<b>__checkUpgradePyQt</b>(<i>packages</i>) -<p> - Private method to check, if an upgrade of PyQt packages is attempted. -</p><dl> -<dt><i>packages</i> (list of str)</dt> -<dd> -list of packages to upgrade -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -flag indicating to abort the upgrade attempt -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -bool -</dd> -</dl><a NAME="Pip.__editConfiguration" ID="Pip.__editConfiguration"></a> -<h4>Pip.__editConfiguration</h4> -<b>__editConfiguration</b>(<i>virtualenv=False</i>) -<p> - Private method to edit a configuration. -</p><dl> -<dt><i>virtualenv</i> (bool)</dt> -<dd> -flag indicating to edit the current virtualenv - configuration file -</dd> -</dl><a NAME="Pip.__editUserConfiguration" ID="Pip.__editUserConfiguration"></a> -<h4>Pip.__editUserConfiguration</h4> -<b>__editUserConfiguration</b>(<i></i>) -<p> - Private slot to edit the user configuration. -</p><a NAME="Pip.__editVirtualenvConfiguration" ID="Pip.__editVirtualenvConfiguration"></a> -<h4>Pip.__editVirtualenvConfiguration</h4> -<b>__editVirtualenvConfiguration</b>(<i></i>) -<p> - Private slot to edit the current virtualenv configuration. -</p><a NAME="Pip.__generateRequirements" ID="Pip.__generateRequirements"></a> -<h4>Pip.__generateRequirements</h4> -<b>__generateRequirements</b>(<i></i>) -<p> - Private slot to generate the contents for a requirements file. -</p><a NAME="Pip.__getUserConfig" ID="Pip.__getUserConfig"></a> -<h4>Pip.__getUserConfig</h4> -<b>__getUserConfig</b>(<i></i>) -<p> - Private method to get the name of the user configuration file. -</p><dl> -<dt>Returns:</dt> -<dd> -path of the user configuration file -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -str -</dd> -</dl><a NAME="Pip.__getVirtualenvConfig" ID="Pip.__getVirtualenvConfig"></a> -<h4>Pip.__getVirtualenvConfig</h4> -<b>__getVirtualenvConfig</b>(<i></i>) -<p> - Private method to get the name of the virtualenv configuration file. -</p><dl> -<dt>Returns:</dt> -<dd> -path of the virtualenv configuration file -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -str -</dd> -</dl><a NAME="Pip.__handleTearOffMenu" ID="Pip.__handleTearOffMenu"></a> -<h4>Pip.__handleTearOffMenu</h4> -<b>__handleTearOffMenu</b>(<i>venvName</i>) -<p> - Private slot to handle a change of the selected virtual environment. -</p><dl> -<dt><i>venvName</i> (str)</dt> -<dd> -logical name of the virtual environment -</dd> -</dl><a NAME="Pip.__installLocalPackage" ID="Pip.__installLocalPackage"></a> -<h4>Pip.__installLocalPackage</h4> -<b>__installLocalPackage</b>(<i></i>) -<p> - Private slot to install a package available on local storage. -</p><a NAME="Pip.__installPackages" ID="Pip.__installPackages"></a> -<h4>Pip.__installPackages</h4> -<b>__installPackages</b>(<i></i>) -<p> - Private slot to install packages to be given by the user. -</p><a NAME="Pip.__installPip" ID="Pip.__installPip"></a> -<h4>Pip.__installPip</h4> -<b>__installPip</b>(<i>userSite=False</i>) -<p> - Private slot to install pip. -</p><dl> -<dt><i>userSite</i> (bool)</dt> -<dd> -flag indicating an install to the user install - directory -</dd> -</dl><a NAME="Pip.__installRequirements" ID="Pip.__installRequirements"></a> -<h4>Pip.__installRequirements</h4> -<b>__installRequirements</b>(<i></i>) -<p> - Private slot to install packages as given in a requirements file. -</p><a NAME="Pip.__listOutdatedPackages" ID="Pip.__listOutdatedPackages"></a> -<h4>Pip.__listOutdatedPackages</h4> -<b>__listOutdatedPackages</b>(<i></i>) -<p> - Private slot to list all installed, up-to-date packages. -</p><a NAME="Pip.__listPackages" ID="Pip.__listPackages"></a> -<h4>Pip.__listPackages</h4> -<b>__listPackages</b>(<i></i>) -<p> - Private slot to list all installed packages. -</p><a NAME="Pip.__listUptodatePackages" ID="Pip.__listUptodatePackages"></a> -<h4>Pip.__listUptodatePackages</h4> -<b>__listUptodatePackages</b>(<i></i>) -<p> - Private slot to list all installed, up-to-date packages. -</p><a NAME="Pip.__pipConfigure" ID="Pip.__pipConfigure"></a> -<h4>Pip.__pipConfigure</h4> -<b>__pipConfigure</b>(<i></i>) -<p> - Private slot to open the configuration page. -</p><a NAME="Pip.__repairPip" ID="Pip.__repairPip"></a> -<h4>Pip.__repairPip</h4> -<b>__repairPip</b>(<i></i>) -<p> - Private method to repair the pip installation. -</p><dl> -<dt>Returns:</dt> -<dd> -flag indicating a successful execution -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -bool -</dd> -</dl><a NAME="Pip.__searchPyPI" ID="Pip.__searchPyPI"></a> -<h4>Pip.__searchPyPI</h4> -<b>__searchPyPI</b>(<i></i>) -<p> - Private slot to search the Python Package Index. -</p><a NAME="Pip.__selectPipVirtualenv" ID="Pip.__selectPipVirtualenv"></a> -<h4>Pip.__selectPipVirtualenv</h4> -<b>__selectPipVirtualenv</b>(<i></i>) -<p> - Private method to select the virtual environment to be used. -</p><a NAME="Pip.__uninstallPackages" ID="Pip.__uninstallPackages"></a> -<h4>Pip.__uninstallPackages</h4> -<b>__uninstallPackages</b>(<i></i>) -<p> - Private slot to uninstall packages to be given by the user. -</p><a NAME="Pip.__uninstallRequirements" ID="Pip.__uninstallRequirements"></a> -<h4>Pip.__uninstallRequirements</h4> -<b>__uninstallRequirements</b>(<i></i>) -<p> - Private slot to uninstall packages as given in a requirements file. -</p><a NAME="Pip.__upgradePackages" ID="Pip.__upgradePackages"></a> -<h4>Pip.__upgradePackages</h4> -<b>__upgradePackages</b>(<i></i>) -<p> - Private slot to upgrade packages to be given by the user. -</p><a NAME="Pip.getDefaultEnvironmentString" ID="Pip.getDefaultEnvironmentString"></a> -<h4>Pip.getDefaultEnvironmentString</h4> -<b>getDefaultEnvironmentString</b>(<i></i>) -<p> - Public method to get the string for the default environment. -</p><dl> -<dt>Returns:</dt> -<dd> -string for the default environment -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -str -</dd> -</dl><a NAME="Pip.getMenu" ID="Pip.getMenu"></a> -<h4>Pip.getMenu</h4> -<b>getMenu</b>(<i>name</i>) -<p> - Public method to get a reference to the requested menu. -</p><dl> -<dt><i>name</i> (str)</dt> -<dd> -name of the menu -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -reference to the menu or None, if no - menu with the given name exists -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -QMenu or None -</dd> -</dl><a NAME="Pip.getMenuNames" ID="Pip.getMenuNames"></a> -<h4>Pip.getMenuNames</h4> -<b>getMenuNames</b>(<i></i>) -<p> - Public method to get the names of all menus. -</p><dl> -<dt>Returns:</dt> -<dd> -menu names -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -list of str -</dd> -</dl><a NAME="Pip.getProjectEnvironmentString" ID="Pip.getProjectEnvironmentString"></a> -<h4>Pip.getProjectEnvironmentString</h4> -<b>getProjectEnvironmentString</b>(<i></i>) -<p> - Public method to get the string for the project environment. -</p><dl> -<dt>Returns:</dt> -<dd> -string for the project environment -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -str -</dd> -</dl><a NAME="Pip.getVirtualenvInterpreter" ID="Pip.getVirtualenvInterpreter"></a> -<h4>Pip.getVirtualenvInterpreter</h4> -<b>getVirtualenvInterpreter</b>(<i>venvName</i>) -<p> - Public method to get the interpreter for a virtual environment. -</p><dl> -<dt><i>venvName</i> (str)</dt> -<dd> -logical name for the virtual environment -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -interpreter path -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -str -</dd> -</dl><a NAME="Pip.getVirtualenvNames" ID="Pip.getVirtualenvNames"></a> -<h4>Pip.getVirtualenvNames</h4> -<b>getVirtualenvNames</b>(<i></i>) -<p> - Public method to get a sorted list of virtual environment names. -</p><dl> -<dt>Returns:</dt> -<dd> -sorted list of virtual environment names -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -list of str -</dd> -</dl><a NAME="Pip.initActions" ID="Pip.initActions"></a> -<h4>Pip.initActions</h4> -<b>initActions</b>(<i></i>) -<p> - Public method to define the actions. -</p><a NAME="Pip.initMenu" ID="Pip.initMenu"></a> -<h4>Pip.initMenu</h4> -<b>initMenu</b>(<i></i>) -<p> - Public slot to initialize the menu. -</p><dl> -<dt>Returns:</dt> -<dd> -the menu generated -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -QMenu -</dd> -</dl><a NAME="Pip.installPackages" ID="Pip.installPackages"></a> -<h4>Pip.installPackages</h4> -<b>installPackages</b>(<i>packages, venvName="", userSite=False</i>) -<p> - Public method to install the given list of packages. -</p><dl> -<dt><i>packages</i> (list of str)</dt> -<dd> -list of packages to install -</dd><dt><i>venvName</i> (str)</dt> -<dd> -name of the virtual environment to be used -</dd><dt><i>userSite</i> (bool)</dt> -<dd> -flag indicating an install to the user install - directory -</dd> -</dl><a NAME="Pip.runProcess" ID="Pip.runProcess"></a> -<h4>Pip.runProcess</h4> -<b>runProcess</b>(<i>args, interpreter</i>) -<p> - Public method to execute the current pip with the given arguments. -</p><p> - The selected pip executable is called with the given arguments and - waited for its end. -</p><dl> -<dt><i>args</i> (list of str)</dt> -<dd> -list of command line arguments -</dd><dt><i>interpreter</i> (str)</dt> -<dd> -path of the Python interpreter to be used -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -tuple containing a flag indicating success and the output - of the process -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -tuple of (bool, str) -</dd> -</dl><a NAME="Pip.uninstallPackages" ID="Pip.uninstallPackages"></a> -<h4>Pip.uninstallPackages</h4> -<b>uninstallPackages</b>(<i>packages, venvName=""</i>) -<p> - Public method to uninstall the given list of packages. -</p><dl> -<dt><i>packages</i> (list of str)</dt> -<dd> -list of packages to uninstall -</dd><dt><i>venvName</i> (str)</dt> -<dd> -name of the virtual environment to be used -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -flag indicating a successful execution -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -bool -</dd> -</dl><a NAME="Pip.upgradePackages" ID="Pip.upgradePackages"></a> -<h4>Pip.upgradePackages</h4> -<b>upgradePackages</b>(<i>packages, venvName="", userSite=False</i>) -<p> - Public method to upgrade the given list of packages. -</p><dl> -<dt><i>packages</i> (list of str)</dt> -<dd> -list of packages to upgrade -</dd><dt><i>venvName</i> (str)</dt> -<dd> -name of the virtual environment to be used -</dd><dt><i>userSite</i> (bool)</dt> -<dd> -flag indicating an install to the user install - directory -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -flag indicating a successful execution -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -bool -</dd> -</dl><a NAME="Pip.upgradePip" ID="Pip.upgradePip"></a> -<h4>Pip.upgradePip</h4> -<b>upgradePip</b>(<i>venvName="", userSite=False</i>) -<p> - Public method to upgrade pip itself. -</p><dl> -<dt><i>venvName</i> (str)</dt> -<dd> -name of the virtual environment to be used -</dd><dt><i>userSite</i> (bool)</dt> -<dd> -flag indicating an install to the user install - directory -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -flag indicating a successful execution -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -bool -</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.PipInterface.PipDialog.html Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,224 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric6.Plugins.UiExtensionPlugins.PipInterface.PipDialog</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.PipInterface.PipDialog</h1> -<p> -Module implementing a dialog showing the output of a pip command. -</p> -<h3>Global Attributes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Classes</h3> -<table> -<tr> -<td><a href="#PipDialog">PipDialog</a></td> -<td>Class implementing a dialog showing the output of a 'python -m pip' command.</td> -</tr> -</table> -<h3>Functions</h3> -<table> -<tr><td>None</td></tr> -</table> -<hr /><hr /> -<a NAME="PipDialog" ID="PipDialog"></a> -<h2>PipDialog</h2> -<p> - Class implementing a dialog showing the output of a 'python -m pip' - command. -</p> -<h3>Derived from</h3> -QDialog, Ui_PipDialog -<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="#PipDialog.__init__">PipDialog</a></td> -<td>Constructor</td> -</tr><tr> -<td><a href="#PipDialog.__addOutput">__addOutput</a></td> -<td>Private method to add some text to the output pane.</td> -</tr><tr> -<td><a href="#PipDialog.__finish">__finish</a></td> -<td>Private slot called when the process finished or the user pressed the button.</td> -</tr><tr> -<td><a href="#PipDialog.__procFinished">__procFinished</a></td> -<td>Private slot connected to the finished signal.</td> -</tr><tr> -<td><a href="#PipDialog.__readStderr">__readStderr</a></td> -<td>Private slot to handle the readyReadStandardError signal.</td> -</tr><tr> -<td><a href="#PipDialog.__readStdout">__readStdout</a></td> -<td>Private slot to handle the readyReadStandardOutput signal.</td> -</tr><tr> -<td><a href="#PipDialog.closeEvent">closeEvent</a></td> -<td>Protected slot implementing a close event handler.</td> -</tr><tr> -<td><a href="#PipDialog.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="#PipDialog.startProcess">startProcess</a></td> -<td>Public slot used to start the process.</td> -</tr><tr> -<td><a href="#PipDialog.startProcesses">startProcesses</a></td> -<td>Public method to issue a list of commands to be executed.</td> -</tr> -</table> -<h3>Static Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<a NAME="PipDialog.__init__" ID="PipDialog.__init__"></a> -<h4>PipDialog (Constructor)</h4> -<b>PipDialog</b>(<i>text, parent=None</i>) -<p> - Constructor -</p><dl> -<dt><i>text</i> (str)</dt> -<dd> -text to be shown by the label -</dd><dt><i>parent</i> (QWidget)</dt> -<dd> -reference to the parent widget -</dd> -</dl><a NAME="PipDialog.__addOutput" ID="PipDialog.__addOutput"></a> -<h4>PipDialog.__addOutput</h4> -<b>__addOutput</b>(<i>txt</i>) -<p> - Private method to add some text to the output pane. -</p><dl> -<dt><i>txt</i> (str)</dt> -<dd> -text to be added -</dd> -</dl><a NAME="PipDialog.__finish" ID="PipDialog.__finish"></a> -<h4>PipDialog.__finish</h4> -<b>__finish</b>(<i></i>) -<p> - Private slot called when the process finished or the user pressed - the button. -</p><a NAME="PipDialog.__procFinished" ID="PipDialog.__procFinished"></a> -<h4>PipDialog.__procFinished</h4> -<b>__procFinished</b>(<i>exitCode, exitStatus</i>) -<p> - Private slot connected to the finished signal. -</p><dl> -<dt><i>exitCode</i> (int)</dt> -<dd> -exit code of the process -</dd><dt><i>exitStatus</i> (QProcess.ExitStatus)</dt> -<dd> -exit status of the process -</dd> -</dl><a NAME="PipDialog.__readStderr" ID="PipDialog.__readStderr"></a> -<h4>PipDialog.__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="PipDialog.__readStdout" ID="PipDialog.__readStdout"></a> -<h4>PipDialog.__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="PipDialog.closeEvent" ID="PipDialog.closeEvent"></a> -<h4>PipDialog.closeEvent</h4> -<b>closeEvent</b>(<i>e</i>) -<p> - Protected slot implementing a close event handler. -</p><dl> -<dt><i>e</i> (QCloseEvent)</dt> -<dd> -close event -</dd> -</dl><a NAME="PipDialog.on_buttonBox_clicked" ID="PipDialog.on_buttonBox_clicked"></a> -<h4>PipDialog.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> (QAbstractButton)</dt> -<dd> -button that was clicked -</dd> -</dl><a NAME="PipDialog.startProcess" ID="PipDialog.startProcess"></a> -<h4>PipDialog.startProcess</h4> -<b>startProcess</b>(<i>cmd, args, showArgs=True</i>) -<p> - Public slot used to start the process. -</p><dl> -<dt><i>cmd</i> (str)</dt> -<dd> -name of the pip executable to be used -</dd><dt><i>args</i> (list of str)</dt> -<dd> -list of arguments for the process -</dd><dt><i>showArgs=</i> (bool)</dt> -<dd> -flag indicating to show the arguments -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -flag indicating a successful start of the process -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -bool -</dd> -</dl><a NAME="PipDialog.startProcesses" ID="PipDialog.startProcesses"></a> -<h4>PipDialog.startProcesses</h4> -<b>startProcesses</b>(<i>processParams</i>) -<p> - Public method to issue a list of commands to be executed. -</p><dl> -<dt><i>processParams</i> (list of tuples of (str, list of str))</dt> -<dd> -list of tuples containing the command - and arguments -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -flag indicating a successful start of the first process -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -bool -</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.PipInterface.PipFileSelectionDialog.html Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric6.Plugins.UiExtensionPlugins.PipInterface.PipFileSelectionDialog</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.PipInterface.PipFileSelectionDialog</h1> -<p> -Module implementing a dialog to enter a file to be processed. -</p> -<h3>Global Attributes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Classes</h3> -<table> -<tr> -<td><a href="#PipFileSelectionDialog">PipFileSelectionDialog</a></td> -<td>Class implementing a dialog to enter a file to be processed.</td> -</tr> -</table> -<h3>Functions</h3> -<table> -<tr><td>None</td></tr> -</table> -<hr /><hr /> -<a NAME="PipFileSelectionDialog" ID="PipFileSelectionDialog"></a> -<h2>PipFileSelectionDialog</h2> -<p> - Class implementing a dialog to enter a file to be processed. -</p> -<h3>Derived from</h3> -QDialog, Ui_PipFileSelectionDialog -<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="#PipFileSelectionDialog.__init__">PipFileSelectionDialog</a></td> -<td>Constructor</td> -</tr><tr> -<td><a href="#PipFileSelectionDialog.getData">getData</a></td> -<td>Public method to get the entered data.</td> -</tr><tr> -<td><a href="#PipFileSelectionDialog.on_filePicker_textChanged">on_filePicker_textChanged</a></td> -<td>Private slot to handle entering the name of a file.</td> -</tr> -</table> -<h3>Static Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<a NAME="PipFileSelectionDialog.__init__" ID="PipFileSelectionDialog.__init__"></a> -<h4>PipFileSelectionDialog (Constructor)</h4> -<b>PipFileSelectionDialog</b>(<i>pip, mode, install=True, parent=None</i>) -<p> - Constructor -</p><dl> -<dt><i>pip</i> (Pip)</dt> -<dd> -reference to the pip object -</dd><dt><i>mode</i> (str)</dt> -<dd> -mode of the dialog -</dd><dt><i>install</i> (bool)</dt> -<dd> -flag indicating an install action -</dd><dt><i>parent</i> (QWidget)</dt> -<dd> -reference to the parent widget -</dd> -</dl><a NAME="PipFileSelectionDialog.getData" ID="PipFileSelectionDialog.getData"></a> -<h4>PipFileSelectionDialog.getData</h4> -<b>getData</b>(<i></i>) -<p> - Public method to get the entered data. -</p><dl> -<dt>Returns:</dt> -<dd> -tuple with the environment name, the name of the - selected file and a flag indicating to install to the - user install directory -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -tuple of (str, str, bool) -</dd> -</dl><a NAME="PipFileSelectionDialog.on_filePicker_textChanged" ID="PipFileSelectionDialog.on_filePicker_textChanged"></a> -<h4>PipFileSelectionDialog.on_filePicker_textChanged</h4> -<b>on_filePicker_textChanged</b>(<i>txt</i>) -<p> - Private slot to handle entering the name of a file. -</p><dl> -<dt><i>txt</i> (str)</dt> -<dd> -name of the file -</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.PipInterface.PipFreezeDialog.html Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,245 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric6.Plugins.UiExtensionPlugins.PipInterface.PipFreezeDialog</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.PipInterface.PipFreezeDialog</h1> -<p> -Module implementing a dialog to generate a requirements file. -</p> -<h3>Global Attributes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Classes</h3> -<table> -<tr> -<td><a href="#PipFreezeDialog">PipFreezeDialog</a></td> -<td>Class implementing a dialog to generate a requirements file.</td> -</tr> -</table> -<h3>Functions</h3> -<table> -<tr><td>None</td></tr> -</table> -<hr /><hr /> -<a NAME="PipFreezeDialog" ID="PipFreezeDialog"></a> -<h2>PipFreezeDialog</h2> -<p> - Class implementing a dialog to generate a requirements file. -</p> -<h3>Derived from</h3> -QDialog, Ui_PipFreezeDialog -<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="#PipFreezeDialog.__init__">PipFreezeDialog</a></td> -<td>Constructor</td> -</tr><tr> -<td><a href="#PipFreezeDialog.__refresh">__refresh</a></td> -<td>Private slot to refresh the displayed list.</td> -</tr><tr> -<td><a href="#PipFreezeDialog.__updateButtons">__updateButtons</a></td> -<td>Private method to set the state of the various buttons.</td> -</tr><tr> -<td><a href="#PipFreezeDialog.__writeToFile">__writeToFile</a></td> -<td>Private method to write the requirements text to a file.</td> -</tr><tr> -<td><a href="#PipFreezeDialog.closeEvent">closeEvent</a></td> -<td>Protected slot implementing a close event handler.</td> -</tr><tr> -<td><a href="#PipFreezeDialog.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="#PipFreezeDialog.on_copyButton_clicked">on_copyButton_clicked</a></td> -<td>Private slot to copy the requirements text to the clipboard.</td> -</tr><tr> -<td><a href="#PipFreezeDialog.on_insertButton_clicked">on_insertButton_clicked</a></td> -<td>Private slot to insert the requirements text at the cursor position of the current editor.</td> -</tr><tr> -<td><a href="#PipFreezeDialog.on_localCheckBox_clicked">on_localCheckBox_clicked</a></td> -<td>Private slot handling the switching of the local mode.</td> -</tr><tr> -<td><a href="#PipFreezeDialog.on_replaceAllButton_clicked">on_replaceAllButton_clicked</a></td> -<td>Private slot to replace the text of the current editor with the requirements text.</td> -</tr><tr> -<td><a href="#PipFreezeDialog.on_replaceSelectionButton_clicked">on_replaceSelectionButton_clicked</a></td> -<td>Private slot to replace the selected text of the current editor with the requirements text.</td> -</tr><tr> -<td><a href="#PipFreezeDialog.on_requirementsEdit_textChanged">on_requirementsEdit_textChanged</a></td> -<td>Private slot handling changes of the requirements text.</td> -</tr><tr> -<td><a href="#PipFreezeDialog.on_requirementsFilePicker_textChanged">on_requirementsFilePicker_textChanged</a></td> -<td>Private slot handling a change of the requirements file name.</td> -</tr><tr> -<td><a href="#PipFreezeDialog.on_saveButton_clicked">on_saveButton_clicked</a></td> -<td>Private slot to save the requirements text to the requirements file.</td> -</tr><tr> -<td><a href="#PipFreezeDialog.on_saveToButton_clicked">on_saveToButton_clicked</a></td> -<td>Private slot to write the requirements text to a new file.</td> -</tr><tr> -<td><a href="#PipFreezeDialog.on_venvComboBox_activated">on_venvComboBox_activated</a></td> -<td>Private slot handling the selection of a virtual environment.</td> -</tr><tr> -<td><a href="#PipFreezeDialog.start">start</a></td> -<td>Public method to start the command.</td> -</tr> -</table> -<h3>Static Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<a NAME="PipFreezeDialog.__init__" ID="PipFreezeDialog.__init__"></a> -<h4>PipFreezeDialog (Constructor)</h4> -<b>PipFreezeDialog</b>(<i>pip, parent=None</i>) -<p> - Constructor -</p><dl> -<dt><i>pip</i> (Pip)</dt> -<dd> -reference to the master object -</dd><dt><i>parent</i> (QWidget)</dt> -<dd> -reference to the parent widget -</dd> -</dl><a NAME="PipFreezeDialog.__refresh" ID="PipFreezeDialog.__refresh"></a> -<h4>PipFreezeDialog.__refresh</h4> -<b>__refresh</b>(<i></i>) -<p> - Private slot to refresh the displayed list. -</p><a NAME="PipFreezeDialog.__updateButtons" ID="PipFreezeDialog.__updateButtons"></a> -<h4>PipFreezeDialog.__updateButtons</h4> -<b>__updateButtons</b>(<i></i>) -<p> - Private method to set the state of the various buttons. -</p><a NAME="PipFreezeDialog.__writeToFile" ID="PipFreezeDialog.__writeToFile"></a> -<h4>PipFreezeDialog.__writeToFile</h4> -<b>__writeToFile</b>(<i>fileName</i>) -<p> - Private method to write the requirements text to a file. -</p><dl> -<dt><i>fileName</i> (str)</dt> -<dd> -name of the file to write to -</dd> -</dl><a NAME="PipFreezeDialog.closeEvent" ID="PipFreezeDialog.closeEvent"></a> -<h4>PipFreezeDialog.closeEvent</h4> -<b>closeEvent</b>(<i>e</i>) -<p> - Protected slot implementing a close event handler. -</p><dl> -<dt><i>e</i> (QCloseEvent)</dt> -<dd> -close event -</dd> -</dl><a NAME="PipFreezeDialog.on_buttonBox_clicked" ID="PipFreezeDialog.on_buttonBox_clicked"></a> -<h4>PipFreezeDialog.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> (QAbstractButton)</dt> -<dd> -button that was clicked -</dd> -</dl><a NAME="PipFreezeDialog.on_copyButton_clicked" ID="PipFreezeDialog.on_copyButton_clicked"></a> -<h4>PipFreezeDialog.on_copyButton_clicked</h4> -<b>on_copyButton_clicked</b>(<i></i>) -<p> - Private slot to copy the requirements text to the clipboard. -</p><a NAME="PipFreezeDialog.on_insertButton_clicked" ID="PipFreezeDialog.on_insertButton_clicked"></a> -<h4>PipFreezeDialog.on_insertButton_clicked</h4> -<b>on_insertButton_clicked</b>(<i></i>) -<p> - Private slot to insert the requirements text at the cursor position - of the current editor. -</p><a NAME="PipFreezeDialog.on_localCheckBox_clicked" ID="PipFreezeDialog.on_localCheckBox_clicked"></a> -<h4>PipFreezeDialog.on_localCheckBox_clicked</h4> -<b>on_localCheckBox_clicked</b>(<i>checked</i>) -<p> - Private slot handling the switching of the local mode. -</p><dl> -<dt><i>checked</i> (bool)</dt> -<dd> -state of the local check box -</dd> -</dl><a NAME="PipFreezeDialog.on_replaceAllButton_clicked" ID="PipFreezeDialog.on_replaceAllButton_clicked"></a> -<h4>PipFreezeDialog.on_replaceAllButton_clicked</h4> -<b>on_replaceAllButton_clicked</b>(<i></i>) -<p> - Private slot to replace the text of the current editor with the - requirements text. -</p><a NAME="PipFreezeDialog.on_replaceSelectionButton_clicked" ID="PipFreezeDialog.on_replaceSelectionButton_clicked"></a> -<h4>PipFreezeDialog.on_replaceSelectionButton_clicked</h4> -<b>on_replaceSelectionButton_clicked</b>(<i></i>) -<p> - Private slot to replace the selected text of the current editor - with the requirements text. -</p><a NAME="PipFreezeDialog.on_requirementsEdit_textChanged" ID="PipFreezeDialog.on_requirementsEdit_textChanged"></a> -<h4>PipFreezeDialog.on_requirementsEdit_textChanged</h4> -<b>on_requirementsEdit_textChanged</b>(<i></i>) -<p> - Private slot handling changes of the requirements text. -</p><a NAME="PipFreezeDialog.on_requirementsFilePicker_textChanged" ID="PipFreezeDialog.on_requirementsFilePicker_textChanged"></a> -<h4>PipFreezeDialog.on_requirementsFilePicker_textChanged</h4> -<b>on_requirementsFilePicker_textChanged</b>(<i>txt</i>) -<p> - Private slot handling a change of the requirements file name. -</p><dl> -<dt><i>txt</i> (str)</dt> -<dd> -name of the requirements file -</dd> -</dl><a NAME="PipFreezeDialog.on_saveButton_clicked" ID="PipFreezeDialog.on_saveButton_clicked"></a> -<h4>PipFreezeDialog.on_saveButton_clicked</h4> -<b>on_saveButton_clicked</b>(<i></i>) -<p> - Private slot to save the requirements text to the requirements file. -</p><a NAME="PipFreezeDialog.on_saveToButton_clicked" ID="PipFreezeDialog.on_saveToButton_clicked"></a> -<h4>PipFreezeDialog.on_saveToButton_clicked</h4> -<b>on_saveToButton_clicked</b>(<i></i>) -<p> - Private slot to write the requirements text to a new file. -</p><a NAME="PipFreezeDialog.on_venvComboBox_activated" ID="PipFreezeDialog.on_venvComboBox_activated"></a> -<h4>PipFreezeDialog.on_venvComboBox_activated</h4> -<b>on_venvComboBox_activated</b>(<i>txt</i>) -<p> - Private slot handling the selection of a virtual environment. -</p><dl> -<dt><i>txt</i> (str)</dt> -<dd> -virtual environment -</dd> -</dl><a NAME="PipFreezeDialog.start" ID="PipFreezeDialog.start"></a> -<h4>PipFreezeDialog.start</h4> -<b>start</b>(<i></i>) -<p> - Public method to start the command. -</p> -<div align="right"><a href="#top">Up</a></div> -<hr /> -</body></html> \ No newline at end of file
--- a/Documentation/Source/eric6.Plugins.UiExtensionPlugins.PipInterface.PipListDialog.html Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,331 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric6.Plugins.UiExtensionPlugins.PipInterface.PipListDialog</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.PipInterface.PipListDialog</h1> -<p> -Module implementing a dialog to list installed packages. -</p> -<h3>Global Attributes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Classes</h3> -<table> -<tr> -<td><a href="#PipListDialog">PipListDialog</a></td> -<td>Class implementing a dialog to list installed packages.</td> -</tr> -</table> -<h3>Functions</h3> -<table> -<tr><td>None</td></tr> -</table> -<hr /><hr /> -<a NAME="PipListDialog" ID="PipListDialog"></a> -<h2>PipListDialog</h2> -<p> - Class implementing a dialog to list installed packages. -</p> -<h3>Derived from</h3> -QDialog, Ui_PipListDialog -<h3>Class Attributes</h3> -<table> -<tr><td>CommandArguments</td></tr><tr><td>ShowProcessClassifiersMode</td></tr><tr><td>ShowProcessEntryPointsMode</td></tr><tr><td>ShowProcessFilesListMode</td></tr><tr><td>ShowProcessGeneralMode</td></tr> -</table> -<h3>Class Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Methods</h3> -<table> -<tr> -<td><a href="#PipListDialog.__init__">PipListDialog</a></td> -<td>Constructor</td> -</tr><tr> -<td><a href="#PipListDialog.__executeUpgradePackages">__executeUpgradePackages</a></td> -<td>Private method to execute the pip upgrade command.</td> -</tr><tr> -<td><a href="#PipListDialog.__finish">__finish</a></td> -<td>Private slot called when the process finished or the user pressed the cancel button.</td> -</tr><tr> -<td><a href="#PipListDialog.__procFinished">__procFinished</a></td> -<td>Private slot connected to the finished signal.</td> -</tr><tr> -<td><a href="#PipListDialog.__processOutput">__processOutput</a></td> -<td>Private method to process the captured output.</td> -</tr><tr> -<td><a href="#PipListDialog.__readStderr">__readStderr</a></td> -<td>Private slot to handle the readyReadStandardError signal.</td> -</tr><tr> -<td><a href="#PipListDialog.__readStdout">__readStdout</a></td> -<td>Private slot to handle the readyReadStandardOutput signal.</td> -</tr><tr> -<td><a href="#PipListDialog.__refresh">__refresh</a></td> -<td>Private slot to refresh the displayed list.</td> -</tr><tr> -<td><a href="#PipListDialog.__stopProcess">__stopProcess</a></td> -<td>Private slot to stop the running process.</td> -</tr><tr> -<td><a href="#PipListDialog.__uninstallPackages">__uninstallPackages</a></td> -<td>Private slot to uninstall the selected packages.</td> -</tr><tr> -<td><a href="#PipListDialog.__upgradeAllPackages">__upgradeAllPackages</a></td> -<td>Private slot to upgrade all listed packages.</td> -</tr><tr> -<td><a href="#PipListDialog.__upgradePackages">__upgradePackages</a></td> -<td>Private slot to upgrade the selected packages.</td> -</tr><tr> -<td><a href="#PipListDialog.__upgradePip">__upgradePip</a></td> -<td>Private slot to upgrade pip itself.</td> -</tr><tr> -<td><a href="#PipListDialog.closeEvent">closeEvent</a></td> -<td>Protected slot implementing a close event handler.</td> -</tr><tr> -<td><a href="#PipListDialog.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="#PipListDialog.on_installedFilesCheckBox_clicked">on_installedFilesCheckBox_clicked</a></td> -<td>Private slot to handle a change of the installed files information checkbox.</td> -</tr><tr> -<td><a href="#PipListDialog.on_localCheckBox_clicked">on_localCheckBox_clicked</a></td> -<td>Private slot handling the switching of the local mode.</td> -</tr><tr> -<td><a href="#PipListDialog.on_notRequiredCheckBox_clicked">on_notRequiredCheckBox_clicked</a></td> -<td>Private slot handling the switching of the 'not required' mode.</td> -</tr><tr> -<td><a href="#PipListDialog.on_packageList_itemSelectionChanged">on_packageList_itemSelectionChanged</a></td> -<td>Private slot handling the selection of a package.</td> -</tr><tr> -<td><a href="#PipListDialog.on_userCheckBox_clicked">on_userCheckBox_clicked</a></td> -<td>Private slot handling the switching of the 'user-site' mode.</td> -</tr><tr> -<td><a href="#PipListDialog.on_venvComboBox_activated">on_venvComboBox_activated</a></td> -<td>Private slot handling the selection of a virtual environment.</td> -</tr><tr> -<td><a href="#PipListDialog.on_verboseCheckBox_clicked">on_verboseCheckBox_clicked</a></td> -<td>Private slot to handle a change of the verbose package information checkbox.</td> -</tr><tr> -<td><a href="#PipListDialog.start">start</a></td> -<td>Public method to start the command.</td> -</tr> -</table> -<h3>Static Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<a NAME="PipListDialog.__init__" ID="PipListDialog.__init__"></a> -<h4>PipListDialog (Constructor)</h4> -<b>PipListDialog</b>(<i>pip, mode, indexUrl, title, parent=None</i>) -<p> - Constructor -</p><dl> -<dt><i>pip</i> (Pip)</dt> -<dd> -reference to the master object -</dd><dt><i>mode</i> (str)</dt> -<dd> -list command mode (one of 'list', 'uptodate', 'outdated') -</dd><dt><i>indexUrl</i> (str)</dt> -<dd> -URL of the pypi index -</dd><dt><i>title</i> (str)</dt> -<dd> -title of the dialog -</dd><dt><i>parent</i> (QWidget)</dt> -<dd> -reference to the parent widget -</dd> -</dl><a NAME="PipListDialog.__executeUpgradePackages" ID="PipListDialog.__executeUpgradePackages"></a> -<h4>PipListDialog.__executeUpgradePackages</h4> -<b>__executeUpgradePackages</b>(<i>packages</i>) -<p> - Private method to execute the pip upgrade command. -</p><dl> -<dt><i>packages</i> (list of str)</dt> -<dd> -list of package names to be upgraded -</dd> -</dl><a NAME="PipListDialog.__finish" ID="PipListDialog.__finish"></a> -<h4>PipListDialog.__finish</h4> -<b>__finish</b>(<i></i>) -<p> - Private slot called when the process finished or the user pressed - the cancel button. -</p><a NAME="PipListDialog.__procFinished" ID="PipListDialog.__procFinished"></a> -<h4>PipListDialog.__procFinished</h4> -<b>__procFinished</b>(<i>exitCode, exitStatus</i>) -<p> - Private slot connected to the finished signal. -</p><dl> -<dt><i>exitCode</i> (int)</dt> -<dd> -exit code of the process -</dd><dt><i>exitStatus</i> (QProcess.ExitStatus)</dt> -<dd> -exit status of the process -</dd> -</dl><a NAME="PipListDialog.__processOutput" ID="PipListDialog.__processOutput"></a> -<h4>PipListDialog.__processOutput</h4> -<b>__processOutput</b>(<i></i>) -<p> - Private method to process the captured output. -</p><a NAME="PipListDialog.__readStderr" ID="PipListDialog.__readStderr"></a> -<h4>PipListDialog.__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="PipListDialog.__readStdout" ID="PipListDialog.__readStdout"></a> -<h4>PipListDialog.__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="PipListDialog.__refresh" ID="PipListDialog.__refresh"></a> -<h4>PipListDialog.__refresh</h4> -<b>__refresh</b>(<i></i>) -<p> - Private slot to refresh the displayed list. -</p><a NAME="PipListDialog.__stopProcess" ID="PipListDialog.__stopProcess"></a> -<h4>PipListDialog.__stopProcess</h4> -<b>__stopProcess</b>(<i></i>) -<p> - Private slot to stop the running process. -</p><a NAME="PipListDialog.__uninstallPackages" ID="PipListDialog.__uninstallPackages"></a> -<h4>PipListDialog.__uninstallPackages</h4> -<b>__uninstallPackages</b>(<i></i>) -<p> - Private slot to uninstall the selected packages. -</p><a NAME="PipListDialog.__upgradeAllPackages" ID="PipListDialog.__upgradeAllPackages"></a> -<h4>PipListDialog.__upgradeAllPackages</h4> -<b>__upgradeAllPackages</b>(<i></i>) -<p> - Private slot to upgrade all listed packages. -</p><a NAME="PipListDialog.__upgradePackages" ID="PipListDialog.__upgradePackages"></a> -<h4>PipListDialog.__upgradePackages</h4> -<b>__upgradePackages</b>(<i></i>) -<p> - Private slot to upgrade the selected packages. -</p><a NAME="PipListDialog.__upgradePip" ID="PipListDialog.__upgradePip"></a> -<h4>PipListDialog.__upgradePip</h4> -<b>__upgradePip</b>(<i></i>) -<p> - Private slot to upgrade pip itself. -</p><a NAME="PipListDialog.closeEvent" ID="PipListDialog.closeEvent"></a> -<h4>PipListDialog.closeEvent</h4> -<b>closeEvent</b>(<i>e</i>) -<p> - Protected slot implementing a close event handler. -</p><dl> -<dt><i>e</i> (QCloseEvent)</dt> -<dd> -close event -</dd> -</dl><a NAME="PipListDialog.on_buttonBox_clicked" ID="PipListDialog.on_buttonBox_clicked"></a> -<h4>PipListDialog.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> (QAbstractButton)</dt> -<dd> -button that was clicked -</dd> -</dl><a NAME="PipListDialog.on_installedFilesCheckBox_clicked" ID="PipListDialog.on_installedFilesCheckBox_clicked"></a> -<h4>PipListDialog.on_installedFilesCheckBox_clicked</h4> -<b>on_installedFilesCheckBox_clicked</b>(<i>checked</i>) -<p> - Private slot to handle a change of the installed files information - checkbox. -</p><dl> -<dt><i>checked</i> (bool)</dt> -<dd> -state of the checkbox -</dd> -</dl><a NAME="PipListDialog.on_localCheckBox_clicked" ID="PipListDialog.on_localCheckBox_clicked"></a> -<h4>PipListDialog.on_localCheckBox_clicked</h4> -<b>on_localCheckBox_clicked</b>(<i>checked</i>) -<p> - Private slot handling the switching of the local mode. -</p><dl> -<dt><i>checked</i> (bool)</dt> -<dd> -state of the local check box -</dd> -</dl><a NAME="PipListDialog.on_notRequiredCheckBox_clicked" ID="PipListDialog.on_notRequiredCheckBox_clicked"></a> -<h4>PipListDialog.on_notRequiredCheckBox_clicked</h4> -<b>on_notRequiredCheckBox_clicked</b>(<i>checked</i>) -<p> - Private slot handling the switching of the 'not required' mode. -</p><dl> -<dt><i>checked</i> (bool)</dt> -<dd> -state of the 'not required' check box -</dd> -</dl><a NAME="PipListDialog.on_packageList_itemSelectionChanged" ID="PipListDialog.on_packageList_itemSelectionChanged"></a> -<h4>PipListDialog.on_packageList_itemSelectionChanged</h4> -<b>on_packageList_itemSelectionChanged</b>(<i></i>) -<p> - Private slot handling the selection of a package. -</p><a NAME="PipListDialog.on_userCheckBox_clicked" ID="PipListDialog.on_userCheckBox_clicked"></a> -<h4>PipListDialog.on_userCheckBox_clicked</h4> -<b>on_userCheckBox_clicked</b>(<i>checked</i>) -<p> - Private slot handling the switching of the 'user-site' mode. -</p><dl> -<dt><i>checked</i> (bool)</dt> -<dd> -state of the 'user-site' check box -</dd> -</dl><a NAME="PipListDialog.on_venvComboBox_activated" ID="PipListDialog.on_venvComboBox_activated"></a> -<h4>PipListDialog.on_venvComboBox_activated</h4> -<b>on_venvComboBox_activated</b>(<i>txt</i>) -<p> - Private slot handling the selection of a virtual environment. -</p><dl> -<dt><i>txt</i> (str)</dt> -<dd> -virtual environment -</dd> -</dl><a NAME="PipListDialog.on_verboseCheckBox_clicked" ID="PipListDialog.on_verboseCheckBox_clicked"></a> -<h4>PipListDialog.on_verboseCheckBox_clicked</h4> -<b>on_verboseCheckBox_clicked</b>(<i>checked</i>) -<p> - Private slot to handle a change of the verbose package information - checkbox. -</p><dl> -<dt><i>checked</i> (bool)</dt> -<dd> -state of the checkbox -</dd> -</dl><a NAME="PipListDialog.start" ID="PipListDialog.start"></a> -<h4>PipListDialog.start</h4> -<b>start</b>(<i></i>) -<p> - Public method to start the command. -</p> -<div align="right"><a href="#top">Up</a></div> -<hr /> -</body></html> \ No newline at end of file
--- a/Documentation/Source/eric6.Plugins.UiExtensionPlugins.PipInterface.PipPackageDetailsDialog.html Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,198 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric6.Plugins.UiExtensionPlugins.PipInterface.PipPackageDetailsDialog</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.PipInterface.PipPackageDetailsDialog</h1> -<p> -Module implementing a dialog to show details about a package. -</p> -<h3>Global Attributes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Classes</h3> -<table> -<tr> -<td><a href="#PipPackageDetailsDialog">PipPackageDetailsDialog</a></td> -<td>Class implementing a dialog to show details about a package.</td> -</tr> -</table> -<h3>Functions</h3> -<table> -<tr><td>None</td></tr> -</table> -<hr /><hr /> -<a NAME="PipPackageDetailsDialog" ID="PipPackageDetailsDialog"></a> -<h2>PipPackageDetailsDialog</h2> -<p> - Class implementing a dialog to show details about a package. -</p> -<h3>Derived from</h3> -QDialog, Ui_PipPackageDetailsDialog -<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="#PipPackageDetailsDialog.__init__">PipPackageDetailsDialog</a></td> -<td>Constructor</td> -</tr><tr> -<td><a href="#PipPackageDetailsDialog.__formatSize">__formatSize</a></td> -<td>Private slot to format the size.</td> -</tr><tr> -<td><a href="#PipPackageDetailsDialog.__formatUploadDate">__formatUploadDate</a></td> -<td>Private method to format the upload date.</td> -</tr><tr> -<td><a href="#PipPackageDetailsDialog.__populateDetails">__populateDetails</a></td> -<td>Private method to populate the details tab.</td> -</tr><tr> -<td><a href="#PipPackageDetailsDialog.__populateDownloadUrls">__populateDownloadUrls</a></td> -<td>Private method to populate the download URLs tab.</td> -</tr><tr> -<td><a href="#PipPackageDetailsDialog.__populateRequiresProvides">__populateRequiresProvides</a></td> -<td>Private method to populate the requires/provides tab.</td> -</tr><tr> -<td><a href="#PipPackageDetailsDialog.__sanitize">__sanitize</a></td> -<td>Private method to clean-up the given text.</td> -</tr> -</table> -<h3>Static Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<a NAME="PipPackageDetailsDialog.__init__" ID="PipPackageDetailsDialog.__init__"></a> -<h4>PipPackageDetailsDialog (Constructor)</h4> -<b>PipPackageDetailsDialog</b>(<i>detailsData, downloadsData, parent=None</i>) -<p> - Constructor -</p><dl> -<dt><i>detailsData</i> (dict)</dt> -<dd> -package details -</dd><dt><i>downloadsData</i> (dict)</dt> -<dd> -downloads information -</dd><dt><i>parent</i> (QWidget)</dt> -<dd> -reference to the parent widget -</dd> -</dl><a NAME="PipPackageDetailsDialog.__formatSize" ID="PipPackageDetailsDialog.__formatSize"></a> -<h4>PipPackageDetailsDialog.__formatSize</h4> -<b>__formatSize</b>(<i>size</i>) -<p> - Private slot to format the size. -</p><dl> -<dt><i>size</i> (int)</dt> -<dd> -size to be formatted -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -formatted size -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -str -</dd> -</dl><a NAME="PipPackageDetailsDialog.__formatUploadDate" ID="PipPackageDetailsDialog.__formatUploadDate"></a> -<h4>PipPackageDetailsDialog.__formatUploadDate</h4> -<b>__formatUploadDate</b>(<i>datetime</i>) -<p> - Private method to format the upload date. -</p><dl> -<dt><i>datetime</i> (xmlrpc.DateTime or str)</dt> -<dd> -upload date and time -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -formatted date string -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -str -</dd> -</dl><a NAME="PipPackageDetailsDialog.__populateDetails" ID="PipPackageDetailsDialog.__populateDetails"></a> -<h4>PipPackageDetailsDialog.__populateDetails</h4> -<b>__populateDetails</b>(<i>detailsData</i>) -<p> - Private method to populate the details tab. -</p><dl> -<dt><i>detailsData</i> (dict)</dt> -<dd> -package details -</dd> -</dl><a NAME="PipPackageDetailsDialog.__populateDownloadUrls" ID="PipPackageDetailsDialog.__populateDownloadUrls"></a> -<h4>PipPackageDetailsDialog.__populateDownloadUrls</h4> -<b>__populateDownloadUrls</b>(<i>downloadsData</i>) -<p> - Private method to populate the download URLs tab. -</p><dl> -<dt><i>downloadsData</i> (dict)</dt> -<dd> -downloads information -</dd> -</dl><a NAME="PipPackageDetailsDialog.__populateRequiresProvides" ID="PipPackageDetailsDialog.__populateRequiresProvides"></a> -<h4>PipPackageDetailsDialog.__populateRequiresProvides</h4> -<b>__populateRequiresProvides</b>(<i>detailsData</i>) -<p> - Private method to populate the requires/provides tab. -</p><dl> -<dt><i>detailsData</i> (dict)</dt> -<dd> -package details -</dd> -</dl><a NAME="PipPackageDetailsDialog.__sanitize" ID="PipPackageDetailsDialog.__sanitize"></a> -<h4>PipPackageDetailsDialog.__sanitize</h4> -<b>__sanitize</b>(<i>text, forUrl=False</i>) -<p> - Private method to clean-up the given text. -</p><dl> -<dt><i>text</i> (str)</dt> -<dd> -raw text -</dd><dt><i>forUrl</i> (bool)</dt> -<dd> -flag indicating to sanitize an URL text -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -processed text -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -str -</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.PipInterface.PipPackagesInputDialog.html Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric6.Plugins.UiExtensionPlugins.PipInterface.PipPackagesInputDialog</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.PipInterface.PipPackagesInputDialog</h1> -<p> -Module implementing a dialog to enter package specifications. -</p> -<h3>Global Attributes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Classes</h3> -<table> -<tr> -<td><a href="#PipPackagesInputDialog">PipPackagesInputDialog</a></td> -<td>Class implementing a dialog to enter package specifications.</td> -</tr> -</table> -<h3>Functions</h3> -<table> -<tr><td>None</td></tr> -</table> -<hr /><hr /> -<a NAME="PipPackagesInputDialog" ID="PipPackagesInputDialog"></a> -<h2>PipPackagesInputDialog</h2> -<p> - Class implementing a dialog to enter package specifications. -</p> -<h3>Derived from</h3> -QDialog, Ui_PipPackagesInputDialog -<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="#PipPackagesInputDialog.__init__">PipPackagesInputDialog</a></td> -<td>Constructor</td> -</tr><tr> -<td><a href="#PipPackagesInputDialog.getData">getData</a></td> -<td>Public method to get the entered data.</td> -</tr><tr> -<td><a href="#PipPackagesInputDialog.on_packagesEdit_textChanged">on_packagesEdit_textChanged</a></td> -<td>Private slot handling entering package names.</td> -</tr> -</table> -<h3>Static Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<a NAME="PipPackagesInputDialog.__init__" ID="PipPackagesInputDialog.__init__"></a> -<h4>PipPackagesInputDialog (Constructor)</h4> -<b>PipPackagesInputDialog</b>(<i>pip, title, install=True, parent=None</i>) -<p> - Constructor -</p><dl> -<dt><i>pip</i> (Pip)</dt> -<dd> -reference to the pip object -</dd><dt><i>title</i> (str)</dt> -<dd> -dialog title -</dd><dt><i>install</i> (bool)</dt> -<dd> -flag indicating an install action -</dd><dt><i>parent</i> (QWidget)</dt> -<dd> -reference to the parent widget -</dd> -</dl><a NAME="PipPackagesInputDialog.getData" ID="PipPackagesInputDialog.getData"></a> -<h4>PipPackagesInputDialog.getData</h4> -<b>getData</b>(<i></i>) -<p> - Public method to get the entered data. -</p><dl> -<dt>Returns:</dt> -<dd> -tuple with the environment name, the list of package - specifications and a flag indicating to install to the user - install directory -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -tuple of (str, list of str, bool) -</dd> -</dl><a NAME="PipPackagesInputDialog.on_packagesEdit_textChanged" ID="PipPackagesInputDialog.on_packagesEdit_textChanged"></a> -<h4>PipPackagesInputDialog.on_packagesEdit_textChanged</h4> -<b>on_packagesEdit_textChanged</b>(<i>txt</i>) -<p> - Private slot handling entering package names. -</p><dl> -<dt><i>txt</i> (str)</dt> -<dd> -name of the requirements file -</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.PipInterface.PipSearchDialog.html Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,321 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric6.Plugins.UiExtensionPlugins.PipInterface.PipSearchDialog</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.PipInterface.PipSearchDialog</h1> -<p> -Module implementing a dialog to search PyPI. -</p> -<h3>Global Attributes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Classes</h3> -<table> -<tr> -<td><a href="#PipSearchDialog">PipSearchDialog</a></td> -<td>Class implementing a dialog to search PyPI.</td> -</tr> -</table> -<h3>Functions</h3> -<table> -<tr><td>None</td></tr> -</table> -<hr /><hr /> -<a NAME="PipSearchDialog" ID="PipSearchDialog"></a> -<h2>PipSearchDialog</h2> -<p> - Class implementing a dialog to search PyPI. -</p> -<h3>Derived from</h3> -QDialog, Ui_PipSearchDialog -<h3>Class Attributes</h3> -<table> -<tr><td>Stopwords</td></tr><tr><td>VersionRole</td></tr> -</table> -<h3>Class Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Methods</h3> -<table> -<tr> -<td><a href="#PipSearchDialog.__init__">PipSearchDialog</a></td> -<td>Constructor</td> -</tr><tr> -<td><a href="#PipSearchDialog.__detailsError">__detailsError</a></td> -<td>Private method handling a details error.</td> -</tr><tr> -<td><a href="#PipSearchDialog.__displayPackageDetails">__displayPackageDetails</a></td> -<td>Private method to display the returned package details.</td> -</tr><tr> -<td><a href="#PipSearchDialog.__finish">__finish</a></td> -<td>Private slot performing the finishing actions.</td> -</tr><tr> -<td><a href="#PipSearchDialog.__getPackageDownloadsData">__getPackageDownloadsData</a></td> -<td>Private method to store the details data and get downloads information.</td> -</tr><tr> -<td><a href="#PipSearchDialog.__install">__install</a></td> -<td>Private slot to install the selected packages.</td> -</tr><tr> -<td><a href="#PipSearchDialog.__processSearchResult">__processSearchResult</a></td> -<td>Private method to process the search result data from PyPI.</td> -</tr><tr> -<td><a href="#PipSearchDialog.__score">__score</a></td> -<td>Private method to calculate some score for a search result.</td> -</tr><tr> -<td><a href="#PipSearchDialog.__search">__search</a></td> -<td>Private method to perform the search.</td> -</tr><tr> -<td><a href="#PipSearchDialog.__searchError">__searchError</a></td> -<td>Private method handling a search error.</td> -</tr><tr> -<td><a href="#PipSearchDialog.__showDetails">__showDetails</a></td> -<td>Private slot to show details about the selected package.</td> -</tr><tr> -<td><a href="#PipSearchDialog.__transformHits">__transformHits</a></td> -<td>Private method to convert the list returned from pypi into a packages list.</td> -</tr><tr> -<td><a href="#PipSearchDialog.closeEvent">closeEvent</a></td> -<td>Protected slot implementing a close event handler.</td> -</tr><tr> -<td><a href="#PipSearchDialog.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="#PipSearchDialog.on_resultList_itemActivated">on_resultList_itemActivated</a></td> -<td>Private slot reacting on an item activation.</td> -</tr><tr> -<td><a href="#PipSearchDialog.on_resultList_itemSelectionChanged">on_resultList_itemSelectionChanged</a></td> -<td>Private slot handling changes of the selection.</td> -</tr><tr> -<td><a href="#PipSearchDialog.on_searchButton_clicked">on_searchButton_clicked</a></td> -<td>Private slot handling a press of the search button.</td> -</tr><tr> -<td><a href="#PipSearchDialog.on_searchEdit_textChanged">on_searchEdit_textChanged</a></td> -<td>Private slot handling a change of the search term.</td> -</tr> -</table> -<h3>Static Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<a NAME="PipSearchDialog.__init__" ID="PipSearchDialog.__init__"></a> -<h4>PipSearchDialog (Constructor)</h4> -<b>PipSearchDialog</b>(<i>pip, indexUrl, parent=None</i>) -<p> - Constructor -</p><dl> -<dt><i>pip</i> (Pip)</dt> -<dd> -reference to the master object -</dd><dt><i>indexUrl</i> (str)</dt> -<dd> -URL of XML RPC interface to the pypi index -</dd><dt><i>parent</i> (QWidget)</dt> -<dd> -reference to the parent widget -</dd> -</dl><a NAME="PipSearchDialog.__detailsError" ID="PipSearchDialog.__detailsError"></a> -<h4>PipSearchDialog.__detailsError</h4> -<b>__detailsError</b>(<i>errorCode, errorString</i>) -<p> - Private method handling a details error. -</p><dl> -<dt><i>errorCode</i> (int)</dt> -<dd> -code of the error -</dd><dt><i>errorString</i> (str)</dt> -<dd> -error message -</dd> -</dl><a NAME="PipSearchDialog.__displayPackageDetails" ID="PipSearchDialog.__displayPackageDetails"></a> -<h4>PipSearchDialog.__displayPackageDetails</h4> -<b>__displayPackageDetails</b>(<i>data</i>) -<p> - Private method to display the returned package details. -</p><dl> -<dt><i>data</i> (tuple)</dt> -<dd> -result data with downloads information in the first element -</dd> -</dl><a NAME="PipSearchDialog.__finish" ID="PipSearchDialog.__finish"></a> -<h4>PipSearchDialog.__finish</h4> -<b>__finish</b>(<i></i>) -<p> - Private slot performing the finishing actions. -</p><a NAME="PipSearchDialog.__getPackageDownloadsData" ID="PipSearchDialog.__getPackageDownloadsData"></a> -<h4>PipSearchDialog.__getPackageDownloadsData</h4> -<b>__getPackageDownloadsData</b>(<i>packageVersion, data</i>) -<p> - Private method to store the details data and get downloads - information. -</p><dl> -<dt><i>packageVersion</i> (str)</dt> -<dd> -version info -</dd><dt><i>data</i> (tuple)</dt> -<dd> -result data with package details in the first - element -</dd> -</dl><a NAME="PipSearchDialog.__install" ID="PipSearchDialog.__install"></a> -<h4>PipSearchDialog.__install</h4> -<b>__install</b>(<i>userSite=False</i>) -<p> - Private slot to install the selected packages. -</p><dl> -<dt><i>userSite</i> (bool)</dt> -<dd> -flag indicating to install to the user directory -</dd> -</dl><a NAME="PipSearchDialog.__processSearchResult" ID="PipSearchDialog.__processSearchResult"></a> -<h4>PipSearchDialog.__processSearchResult</h4> -<b>__processSearchResult</b>(<i>data</i>) -<p> - Private method to process the search result data from PyPI. -</p><dl> -<dt><i>data</i> (tuple)</dt> -<dd> -result data with hits in the first element -</dd> -</dl><a NAME="PipSearchDialog.__score" ID="PipSearchDialog.__score"></a> -<h4>PipSearchDialog.__score</h4> -<b>__score</b>(<i>name, summary</i>) -<p> - Private method to calculate some score for a search result. -</p><dl> -<dt><i>name</i> (str)</dt> -<dd> -name of the returned package -</dd><dt><i>summary</i> (str)</dt> -<dd> -summary text for the package -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -score value -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -int -</dd> -</dl><a NAME="PipSearchDialog.__search" ID="PipSearchDialog.__search"></a> -<h4>PipSearchDialog.__search</h4> -<b>__search</b>(<i></i>) -<p> - Private method to perform the search. -</p><a NAME="PipSearchDialog.__searchError" ID="PipSearchDialog.__searchError"></a> -<h4>PipSearchDialog.__searchError</h4> -<b>__searchError</b>(<i>errorCode, errorString</i>) -<p> - Private method handling a search error. -</p><dl> -<dt><i>errorCode</i> (int)</dt> -<dd> -code of the error -</dd><dt><i>errorString</i> (str)</dt> -<dd> -error message -</dd> -</dl><a NAME="PipSearchDialog.__showDetails" ID="PipSearchDialog.__showDetails"></a> -<h4>PipSearchDialog.__showDetails</h4> -<b>__showDetails</b>(<i></i>) -<p> - Private slot to show details about the selected package. -</p><a NAME="PipSearchDialog.__transformHits" ID="PipSearchDialog.__transformHits"></a> -<h4>PipSearchDialog.__transformHits</h4> -<b>__transformHits</b>(<i>hits</i>) -<p> - Private method to convert the list returned from pypi into a - packages list. -</p><dl> -<dt><i>hits</i> (list of dict)</dt> -<dd> -list returned from pypi -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -list of packages -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -list of dict -</dd> -</dl><a NAME="PipSearchDialog.closeEvent" ID="PipSearchDialog.closeEvent"></a> -<h4>PipSearchDialog.closeEvent</h4> -<b>closeEvent</b>(<i>e</i>) -<p> - Protected slot implementing a close event handler. -</p><dl> -<dt><i>e</i> (QCloseEvent)</dt> -<dd> -close event -</dd> -</dl><a NAME="PipSearchDialog.on_buttonBox_clicked" ID="PipSearchDialog.on_buttonBox_clicked"></a> -<h4>PipSearchDialog.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> (QAbstractButton)</dt> -<dd> -button that was clicked -</dd> -</dl><a NAME="PipSearchDialog.on_resultList_itemActivated" ID="PipSearchDialog.on_resultList_itemActivated"></a> -<h4>PipSearchDialog.on_resultList_itemActivated</h4> -<b>on_resultList_itemActivated</b>(<i>item, column</i>) -<p> - Private slot reacting on an item activation. -</p><dl> -<dt><i>item</i> (QTreeWidgetItem)</dt> -<dd> -reference to the activated item -</dd><dt><i>column</i> (int)</dt> -<dd> -activated column -</dd> -</dl><a NAME="PipSearchDialog.on_resultList_itemSelectionChanged" ID="PipSearchDialog.on_resultList_itemSelectionChanged"></a> -<h4>PipSearchDialog.on_resultList_itemSelectionChanged</h4> -<b>on_resultList_itemSelectionChanged</b>(<i></i>) -<p> - Private slot handling changes of the selection. -</p><a NAME="PipSearchDialog.on_searchButton_clicked" ID="PipSearchDialog.on_searchButton_clicked"></a> -<h4>PipSearchDialog.on_searchButton_clicked</h4> -<b>on_searchButton_clicked</b>(<i></i>) -<p> - Private slot handling a press of the search button. -</p><a NAME="PipSearchDialog.on_searchEdit_textChanged" ID="PipSearchDialog.on_searchEdit_textChanged"></a> -<h4>PipSearchDialog.on_searchEdit_textChanged</h4> -<b>on_searchEdit_textChanged</b>(<i>txt</i>) -<p> - Private slot handling a change of the search term. -</p><dl> -<dt><i>txt</i> (str)</dt> -<dd> -search term -</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.PipInterface.PipSelectionDialog.html Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric6.Plugins.UiExtensionPlugins.PipInterface.PipSelectionDialog</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.PipInterface.PipSelectionDialog</h1> -<p> -Module implementing a dialog to select the pip executable to be used. -</p> -<h3>Global Attributes</h3> -<table> -<tr><td>None</td></tr> -</table> -<h3>Classes</h3> -<table> -<tr> -<td><a href="#PipSelectionDialog">PipSelectionDialog</a></td> -<td>Class implementing a dialog to select the pip executable to be used.</td> -</tr> -</table> -<h3>Functions</h3> -<table> -<tr><td>None</td></tr> -</table> -<hr /><hr /> -<a NAME="PipSelectionDialog" ID="PipSelectionDialog"></a> -<h2>PipSelectionDialog</h2> -<p> - Class implementing a dialog to select the pip executable to be used. -</p> -<h3>Derived from</h3> -QDialog, Ui_PipSelectionDialog -<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="#PipSelectionDialog.__init__">PipSelectionDialog</a></td> -<td>Constructor</td> -</tr><tr> -<td><a href="#PipSelectionDialog.getData">getData</a></td> -<td>Public method to get the entered data.</td> -</tr> -</table> -<h3>Static Methods</h3> -<table> -<tr><td>None</td></tr> -</table> -<a NAME="PipSelectionDialog.__init__" ID="PipSelectionDialog.__init__"></a> -<h4>PipSelectionDialog (Constructor)</h4> -<b>PipSelectionDialog</b>(<i>pip, parent=None</i>) -<p> - Constructor -</p><dl> -<dt><i>pip</i> (Pip)</dt> -<dd> -reference to the pip object -</dd><dt><i>parent</i> (QWidget)</dt> -<dd> -reference to the parent widget -</dd> -</dl><a NAME="PipSelectionDialog.getData" ID="PipSelectionDialog.getData"></a> -<h4>PipSelectionDialog.getData</h4> -<b>getData</b>(<i></i>) -<p> - Public method to get the entered data. -</p><dl> -<dt>Returns:</dt> -<dd> -tuple with the environment name and a flag indicating to - install to the user install directory -</dd> -</dl><dl> -<dt>Return Type:</dt> -<dd> -tuple of (str, bool) -</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.PipInterface.ConfigurationPage.html Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric6.Plugins.UiExtensionPlugins.PipInterface.ConfigurationPage</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.PipInterface.ConfigurationPage</h1> -<p> -Package implementing the configuration page. -</p> - - -<h3>Modules</h3> -<table> -<tr> -<td><a href="eric6.Plugins.UiExtensionPlugins.PipInterface.ConfigurationPage.PipPage.html">PipPage</a></td> -<td>Package implementing the pip configuration page.</td> -</tr> -</table> -</body></html> \ No newline at end of file
--- a/Documentation/Source/index-eric6.Plugins.UiExtensionPlugins.PipInterface.html Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric6.Plugins.UiExtensionPlugins.PipInterface</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.PipInterface</h1> -<p> -Package implementing the various pip dialogs and data. -</p> - -<h3>Packages</h3> -<table> -<tr> -<td><a href="index-eric6.Plugins.UiExtensionPlugins.PipInterface.ConfigurationPage.html">ConfigurationPage</a></td> -<td>Package implementing the configuration page.</td> -</tr> -</table> - -<h3>Modules</h3> -<table> -<tr> -<td><a href="eric6.Plugins.UiExtensionPlugins.PipInterface.Pip.html">Pip</a></td> -<td>Package implementing the pip GUI logic.</td> -</tr><tr> -<td><a href="eric6.Plugins.UiExtensionPlugins.PipInterface.PipDialog.html">PipDialog</a></td> -<td>Module implementing a dialog showing the output of a pip command.</td> -</tr><tr> -<td><a href="eric6.Plugins.UiExtensionPlugins.PipInterface.PipFileSelectionDialog.html">PipFileSelectionDialog</a></td> -<td>Module implementing a dialog to enter a file to be processed.</td> -</tr><tr> -<td><a href="eric6.Plugins.UiExtensionPlugins.PipInterface.PipFreezeDialog.html">PipFreezeDialog</a></td> -<td>Module implementing a dialog to generate a requirements file.</td> -</tr><tr> -<td><a href="eric6.Plugins.UiExtensionPlugins.PipInterface.PipListDialog.html">PipListDialog</a></td> -<td>Module implementing a dialog to list installed packages.</td> -</tr><tr> -<td><a href="eric6.Plugins.UiExtensionPlugins.PipInterface.PipPackageDetailsDialog.html">PipPackageDetailsDialog</a></td> -<td>Module implementing a dialog to show details about a package.</td> -</tr><tr> -<td><a href="eric6.Plugins.UiExtensionPlugins.PipInterface.PipPackagesInputDialog.html">PipPackagesInputDialog</a></td> -<td>Module implementing a dialog to enter package specifications.</td> -</tr><tr> -<td><a href="eric6.Plugins.UiExtensionPlugins.PipInterface.PipSearchDialog.html">PipSearchDialog</a></td> -<td>Module implementing a dialog to search PyPI.</td> -</tr><tr> -<td><a href="eric6.Plugins.UiExtensionPlugins.PipInterface.PipSelectionDialog.html">PipSelectionDialog</a></td> -<td>Module implementing a dialog to select the pip executable to be used.</td> -</tr> -</table> -</body></html> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PipInterface/Pip.py Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,1144 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Package implementing the pip GUI logic. +""" + +from __future__ import unicode_literals +try: + str = unicode # __IGNORE_EXCEPTION__ +except NameError: + pass + +import os +import sys + +from PyQt5.QtCore import pyqtSlot, QObject, QProcess +from PyQt5.QtWidgets import QMenu, QInputDialog, QDialog + +from E5Gui import E5MessageBox +from E5Gui.E5Action import E5Action +from E5Gui.E5Application import e5App + +from .PipDialog import PipDialog +from . import DefaultIndexUrlXml + +import Preferences +import Globals + +import UI.PixmapCache + + +class Pip(QObject): + """ + Class implementing the pip GUI logic. + """ + def __init__(self, plugin, parent=None): + """ + Constructor + + @param plugin reference to the plugin object + @type PipInterfacePlugin + @param parent parent + @type QObject + """ + super(Pip, self).__init__(parent) + + self.__plugin = plugin + self.__ui = parent + + self.__virtualenvManager = e5App().getObject("VirtualEnvManager") + self.__project = e5App().getObject("Project") + + self.__menus = {} # dictionary with references to menus + + self.__plugin.currentEnvironmentChanged.connect( + self.__handleTearOffMenu) + + def initActions(self): + """ + Public method to define the actions. + """ + self.actions = [] + + self.selectEnvironmentAct = E5Action( + self.tr('Virtual Environment for pip'), + self.tr('&Virtual Environment for pip'), + 0, 0, + self, 'pip_select_environment') + self.selectEnvironmentAct.setStatusTip(self.tr( + 'Selects the virtual environment to be used for pip')) + self.selectEnvironmentAct.setWhatsThis(self.tr( + """<b>Virtual Environment for pip</b>""" + """<p>This selects the virtual environment to be used for pip.""" + """</p>""" + )) + self.selectEnvironmentAct.triggered.connect(self.__selectPipVirtualenv) + self.actions.append(self.selectEnvironmentAct) + + ############################################## + ## Actions for listing packages + ############################################## + + self.listPackagesAct = E5Action( + self.tr('List Installed Packages'), + self.tr('&List Installed Packages...'), + 0, 0, + self, 'pip_list_packages') + self.listPackagesAct.setStatusTip(self.tr( + 'List all installed packages with versions')) + self.listPackagesAct.setWhatsThis(self.tr( + """<b>List Installed Packages</b>""" + """<p>This lists all the installed packages together""" + """ with their versions.</p>""" + )) + self.listPackagesAct.triggered.connect(self.__listPackages) + self.actions.append(self.listPackagesAct) + + self.listUptodatePackagesAct = E5Action( + self.tr('List Up-to-date Packages'), + self.tr('List Up-to-&date Packages...'), + 0, 0, + self, 'pip_list_uptodate_packages') + self.listUptodatePackagesAct.setStatusTip(self.tr( + 'List all installed, up-to-date packages with versions')) + self.listUptodatePackagesAct.setWhatsThis(self.tr( + """<b>List Up-to-date Packages</b>""" + """<p>This lists all the installed, up-to-date packages together""" + """ with their versions.</p>""" + )) + self.listUptodatePackagesAct.triggered.connect( + self.__listUptodatePackages) + self.actions.append(self.listUptodatePackagesAct) + + self.listOutdatedPackagesAct = E5Action( + self.tr('List Outdated Packages'), + self.tr('List &Outdated Packages...'), + 0, 0, + self, 'pip_list_outdated_packages') + self.listOutdatedPackagesAct.setStatusTip(self.tr( + 'List all installed, outdated packages with versions')) + self.listOutdatedPackagesAct.setWhatsThis(self.tr( + """<b>List Up-to-date Packages</b>""" + """<p>This lists all the installed, outdated packages together""" + """ with their current and latest versions.</p>""" + )) + self.listOutdatedPackagesAct.triggered.connect( + self.__listOutdatedPackages) + self.actions.append(self.listOutdatedPackagesAct) + + ############################################## + ## Actions for installing packages + ############################################## + + self.installPackagesAct = E5Action( + self.tr('Install Packages'), + self.tr('&Install Packages'), + 0, 0, + self, 'pip_install_packages') + self.installPackagesAct.setStatusTip(self.tr( + 'Install packages according to user input')) + self.installPackagesAct.setWhatsThis(self.tr( + """<b>Install Packages</b>""" + """<p>This installs packages according to user input.</p>""" + )) + self.installPackagesAct.triggered.connect(self.__installPackages) + self.actions.append(self.installPackagesAct) + + self.installLocalPackageAct = E5Action( + self.tr('Install Local Package'), + self.tr('Install Local Package'), + 0, 0, + self, 'pip_install_local_package') + self.installLocalPackageAct.setStatusTip(self.tr( + 'Install a package from local storage')) + self.installLocalPackageAct.setWhatsThis(self.tr( + """<b>Install Local Package</b>""" + """<p>This installs a package available on local storage.</p>""" + )) + self.installLocalPackageAct.triggered.connect( + self.__installLocalPackage) + self.actions.append(self.installLocalPackageAct) + + self.installRequirementsAct = E5Action( + self.tr('Install Requirements'), + self.tr('Install Requirements'), + 0, 0, + self, 'pip_install_requirements') + self.installRequirementsAct.setStatusTip(self.tr( + 'Install packages according to a requirements file')) + self.installRequirementsAct.setWhatsThis(self.tr( + """<b>Install Requirements</b>""" + """<p>This installs packages according to a requirements""" + """ file.</p>""" + )) + self.installRequirementsAct.triggered.connect( + self.__installRequirements) + self.actions.append(self.installRequirementsAct) + + self.installPipAct = E5Action( + self.tr('Install Pip'), + self.tr('Install Pip'), + 0, 0, + self, 'pip_install_pip') + self.installPipAct.setStatusTip(self.tr( + 'Install the pip package itself')) + self.installPipAct.setWhatsThis(self.tr( + """<b>Install Pip</b>""" + """<p>This installs the pip package itself.</p>""" + )) + self.installPipAct.triggered.connect(self.__installPip) + self.actions.append(self.installPipAct) + + self.repairPipAct = E5Action( + self.tr('Repair Pip'), + self.tr('Repair Pip'), + 0, 0, + self, 'pip_repair_pip') + self.repairPipAct.setStatusTip(self.tr( + 'Repair the pip package')) + self.repairPipAct.setWhatsThis(self.tr( + """<b>Repair Pip</b>""" + """<p>This repairs the pip package by re-installing it.</p>""" + )) + self.repairPipAct.triggered.connect(self.__repairPip) + self.actions.append(self.repairPipAct) + + self.upgradePipAct = E5Action( + self.tr('Upgrade Pip'), + self.tr('Upgrade &Pip'), + 0, 0, + self, 'pip_upgrade_pip') + self.upgradePipAct.setStatusTip(self.tr( + 'Upgrade the pip package itself')) + self.upgradePipAct.setWhatsThis(self.tr( + """<b>Upgrade Pip</b>""" + """<p>This upgrades the pip package itself.</p>""" + )) + self.upgradePipAct.triggered.connect(self.upgradePip) + self.actions.append(self.upgradePipAct) + + self.upgradePackagesAct = E5Action( + self.tr('Upgrade Packages'), + self.tr('&Upgrade Packages'), + 0, 0, + self, 'pip_upgrade_packages') + self.upgradePackagesAct.setStatusTip(self.tr( + 'Upgrade packages according to user input')) + self.upgradePackagesAct.setWhatsThis(self.tr( + """<b>Upgrade Packages</b>""" + """<p>This upgrades packages according to user input.</p>""" + )) + self.upgradePackagesAct.triggered.connect(self.__upgradePackages) + self.actions.append(self.upgradePackagesAct) + + ############################################## + ## Actions for uninstalling packages + ############################################## + + self.uninstallPackagesAct = E5Action( + self.tr('Uninstall Packages'), + self.tr('Uninstall Packages'), + 0, 0, + self, 'pip_uninstall_packages') + self.uninstallPackagesAct.setStatusTip(self.tr( + 'Uninstall packages according to user input')) + self.uninstallPackagesAct.setWhatsThis(self.tr( + """<b>Uninstall Packages</b>""" + """<p>This uninstalls packages according to user input.</p>""" + )) + self.uninstallPackagesAct.triggered.connect(self.__uninstallPackages) + self.actions.append(self.uninstallPackagesAct) + + self.uninstallRequirementsAct = E5Action( + self.tr('Uninstall Requirements'), + self.tr('Uninstall Requirements'), + 0, 0, + self, 'pip_uninstall_requirements') + self.uninstallRequirementsAct.setStatusTip(self.tr( + 'Uninstall packages according to a requirements file')) + self.uninstallRequirementsAct.setWhatsThis(self.tr( + """<b>Uninstall Requirements</b>""" + """<p>This uninstalls packages according to a requirements""" + """ file.</p>""" + )) + self.uninstallRequirementsAct.triggered.connect( + self.__uninstallRequirements) + self.actions.append(self.uninstallRequirementsAct) + + ############################################## + ## Actions for generating requirements files + ############################################## + + self.generateRequirementsAct = E5Action( + self.tr('Generate Requirements'), + self.tr('&Generate Requirements...'), + 0, 0, + self, 'pip_generate_requirements') + self.generateRequirementsAct.setStatusTip(self.tr( + 'Generate the contents of a requirements file')) + self.generateRequirementsAct.setWhatsThis(self.tr( + """<b>Generate Requirements</b>""" + """<p>This generates the contents of a requirements file.</p>""" + )) + self.generateRequirementsAct.triggered.connect( + self.__generateRequirements) + self.actions.append(self.generateRequirementsAct) + + ############################################## + ## Actions for generating requirements files + ############################################## + + self.searchPyPIAct = E5Action( + self.tr('Search PyPI'), + self.tr('&Search PyPI...'), + 0, 0, + self, 'pip_search_pypi') + self.searchPyPIAct.setStatusTip(self.tr( + 'Open a dialog to search the Python Package Index')) + self.searchPyPIAct.setWhatsThis(self.tr( + """<b>Search PyPI</b>""" + """<p>This opens a dialog to search the Python Package""" + """ Index.</p>""" + )) + self.searchPyPIAct.triggered.connect(self.__searchPyPI) + self.actions.append(self.searchPyPIAct) + + ############################################## + ## Actions for editing configuration files + ############################################## + + self.editUserConfigAct = E5Action( + self.tr('Edit User Configuration'), + self.tr('Edit User Configuration...'), + 0, 0, + self, 'pip_edit_user_config') + self.editUserConfigAct.setStatusTip(self.tr( + 'Open the per user configuration file in an editor')) + self.editUserConfigAct.setWhatsThis(self.tr( + """<b>Edit User Configuration</b>""" + """<p>This opens the per user configuration file in an editor.""" + """</p>""" + )) + self.editUserConfigAct.triggered.connect(self.__editUserConfiguration) + self.actions.append(self.editUserConfigAct) + + self.editVirtualenvConfigAct = E5Action( + self.tr('Edit Current Virtualenv Configuration'), + self.tr('Edit Current Virtualenv Configuration...'), + 0, 0, + self, 'pip_edit_virtualenv_config') + self.editVirtualenvConfigAct.setStatusTip(self.tr( + 'Open the current virtualenv configuration file in an editor')) + self.editVirtualenvConfigAct.setWhatsThis(self.tr( + """<b>Edit Current Virtualenv Configuration</b>""" + """<p>This opens the current virtualenv configuration file in""" + """ an editor. </p>""" + )) + self.editVirtualenvConfigAct.triggered.connect( + self.__editVirtualenvConfiguration) + self.actions.append(self.editVirtualenvConfigAct) + + self.pipConfigAct = E5Action( + self.tr('Configure'), + self.tr('Configure...'), + 0, 0, self, 'pip_configure') + self.pipConfigAct.setStatusTip(self.tr( + 'Show the configuration dialog with the Python Package Management' + ' page selected' + )) + self.pipConfigAct.setWhatsThis(self.tr( + """<b>Configure</b>""" + """<p>Show the configuration dialog with the Python Package""" + """ Management page selected.</p>""" + )) + self.pipConfigAct.triggered.connect(self.__pipConfigure) + self.actions.append(self.pipConfigAct) + + def initMenu(self): + """ + Public slot to initialize the menu. + + @return the menu generated + @rtype QMenu + """ + self.__menus = {} # clear menus references + + menu = QMenu(self.tr('P&ython Package Management'), self.__ui) + menu.setTearOffEnabled(True) + menu.setIcon(UI.PixmapCache.getIcon("pypi.png")) + + menu.addAction(self.selectEnvironmentAct) + menu.addSeparator() + menu.addAction(self.listPackagesAct) + menu.addAction(self.listUptodatePackagesAct) + menu.addAction(self.listOutdatedPackagesAct) + menu.addSeparator() + menu.addAction(self.installPipAct) + menu.addSeparator() + menu.addAction(self.installPackagesAct) + menu.addAction(self.installLocalPackageAct) + menu.addAction(self.installRequirementsAct) + menu.addSeparator() + menu.addAction(self.upgradePipAct) + menu.addAction(self.upgradePackagesAct) + menu.addSeparator() + menu.addAction(self.uninstallPackagesAct) + menu.addAction(self.uninstallRequirementsAct) + menu.addSeparator() + menu.addAction(self.generateRequirementsAct) + menu.addSeparator() + menu.addAction(self.searchPyPIAct) + menu.addSeparator() + menu.addAction(self.repairPipAct) + menu.addSeparator() + menu.addAction(self.editUserConfigAct) + menu.addAction(self.editVirtualenvConfigAct) + menu.addSeparator() + menu.addAction(self.pipConfigAct) + + self.__menus["main"] = menu + + menu.aboutToShow.connect(self.__aboutToShowMenu) + + return menu + + def __aboutToShowMenu(self): + """ + Private slot to set the action enabled status. + """ + enable = bool(self.__plugin.getPreferences("CurrentEnvironment")) + for act in self.actions: + if act not in [self.selectEnvironmentAct, + self.installPipAct, + self.editUserConfigAct, + self.editVirtualenvConfigAct, + self.pipConfigAct]: + act.setEnabled(enable) + + def getMenu(self, name): + """ + Public method to get a reference to the requested menu. + + @param name name of the menu + @type str + @return reference to the menu or None, if no + menu with the given name exists + @rtype QMenu or None + """ + if name in self.__menus: + return self.__menus[name] + else: + return None + + def getMenuNames(self): + """ + Public method to get the names of all menus. + + @return menu names + @rtype list of str + """ + return list(self.__menus.keys()) + + def __handleTearOffMenu(self, venvName): + """ + Private slot to handle a change of the selected virtual environment. + + @param venvName logical name of the virtual environment + @type str + """ + if self.__menus["main"].isTearOffMenuVisible(): + # determine, if torn off menu needs to be refreshed + enabled = self.listPackagesAct.isEnabled() + if ((bool(venvName) and not enabled) or + (not bool(venvName) and enabled)): + self.__menus["main"].hideTearOffMenu() + + ########################################################################## + ## Methods below implement some utility functions + ########################################################################## + + def runProcess(self, args, interpreter): + """ + Public method to execute the current pip with the given arguments. + + The selected pip executable is called with the given arguments and + waited for its end. + + @param args list of command line arguments + @type list of str + @param interpreter path of the Python interpreter to be used + @type str + @return tuple containing a flag indicating success and the output + of the process + @rtype tuple of (bool, str) + """ + ioEncoding = Preferences.getSystem("IOEncoding") + + process = QProcess() + process.start(interpreter, args) + procStarted = process.waitForStarted() + if procStarted: + finished = process.waitForFinished(30000) + if finished: + if process.exitCode() == 0: + output = str(process.readAllStandardOutput(), ioEncoding, + 'replace') + return True, output + else: + return (False, + self.tr("python exited with an error ({0}).") + .format(process.exitCode())) + else: + process.terminate() + process.waitForFinished(2000) + process.kill() + process.waitForFinished(3000) + return False, self.tr("python did not finish within" + " 30 seconds.") + + return False, self.tr("python could not be started.") + + def __getUserConfig(self): + """ + Private method to get the name of the user configuration file. + + @return path of the user configuration file + @rtype str + """ + # Unix: ~/.config/pip/pip.conf + # OS X: ~/Library/Application Support/pip/pip.conf + # Windows: %APPDATA%\pip\pip.ini + # Environment: $PIP_CONFIG_FILE + + try: + return os.environ["PIP_CONFIG_FILE"] + except KeyError: + pass + + if Globals.isWindowsPlatform(): + config = os.path.join(os.environ["APPDATA"], "pip", "pip.ini") + elif Globals.isMacPlatform(): + config = os.path.expanduser( + "~/Library/Application Support/pip/pip.conf") + else: + config = os.path.expanduser("~/.config/pip/pip.conf") + + return config + + def __getVirtualenvConfig(self): + """ + Private method to get the name of the virtualenv configuration file. + + @return path of the virtualenv configuration file + @rtype str + """ + # Unix, OS X: $VIRTUAL_ENV/pip.conf + # Windows: %VIRTUAL_ENV%\pip.ini + + if Globals.isWindowsPlatform(): + pip = "pip.ini" + else: + pip = "pip.conf" + try: + venvDirectory = os.environ["VIRTUAL_ENV"] + except KeyError: + venvName = self.__plugin.getPreferences("CurrentEnvironment") + if not venvName: + self.__selectPipVirtualenv() + venvName = self.__plugin.getPreferences("CurrentEnvironment") + if self.__virtualenvManager.isGlobalEnvironment(venvName): + venvDirectory = self.__getUserConfig() + else: + venvDirectory = \ + self.__virtualenvManager.getVirtualenvDirectory(venvName) + + return os.path.join(venvDirectory, pip) + + def getDefaultEnvironmentString(self): + """ + Public method to get the string for the default environment. + + @return string for the default environment + @rtype str + """ + return self.tr("<standard>") + + def getProjectEnvironmentString(self): + """ + Public method to get the string for the project environment. + + @return string for the project environment + @rtype str + """ + if self.__project.isOpen(): + return self.tr("<project>") + else: + return "" + + def getVirtualenvInterpreter(self, venvName): + """ + Public method to get the interpreter for a virtual environment. + + @param venvName logical name for the virtual environment + @type str + @return interpreter path + @rtype str + """ + if venvName == self.getDefaultEnvironmentString(): + venvName = self.__plugin.getPreferences("CurrentEnvironment") + elif venvName == self.getProjectEnvironmentString(): + venvName = self.__project.getDebugProperty("VIRTUALENV") + if not venvName: + # fall back to standard if not defined + venvName = self.__plugin.getPreferences("CurrentEnvironment") + + interpreter = self.__virtualenvManager.getVirtualenvInterpreter( + venvName) + if not interpreter: + E5MessageBox.critical( + None, + self.tr("Interpreter for Virtual Environment"), + self.tr("""No interpreter configured for the selected""" + """ virtual environment.""")) + + return interpreter + + def getVirtualenvNames(self): + """ + Public method to get a sorted list of virtual environment names. + + @return sorted list of virtual environment names + @rtype list of str + """ + return sorted(self.__virtualenvManager.getVirtualenvNames()) + + ########################################################################## + ## Methods below implement the individual menu entries + ########################################################################## + + def __selectPipVirtualenv(self): + """ + Private method to select the virtual environment to be used. + """ + environments = self.getVirtualenvNames() + if environments: + currentEnvironment = self.__plugin.getPreferences( + "CurrentEnvironment") + try: + index = environments.index(currentEnvironment) + except ValueError: + index = 0 + environment, ok = QInputDialog.getItem( + None, + self.tr("Virtual Environment for pip"), + self.tr("Select the virtual environment to be used:"), + environments, index, False) + + if ok and environment: + self.__plugin.setPreferences("CurrentEnvironment", + environment) + else: + E5MessageBox.warning( + None, + self.tr("Virtual Environment for pip"), + self.tr("""No virtual environments have been configured yet.""" + """ Please use the Virtualenv Manager to do that.""")) + + def __listPackages(self): + """ + Private slot to list all installed packages. + """ + from .PipListDialog import PipListDialog + self.__listDialog = PipListDialog( + self, "list", self.__plugin.getPreferences("PipSearchIndex"), + self.tr("Installed Packages")) + self.__listDialog.show() + self.__listDialog.start() + + def __listUptodatePackages(self): + """ + Private slot to list all installed, up-to-date packages. + """ + from .PipListDialog import PipListDialog + self.__listUptodateDialog = PipListDialog( + self, "uptodate", self.__plugin.getPreferences("PipSearchIndex"), + self.tr("Up-to-date Packages")) + self.__listUptodateDialog.show() + self.__listUptodateDialog.start() + + def __listOutdatedPackages(self): + """ + Private slot to list all installed, up-to-date packages. + """ + from .PipListDialog import PipListDialog + self.__listOutdatedDialog = PipListDialog( + self, "outdated", self.__plugin.getPreferences("PipSearchIndex"), + self.tr("Outdated Packages")) + self.__listOutdatedDialog.show() + self.__listOutdatedDialog.start() + + def __editUserConfiguration(self): + """ + Private slot to edit the user configuration. + """ + self.__editConfiguration() + + def __editVirtualenvConfiguration(self): + """ + Private slot to edit the current virtualenv configuration. + """ + self.__editConfiguration(virtualenv=True) + + def __editConfiguration(self, virtualenv=False): + """ + Private method to edit a configuration. + + @param virtualenv flag indicating to edit the current virtualenv + configuration file + @type bool + """ + from QScintilla.MiniEditor import MiniEditor + if virtualenv: + cfgFile = self.__getVirtualenvConfig() + else: + cfgFile = self.__getUserConfig() + cfgDir = os.path.dirname(cfgFile) + if not cfgDir: + E5MessageBox.critical( + None, + self.tr("Edit Configuration"), + self.tr("""No valid configuration path determined.""" + """ Is a virtual environment selected? Aborting""")) + return + + try: + if not os.path.isdir(cfgDir): + os.makedirs(cfgDir) + except OSError: + E5MessageBox.critical( + None, + self.tr("Edit Configuration"), + self.tr("""No valid configuration path determined.""" + """ Is a virtual environment selected? Aborting""")) + return + + if not os.path.exists(cfgFile): + try: + f = open(cfgFile, "w") + f.write("[global]\n") + f.close() + except (IOError, OSError): + # ignore these + pass + + # check, if the destination is writeable + if not os.access(cfgFile, os.W_OK): + E5MessageBox.critical( + None, + self.tr("Edit Configuration"), + self.tr("""No valid configuartion path determined.""" + """ Is a virtual environment selected? Aborting""")) + return + + self.__editor = MiniEditor(cfgFile, "Properties") + self.__editor.show() + + def __installPip(self, userSite=False): + """ + Private slot to install pip. + + @param userSite flag indicating an install to the user install + directory + @type bool + """ + from .PipSelectionDialog import PipSelectionDialog + dlg = PipSelectionDialog(self) + if dlg.exec_() != QDialog.Accepted: + return + + venvName, userSite = dlg.getData() + interpreter = self.getVirtualenvInterpreter(venvName) + if not interpreter: + return + + dia = PipDialog(self.tr('Install PIP')) + if userSite: + commands = [(interpreter, ["-m", "ensurepip", "--user"])] + else: + commands = [(interpreter, ["-m", "ensurepip"])] + if self.__plugin.getPreferences("PipSearchIndex"): + indexUrl = \ + self.__plugin.getPreferences("PipSearchIndex") + "/simple" + args = ["-m", "pip", "install", "--index-url", indexUrl, + "--upgrade"] + else: + args = ["-m", "pip", "install", "--upgrade"] + if userSite: + args.append("--user") + args.append("pip") + commands.append((interpreter, args[:])) + + res = dia.startProcesses(commands) + if res: + dia.exec_() + + @pyqtSlot() + def upgradePip(self, venvName="", userSite=False): + """ + Public method to upgrade pip itself. + + @param venvName name of the virtual environment to be used + @type str + @param userSite flag indicating an install to the user install + directory + @type bool + @return flag indicating a successful execution + @rtype bool + """ + # Upgrading pip needs to be treated specially because + # it must be done using the python executable + + if not venvName: + from .PipSelectionDialog import PipSelectionDialog + dlg = PipSelectionDialog(self) + if dlg.exec_() != QDialog.Accepted: + return + + venvName, userSite = dlg.getData() + + interpreter = self.getVirtualenvInterpreter(venvName) + if not interpreter: + return + + if self.__plugin.getPreferences("PipSearchIndex"): + indexUrl = \ + self.__plugin.getPreferences("PipSearchIndex") + "/simple" + args = ["-m", "pip", "install", "--index-url", indexUrl, + "--upgrade"] + else: + args = ["-m", "pip", "install", "--upgrade"] + if userSite: + args.append("--user") + args.append("pip") + + dia = PipDialog(self.tr('Upgrade PIP')) + res = dia.startProcess(interpreter, args) + if res: + dia.exec_() + return res + + @pyqtSlot() + def __repairPip(self): + """ + Private method to repair the pip installation. + + @return flag indicating a successful execution + @rtype bool + """ + from .PipSelectionDialog import PipSelectionDialog + dlg = PipSelectionDialog(self) + if dlg.exec_() != QDialog.Accepted: + return False + + venvName, userSite = dlg.getData() + interpreter = self.getVirtualenvInterpreter(venvName) + if not interpreter: + return + + # python -m pip install --ignore-installed pip + if self.__plugin.getPreferences("PipSearchIndex"): + indexUrl = \ + self.__plugin.getPreferences("PipSearchIndex") + "/simple" + args = ["-m", "pip", "install", "--index-url", indexUrl, + "--ignore-installed"] + else: + args = ["-m", "pip", "install", "--ignore-installed"] + if userSite: + args.append("--user") + args.append("pip") + + dia = PipDialog(self.tr('Repair PIP')) + res = dia.startProcess(interpreter, args) + if res: + dia.exec_() + + def __checkUpgradePyQt(self, packages): + """ + Private method to check, if an upgrade of PyQt packages is attempted. + + @param packages list of packages to upgrade + @type list of str + @return flag indicating to abort the upgrade attempt + @rtype bool + """ + pyqtPackages = [p for p in packages + if p.lower() in ["pyqt5", "qscintilla", "sip"]] + + if bool(pyqtPackages): + abort = not E5MessageBox.yesNo( + None, + self.tr("Upgrade Packages"), + self.tr( + """You are trying to upgrade PyQt packages. This will""" + """ not work for the current instance of Python ({0}).""" + """ Do you want to continue?""").format(sys.executable), + icon=E5MessageBox.Critical) + else: + abort = False + + return abort + + def upgradePackages(self, packages, venvName="", userSite=False): + """ + Public method to upgrade the given list of packages. + + @param packages list of packages to upgrade + @type list of str + @param venvName name of the virtual environment to be used + @type str + @param userSite flag indicating an install to the user install + directory + @type bool + @return flag indicating a successful execution + @rtype bool + """ + if self.__checkUpgradePyQt(packages): + return False + + if not venvName: + venvName = self.__plugin.getPreferences("CurrentEnvironment") + interpreter = self.getVirtualenvInterpreter(venvName) + if not interpreter: + return + + if self.__plugin.getPreferences("PipSearchIndex"): + indexUrl = \ + self.__plugin.getPreferences("PipSearchIndex") + "/simple" + args = ["-m", "pip", "install", "--index-url", indexUrl, + "--upgrade"] + else: + args = ["-m", "pip", "install", "--upgrade"] + if userSite: + args.append("--user") + args += packages + dia = PipDialog(self.tr('Upgrade Packages')) + res = dia.startProcess(interpreter, args) + if res: + dia.exec_() + return res + + def __upgradePackages(self): + """ + Private slot to upgrade packages to be given by the user. + """ + from .PipPackagesInputDialog import PipPackagesInputDialog + dlg = PipPackagesInputDialog(self, self.tr("Upgrade Packages")) + if dlg.exec_() == QDialog.Accepted: + venvName, packages, user = dlg.getData() + if packages: + self.upgradePackages(packages, venvName=venvName, + userSite=user) + + def installPackages(self, packages, venvName="", userSite=False): + """ + Public method to install the given list of packages. + + @param packages list of packages to install + @type list of str + @param venvName name of the virtual environment to be used + @type str + @param userSite flag indicating an install to the user install + directory + @type bool + """ + if not venvName: + venvName = self.__plugin.getPreferences("CurrentEnvironment") + interpreter = self.getVirtualenvInterpreter(venvName) + if not interpreter: + return + + if self.__plugin.getPreferences("PipSearchIndex"): + indexUrl = \ + self.__plugin.getPreferences("PipSearchIndex") + "/simple" + args = ["-m", "pip", "install", "--index-url", indexUrl] + else: + args = ["-m", "pip", "install"] + if userSite: + args.append("--user") + args += packages + dia = PipDialog(self.tr('Install Packages')) + res = dia.startProcess(interpreter, args) + if res: + dia.exec_() + + def __installPackages(self): + """ + Private slot to install packages to be given by the user. + """ + from .PipPackagesInputDialog import PipPackagesInputDialog + dlg = PipPackagesInputDialog( + self, self.tr("Install Packages")) + if dlg.exec_() == QDialog.Accepted: + venvName, packages, user = dlg.getData() + if packages: + self.installPackages(packages, venvName=venvName, + userSite=user) + + def __installLocalPackage(self): + """ + Private slot to install a package available on local storage. + """ + from .PipFileSelectionDialog import PipFileSelectionDialog + dlg = PipFileSelectionDialog(self, "package") + if dlg.exec_() == QDialog.Accepted: + venvName, package, user = dlg.getData() + if package and os.path.exists(package): + self.installPackages([package], venvName=venvName, + userSite=user) + + def __installRequirements(self): + """ + Private slot to install packages as given in a requirements file. + """ + from .PipFileSelectionDialog import PipFileSelectionDialog + dlg = PipFileSelectionDialog(self, "requirements") + if dlg.exec_() == QDialog.Accepted: + venvName, requirements, user = dlg.getData() + if requirements and os.path.exists(requirements): + interpreter = self.getVirtualenvInterpreter(venvName) + if not interpreter: + return + if self.__plugin.getPreferences("PipSearchIndex"): + indexUrl = \ + self.__plugin.getPreferences("PipSearchIndex") + \ + "/simple" + args = ["-m", "pip", "install", "--index-url", indexUrl] + else: + args = ["-m", "pip", "install"] + if user: + args.append("--user") + args += ["--requirement", requirements] + dia = PipDialog(self.tr('Install Packages from Requirements')) + res = dia.startProcess(interpreter, args) + if res: + dia.exec_() + + def uninstallPackages(self, packages, venvName=""): + """ + Public method to uninstall the given list of packages. + + @param packages list of packages to uninstall + @type list of str + @param venvName name of the virtual environment to be used + @type str + @return flag indicating a successful execution + @rtype bool + """ + res = False + if packages: + from UI.DeleteFilesConfirmationDialog import \ + DeleteFilesConfirmationDialog + dlg = DeleteFilesConfirmationDialog( + self.parent(), + self.tr("Uninstall Packages"), + self.tr( + "Do you really want to uninstall these packages?"), + packages) + if dlg.exec_() == QDialog.Accepted: + if not venvName: + venvName = self.__plugin.getPreferences( + "CurrentEnvironment") + interpreter = self.getVirtualenvInterpreter(venvName) + if not interpreter: + return + args = ["-m", "pip", "uninstall", "--yes"] + packages + dia = PipDialog(self.tr('Uninstall Packages')) + res = dia.startProcess(interpreter, args) + if res: + dia.exec_() + return res + + def __uninstallPackages(self): + """ + Private slot to uninstall packages to be given by the user. + """ + from .PipPackagesInputDialog import PipPackagesInputDialog + dlg = PipPackagesInputDialog( + self, self.tr("Uninstall Packages"), install=False) + if dlg.exec_() == QDialog.Accepted: + venvName, packages, _user = dlg.getData() + if packages: + self.uninstallPackages(packages, venvName=venvName) + + def __uninstallRequirements(self): + """ + Private slot to uninstall packages as given in a requirements file. + """ + from .PipFileSelectionDialog import PipFileSelectionDialog + dlg = PipFileSelectionDialog(self, "requirements", + install=False) + if dlg.exec_() == QDialog.Accepted: + venvName, requirements, _user = dlg.getData() + if requirements and os.path.exists(requirements): + try: + f = open(requirements, "r") + reqs = f.read().splitlines() + f.close() + except (OSError, IOError): + return + + from UI.DeleteFilesConfirmationDialog import \ + DeleteFilesConfirmationDialog + dlg = DeleteFilesConfirmationDialog( + self.parent(), + self.tr("Uninstall Packages"), + self.tr( + "Do you really want to uninstall these packages?"), + reqs) + if dlg.exec_() == QDialog.Accepted: + if not venvName: + venvName = self.__plugin.getPreferences( + "CurrentEnvironment") + interpreter = self.getVirtualenvInterpreter(venvName) + if not interpreter: + return + args = ["-m", "pip", "uninstall", "--requirement", + requirements] + dia = PipDialog( + self.tr('Uninstall Packages from Requirements')) + res = dia.startProcess(interpreter, args) + if res: + dia.exec_() + + def __generateRequirements(self): + """ + Private slot to generate the contents for a requirements file. + """ + from .PipFreezeDialog import PipFreezeDialog + self.__freezeDialog = PipFreezeDialog(self) + self.__freezeDialog.show() + self.__freezeDialog.start() + + def __searchPyPI(self): + """ + Private slot to search the Python Package Index. + """ + from .PipSearchDialog import PipSearchDialog + + if self.__plugin.getPreferences("PipSearchIndex"): + indexUrl = self.__plugin.getPreferences("PipSearchIndex") + "/pypi" + else: + indexUrl = DefaultIndexUrlXml + + self.__searchDialog = PipSearchDialog(self, indexUrl) + self.__searchDialog.show() + + def __pipConfigure(self): + """ + Private slot to open the configuration page. + """ + e5App().getObject("UserInterface").showPreferences("pipPage")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PipInterface/PipDialog.py Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,205 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog showing the output of a pip command. +""" + +from __future__ import unicode_literals +try: + str = unicode # __IGNORE_EXCEPTION__ +except NameError: + pass + +from PyQt5.QtCore import pyqtSlot, Qt, QCoreApplication, QTimer, \ + QProcess +from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton + +from E5Gui import E5MessageBox + +from .Ui_PipDialog import Ui_PipDialog + +import Preferences + + +class PipDialog(QDialog, Ui_PipDialog): + """ + Class implementing a dialog showing the output of a 'python -m pip' + command. + """ + def __init__(self, text, parent=None): + """ + Constructor + + @param text text to be shown by the label + @type str + @param parent reference to the parent widget + @type QWidget + """ + super(PipDialog, self).__init__(parent) + self.setupUi(self) + + self.proc = None + self.__processQueue = [] + self.__ioEncoding = Preferences.getSystem("IOEncoding") + + self.outputGroup.setTitle(text) + + self.show() + QCoreApplication.processEvents() + + def closeEvent(self, e): + """ + Protected slot implementing a close event handler. + + @param e close event + @type QCloseEvent + """ + self.__processQueue = [] + + if self.proc is not None and \ + self.proc.state() != QProcess.NotRunning: + self.proc.terminate() + QTimer.singleShot(2000, self.proc.kill) + self.proc.waitForFinished(3000) + + self.proc = None + + e.accept() + + def __finish(self): + """ + Private slot called when the process finished or the user pressed + the button. + """ + if self.proc is not None and \ + self.proc.state() != QProcess.NotRunning: + self.proc.terminate() + QTimer.singleShot(2000, self.proc.kill) + self.proc.waitForFinished(3000) + + self.proc = None + + self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) + self.buttonBox.button(QDialogButtonBox.Close).setFocus( + Qt.OtherFocusReason) + + if self.__processQueue: + cmd, args = self.__processQueue.pop(0) + self.__addOutput("\n\n") + self.startProcess(cmd, args) + + @pyqtSlot(QAbstractButton) + def on_buttonBox_clicked(self, button): + """ + Private slot called by a button of the button box clicked. + + @param button button that was clicked + @type QAbstractButton + """ + if button == self.buttonBox.button(QDialogButtonBox.Close): + self.close() + + def __procFinished(self, exitCode, exitStatus): + """ + Private slot connected to the finished signal. + + @param exitCode exit code of the process + @type int + @param exitStatus exit status of the process + @type QProcess.ExitStatus + """ + self.__finish() + + def startProcess(self, cmd, args, showArgs=True): + """ + Public slot used to start the process. + + @param cmd name of the pip executable to be used + @type str + @param args list of arguments for the process + @type list of str + @keyparam showArgs flag indicating to show the arguments + @type bool + @return flag indicating a successful start of the process + @rtype bool + """ + if len(self.errors.toPlainText()) == 0: + self.errorGroup.hide() + + if showArgs: + self.resultbox.append(cmd + ' ' + ' '.join(args)) + self.resultbox.append('') + + self.proc = QProcess() + self.proc.finished.connect(self.__procFinished) + self.proc.readyReadStandardOutput.connect(self.__readStdout) + self.proc.readyReadStandardError.connect(self.__readStderr) + self.proc.start(cmd, args) + procStarted = self.proc.waitForStarted(5000) + if not procStarted: + self.buttonBox.setFocus() + E5MessageBox.critical( + self, + self.tr('Process Generation Error'), + self.tr( + 'The process {0} could not be started.' + ).format(cmd)) + return procStarted + + def startProcesses(self, processParams): + """ + Public method to issue a list of commands to be executed. + + @param processParams list of tuples containing the command + and arguments + @type list of tuples of (str, list of str) + @return flag indicating a successful start of the first process + @rtype bool + """ + if len(processParams) > 1: + for cmd, args in processParams[1:]: + self.__processQueue.append((cmd, args[:])) + cmd, args = processParams[0] + return self.startProcess(cmd, args) + + 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. + """ + if self.proc is not None: + txt = str(self.proc.readAllStandardOutput(), + self.__ioEncoding, 'replace') + self.__addOutput(txt) + + def __addOutput(self, txt): + """ + Private method to add some text to the output pane. + + @param txt text to be added + @type str + """ + self.resultbox.insertPlainText(txt) + self.resultbox.ensureCursorVisible() + QCoreApplication.processEvents() + + 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. + """ + if self.proc is not None: + s = str(self.proc.readAllStandardError(), + self.__ioEncoding, 'replace') + self.errorGroup.show() + self.errors.insertPlainText(s) + self.errors.ensureCursorVisible() + + QCoreApplication.processEvents()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PipInterface/PipDialog.ui Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PipDialog</class> + <widget class="QDialog" name="PipDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>500</height> + </rect> + </property> + <property name="windowTitle"> + <string>pip</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout"> + <item> + <widget class="QGroupBox" name="outputGroup"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>2</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Output</string> + </property> + <layout class="QVBoxLayout"> + <item> + <widget class="QTextEdit" name="resultbox"> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="acceptRichText"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="errorGroup"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Errors</string> + </property> + <layout class="QVBoxLayout"> + <item> + <widget class="QTextEdit" name="errors"> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="acceptRichText"> + <bool>false</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::Close</set> + </property> + </widget> + </item> + </layout> + </widget> + <layoutdefault spacing="6" margin="11"/> + <pixmapfunction>qPixmapFromMimeSource</pixmapfunction> + <tabstops> + <tabstop>resultbox</tabstop> + <tabstop>errors</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections/> +</ui>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PipInterface/PipFileSelectionDialog.py Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> +# + + +""" +Module implementing a dialog to enter a file to be processed. +""" + +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_PipFileSelectionDialog import Ui_PipFileSelectionDialog + +import Utilities + + +class PipFileSelectionDialog(QDialog, Ui_PipFileSelectionDialog): + """ + Class implementing a dialog to enter a file to be processed. + """ + def __init__(self, pip, mode, install=True, parent=None): + """ + Constructor + + @param pip reference to the pip object + @type Pip + @param mode mode of the dialog + @type str + @param install flag indicating an install action + @type bool + @param parent reference to the parent widget + @type QWidget + """ + super(PipFileSelectionDialog, self).__init__(parent) + self.setupUi(self) + + if mode == "requirements": + self.fileLabel.setText(self.tr("Enter requirements file:")) + self.filePicker.setMode(E5PathPickerModes.OpenFileMode) + self.filePicker.setToolTip(self.tr( + "Press to select the requirements file through a file" + " selection dialog.")) + self.filePicker.setFilters( + self.tr("Text Files (*.txt);;All Files (*)")) + elif mode == "package": + self.fileLabel.setText(self.tr("Enter package file:")) + self.filePicker.setMode(E5PathPickerModes.OpenFileMode) + self.filePicker.setToolTip(self.tr( + "Press to select the package file through a file" + " selection dialog.")) + self.filePicker.setFilters( + self.tr("Python Wheel (*.whl);;" + "Archive Files (*.tar.gz *.zip);;" + "All Files (*)")) + else: + self.fileLabel.setText(self.tr("Enter file name:")) + self.filePicker.setMode(E5PathPickerModes.OpenFileMode) + self.filePicker.setToolTip(self.tr( + "Press to select a file through a file selection dialog.")) + self.filePicker.setFilters(self.tr("All Files (*)")) + self.filePicker.setDefaultDirectory(os.path.expanduser("~")) + + self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) + + self.venvComboBox.addItem(pip.getDefaultEnvironmentString()) + projectVenv = pip.getProjectEnvironmentString() + if projectVenv: + self.venvComboBox.addItem(projectVenv) + self.venvComboBox.addItems(pip.getVirtualenvNames()) + + self.userCheckBox.setVisible(install) + + msh = self.minimumSizeHint() + self.resize(max(self.width(), msh.width()), msh.height()) + + @pyqtSlot(str) + def on_filePicker_textChanged(self, txt): + """ + Private slot to handle entering the name of a file. + + @param txt name of the file + @type str + """ + self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( + bool(txt) and + os.path.exists(Utilities.toNativeSeparators(txt)) + ) + + def getData(self): + """ + Public method to get the entered data. + + @return tuple with the environment name, the name of the + selected file and a flag indicating to install to the + user install directory + @rtype tuple of (str, str, bool) + """ + return ( + self.venvComboBox.currentText(), + self.filePicker.text(), + self.userCheckBox.isChecked() + )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PipInterface/PipFileSelectionDialog.ui Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PipFileSelectionDialog</class> + <widget class="QDialog" name="PipFileSelectionDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>170</height> + </rect> + </property> + <property name="windowTitle"> + <string>Select File</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Virtual Environment:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="venvComboBox"> + <property name="toolTip"> + <string>Select the virtual environment to be used</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="fileLabel"> + <property name="text"> + <string>File Name:</string> + </property> + </widget> + </item> + <item> + <widget class="E5PathPicker" name="filePicker" native="true"> + <property name="focusPolicy"> + <enum>Qt::StrongFocus</enum> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="userCheckBox"> + <property name="toolTip"> + <string>Select to install to the Python user install directory</string> + </property> + <property name="text"> + <string>Install into User Directory</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>PipFileSelectionDialog</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>PipFileSelectionDialog</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/PipInterface/PipFreezeDialog.py Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,300 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to generate a requirements file. +""" + +from __future__ import unicode_literals +try: + str = unicode # __IGNORE_EXCEPTION__ +except NameError: + pass + +import os + +from PyQt5.QtCore import pyqtSlot, Qt +from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton, \ + QApplication + +from E5Gui import E5MessageBox, E5FileDialog +from E5Gui.E5PathPicker import E5PathPickerModes +from E5Gui.E5Application import e5App + +from .Ui_PipFreezeDialog import Ui_PipFreezeDialog + +import Utilities + + +class PipFreezeDialog(QDialog, Ui_PipFreezeDialog): + """ + Class implementing a dialog to generate a requirements file. + """ + def __init__(self, pip, parent=None): + """ + Constructor + + @param pip reference to the master object + @type Pip + @param parent reference to the parent widget + @type QWidget + """ + super(PipFreezeDialog, self).__init__(parent) + self.setupUi(self) + self.setWindowFlags(Qt.Window) + + self.__refreshButton = self.buttonBox.addButton( + self.tr("&Refresh"), QDialogButtonBox.ActionRole) + + self.requirementsFilePicker.setMode(E5PathPickerModes.SaveFileMode) + self.requirementsFilePicker.setFilters( + self.tr("Text Files (*.txt);;All Files (*)")) + + self.__pip = pip + + self.venvComboBox.addItem(pip.getDefaultEnvironmentString()) + projectVenv = self.__pip.getProjectEnvironmentString() + if projectVenv: + self.venvComboBox.addItem(projectVenv) + self.venvComboBox.addItems(pip.getVirtualenvNames()) + + self.__requirementsEdited = False + self.__requirementsAvailable = False + + self.__updateButtons() + + def closeEvent(self, e): + """ + Protected slot implementing a close event handler. + + @param e close event + @type QCloseEvent + """ + QApplication.restoreOverrideCursor() + e.accept() + + @pyqtSlot(str) + def on_venvComboBox_activated(self, txt): + """ + Private slot handling the selection of a virtual environment. + + @param txt virtual environment + @type str + """ + self.__refresh() + + @pyqtSlot(bool) + def on_localCheckBox_clicked(self, checked): + """ + Private slot handling the switching of the local mode. + + @param checked state of the local check box + @type bool + """ + self.__refresh() + + @pyqtSlot(str) + def on_requirementsFilePicker_textChanged(self, txt): + """ + Private slot handling a change of the requirements file name. + + @param txt name of the requirements file + @type str + """ + self.__updateButtons() + + @pyqtSlot() + def on_requirementsEdit_textChanged(self): + """ + Private slot handling changes of the requirements text. + """ + self.__requirementsEdited = True + + @pyqtSlot(QAbstractButton) + def on_buttonBox_clicked(self, button): + """ + Private slot called by a button of the button box clicked. + + @param button button that was clicked + @type QAbstractButton + """ + if button == self.buttonBox.button(QDialogButtonBox.Close): + self.close() + elif button == self.__refreshButton: + self.__refresh() + + def __refresh(self): + """ + Private slot to refresh the displayed list. + """ + if self.__requirementsEdited: + ok = E5MessageBox.yesNo( + self, + self.tr("Generate Requirements"), + self.tr("""The requirements were changed. Do you want""" + """ to overwrite these changes?""")) + else: + ok = True + if ok: + self.start() + + def start(self): + """ + Public method to start the command. + """ + self.requirementsEdit.clear() + self.__requirementsAvailable = False + + venvName = self.venvComboBox.currentText() + interpreter = self.__pip.getVirtualenvInterpreter(venvName) + if not interpreter: + return + + args = ["-m", "pip", "freeze"] + if self.localCheckBox.isChecked(): + args.append("--local") + if self.requirementsFilePicker.text(): + fileName = Utilities.toNativeSeparators( + self.requirementsFilePicker.text()) + if os.path.exists(fileName): + args.append("--requirement") + args.append(fileName) + + QApplication.setOverrideCursor(Qt.WaitCursor) + success, output = self.__pip.runProcess(args, interpreter) + + if success: + self.requirementsEdit.setPlainText(output) + self.__requirementsAvailable = True + else: + self.requirementsEdit.setPlainText( + self.tr("No output generated by 'pip freeze'.")) + + QApplication.restoreOverrideCursor() + self.__updateButtons() + + self.__requirementsEdited = False + + def __updateButtons(self): + """ + Private method to set the state of the various buttons. + """ + self.saveButton.setEnabled( + self.__requirementsAvailable and + bool(self.requirementsFilePicker.text()) + ) + self.saveToButton.setEnabled(self.__requirementsAvailable) + self.copyButton.setEnabled(self.__requirementsAvailable) + + aw = e5App().getObject("ViewManager").activeWindow() + if aw and self.__requirementsAvailable: + self.insertButton.setEnabled(True) + self.replaceAllButton.setEnabled(True) + self.replaceSelectionButton.setEnabled( + aw.hasSelectedText()) + else: + self.insertButton.setEnabled(False) + self.replaceAllButton.setEnabled(False) + self.replaceSelectionButton.setEnabled(False) + + def __writeToFile(self, fileName): + """ + Private method to write the requirements text to a file. + + @param fileName name of the file to write to + @type str + """ + if os.path.exists(fileName): + ok = E5MessageBox.warning( + self, + self.tr("Generate Requirements"), + self.tr("""The file <b>{0}</b> already exists. Do you want""" + """ to overwrite it?""").format(fileName)) + if not ok: + return + + try: + f = open(fileName, "w") + f.write(self.requirementsEdit.toPlainText()) + f.close() + except (OSError, IOError) as err: + E5MessageBox.critical( + self, + self.tr("Generate Requirements"), + self.tr("""<p>The requirements could not be written""" + """ to <b>{0}</b>.</p><p>Reason: {1}</p>""") + .format(fileName, str(err))) + + @pyqtSlot() + def on_saveButton_clicked(self): + """ + Private slot to save the requirements text to the requirements file. + """ + fileName = self.requirementsFilePicker.text() + self.__writeToFile(fileName) + + @pyqtSlot() + def on_saveToButton_clicked(self): + """ + Private slot to write the requirements text to a new file. + """ + fileName, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( + self, + self.tr("Generate Requirements"), + os.path.expanduser("~"), + self.tr("Text Files (*.txt);;All Files (*)"), + None, + E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite) + ) + if fileName: + ext = os.path.splitext(fileName)[1] + if not ext: + ex = selectedFilter.split("(*")[1].split(")")[0] + if ex: + fileName += ex + self.__writeToFile(fileName) + + @pyqtSlot() + def on_copyButton_clicked(self): + """ + Private slot to copy the requirements text to the clipboard. + """ + txt = self.requirementsEdit.toPlainText() + cb = QApplication.clipboard() + cb.setText(txt) + + @pyqtSlot() + def on_insertButton_clicked(self): + """ + Private slot to insert the requirements text at the cursor position + of the current editor. + """ + aw = e5App().getObject("ViewManager").activeWindow() + if aw: + aw.beginUndoAction() + aw.insert(self.requirementsEdit.toPlainText()) + aw.endUndoAction() + + @pyqtSlot() + def on_replaceSelectionButton_clicked(self): + """ + Private slot to replace the selected text of the current editor + with the requirements text. + """ + aw = e5App().getObject("ViewManager").activeWindow() + if aw: + aw.beginUndoAction() + aw.replaceSelectedText(self.requirementsEdit.toPlainText()) + aw.endUndoAction() + + @pyqtSlot() + def on_replaceAllButton_clicked(self): + """ + Private slot to replace the text of the current editor with the + requirements text. + """ + aw = e5App().getObject("ViewManager").activeWindow() + if aw: + aw.setText(self.requirementsEdit.toPlainText())
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PipInterface/PipFreezeDialog.ui Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,232 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PipFreezeDialog</class> + <widget class="QDialog" name="PipFreezeDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>550</height> + </rect> + </property> + <property name="windowTitle"> + <string>Generate Requirements</string> + </property> + <property name="toolTip"> + <string>Replace the current selection with the requirements text</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Virtual Environment:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="venvComboBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Select the virtual environment to be used</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QCheckBox" name="localCheckBox"> + <property name="toolTip"> + <string>Select to show requirements for locally-installed packages only</string> + </property> + <property name="text"> + <string>Local packages only</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Requirements File:</string> + </property> + </widget> + </item> + <item> + <widget class="E5PathPicker" name="requirementsFilePicker" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="focusPolicy"> + <enum>Qt::StrongFocus</enum> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="1"> + <widget class="QPushButton" name="saveButton"> + <property name="toolTip"> + <string>Press to save to the requirements file</string> + </property> + <property name="text"> + <string>Save</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QPushButton" name="saveToButton"> + <property name="toolTip"> + <string>Save to a new file</string> + </property> + <property name="text"> + <string>Save To</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QPushButton" name="copyButton"> + <property name="toolTip"> + <string>Copy the requirements text to the clipboard</string> + </property> + <property name="text"> + <string>Copy</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QPushButton" name="insertButton"> + <property name="toolTip"> + <string>Insert the requirements text at the cursor position</string> + </property> + <property name="text"> + <string>Insert</string> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QPushButton" name="replaceSelectionButton"> + <property name="text"> + <string>Replace Selection</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QPushButton" name="replaceAllButton"> + <property name="toolTip"> + <string>Replace all text with the requirements text</string> + </property> + <property name="text"> + <string>Replace All</string> + </property> + </widget> + </item> + <item row="6" column="1"> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="0" rowspan="7"> + <widget class="QPlainTextEdit" name="requirementsEdit"> + <property name="tabChangesFocus"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Close</set> + </property> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>E5PathPicker</class> + <extends>QWidget</extends> + <header>E5Gui/E5PathPicker.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <tabstops> + <tabstop>venvComboBox</tabstop> + <tabstop>localCheckBox</tabstop> + <tabstop>requirementsFilePicker</tabstop> + <tabstop>requirementsEdit</tabstop> + <tabstop>saveButton</tabstop> + <tabstop>saveToButton</tabstop> + <tabstop>copyButton</tabstop> + <tabstop>insertButton</tabstop> + <tabstop>replaceSelectionButton</tabstop> + <tabstop>replaceAllButton</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>PipFreezeDialog</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>PipFreezeDialog</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/PipInterface/PipListDialog.py Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,551 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to list installed packages. +""" + +from __future__ import unicode_literals +try: + str = unicode # __IGNORE_EXCEPTION__ +except NameError: + pass + +import json + +from PyQt5.QtCore import pyqtSlot, Qt, QProcess, QTimer +from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton, \ + QApplication, QTreeWidgetItem, QHeaderView + +from E5Gui import E5MessageBox + +from .Ui_PipListDialog import Ui_PipListDialog + +import Preferences + + +class PipListDialog(QDialog, Ui_PipListDialog): + """ + Class implementing a dialog to list installed packages. + """ + CommandArguments = { + "list": ["list", "--format=json"], + "uptodate": ["list", "--uptodate", "--format=json"], + "outdated": ["list", "--outdated", "--format=json"], + } + + ShowProcessGeneralMode = 0 + ShowProcessClassifiersMode = 1 + ShowProcessEntryPointsMode = 2 + ShowProcessFilesListMode = 3 + + def __init__(self, pip, mode, indexUrl, title, parent=None): + """ + Constructor + + @param pip reference to the master object + @type Pip + @param mode list command mode (one of 'list', 'uptodate', 'outdated') + @type str + @param indexUrl URL of the pypi index + @type str + @param title title of the dialog + @type str + @param parent reference to the parent widget + @type QWidget + """ + assert mode in PipListDialog.CommandArguments + + super(PipListDialog, self).__init__(parent) + self.setupUi(self) + self.setWindowFlags(Qt.Window) + + self.setWindowTitle(title) + + self.__refreshButton = self.buttonBox.addButton( + self.tr("&Refresh"), QDialogButtonBox.ActionRole) + self.__refreshButton.setEnabled(False) + if mode == "outdated": + self.__upgradeButton = self.buttonBox.addButton( + self.tr("Up&grade"), QDialogButtonBox.ActionRole) + self.__upgradeButton.setEnabled(False) + self.__upgradeAllButton = self.buttonBox.addButton( + self.tr("Upgrade &All"), QDialogButtonBox.ActionRole) + self.__upgradeAllButton.setEnabled(False) + else: + self.__upgradeButton = None + self.__upgradeAllButton = None + self.__uninstallButton = self.buttonBox.addButton( + self.tr("&Uninstall"), QDialogButtonBox.ActionRole) + self.__uninstallButton.setEnabled(False) + + self.__pip = pip + self.__mode = mode + self.__ioEncoding = Preferences.getSystem("IOEncoding") + self.__indexUrl = indexUrl + self.__errors = "" + self.__output = [] + + self.__nothingStrings = { + "list": self.tr("Nothing to show"), + "uptodate": self.tr("All packages outdated"), + "outdated": self.tr("All packages up-to-date"), + } + + self.venvComboBox.addItem(self.__pip.getDefaultEnvironmentString()) + projectVenv = self.__pip.getProjectEnvironmentString() + if projectVenv: + self.venvComboBox.addItem(projectVenv) + self.venvComboBox.addItems(self.__pip.getVirtualenvNames()) + + if mode == "list": + self.infoLabel.setText(self.tr("Installed Packages:")) + self.packageList.setHeaderLabels([ + self.tr("Package"), + self.tr("Version"), + ]) + elif mode == "uptodate": + self.infoLabel.setText(self.tr("Up-to-date Packages:")) + self.packageList.setHeaderLabels([ + self.tr("Package"), + self.tr("Version"), + ]) + elif mode == "outdated": + self.infoLabel.setText(self.tr("Outdated Packages:")) + self.packageList.setHeaderLabels([ + self.tr("Package"), + self.tr("Current Version"), + self.tr("Latest Version"), + self.tr("Package Type"), + ]) + + self.packageList.header().setSortIndicator(0, Qt.AscendingOrder) + + self.__infoLabels = { + "name": self.tr("Name:"), + "version": self.tr("Version:"), + "location": self.tr("Location:"), + "requires": self.tr("Requires:"), + "summary": self.tr("Summary:"), + "home-page": self.tr("Homepage:"), + "author": self.tr("Author:"), + "author-email": self.tr("Author Email:"), + "license": self.tr("License:"), + "metadata-version": self.tr("Metadata Version:"), + "installer": self.tr("Installer:"), + "classifiers": self.tr("Classifiers:"), + "entry-points": self.tr("Entry Points:"), + "files": self.tr("Files:"), + } + self.infoWidget.setHeaderLabels(["Key", "Value"]) + + self.process = QProcess() + self.process.finished.connect(self.__procFinished) + self.process.readyReadStandardOutput.connect(self.__readStdout) + self.process.readyReadStandardError.connect(self.__readStderr) + + self.show() + QApplication.processEvents() + + def __stopProcess(self): + """ + Private slot to stop the running process. + """ + if self.process.state() != QProcess.NotRunning: + self.process.terminate() + QTimer.singleShot(2000, self.process.kill) + self.process.waitForFinished(3000) + + QApplication.restoreOverrideCursor() + + def closeEvent(self, e): + """ + Protected slot implementing a close event handler. + + @param e close event + @type QCloseEvent + """ + self.__stopProcess() + e.accept() + + def __finish(self): + """ + Private slot called when the process finished or the user pressed + the cancel button. + """ + self.__stopProcess() + + self.__processOutput() + + self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) + self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) + self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) + self.buttonBox.button(QDialogButtonBox.Close).setFocus( + Qt.OtherFocusReason) + self.__refreshButton.setEnabled(True) + + if self.packageList.topLevelItemCount() == 0: + QTreeWidgetItem(self.packageList, + [self.__nothingStrings[self.__mode]]) + if self.__errors and not self.__errors.startswith("DEPRECATION"): + E5MessageBox.critical( + self, + self.windowTitle(), + self.tr("""<p>The command failed.</p>""" + """<p>Reason: {0}</p>""").format( + self.__errors.replace("\r\n", "<br/>") + .replace("\n", "<br/>").replace("\r", "<br/>") + .replace(" ", " "))) + if self.__upgradeAllButton is not None: + self.__upgradeAllButton.setEnabled(False) + else: + if self.__upgradeAllButton is not None: + self.__upgradeAllButton.setEnabled(True) + + self.packageList.sortItems( + 0, + self.packageList.header().sortIndicatorOrder()) + self.packageList.header().resizeSections( + QHeaderView.ResizeToContents) + self.packageList.header().setStretchLastSection(True) + + @pyqtSlot(QAbstractButton) + def on_buttonBox_clicked(self, button): + """ + Private slot called by a button of the button box clicked. + + @param button button that was clicked + @type QAbstractButton + """ + if button == self.buttonBox.button(QDialogButtonBox.Close): + self.close() + elif button == self.buttonBox.button(QDialogButtonBox.Cancel): + self.__finish() + elif button == self.__refreshButton: + self.__refresh() + elif button == self.__upgradeButton: + self.__upgradePackages() + elif button == self.__upgradeAllButton: + self.__upgradeAllPackages() + elif button == self.__uninstallButton: + self.__uninstallPackages() + + def __procFinished(self, exitCode, exitStatus): + """ + Private slot connected to the finished signal. + + @param exitCode exit code of the process + @type int + @param exitStatus exit status of the process + @type QProcess.ExitStatus + """ + self.__finish() + + def __refresh(self): + """ + Private slot to refresh the displayed list. + """ + self.__stopProcess() + self.start() + + def start(self): + """ + Public method to start the command. + """ + self.packageList.clear() + self.__errors = "" + self.__output = [] + + self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) + self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) + self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) + self.__refreshButton.setEnabled(False) + if self.__upgradeAllButton is not None: + self.__upgradeAllButton.setEnabled(False) + QApplication.processEvents() + + QApplication.setOverrideCursor(Qt.WaitCursor) + QApplication.processEvents() + + venvName = self.venvComboBox.currentText() + interpreter = self.__pip.getVirtualenvInterpreter(venvName) + if not interpreter: + return + + args = ["-m", "pip"] + PipListDialog.CommandArguments[self.__mode] + if self.localCheckBox.isChecked(): + args.append("--local") + if self.notRequiredCheckBox.isChecked(): + args.append("--not-required") + if self.userCheckBox.isChecked(): + args.append("--user") + + if self.__indexUrl: + args.append("--index-url") + args.append(self.__indexUrl + "/simple") + + self.process.start(interpreter, args) + procStarted = self.process.waitForStarted(5000) + if not procStarted: + self.buttonBox.setFocus() + self.__stopProcess() + E5MessageBox.critical( + self, + self.tr('Process Generation Error'), + self.tr( + 'The process {0} could not be started.' + ).format(interpreter)) + self.__finish() + + def __processOutput(self): + """ + Private method to process the captured output. + """ + if self.__output: + try: + packageData = json.loads("\n".join(self.__output)) + for package in packageData: + data = [ + package["name"], + package["version"], + ] + if self.__mode == "outdated": + data.extend([ + package["latest_version"], + package["latest_filetype"], + ]) + QTreeWidgetItem(self.packageList, data) + except ValueError as err: + self.__errors += str(err) + "\n" + self.__errors += "received output:\n" + self.__errors += "\n".join(self.__output) + + 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(): + line = str(self.process.readLine(), self.__ioEncoding, + 'replace').strip() + self.__output.append(line) + + 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.__errors += str(self.process.readAllStandardError(), + self.__ioEncoding, 'replace') + + @pyqtSlot(str) + def on_venvComboBox_activated(self, txt): + """ + Private slot handling the selection of a virtual environment. + + @param txt virtual environment + @type str + """ + self.__refresh() + + @pyqtSlot(bool) + def on_localCheckBox_clicked(self, checked): + """ + Private slot handling the switching of the local mode. + + @param checked state of the local check box + @type bool + """ + self.__refresh() + + @pyqtSlot(bool) + def on_notRequiredCheckBox_clicked(self, checked): + """ + Private slot handling the switching of the 'not required' mode. + + @param checked state of the 'not required' check box + @type bool + """ + self.__refresh() + + @pyqtSlot(bool) + def on_userCheckBox_clicked(self, checked): + """ + Private slot handling the switching of the 'user-site' mode. + + @param checked state of the 'user-site' check box + @type bool + """ + self.__refresh() + + @pyqtSlot() + def on_packageList_itemSelectionChanged(self): + """ + Private slot handling the selection of a package. + """ + self.infoWidget.clear() + + if len(self.packageList.selectedItems()) == 1: + itm = self.packageList.selectedItems()[0] + + environment = self.venvComboBox.currentText() + interpreter = self.__pip.getVirtualenvInterpreter(environment) + if not interpreter: + return + + QApplication.setOverrideCursor(Qt.WaitCursor) + + args = ["-m", "pip", "show"] + if self.verboseCheckBox.isChecked(): + args.append("--verbose") + if self.installedFilesCheckBox.isChecked(): + args.append("--files") + args.append(itm.text(0)) + success, output = self.__pip.runProcess(args, interpreter) + + if success and output: + mode = PipListDialog.ShowProcessGeneralMode + for line in output.splitlines(): + line = line.rstrip() + if line != "---": + if mode != PipListDialog.ShowProcessGeneralMode: + if line[0] == " ": + QTreeWidgetItem( + self.infoWidget, + [" ", line.strip()]) + else: + mode = PipListDialog.ShowProcessGeneralMode + if mode == PipListDialog.ShowProcessGeneralMode: + try: + label, info = line.split(": ", 1) + except ValueError: + label = line[:-1] + info = "" + label = label.lower() + if label in self.__infoLabels: + QTreeWidgetItem( + self.infoWidget, + [self.__infoLabels[label], info]) + if label == "files": + mode = PipListDialog.ShowProcessFilesListMode + elif label == "classifiers": + mode = PipListDialog.ShowProcessClassifiersMode + elif label == "entry-points": + mode = PipListDialog.ShowProcessEntryPointsMode + self.infoWidget.scrollToTop() + + header = self.infoWidget.header() + header.setStretchLastSection(False) + header.resizeSections(QHeaderView.ResizeToContents) + if header.sectionSize(0) + header.sectionSize(1) < header.width(): + header.setStretchLastSection(True) + + QApplication.restoreOverrideCursor() + + enable = (len(self.packageList.selectedItems()) > 1 or + (len(self.packageList.selectedItems()) == 1 and + self.packageList.selectedItems()[0].text(0) not in + self.__nothingStrings.values())) + self.__upgradeButton and self.__upgradeButton.setEnabled(enable) + self.__uninstallButton.setEnabled(enable) + + @pyqtSlot(bool) + def on_verboseCheckBox_clicked(self, checked): + """ + Private slot to handle a change of the verbose package information + checkbox. + + @param checked state of the checkbox + @type bool + """ + self.on_packageList_itemSelectionChanged() + + @pyqtSlot(bool) + def on_installedFilesCheckBox_clicked(self, checked): + """ + Private slot to handle a change of the installed files information + checkbox. + + @param checked state of the checkbox + @type bool + """ + self.on_packageList_itemSelectionChanged() + + def __upgradePackages(self): + """ + Private slot to upgrade the selected packages. + """ + packages = [] + for itm in self.packageList.selectedItems(): + packages.append(itm.text(0)) + + if packages: + if "pip" in packages: + self.__upgradePip() + else: + self.__executeUpgradePackages(packages) + + def __upgradeAllPackages(self): + """ + Private slot to upgrade all listed packages. + """ + packages = [] + for index in range(self.packageList.topLevelItemCount()): + itm = self.packageList.topLevelItem(index) + packages.append(itm.text(0)) + + if packages: + if "pip" in packages: + self.__upgradePip() + else: + self.__executeUpgradePackages(packages) + + def __upgradePip(self): + """ + Private slot to upgrade pip itself. + """ + res = self.__pip.upgradePip( + venvName=self.venvComboBox.currentText(), + userSite=self.userCheckBox.isChecked()) + if res: + self.__refresh() + + def __executeUpgradePackages(self, packages): + """ + Private method to execute the pip upgrade command. + + @param packages list of package names to be upgraded + @type list of str + """ + res = self.__pip.upgradePackages( + packages, venvName=self.venvComboBox.currentText(), + userSite=self.userCheckBox.isChecked()) + if res: + self.activateWindow() + self.raise_() + self.__refresh() + + def __uninstallPackages(self): + """ + Private slot to uninstall the selected packages. + """ + packages = [] + for itm in self.packageList.selectedItems(): + packages.append(itm.text(0)) + + if packages: + res = self.__pip.uninstallPackages( + packages, + venvName=self.venvComboBox.currentText()) + if res: + self.activateWindow() + self.raise_() + self.__refresh()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PipInterface/PipListDialog.ui Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,253 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PipListDialog</class> + <widget class="QDialog" name="PipListDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>650</height> + </rect> + </property> + <property name="windowTitle"> + <string>Package List</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Virtual Environment:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="venvComboBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Select the virtual environment to be used</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="infoLabel"> + <property name="text"> + <string notr="true">TextLabel</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <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> + <item row="0" column="2"> + <widget class="QCheckBox" name="localCheckBox"> + <property name="toolTip"> + <string>Select to show only locally-installed packages</string> + </property> + <property name="text"> + <string>Local packages only</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QCheckBox" name="notRequiredCheckBox"> + <property name="toolTip"> + <string>Select to list packages that are not dependencies of installed packages</string> + </property> + <property name="text"> + <string>Not required Packages</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QCheckBox" name="userCheckBox"> + <property name="toolTip"> + <string>Select to show only packages installed to the user-site</string> + </property> + <property name="text"> + <string>User-Site only</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QSplitter" name="splitter"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="childrenCollapsible"> + <bool>false</bool> + </property> + <widget class="QTreeWidget" name="packageList"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>3</verstretch> + </sizepolicy> + </property> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::ExtendedSelection</enum> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="itemsExpandable"> + <bool>false</bool> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string notr="true">1</string> + </property> + </column> + </widget> + <widget class="QWidget" name="widget" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QCheckBox" name="verboseCheckBox"> + <property name="toolTip"> + <string>Select to show verbose package information</string> + </property> + <property name="text"> + <string>Verbose Package Information</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="installedFilesCheckBox"> + <property name="toolTip"> + <string>Select to show information about installed files</string> + </property> + <property name="text"> + <string>Installed Files Information</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QTreeWidget" name="infoWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="itemsExpandable"> + <bool>false</bool> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="columnCount"> + <number>2</number> + </property> + <attribute name="headerVisible"> + <bool>false</bool> + </attribute> + <attribute name="headerStretchLastSection"> + <bool>false</bool> + </attribute> + <column> + <property name="text"> + <string notr="true">1</string> + </property> + </column> + <column> + <property name="text"> + <string notr="true">2</string> + </property> + </column> + </widget> + </item> + </layout> + </widget> + </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> + <tabstops> + <tabstop>venvComboBox</tabstop> + <tabstop>localCheckBox</tabstop> + <tabstop>notRequiredCheckBox</tabstop> + <tabstop>userCheckBox</tabstop> + <tabstop>packageList</tabstop> + <tabstop>verboseCheckBox</tabstop> + <tabstop>installedFilesCheckBox</tabstop> + <tabstop>infoWidget</tabstop> + </tabstops> + <resources/> + <connections/> +</ui>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PipInterface/PipPackageDetailsDialog.py Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,229 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to show details about a package. +""" + +from __future__ import unicode_literals +try: + basestring # __IGNORE_WARNING__ +except NameError: + basestring = str + +from PyQt5.QtCore import Qt, QLocale +from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QTreeWidgetItem, \ + QLabel, QHeaderView + +from .Ui_PipPackageDetailsDialog import Ui_PipPackageDetailsDialog + + +class PipPackageDetailsDialog(QDialog, Ui_PipPackageDetailsDialog): + """ + Class implementing a dialog to show details about a package. + """ + def __init__(self, detailsData, downloadsData, parent=None): + """ + Constructor + + @param detailsData package details + @type dict + @param downloadsData downloads information + @type dict + @param parent reference to the parent widget + @type QWidget + """ + super(PipPackageDetailsDialog, self).__init__(parent) + self.setupUi(self) + self.setWindowFlags(Qt.Window) + + self.__locale = QLocale() + self.__packageTypeMap = { + "sdist": self.tr("Source"), + "bdist_wheel": self.tr("Python Wheel"), + "bdist_egg": self.tr("Python Egg"), + "bdist_wininst": self.tr("MS Windows Installer"), + "bdist_msi": self.tr("MS Windows Installer"), + "bdist_rpm": self.tr("Unix Installer"), + "bdist_deb": self.tr("Unix Installer"), + "bdist_dumb": self.tr("Archive"), + } + + self.__populateDetails(detailsData) + self.__populateDownloadUrls(downloadsData) + self.__populateRequiresProvides(detailsData) + + def __populateDetails(self, detailsData): + """ + Private method to populate the details tab. + + @param detailsData package details + @type dict + """ + self.packageNameLabel.setText( + "<h1>{0} {1}</h1".format(self.__sanitize(detailsData["name"]), + self.__sanitize(detailsData["version"]))) + self.summaryLabel.setText( + self.__sanitize(detailsData["summary"][:240])) + self.descriptionEdit.setPlainText( + self.__sanitize(detailsData["description"])) + self.authorLabel.setText(self.__sanitize(detailsData["author"])) + self.authorEmailLabel.setText( + '<a href="mailto:{0}">{0}</a>'.format( + self.__sanitize(detailsData["author_email"]))) + self.licenseLabel.setText(self.__sanitize(detailsData["license"])) + self.platformLabel.setText(self.__sanitize(detailsData["platform"])) + self.homePageLabel.setText( + '<a href="{0}">{0}</a>'.format( + self.__sanitize(detailsData["home_page"], forUrl=True))) + self.packageUrlLabel.setText( + '<a href="{0}">{0}</a>'.format( + self.__sanitize(detailsData["package_url"], forUrl=True))) + self.releaseUrlLabel.setText( + '<a href="{0}">{0}</a>'.format( + self.__sanitize(detailsData["release_url"], forUrl=True))) + self.docsUrlLabel.setText( + '<a href="{0}">{0}</a>'.format( + self.__sanitize(detailsData["docs_url"], forUrl=True))) + self.downloadsDayLabel.setText(self.__locale.toString( + detailsData["downloads"]["last_day"])) + self.downloadsWeekLabel.setText(self.__locale.toString( + detailsData["downloads"]["last_week"])) + self.downloadsMonthLabel.setText(self.__locale.toString( + detailsData["downloads"]["last_month"])) + self.classifiersList.addItems(detailsData["classifiers"]) + + self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) + self.buttonBox.button(QDialogButtonBox.Close).setFocus( + Qt.OtherFocusReason) + + def __populateDownloadUrls(self, downloadsData): + """ + Private method to populate the download URLs tab. + + @param downloadsData downloads information + @type dict + """ + index = self.infoWidget.indexOf(self.urls) + if downloadsData: + self.infoWidget.setTabEnabled(index, True) + for download in downloadsData: + itm = QTreeWidgetItem(self.downloadUrlsList, [ + "", + self.__packageTypeMap[download["packagetype"]] + if download["packagetype"] in self.__packageTypeMap + else "", + download["python_version"] + if download["python_version"] != "source" + else "", + self.__locale.toString(download["downloads"]), + self.__formatUploadDate(download["upload_time"]), + self.__formatSize(download["size"]), + ]) + if download["has_sig"]: + pgpLink = ' (<a href="{0}">pgp</a>)'.format( + download["url"] + ".asc") + else: + pgpLink = "" + urlLabel = QLabel('<a href="{0}#md5={2}">{1}</a>{3}'.format( + download["url"], download["filename"], + download["md5_digest"], pgpLink)) + urlLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse) + urlLabel.setOpenExternalLinks(True) + self.downloadUrlsList.setItemWidget(itm, 0, urlLabel) + header = self.downloadUrlsList.header() + header.resizeSections(QHeaderView.ResizeToContents) + else: + self.infoWidget.setTabEnabled(index, False) + + def __populateRequiresProvides(self, detailsData): + """ + Private method to populate the requires/provides tab. + + @param detailsData package details + @type dict + """ + populatedItems = 0 + + if "requires" in detailsData: + self.requiredPackagesList.addItems(detailsData["requires"]) + populatedItems += len(detailsData["requires"]) + if "requires_dist" in detailsData: + self.requiredDistributionsList.addItems( + detailsData["requires_dist"]) + populatedItems += len(detailsData["requires_dist"]) + if "provides" in detailsData: + self.providedPackagesList.addItems(detailsData["provides"]) + populatedItems += len(detailsData["provides"]) + if "provides_dist" in detailsData: + self.providedDistributionsList.addItems( + detailsData["provides_dist"]) + populatedItems += len(detailsData["provides_dist"]) + + index = self.infoWidget.indexOf(self.requires) + self.infoWidget.setTabEnabled(index, populatedItems > 0) + + def __sanitize(self, text, forUrl=False): + """ + Private method to clean-up the given text. + + @param text raw text + @type str + @param forUrl flag indicating to sanitize an URL text + @type bool + @return processed text + @rtype str + """ + if text == "UNKNOWN": + text = "" + elif text == "any": + text = self.tr("any") + elif text is None: + text = "" + if forUrl: + if not isinstance(text, basestring) or \ + not text.startswith(("http://", "https://", "ftp://")): + # ignore if the schema is not one of the listed ones + text = "" + + return text + + def __formatUploadDate(self, datetime): + """ + Private method to format the upload date. + + @param datetime upload date and time + @type xmlrpc.DateTime or str + @return formatted date string + @rtype str + """ + if isinstance(datetime, str): + return datetime.split("T")[0] + else: + date = datetime.value.split("T")[0] + return "{0}-{1}-{2}".format(date[:4], date[4:6], date[6:]) + + def __formatSize(self, size): + """ + Private slot to format the size. + + @param size size to be formatted + @type int + @return formatted size + @rtype str + """ + unit = "" + if size < 1024: + unit = self.tr("B") + elif size < 1024 * 1024: + size /= 1024 + unit = self.tr("KB") + elif size < 1024 * 1024 * 1024: + size /= 1024 * 1024 + unit = self.tr("MB") + else: + size /= 1024 * 1024 * 1024 + unit = self.tr("GB") + return self.tr("{0:.1f} {1}", "value, unit").format(size, unit)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PipInterface/PipPackageDetailsDialog.ui Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,517 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PipPackageDetailsDialog</class> + <widget class="QDialog" name="PipPackageDetailsDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>700</height> + </rect> + </property> + <property name="windowTitle"> + <string>Package Details</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="packageNameLabel"/> + </item> + <item> + <widget class="QTabWidget" name="infoWidget"> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="details"> + <attribute name="title"> + <string>Details</string> + </attribute> + <attribute name="toolTip"> + <string>Lists package informations</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="1"> + <widget class="QLabel" name="summaryLabel"> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Description:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="authorEmailLabel"> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QPlainTextEdit" name="descriptionEdit"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>5</verstretch> + </sizepolicy> + </property> + <property name="tabChangesFocus"> + <bool>true</bool> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Author:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="authorLabel"/> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Author Email:</string> + </property> + </widget> + </item> + <item row="7" column="1"> + <widget class="QLabel" name="packageUrlLabel"> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>License:</string> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QLabel" name="licenseLabel"/> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Summary:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>Platform:</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QLabel" name="platformLabel"/> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>Home Page:</string> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QLabel" name="homePageLabel"> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="7" column="0"> + <widget class="QLabel" name="label_9"> + <property name="text"> + <string>Package URL:</string> + </property> + </widget> + </item> + <item row="8" column="0"> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string>Release URL:</string> + </property> + </widget> + </item> + <item row="8" column="1"> + <widget class="QLabel" name="releaseUrlLabel"> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="9" column="0"> + <widget class="QLabel" name="label_11"> + <property name="text"> + <string>Documentation URL:</string> + </property> + </widget> + </item> + <item row="9" column="1"> + <widget class="QLabel" name="docsUrlLabel"> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="10" column="0"> + <widget class="QLabel" name="label_12"> + <property name="text"> + <string>Downloads:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="10" column="1"> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_13"> + <property name="text"> + <string>Last Day:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="downloadsDayLabel"> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="0" column="2"> + <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> + <item row="1" column="0"> + <widget class="QLabel" name="label_14"> + <property name="text"> + <string>Last Week:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="downloadsWeekLabel"> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_15"> + <property name="text"> + <string>Last Month:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="downloadsMonthLabel"> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + </layout> + </item> + <item row="11" column="0"> + <widget class="QLabel" name="label_16"> + <property name="text"> + <string>Classifiers:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="11" column="1"> + <widget class="QListWidget" name="classifiersList"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::NoSelection</enum> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="urls"> + <attribute name="title"> + <string>Download URLs</string> + </attribute> + <attribute name="toolTip"> + <string>Lists the download URLs</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QTreeWidget" name="downloadUrlsList"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::NoSelection</enum> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="itemsExpandable"> + <bool>false</bool> + </property> + <attribute name="headerStretchLastSection"> + <bool>false</bool> + </attribute> + <column> + <property name="text"> + <string>File</string> + </property> + </column> + <column> + <property name="text"> + <string>Type</string> + </property> + </column> + <column> + <property name="text"> + <string>Py Version</string> + </property> + </column> + <column> + <property name="text"> + <string>Downloads</string> + </property> + </column> + <column> + <property name="text"> + <string>Uploaded on</string> + </property> + </column> + <column> + <property name="text"> + <string>Size</string> + </property> + </column> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="requires"> + <attribute name="title"> + <string>Requires/Provides</string> + </attribute> + <attribute name="toolTip"> + <string>Lists required and provided packages</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Requires</string> + </property> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="0" column="0"> + <widget class="QLabel" name="label_17"> + <property name="text"> + <string>Required Packages:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QListWidget" name="requiredPackagesList"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::NoSelection</enum> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_18"> + <property name="text"> + <string>Required Distributions:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QListWidget" name="requiredDistributionsList"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::NoSelection</enum> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Provides</string> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QLabel" name="label_20"> + <property name="text"> + <string>Provided Packages:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QListWidget" name="providedPackagesList"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::NoSelection</enum> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_19"> + <property name="text"> + <string>Provided Distributions:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QListWidget" name="providedDistributionsList"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::NoSelection</enum> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Close</set> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>infoWidget</tabstop> + <tabstop>descriptionEdit</tabstop> + <tabstop>classifiersList</tabstop> + <tabstop>downloadUrlsList</tabstop> + <tabstop>requiredPackagesList</tabstop> + <tabstop>requiredDistributionsList</tabstop> + <tabstop>providedPackagesList</tabstop> + <tabstop>providedDistributionsList</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>PipPackageDetailsDialog</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>PipPackageDetailsDialog</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/PipInterface/PipPackagesInputDialog.py Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to enter package specifications. +""" + +from __future__ import unicode_literals + +from PyQt5.QtCore import pyqtSlot +from PyQt5.QtWidgets import QDialog, QDialogButtonBox + +from .Ui_PipPackagesInputDialog import Ui_PipPackagesInputDialog + + +class PipPackagesInputDialog(QDialog, Ui_PipPackagesInputDialog): + """ + Class implementing a dialog to enter package specifications. + """ + def __init__(self, pip, title, install=True, parent=None): + """ + Constructor + + @param pip reference to the pip object + @type Pip + @param title dialog title + @type str + @param install flag indicating an install action + @type bool + @param parent reference to the parent widget + @type QWidget + """ + super(PipPackagesInputDialog, self).__init__(parent) + self.setupUi(self) + + self.setWindowTitle(title) + + self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) + + self.venvComboBox.addItem(pip.getDefaultEnvironmentString()) + projectVenv = pip.getProjectEnvironmentString() + if projectVenv: + self.venvComboBox.addItem(projectVenv) + self.venvComboBox.addItems(pip.getVirtualenvNames()) + + self.userCheckBox.setVisible(install) + + msh = self.minimumSizeHint() + self.resize(max(self.width(), msh.width()), msh.height()) + + @pyqtSlot(str) + def on_packagesEdit_textChanged(self, txt): + """ + Private slot handling entering package names. + + @param txt name of the requirements file + @type str + """ + self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(bool(txt)) + + def getData(self): + """ + Public method to get the entered data. + + @return tuple with the environment name, the list of package + specifications and a flag indicating to install to the user + install directory + @rtype tuple of (str, list of str, bool) + """ + packages = [p.strip() for p in self.packagesEdit.text().split()] + + return ( + self.venvComboBox.currentText(), + packages, + self.userCheckBox.isChecked() + )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PipInterface/PipPackagesInputDialog.ui Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,101 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PipPackagesInputDialog</class> + <widget class="QDialog" name="PipPackagesInputDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>186</height> + </rect> + </property> + <property name="windowTitle"> + <string>Packages </string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Virtual Environment:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="venvComboBox"> + <property name="toolTip"> + <string>Select the virtual environment to be used</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Package Specifications (separated by whitespace):</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="packagesEdit"/> + </item> + <item> + <widget class="QCheckBox" name="userCheckBox"> + <property name="toolTip"> + <string>Select to install to the Python user install directory</string> + </property> + <property name="text"> + <string>Install into User Directory</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> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>PipPackagesInputDialog</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>PipPackagesInputDialog</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/PipInterface/PipSearchDialog.py Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,465 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to search PyPI. +""" + +from __future__ import unicode_literals + +import textwrap + +from PyQt5.QtCore import pyqtSlot, Qt, QEventLoop, QRegExp +from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton, \ + QApplication, QTreeWidgetItem, QHeaderView, QInputDialog + +from E5Gui import E5MessageBox +try: + from E5Network.E5XmlRpcClient import E5XmlRpcClient +except ImportError: + from .E5XmlRpcClient import E5XmlRpcClient + +from .Ui_PipSearchDialog import Ui_PipSearchDialog + + +class PipSearchDialog(QDialog, Ui_PipSearchDialog): + """ + Class implementing a dialog to search PyPI. + """ + VersionRole = Qt.UserRole + 1 + + Stopwords = { + "a", "and", "are", "as", "at", "be", "but", "by", + "for", "if", "in", "into", "is", "it", + "no", "not", "of", "on", "or", "such", + "that", "the", "their", "then", "there", "these", + "they", "this", "to", "was", "will", + } + + def __init__(self, pip, indexUrl, parent=None): + """ + Constructor + + @param pip reference to the master object + @type Pip + @param indexUrl URL of XML RPC interface to the pypi index + @type str + @param parent reference to the parent widget + @type QWidget + """ + super(PipSearchDialog, self).__init__(parent) + self.setupUi(self) + self.setWindowFlags(Qt.Window) + + self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) + + self.__installButton = self.buttonBox.addButton( + self.tr("&Install"), QDialogButtonBox.ActionRole) + self.__installButton.setEnabled(False) + + self.__installUserButton = self.buttonBox.addButton( + self.tr("Install to &User-Site"), QDialogButtonBox.ActionRole) + self.__installUserButton.setEnabled(False) + + self.__showDetailsButton = self.buttonBox.addButton( + self.tr("&Show Details..."), QDialogButtonBox.ActionRole) + self.__showDetailsButton.setEnabled(False) + + self.__pip = pip + self.__client = E5XmlRpcClient(indexUrl, self) + + self.venvComboBox.addItem(self.__pip.getDefaultEnvironmentString()) + projectVenv = self.__pip.getProjectEnvironmentString() + if projectVenv: + self.venvComboBox.addItem(projectVenv) + self.venvComboBox.addItems(self.__pip.getVirtualenvNames()) + + self.searchEdit.setFocus(Qt.OtherFocusReason) + + self.__canceled = False + self.__detailsData = {} + self.__query = [] + + self.__packageDetailsDialog = None + + def closeEvent(self, e): + """ + Protected slot implementing a close event handler. + + @param e close event + @type QCloseEvent + """ + QApplication.restoreOverrideCursor() + + if self.__packageDetailsDialog is not None: + self.__packageDetailsDialog.close() + + e.accept() + + @pyqtSlot(str) + def on_searchEdit_textChanged(self, txt): + """ + Private slot handling a change of the search term. + + @param txt search term + @type str + """ + self.searchButton.setEnabled(bool(txt)) + + @pyqtSlot() + def on_searchButton_clicked(self): + """ + Private slot handling a press of the search button. + """ + self.__search() + + @pyqtSlot() + def on_resultList_itemSelectionChanged(self): + """ + Private slot handling changes of the selection. + """ + self.__installButton.setEnabled( + len(self.resultList.selectedItems()) > 0) + self.__installUserButton.setEnabled( + len(self.resultList.selectedItems()) > 0) + self.__showDetailsButton.setEnabled( + len(self.resultList.selectedItems()) == 1) + + @pyqtSlot(QAbstractButton) + def on_buttonBox_clicked(self, button): + """ + Private slot called by a button of the button box clicked. + + @param button button that was clicked + @type QAbstractButton + """ + if button == self.buttonBox.button(QDialogButtonBox.Close): + self.close() + elif button == self.buttonBox.button(QDialogButtonBox.Cancel): + self.__client.abort() + self.__canceled = True + elif button == self.__installButton: + self.__install() + elif button == self.__installUserButton: + self.__install(userSite=True) + elif button == self.__showDetailsButton: + self.__showDetails() + + def __search(self): + """ + Private method to perform the search. + """ + self.resultList.clear() + self.infoLabel.clear() + + self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) + self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) + self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) + self.searchButton.setEnabled(False) + QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) + + QApplication.setOverrideCursor(Qt.WaitCursor) + QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) + + self.__canceled = False + + self.__query = [term for term in self.searchEdit.text().strip().split() + if term not in PipSearchDialog.Stopwords] + self.__client.call( + "search", + ({"name": self.__query, "summary": self.__query}, "or"), + self.__processSearchResult, + self.__searchError + ) + + def __processSearchResult(self, data): + """ + Private method to process the search result data from PyPI. + + @param data result data with hits in the first element + @type tuple + """ + if data: + packages = self.__transformHits(data[0]) + if packages: + self.infoLabel.setText(self.tr("%n package(s) found.", "", + len(packages))) + wrapper = textwrap.TextWrapper(width=80) + count = 0 + total = 0 + for package in packages: + if self.__canceled: + self.infoLabel.setText( + self.tr("Canceled - only {0} out of %n package(s)" + " shown", "", len(packages)).format(total)) + break + itm = QTreeWidgetItem( + self.resultList, [ + package['name'].strip(), + "{0:4d}".format(package['score']), + "\n".join([ + wrapper.fill(line) for line in + package['summary'].strip().splitlines() + ]) + ]) + itm.setData(0, self.VersionRole, package['version']) + count += 1 + total += 1 + if count == 100: + count = 0 + QApplication.processEvents() + else: + QApplication.restoreOverrideCursor() + E5MessageBox.warning( + self, + self.tr("Search PyPI"), + self.tr("""<p>The package search did not return""" + """ anything.</p>""")) + self.infoLabel.setText( + self.tr("""<p>The package search did not return""" + """ anything.</p>""")) + else: + QApplication.restoreOverrideCursor() + E5MessageBox.warning( + self, + self.tr("Search PyPI"), + self.tr("""<p>The package search did not return anything.""" + """</p>""")) + self.infoLabel.setText( + self.tr("""<p>The package search did not return anything.""" + """</p>""")) + + header = self.resultList.header() + self.resultList.sortItems(1, Qt.DescendingOrder) + header.setStretchLastSection(False) + header.resizeSections(QHeaderView.ResizeToContents) + headerSize = 0 + for col in range(header.count()): + headerSize += header.sectionSize(col) + if headerSize < header.width(): + header.setStretchLastSection(True) + + self.__finish() + + def __finish(self): + """ + Private slot performing the finishing actions. + """ + QApplication.restoreOverrideCursor() + self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) + self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) + self.searchButton.setEnabled(True) + self.searchButton.setDefault(True) + self.searchEdit.setFocus(Qt.OtherFocusReason) + + def __searchError(self, errorCode, errorString): + """ + Private method handling a search error. + + @param errorCode code of the error + @type int + @param errorString error message + @type str + """ + self.__finish() + E5MessageBox.warning( + self, + self.tr("Search PyPI"), + self.tr("""<p>The package search failed.</p><p>Reason: {0}</p>""") + .format(errorString)) + self.infoLabel.setText(self.tr("Error: {0}").format(errorString)) + + def __transformHits(self, hits): + """ + Private method to convert the list returned from pypi into a + packages list. + + @param hits list returned from pypi + @type list of dict + @return list of packages + @rtype list of dict + """ + # we only include the record with the highest score + packages = {} + for hit in hits: + name = hit['name'].strip() + summary = (hit['summary'] or "").strip() + version = hit['version'].strip() + score = self.__score(name, summary) + # cleanup the summary + if summary in ["UNKNOWN", "."]: + summary = "" + + if name not in packages: + packages[name] = { + 'name': name, + 'summary': summary, + 'version': [version.strip()], + 'score': score} + else: + if score > packages[name]['score']: + packages[name]['score'] = score + packages[name]['summary'] = summary + packages[name]['version'].append(version.strip()) + + return list(packages.values()) + + def __score(self, name, summary): + """ + Private method to calculate some score for a search result. + + @param name name of the returned package + @type str + @param summary summary text for the package + @type str + @return score value + @rtype int + """ + score = 0 + for queryTerm in self.__query: + if queryTerm.lower() in name.lower(): + score += 4 + if queryTerm.lower() == name.lower(): + score += 4 + + if queryTerm.lower() in summary.lower(): + if QRegExp(r'\b{0}\b'.format(QRegExp.escape(queryTerm)), + Qt.CaseInsensitive).indexIn(summary) != -1: + # word match gets even higher score + score += 2 + else: + score += 1 + + return score + + def __install(self, userSite=False): + """ + Private slot to install the selected packages. + + @param userSite flag indicating to install to the user directory + @type bool + """ + venvName = self.venvComboBox.currentText() + + packages = [] + for itm in self.resultList.selectedItems(): + packages.append(itm.text(0).strip()) + if packages: + self.__pip.installPackages(packages, venvName=venvName, + userSite=userSite) + + def __showDetails(self): + """ + Private slot to show details about the selected package. + """ + self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) + self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) + self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) + self.__showDetailsButton.setEnabled(False) + QApplication.setOverrideCursor(Qt.WaitCursor) + QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) + + self.__detailsData = {} + + itm = self.resultList.selectedItems()[0] + packageVersions = itm.data(0, self.VersionRole) + if len(packageVersions) == 1: + packageVersion = packageVersions[0] + elif len(packageVersions) == 0: + packageVersion = "" + else: + packageVersion, ok = QInputDialog.getItem( + self, + self.tr("Show Package Details"), + self.tr("Select the package version:"), + packageVersions, + 0, False) + if not ok: + return + + packageName = itm.text(0) + self.__client.call( + "release_data", + (packageName, packageVersion), + lambda d: self.__getPackageDownloadsData(packageVersion, d), + self.__detailsError + ) + + def __getPackageDownloadsData(self, packageVersion, data): + """ + Private method to store the details data and get downloads + information. + + @param packageVersion version info + @type str + @param data result data with package details in the first + element + @type tuple + """ + if data and data[0]: + self.__detailsData = data[0] + itm = self.resultList.selectedItems()[0] + packageName = itm.text(0) + self.__client.call( + "release_urls", + (packageName, packageVersion), + self.__displayPackageDetails, + self.__detailsError + ) + else: + self.__finish() + E5MessageBox.warning( + self, + self.tr("Search PyPI"), + self.tr("""<p>No package details info available.</p>""")) + + def __displayPackageDetails(self, data): + """ + Private method to display the returned package details. + + @param data result data with downloads information in the first element + @type tuple + """ + from .PipPackageDetailsDialog import PipPackageDetailsDialog + + self.__finish() + self.__showDetailsButton.setEnabled(True) + + if self.__packageDetailsDialog is not None: + self.__packageDetailsDialog.close() + + self.__packageDetailsDialog = \ + PipPackageDetailsDialog(self.__detailsData, data[0], self) + self.__packageDetailsDialog.show() + + def __detailsError(self, errorCode, errorString): + """ + Private method handling a details error. + + @param errorCode code of the error + @type int + @param errorString error message + @type str + """ + self.__finish() + self.__showDetailsButton.setEnabled(True) + E5MessageBox.warning( + self, + self.tr("Search PyPI"), + self.tr("""<p>Package details info could not be retrieved.</p>""" + """<p>Reason: {0}</p>""") + .format(errorString)) + + @pyqtSlot(QTreeWidgetItem, int) + def on_resultList_itemActivated(self, item, column): + """ + Private slot reacting on an item activation. + + @param item reference to the activated item + @type QTreeWidgetItem + @param column activated column + @type int + """ + self.__showDetails()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PipInterface/PipSearchDialog.ui Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PipSearchDialog</class> + <widget class="QDialog" name="PipSearchDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>700</width> + <height>600</height> + </rect> + </property> + <property name="windowTitle"> + <string>Search PyPI</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Virtual Environment:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="venvComboBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Select the virtual environment to be used</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Query:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="searchEdit"> + <property name="toolTip"> + <string>Enter the search term</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="searchButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Press to start the search</string> + </property> + <property name="text"> + <string>Search</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QTreeWidget" name="resultList"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::ExtendedSelection</enum> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="itemsExpandable"> + <bool>false</bool> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string>Package</string> + </property> + </column> + <column> + <property name="text"> + <string>Score</string> + </property> + </column> + <column> + <property name="text"> + <string>Description</string> + </property> + </column> + </widget> + </item> + <item> + <widget class="QLabel" name="infoLabel"/> + </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> + <tabstops> + <tabstop>venvComboBox</tabstop> + <tabstop>searchEdit</tabstop> + <tabstop>searchButton</tabstop> + <tabstop>resultList</tabstop> + </tabstops> + <resources/> + <connections/> +</ui>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PipInterface/PipSelectionDialog.py Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2018 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to select the pip executable to be used. +""" + +from __future__ import unicode_literals + +from PyQt5.QtWidgets import QDialog + +from .Ui_PipSelectionDialog import Ui_PipSelectionDialog + + +class PipSelectionDialog(QDialog, Ui_PipSelectionDialog): + """ + Class implementing a dialog to select the pip executable to be used. + """ + def __init__(self, pip, parent=None): + """ + Constructor + + @param pip reference to the pip object + @type Pip + @param parent reference to the parent widget + @type QWidget + """ + super(PipSelectionDialog, self).__init__(parent) + self.setupUi(self) + + self.venvComboBox.addItem(pip.getDefaultEnvironmentString()) + projectVenv = pip.getProjectEnvironmentString() + if projectVenv: + self.venvComboBox.addItem(projectVenv) + self.venvComboBox.addItems(pip.getVirtualenvNames()) + + msh = self.minimumSizeHint() + self.resize(max(self.width(), msh.width()), msh.height()) + + def getData(self): + """ + Public method to get the entered data. + + @return tuple with the environment name and a flag indicating to + install to the user install directory + @rtype tuple of (str, bool) + """ + return ( + self.venvComboBox.currentText(), + self.userCheckBox.isChecked(), + )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PipInterface/PipSelectionDialog.ui Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PipSelectionDialog</class> + <widget class="QDialog" name="PipSelectionDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>130</height> + </rect> + </property> + <property name="windowTitle"> + <string>Select Virtual Environment</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Virtual Environment:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="venvComboBox"> + <property name="toolTip"> + <string>Select the virtual environment to be used</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="userCheckBox"> + <property name="toolTip"> + <string>Select to install to the Python user install directory</string> + </property> + <property name="text"> + <string>Install into User Directory</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> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>PipSelectionDialog</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>PipSelectionDialog</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/PipInterface/__init__.py Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Package implementing the various pip dialogs and data. +""" + +from __future__ import unicode_literals + +DefaultPyPiUrl = "https://pypi.org" +DefaultIndexUrlXml = DefaultPyPiUrl + "/pypi" +DefaultIndexUrlPip = DefaultPyPiUrl + "/simple"
--- a/Plugins/PluginPipInterface.py Mon Feb 18 19:14:05 2019 +0100 +++ b/Plugins/PluginPipInterface.py Mon Feb 18 19:17:04 2019 +0100 @@ -39,71 +39,71 @@ pipPluginObject = None -def exeDisplayDataList(): - """ - Module function to support the display of some executable info. - - @return list of dictionaries containing the data to query the presence of - the executable - """ - global pipPluginObject - - dataList = [] - data = { - "programEntry": True, - "header": QCoreApplication.translate( - "PipInterfacePlugin", "Package Management - pip"), - "exe": "dummyExe", - "versionCommand": "--version", - "versionStartsWith": "pip", - "versionPosition": 1, - "version": "", - "versionCleanup": None, - "exeModule": ["-m", "pip"], - } - virtualenvManager = e5App().getObject("VirtualEnvManager") - for venvName in virtualenvManager.getVirtualenvNames(): - interpreter = virtualenvManager.getVirtualenvInterpreter(venvName) - data["exe"] = interpreter - dataList.append(data.copy()) - return dataList - - -def createPipPage(configDlg): - """ - Module function to create the pip configuration page. - - @param configDlg reference to the configuration dialog - @return reference to the configuration page - """ - global pipPluginObject - from UiExtensionPlugins.PipInterface.ConfigurationPage.PipPage import \ - PipPage - page = PipPage(pipPluginObject) - return page - - -def getConfigData(): - """ - Module function returning data as required by the configuration dialog. - - @return dictionary containing the relevant data - """ - return { - "pipPage": [ - QCoreApplication.translate( - "PipInterfacePlugin", "Python Package Management"), - "pypi.png", - createPipPage, None, None - ], - } - - -def prepareUninstall(): - """ - Module function to prepare for an un-installation. - """ - Preferences.Prefs.settings.remove(PipInterfacePlugin.PreferencesKey) +##def exeDisplayDataList(): +## """ +## Module function to support the display of some executable info. +## +## @return list of dictionaries containing the data to query the presence of +## the executable +## """ +## global pipPluginObject +## +## dataList = [] +## data = { +## "programEntry": True, +## "header": QCoreApplication.translate( +## "PipInterfacePlugin", "Package Management - pip"), +## "exe": "dummyExe", +## "versionCommand": "--version", +## "versionStartsWith": "pip", +## "versionPosition": 1, +## "version": "", +## "versionCleanup": None, +## "exeModule": ["-m", "pip"], +## } +## virtualenvManager = e5App().getObject("VirtualEnvManager") +## for venvName in virtualenvManager.getVirtualenvNames(): +## interpreter = virtualenvManager.getVirtualenvInterpreter(venvName) +## data["exe"] = interpreter +## dataList.append(data.copy()) +## return dataList +## +## +##def createPipPage(configDlg): +## """ +## Module function to create the pip configuration page. +## +## @param configDlg reference to the configuration dialog +## @return reference to the configuration page +## """ +## global pipPluginObject +## from UiExtensionPlugins.PipInterface.ConfigurationPage.PipPage import \ +## PipPage +## page = PipPage(pipPluginObject) +## return page +## +## +##def getConfigData(): +## """ +## Module function returning data as required by the configuration dialog. +## +## @return dictionary containing the relevant data +## """ +## return { +## "pipPage": [ +## QCoreApplication.translate( +## "PipInterfacePlugin", "Python Package Management"), +## "pypi.png", +## createPipPage, None, None +## ], +## } +## +## +##def prepareUninstall(): +## """ +## Module function to prepare for an un-installation. +## """ +## Preferences.Prefs.settings.remove(PipInterfacePlugin.PreferencesKey) class PipInterfacePlugin(QObject): @@ -176,33 +176,33 @@ self.__mainAct = None self.__initialize() - - def getPreferences(self, key): - """ - Public method to retrieve the various pip related settings. - - @param key the key of the value to get - @type str - @return the requested setting - @rtype any - """ - return Preferences.Prefs.settings.value( - self.PreferencesKey + "/" + key, self.__defaults[key]) - - def setPreferences(self, key, value): - """ - Public method to store the various pip related settings. - - @param key the key of the setting to be set - @type str - @param value the value to be set - @type any - """ - Preferences.Prefs.settings.setValue( - self.PreferencesKey + "/" + key, value) - - if key == "CurrentEnvironment": - self.currentEnvironmentChanged.emit(value) +## +## def getPreferences(self, key): +## """ +## Public method to retrieve the various pip related settings. +## +## @param key the key of the value to get +## @type str +## @return the requested setting +## @rtype any +## """ +## return Preferences.Prefs.settings.value( +## self.PreferencesKey + "/" + key, self.__defaults[key]) +## +## def setPreferences(self, key, value): +## """ +## Public method to store the various pip related settings. +## +## @param key the key of the setting to be set +## @type str +## @param value the value to be set +## @type any +## """ +## Preferences.Prefs.settings.setValue( +## self.PreferencesKey + "/" + key, value) +## +## if key == "CurrentEnvironment": +## self.currentEnvironmentChanged.emit(value) def getMenu(self, name): """
--- a/Plugins/UiExtensionPlugins/PipInterface/ConfigurationPage/PipPage.py Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Package implementing the pip configuration page. -""" - -from __future__ import unicode_literals - -from Preferences.ConfigurationPages.ConfigurationPageBase import \ - ConfigurationPageBase -from .Ui_PipPage import Ui_PipPage - -from .. import DefaultPyPiUrl - - -class PipPage(ConfigurationPageBase, Ui_PipPage): - """ - Class implementing the pip configuration page. - """ - def __init__(self, plugin): - """ - Constructor - - @param plugin reference to the plugin object - @type PipInterfacePlugin - """ - super(PipPage, self).__init__() - self.setupUi(self) - self.setObjectName("PipPage") - - self.__plugin = plugin - - self.indexLabel.setText(self.tr( - '<b>Note:</b> Leave empty to use the default index URL (' - '<a href="{0}">{0}</a>).') - .format(DefaultPyPiUrl)) - - # set initial values - self.indexEdit.setText(self.__plugin.getPreferences("PipSearchIndex")) - - def save(self): - """ - Public slot to save the pip configuration. - """ - self.__plugin.setPreferences( - "PipSearchIndex", self.indexEdit.text().strip())
--- a/Plugins/UiExtensionPlugins/PipInterface/ConfigurationPage/PipPage.ui Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>PipPage</class> - <widget class="QWidget" name="PipPage"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>602</width> - <height>389</height> - </rect> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QLabel" name="headerLabel"> - <property name="text"> - <string><b>Configure pip</b></string> - </property> - </widget> - </item> - <item> - <widget class="Line" name="line9_3"> - <property name="frameShape"> - <enum>QFrame::HLine</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Sunken</enum> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item> - <widget class="QGroupBox" name="groupBox_2"> - <property name="title"> - <string>Index URL</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLineEdit" name="indexEdit"> - <property name="toolTip"> - <string>Enter the URL of the package index or leave empty to use the default</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="indexLabel"> - <property name="text"> - <string/> - </property> - <property name="openExternalLinks"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>234</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - <tabstops> - <tabstop>indexEdit</tabstop> - </tabstops> - <resources/> - <connections/> -</ui>
--- a/Plugins/UiExtensionPlugins/PipInterface/ConfigurationPage/__init__.py Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Package implementing the configuration page. -"""
--- a/Plugins/UiExtensionPlugins/PipInterface/Pip.py Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1144 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Package implementing the pip GUI logic. -""" - -from __future__ import unicode_literals -try: - str = unicode # __IGNORE_EXCEPTION__ -except NameError: - pass - -import os -import sys - -from PyQt5.QtCore import pyqtSlot, QObject, QProcess -from PyQt5.QtWidgets import QMenu, QInputDialog, QDialog - -from E5Gui import E5MessageBox -from E5Gui.E5Action import E5Action -from E5Gui.E5Application import e5App - -from .PipDialog import PipDialog -from . import DefaultIndexUrlXml - -import Preferences -import Globals - -import UI.PixmapCache - - -class Pip(QObject): - """ - Class implementing the pip GUI logic. - """ - def __init__(self, plugin, parent=None): - """ - Constructor - - @param plugin reference to the plugin object - @type PipInterfacePlugin - @param parent parent - @type QObject - """ - super(Pip, self).__init__(parent) - - self.__plugin = plugin - self.__ui = parent - - self.__virtualenvManager = e5App().getObject("VirtualEnvManager") - self.__project = e5App().getObject("Project") - - self.__menus = {} # dictionary with references to menus - - self.__plugin.currentEnvironmentChanged.connect( - self.__handleTearOffMenu) - - def initActions(self): - """ - Public method to define the actions. - """ - self.actions = [] - - self.selectEnvironmentAct = E5Action( - self.tr('Virtual Environment for pip'), - self.tr('&Virtual Environment for pip'), - 0, 0, - self, 'pip_select_environment') - self.selectEnvironmentAct.setStatusTip(self.tr( - 'Selects the virtual environment to be used for pip')) - self.selectEnvironmentAct.setWhatsThis(self.tr( - """<b>Virtual Environment for pip</b>""" - """<p>This selects the virtual environment to be used for pip.""" - """</p>""" - )) - self.selectEnvironmentAct.triggered.connect(self.__selectPipVirtualenv) - self.actions.append(self.selectEnvironmentAct) - - ############################################## - ## Actions for listing packages - ############################################## - - self.listPackagesAct = E5Action( - self.tr('List Installed Packages'), - self.tr('&List Installed Packages...'), - 0, 0, - self, 'pip_list_packages') - self.listPackagesAct.setStatusTip(self.tr( - 'List all installed packages with versions')) - self.listPackagesAct.setWhatsThis(self.tr( - """<b>List Installed Packages</b>""" - """<p>This lists all the installed packages together""" - """ with their versions.</p>""" - )) - self.listPackagesAct.triggered.connect(self.__listPackages) - self.actions.append(self.listPackagesAct) - - self.listUptodatePackagesAct = E5Action( - self.tr('List Up-to-date Packages'), - self.tr('List Up-to-&date Packages...'), - 0, 0, - self, 'pip_list_uptodate_packages') - self.listUptodatePackagesAct.setStatusTip(self.tr( - 'List all installed, up-to-date packages with versions')) - self.listUptodatePackagesAct.setWhatsThis(self.tr( - """<b>List Up-to-date Packages</b>""" - """<p>This lists all the installed, up-to-date packages together""" - """ with their versions.</p>""" - )) - self.listUptodatePackagesAct.triggered.connect( - self.__listUptodatePackages) - self.actions.append(self.listUptodatePackagesAct) - - self.listOutdatedPackagesAct = E5Action( - self.tr('List Outdated Packages'), - self.tr('List &Outdated Packages...'), - 0, 0, - self, 'pip_list_outdated_packages') - self.listOutdatedPackagesAct.setStatusTip(self.tr( - 'List all installed, outdated packages with versions')) - self.listOutdatedPackagesAct.setWhatsThis(self.tr( - """<b>List Up-to-date Packages</b>""" - """<p>This lists all the installed, outdated packages together""" - """ with their current and latest versions.</p>""" - )) - self.listOutdatedPackagesAct.triggered.connect( - self.__listOutdatedPackages) - self.actions.append(self.listOutdatedPackagesAct) - - ############################################## - ## Actions for installing packages - ############################################## - - self.installPackagesAct = E5Action( - self.tr('Install Packages'), - self.tr('&Install Packages'), - 0, 0, - self, 'pip_install_packages') - self.installPackagesAct.setStatusTip(self.tr( - 'Install packages according to user input')) - self.installPackagesAct.setWhatsThis(self.tr( - """<b>Install Packages</b>""" - """<p>This installs packages according to user input.</p>""" - )) - self.installPackagesAct.triggered.connect(self.__installPackages) - self.actions.append(self.installPackagesAct) - - self.installLocalPackageAct = E5Action( - self.tr('Install Local Package'), - self.tr('Install Local Package'), - 0, 0, - self, 'pip_install_local_package') - self.installLocalPackageAct.setStatusTip(self.tr( - 'Install a package from local storage')) - self.installLocalPackageAct.setWhatsThis(self.tr( - """<b>Install Local Package</b>""" - """<p>This installs a package available on local storage.</p>""" - )) - self.installLocalPackageAct.triggered.connect( - self.__installLocalPackage) - self.actions.append(self.installLocalPackageAct) - - self.installRequirementsAct = E5Action( - self.tr('Install Requirements'), - self.tr('Install Requirements'), - 0, 0, - self, 'pip_install_requirements') - self.installRequirementsAct.setStatusTip(self.tr( - 'Install packages according to a requirements file')) - self.installRequirementsAct.setWhatsThis(self.tr( - """<b>Install Requirements</b>""" - """<p>This installs packages according to a requirements""" - """ file.</p>""" - )) - self.installRequirementsAct.triggered.connect( - self.__installRequirements) - self.actions.append(self.installRequirementsAct) - - self.installPipAct = E5Action( - self.tr('Install Pip'), - self.tr('Install Pip'), - 0, 0, - self, 'pip_install_pip') - self.installPipAct.setStatusTip(self.tr( - 'Install the pip package itself')) - self.installPipAct.setWhatsThis(self.tr( - """<b>Install Pip</b>""" - """<p>This installs the pip package itself.</p>""" - )) - self.installPipAct.triggered.connect(self.__installPip) - self.actions.append(self.installPipAct) - - self.repairPipAct = E5Action( - self.tr('Repair Pip'), - self.tr('Repair Pip'), - 0, 0, - self, 'pip_repair_pip') - self.repairPipAct.setStatusTip(self.tr( - 'Repair the pip package')) - self.repairPipAct.setWhatsThis(self.tr( - """<b>Repair Pip</b>""" - """<p>This repairs the pip package by re-installing it.</p>""" - )) - self.repairPipAct.triggered.connect(self.__repairPip) - self.actions.append(self.repairPipAct) - - self.upgradePipAct = E5Action( - self.tr('Upgrade Pip'), - self.tr('Upgrade &Pip'), - 0, 0, - self, 'pip_upgrade_pip') - self.upgradePipAct.setStatusTip(self.tr( - 'Upgrade the pip package itself')) - self.upgradePipAct.setWhatsThis(self.tr( - """<b>Upgrade Pip</b>""" - """<p>This upgrades the pip package itself.</p>""" - )) - self.upgradePipAct.triggered.connect(self.upgradePip) - self.actions.append(self.upgradePipAct) - - self.upgradePackagesAct = E5Action( - self.tr('Upgrade Packages'), - self.tr('&Upgrade Packages'), - 0, 0, - self, 'pip_upgrade_packages') - self.upgradePackagesAct.setStatusTip(self.tr( - 'Upgrade packages according to user input')) - self.upgradePackagesAct.setWhatsThis(self.tr( - """<b>Upgrade Packages</b>""" - """<p>This upgrades packages according to user input.</p>""" - )) - self.upgradePackagesAct.triggered.connect(self.__upgradePackages) - self.actions.append(self.upgradePackagesAct) - - ############################################## - ## Actions for uninstalling packages - ############################################## - - self.uninstallPackagesAct = E5Action( - self.tr('Uninstall Packages'), - self.tr('Uninstall Packages'), - 0, 0, - self, 'pip_uninstall_packages') - self.uninstallPackagesAct.setStatusTip(self.tr( - 'Uninstall packages according to user input')) - self.uninstallPackagesAct.setWhatsThis(self.tr( - """<b>Uninstall Packages</b>""" - """<p>This uninstalls packages according to user input.</p>""" - )) - self.uninstallPackagesAct.triggered.connect(self.__uninstallPackages) - self.actions.append(self.uninstallPackagesAct) - - self.uninstallRequirementsAct = E5Action( - self.tr('Uninstall Requirements'), - self.tr('Uninstall Requirements'), - 0, 0, - self, 'pip_uninstall_requirements') - self.uninstallRequirementsAct.setStatusTip(self.tr( - 'Uninstall packages according to a requirements file')) - self.uninstallRequirementsAct.setWhatsThis(self.tr( - """<b>Uninstall Requirements</b>""" - """<p>This uninstalls packages according to a requirements""" - """ file.</p>""" - )) - self.uninstallRequirementsAct.triggered.connect( - self.__uninstallRequirements) - self.actions.append(self.uninstallRequirementsAct) - - ############################################## - ## Actions for generating requirements files - ############################################## - - self.generateRequirementsAct = E5Action( - self.tr('Generate Requirements'), - self.tr('&Generate Requirements...'), - 0, 0, - self, 'pip_generate_requirements') - self.generateRequirementsAct.setStatusTip(self.tr( - 'Generate the contents of a requirements file')) - self.generateRequirementsAct.setWhatsThis(self.tr( - """<b>Generate Requirements</b>""" - """<p>This generates the contents of a requirements file.</p>""" - )) - self.generateRequirementsAct.triggered.connect( - self.__generateRequirements) - self.actions.append(self.generateRequirementsAct) - - ############################################## - ## Actions for generating requirements files - ############################################## - - self.searchPyPIAct = E5Action( - self.tr('Search PyPI'), - self.tr('&Search PyPI...'), - 0, 0, - self, 'pip_search_pypi') - self.searchPyPIAct.setStatusTip(self.tr( - 'Open a dialog to search the Python Package Index')) - self.searchPyPIAct.setWhatsThis(self.tr( - """<b>Search PyPI</b>""" - """<p>This opens a dialog to search the Python Package""" - """ Index.</p>""" - )) - self.searchPyPIAct.triggered.connect(self.__searchPyPI) - self.actions.append(self.searchPyPIAct) - - ############################################## - ## Actions for editing configuration files - ############################################## - - self.editUserConfigAct = E5Action( - self.tr('Edit User Configuration'), - self.tr('Edit User Configuration...'), - 0, 0, - self, 'pip_edit_user_config') - self.editUserConfigAct.setStatusTip(self.tr( - 'Open the per user configuration file in an editor')) - self.editUserConfigAct.setWhatsThis(self.tr( - """<b>Edit User Configuration</b>""" - """<p>This opens the per user configuration file in an editor.""" - """</p>""" - )) - self.editUserConfigAct.triggered.connect(self.__editUserConfiguration) - self.actions.append(self.editUserConfigAct) - - self.editVirtualenvConfigAct = E5Action( - self.tr('Edit Current Virtualenv Configuration'), - self.tr('Edit Current Virtualenv Configuration...'), - 0, 0, - self, 'pip_edit_virtualenv_config') - self.editVirtualenvConfigAct.setStatusTip(self.tr( - 'Open the current virtualenv configuration file in an editor')) - self.editVirtualenvConfigAct.setWhatsThis(self.tr( - """<b>Edit Current Virtualenv Configuration</b>""" - """<p>This opens the current virtualenv configuration file in""" - """ an editor. </p>""" - )) - self.editVirtualenvConfigAct.triggered.connect( - self.__editVirtualenvConfiguration) - self.actions.append(self.editVirtualenvConfigAct) - - self.pipConfigAct = E5Action( - self.tr('Configure'), - self.tr('Configure...'), - 0, 0, self, 'pip_configure') - self.pipConfigAct.setStatusTip(self.tr( - 'Show the configuration dialog with the Python Package Management' - ' page selected' - )) - self.pipConfigAct.setWhatsThis(self.tr( - """<b>Configure</b>""" - """<p>Show the configuration dialog with the Python Package""" - """ Management page selected.</p>""" - )) - self.pipConfigAct.triggered.connect(self.__pipConfigure) - self.actions.append(self.pipConfigAct) - - def initMenu(self): - """ - Public slot to initialize the menu. - - @return the menu generated - @rtype QMenu - """ - self.__menus = {} # clear menus references - - menu = QMenu(self.tr('P&ython Package Management'), self.__ui) - menu.setTearOffEnabled(True) - menu.setIcon(UI.PixmapCache.getIcon("pypi.png")) - - menu.addAction(self.selectEnvironmentAct) - menu.addSeparator() - menu.addAction(self.listPackagesAct) - menu.addAction(self.listUptodatePackagesAct) - menu.addAction(self.listOutdatedPackagesAct) - menu.addSeparator() - menu.addAction(self.installPipAct) - menu.addSeparator() - menu.addAction(self.installPackagesAct) - menu.addAction(self.installLocalPackageAct) - menu.addAction(self.installRequirementsAct) - menu.addSeparator() - menu.addAction(self.upgradePipAct) - menu.addAction(self.upgradePackagesAct) - menu.addSeparator() - menu.addAction(self.uninstallPackagesAct) - menu.addAction(self.uninstallRequirementsAct) - menu.addSeparator() - menu.addAction(self.generateRequirementsAct) - menu.addSeparator() - menu.addAction(self.searchPyPIAct) - menu.addSeparator() - menu.addAction(self.repairPipAct) - menu.addSeparator() - menu.addAction(self.editUserConfigAct) - menu.addAction(self.editVirtualenvConfigAct) - menu.addSeparator() - menu.addAction(self.pipConfigAct) - - self.__menus["main"] = menu - - menu.aboutToShow.connect(self.__aboutToShowMenu) - - return menu - - def __aboutToShowMenu(self): - """ - Private slot to set the action enabled status. - """ - enable = bool(self.__plugin.getPreferences("CurrentEnvironment")) - for act in self.actions: - if act not in [self.selectEnvironmentAct, - self.installPipAct, - self.editUserConfigAct, - self.editVirtualenvConfigAct, - self.pipConfigAct]: - act.setEnabled(enable) - - def getMenu(self, name): - """ - Public method to get a reference to the requested menu. - - @param name name of the menu - @type str - @return reference to the menu or None, if no - menu with the given name exists - @rtype QMenu or None - """ - if name in self.__menus: - return self.__menus[name] - else: - return None - - def getMenuNames(self): - """ - Public method to get the names of all menus. - - @return menu names - @rtype list of str - """ - return list(self.__menus.keys()) - - def __handleTearOffMenu(self, venvName): - """ - Private slot to handle a change of the selected virtual environment. - - @param venvName logical name of the virtual environment - @type str - """ - if self.__menus["main"].isTearOffMenuVisible(): - # determine, if torn off menu needs to be refreshed - enabled = self.listPackagesAct.isEnabled() - if ((bool(venvName) and not enabled) or - (not bool(venvName) and enabled)): - self.__menus["main"].hideTearOffMenu() - - ########################################################################## - ## Methods below implement some utility functions - ########################################################################## - - def runProcess(self, args, interpreter): - """ - Public method to execute the current pip with the given arguments. - - The selected pip executable is called with the given arguments and - waited for its end. - - @param args list of command line arguments - @type list of str - @param interpreter path of the Python interpreter to be used - @type str - @return tuple containing a flag indicating success and the output - of the process - @rtype tuple of (bool, str) - """ - ioEncoding = Preferences.getSystem("IOEncoding") - - process = QProcess() - process.start(interpreter, args) - procStarted = process.waitForStarted() - if procStarted: - finished = process.waitForFinished(30000) - if finished: - if process.exitCode() == 0: - output = str(process.readAllStandardOutput(), ioEncoding, - 'replace') - return True, output - else: - return (False, - self.tr("python exited with an error ({0}).") - .format(process.exitCode())) - else: - process.terminate() - process.waitForFinished(2000) - process.kill() - process.waitForFinished(3000) - return False, self.tr("python did not finish within" - " 30 seconds.") - - return False, self.tr("python could not be started.") - - def __getUserConfig(self): - """ - Private method to get the name of the user configuration file. - - @return path of the user configuration file - @rtype str - """ - # Unix: ~/.config/pip/pip.conf - # OS X: ~/Library/Application Support/pip/pip.conf - # Windows: %APPDATA%\pip\pip.ini - # Environment: $PIP_CONFIG_FILE - - try: - return os.environ["PIP_CONFIG_FILE"] - except KeyError: - pass - - if Globals.isWindowsPlatform(): - config = os.path.join(os.environ["APPDATA"], "pip", "pip.ini") - elif Globals.isMacPlatform(): - config = os.path.expanduser( - "~/Library/Application Support/pip/pip.conf") - else: - config = os.path.expanduser("~/.config/pip/pip.conf") - - return config - - def __getVirtualenvConfig(self): - """ - Private method to get the name of the virtualenv configuration file. - - @return path of the virtualenv configuration file - @rtype str - """ - # Unix, OS X: $VIRTUAL_ENV/pip.conf - # Windows: %VIRTUAL_ENV%\pip.ini - - if Globals.isWindowsPlatform(): - pip = "pip.ini" - else: - pip = "pip.conf" - try: - venvDirectory = os.environ["VIRTUAL_ENV"] - except KeyError: - venvName = self.__plugin.getPreferences("CurrentEnvironment") - if not venvName: - self.__selectPipVirtualenv() - venvName = self.__plugin.getPreferences("CurrentEnvironment") - if self.__virtualenvManager.isGlobalEnvironment(venvName): - venvDirectory = self.__getUserConfig() - else: - venvDirectory = \ - self.__virtualenvManager.getVirtualenvDirectory(venvName) - - return os.path.join(venvDirectory, pip) - - def getDefaultEnvironmentString(self): - """ - Public method to get the string for the default environment. - - @return string for the default environment - @rtype str - """ - return self.tr("<standard>") - - def getProjectEnvironmentString(self): - """ - Public method to get the string for the project environment. - - @return string for the project environment - @rtype str - """ - if self.__project.isOpen(): - return self.tr("<project>") - else: - return "" - - def getVirtualenvInterpreter(self, venvName): - """ - Public method to get the interpreter for a virtual environment. - - @param venvName logical name for the virtual environment - @type str - @return interpreter path - @rtype str - """ - if venvName == self.getDefaultEnvironmentString(): - venvName = self.__plugin.getPreferences("CurrentEnvironment") - elif venvName == self.getProjectEnvironmentString(): - venvName = self.__project.getDebugProperty("VIRTUALENV") - if not venvName: - # fall back to standard if not defined - venvName = self.__plugin.getPreferences("CurrentEnvironment") - - interpreter = self.__virtualenvManager.getVirtualenvInterpreter( - venvName) - if not interpreter: - E5MessageBox.critical( - None, - self.tr("Interpreter for Virtual Environment"), - self.tr("""No interpreter configured for the selected""" - """ virtual environment.""")) - - return interpreter - - def getVirtualenvNames(self): - """ - Public method to get a sorted list of virtual environment names. - - @return sorted list of virtual environment names - @rtype list of str - """ - return sorted(self.__virtualenvManager.getVirtualenvNames()) - - ########################################################################## - ## Methods below implement the individual menu entries - ########################################################################## - - def __selectPipVirtualenv(self): - """ - Private method to select the virtual environment to be used. - """ - environments = self.getVirtualenvNames() - if environments: - currentEnvironment = self.__plugin.getPreferences( - "CurrentEnvironment") - try: - index = environments.index(currentEnvironment) - except ValueError: - index = 0 - environment, ok = QInputDialog.getItem( - None, - self.tr("Virtual Environment for pip"), - self.tr("Select the virtual environment to be used:"), - environments, index, False) - - if ok and environment: - self.__plugin.setPreferences("CurrentEnvironment", - environment) - else: - E5MessageBox.warning( - None, - self.tr("Virtual Environment for pip"), - self.tr("""No virtual environments have been configured yet.""" - """ Please use the Virtualenv Manager to do that.""")) - - def __listPackages(self): - """ - Private slot to list all installed packages. - """ - from .PipListDialog import PipListDialog - self.__listDialog = PipListDialog( - self, "list", self.__plugin.getPreferences("PipSearchIndex"), - self.tr("Installed Packages")) - self.__listDialog.show() - self.__listDialog.start() - - def __listUptodatePackages(self): - """ - Private slot to list all installed, up-to-date packages. - """ - from .PipListDialog import PipListDialog - self.__listUptodateDialog = PipListDialog( - self, "uptodate", self.__plugin.getPreferences("PipSearchIndex"), - self.tr("Up-to-date Packages")) - self.__listUptodateDialog.show() - self.__listUptodateDialog.start() - - def __listOutdatedPackages(self): - """ - Private slot to list all installed, up-to-date packages. - """ - from .PipListDialog import PipListDialog - self.__listOutdatedDialog = PipListDialog( - self, "outdated", self.__plugin.getPreferences("PipSearchIndex"), - self.tr("Outdated Packages")) - self.__listOutdatedDialog.show() - self.__listOutdatedDialog.start() - - def __editUserConfiguration(self): - """ - Private slot to edit the user configuration. - """ - self.__editConfiguration() - - def __editVirtualenvConfiguration(self): - """ - Private slot to edit the current virtualenv configuration. - """ - self.__editConfiguration(virtualenv=True) - - def __editConfiguration(self, virtualenv=False): - """ - Private method to edit a configuration. - - @param virtualenv flag indicating to edit the current virtualenv - configuration file - @type bool - """ - from QScintilla.MiniEditor import MiniEditor - if virtualenv: - cfgFile = self.__getVirtualenvConfig() - else: - cfgFile = self.__getUserConfig() - cfgDir = os.path.dirname(cfgFile) - if not cfgDir: - E5MessageBox.critical( - None, - self.tr("Edit Configuration"), - self.tr("""No valid configuration path determined.""" - """ Is a virtual environment selected? Aborting""")) - return - - try: - if not os.path.isdir(cfgDir): - os.makedirs(cfgDir) - except OSError: - E5MessageBox.critical( - None, - self.tr("Edit Configuration"), - self.tr("""No valid configuration path determined.""" - """ Is a virtual environment selected? Aborting""")) - return - - if not os.path.exists(cfgFile): - try: - f = open(cfgFile, "w") - f.write("[global]\n") - f.close() - except (IOError, OSError): - # ignore these - pass - - # check, if the destination is writeable - if not os.access(cfgFile, os.W_OK): - E5MessageBox.critical( - None, - self.tr("Edit Configuration"), - self.tr("""No valid configuartion path determined.""" - """ Is a virtual environment selected? Aborting""")) - return - - self.__editor = MiniEditor(cfgFile, "Properties") - self.__editor.show() - - def __installPip(self, userSite=False): - """ - Private slot to install pip. - - @param userSite flag indicating an install to the user install - directory - @type bool - """ - from .PipSelectionDialog import PipSelectionDialog - dlg = PipSelectionDialog(self) - if dlg.exec_() != QDialog.Accepted: - return - - venvName, userSite = dlg.getData() - interpreter = self.getVirtualenvInterpreter(venvName) - if not interpreter: - return - - dia = PipDialog(self.tr('Install PIP')) - if userSite: - commands = [(interpreter, ["-m", "ensurepip", "--user"])] - else: - commands = [(interpreter, ["-m", "ensurepip"])] - if self.__plugin.getPreferences("PipSearchIndex"): - indexUrl = \ - self.__plugin.getPreferences("PipSearchIndex") + "/simple" - args = ["-m", "pip", "install", "--index-url", indexUrl, - "--upgrade"] - else: - args = ["-m", "pip", "install", "--upgrade"] - if userSite: - args.append("--user") - args.append("pip") - commands.append((interpreter, args[:])) - - res = dia.startProcesses(commands) - if res: - dia.exec_() - - @pyqtSlot() - def upgradePip(self, venvName="", userSite=False): - """ - Public method to upgrade pip itself. - - @param venvName name of the virtual environment to be used - @type str - @param userSite flag indicating an install to the user install - directory - @type bool - @return flag indicating a successful execution - @rtype bool - """ - # Upgrading pip needs to be treated specially because - # it must be done using the python executable - - if not venvName: - from .PipSelectionDialog import PipSelectionDialog - dlg = PipSelectionDialog(self) - if dlg.exec_() != QDialog.Accepted: - return - - venvName, userSite = dlg.getData() - - interpreter = self.getVirtualenvInterpreter(venvName) - if not interpreter: - return - - if self.__plugin.getPreferences("PipSearchIndex"): - indexUrl = \ - self.__plugin.getPreferences("PipSearchIndex") + "/simple" - args = ["-m", "pip", "install", "--index-url", indexUrl, - "--upgrade"] - else: - args = ["-m", "pip", "install", "--upgrade"] - if userSite: - args.append("--user") - args.append("pip") - - dia = PipDialog(self.tr('Upgrade PIP')) - res = dia.startProcess(interpreter, args) - if res: - dia.exec_() - return res - - @pyqtSlot() - def __repairPip(self): - """ - Private method to repair the pip installation. - - @return flag indicating a successful execution - @rtype bool - """ - from .PipSelectionDialog import PipSelectionDialog - dlg = PipSelectionDialog(self) - if dlg.exec_() != QDialog.Accepted: - return False - - venvName, userSite = dlg.getData() - interpreter = self.getVirtualenvInterpreter(venvName) - if not interpreter: - return - - # python -m pip install --ignore-installed pip - if self.__plugin.getPreferences("PipSearchIndex"): - indexUrl = \ - self.__plugin.getPreferences("PipSearchIndex") + "/simple" - args = ["-m", "pip", "install", "--index-url", indexUrl, - "--ignore-installed"] - else: - args = ["-m", "pip", "install", "--ignore-installed"] - if userSite: - args.append("--user") - args.append("pip") - - dia = PipDialog(self.tr('Repair PIP')) - res = dia.startProcess(interpreter, args) - if res: - dia.exec_() - - def __checkUpgradePyQt(self, packages): - """ - Private method to check, if an upgrade of PyQt packages is attempted. - - @param packages list of packages to upgrade - @type list of str - @return flag indicating to abort the upgrade attempt - @rtype bool - """ - pyqtPackages = [p for p in packages - if p.lower() in ["pyqt5", "qscintilla", "sip"]] - - if bool(pyqtPackages): - abort = not E5MessageBox.yesNo( - None, - self.tr("Upgrade Packages"), - self.tr( - """You are trying to upgrade PyQt packages. This will""" - """ not work for the current instance of Python ({0}).""" - """ Do you want to continue?""").format(sys.executable), - icon=E5MessageBox.Critical) - else: - abort = False - - return abort - - def upgradePackages(self, packages, venvName="", userSite=False): - """ - Public method to upgrade the given list of packages. - - @param packages list of packages to upgrade - @type list of str - @param venvName name of the virtual environment to be used - @type str - @param userSite flag indicating an install to the user install - directory - @type bool - @return flag indicating a successful execution - @rtype bool - """ - if self.__checkUpgradePyQt(packages): - return False - - if not venvName: - venvName = self.__plugin.getPreferences("CurrentEnvironment") - interpreter = self.getVirtualenvInterpreter(venvName) - if not interpreter: - return - - if self.__plugin.getPreferences("PipSearchIndex"): - indexUrl = \ - self.__plugin.getPreferences("PipSearchIndex") + "/simple" - args = ["-m", "pip", "install", "--index-url", indexUrl, - "--upgrade"] - else: - args = ["-m", "pip", "install", "--upgrade"] - if userSite: - args.append("--user") - args += packages - dia = PipDialog(self.tr('Upgrade Packages')) - res = dia.startProcess(interpreter, args) - if res: - dia.exec_() - return res - - def __upgradePackages(self): - """ - Private slot to upgrade packages to be given by the user. - """ - from .PipPackagesInputDialog import PipPackagesInputDialog - dlg = PipPackagesInputDialog(self, self.tr("Upgrade Packages")) - if dlg.exec_() == QDialog.Accepted: - venvName, packages, user = dlg.getData() - if packages: - self.upgradePackages(packages, venvName=venvName, - userSite=user) - - def installPackages(self, packages, venvName="", userSite=False): - """ - Public method to install the given list of packages. - - @param packages list of packages to install - @type list of str - @param venvName name of the virtual environment to be used - @type str - @param userSite flag indicating an install to the user install - directory - @type bool - """ - if not venvName: - venvName = self.__plugin.getPreferences("CurrentEnvironment") - interpreter = self.getVirtualenvInterpreter(venvName) - if not interpreter: - return - - if self.__plugin.getPreferences("PipSearchIndex"): - indexUrl = \ - self.__plugin.getPreferences("PipSearchIndex") + "/simple" - args = ["-m", "pip", "install", "--index-url", indexUrl] - else: - args = ["-m", "pip", "install"] - if userSite: - args.append("--user") - args += packages - dia = PipDialog(self.tr('Install Packages')) - res = dia.startProcess(interpreter, args) - if res: - dia.exec_() - - def __installPackages(self): - """ - Private slot to install packages to be given by the user. - """ - from .PipPackagesInputDialog import PipPackagesInputDialog - dlg = PipPackagesInputDialog( - self, self.tr("Install Packages")) - if dlg.exec_() == QDialog.Accepted: - venvName, packages, user = dlg.getData() - if packages: - self.installPackages(packages, venvName=venvName, - userSite=user) - - def __installLocalPackage(self): - """ - Private slot to install a package available on local storage. - """ - from .PipFileSelectionDialog import PipFileSelectionDialog - dlg = PipFileSelectionDialog(self, "package") - if dlg.exec_() == QDialog.Accepted: - venvName, package, user = dlg.getData() - if package and os.path.exists(package): - self.installPackages([package], venvName=venvName, - userSite=user) - - def __installRequirements(self): - """ - Private slot to install packages as given in a requirements file. - """ - from .PipFileSelectionDialog import PipFileSelectionDialog - dlg = PipFileSelectionDialog(self, "requirements") - if dlg.exec_() == QDialog.Accepted: - venvName, requirements, user = dlg.getData() - if requirements and os.path.exists(requirements): - interpreter = self.getVirtualenvInterpreter(venvName) - if not interpreter: - return - if self.__plugin.getPreferences("PipSearchIndex"): - indexUrl = \ - self.__plugin.getPreferences("PipSearchIndex") + \ - "/simple" - args = ["-m", "pip", "install", "--index-url", indexUrl] - else: - args = ["-m", "pip", "install"] - if user: - args.append("--user") - args += ["--requirement", requirements] - dia = PipDialog(self.tr('Install Packages from Requirements')) - res = dia.startProcess(interpreter, args) - if res: - dia.exec_() - - def uninstallPackages(self, packages, venvName=""): - """ - Public method to uninstall the given list of packages. - - @param packages list of packages to uninstall - @type list of str - @param venvName name of the virtual environment to be used - @type str - @return flag indicating a successful execution - @rtype bool - """ - res = False - if packages: - from UI.DeleteFilesConfirmationDialog import \ - DeleteFilesConfirmationDialog - dlg = DeleteFilesConfirmationDialog( - self.parent(), - self.tr("Uninstall Packages"), - self.tr( - "Do you really want to uninstall these packages?"), - packages) - if dlg.exec_() == QDialog.Accepted: - if not venvName: - venvName = self.__plugin.getPreferences( - "CurrentEnvironment") - interpreter = self.getVirtualenvInterpreter(venvName) - if not interpreter: - return - args = ["-m", "pip", "uninstall", "--yes"] + packages - dia = PipDialog(self.tr('Uninstall Packages')) - res = dia.startProcess(interpreter, args) - if res: - dia.exec_() - return res - - def __uninstallPackages(self): - """ - Private slot to uninstall packages to be given by the user. - """ - from .PipPackagesInputDialog import PipPackagesInputDialog - dlg = PipPackagesInputDialog( - self, self.tr("Uninstall Packages"), install=False) - if dlg.exec_() == QDialog.Accepted: - venvName, packages, _user = dlg.getData() - if packages: - self.uninstallPackages(packages, venvName=venvName) - - def __uninstallRequirements(self): - """ - Private slot to uninstall packages as given in a requirements file. - """ - from .PipFileSelectionDialog import PipFileSelectionDialog - dlg = PipFileSelectionDialog(self, "requirements", - install=False) - if dlg.exec_() == QDialog.Accepted: - venvName, requirements, _user = dlg.getData() - if requirements and os.path.exists(requirements): - try: - f = open(requirements, "r") - reqs = f.read().splitlines() - f.close() - except (OSError, IOError): - return - - from UI.DeleteFilesConfirmationDialog import \ - DeleteFilesConfirmationDialog - dlg = DeleteFilesConfirmationDialog( - self.parent(), - self.tr("Uninstall Packages"), - self.tr( - "Do you really want to uninstall these packages?"), - reqs) - if dlg.exec_() == QDialog.Accepted: - if not venvName: - venvName = self.__plugin.getPreferences( - "CurrentEnvironment") - interpreter = self.getVirtualenvInterpreter(venvName) - if not interpreter: - return - args = ["-m", "pip", "uninstall", "--requirement", - requirements] - dia = PipDialog( - self.tr('Uninstall Packages from Requirements')) - res = dia.startProcess(interpreter, args) - if res: - dia.exec_() - - def __generateRequirements(self): - """ - Private slot to generate the contents for a requirements file. - """ - from .PipFreezeDialog import PipFreezeDialog - self.__freezeDialog = PipFreezeDialog(self) - self.__freezeDialog.show() - self.__freezeDialog.start() - - def __searchPyPI(self): - """ - Private slot to search the Python Package Index. - """ - from .PipSearchDialog import PipSearchDialog - - if self.__plugin.getPreferences("PipSearchIndex"): - indexUrl = self.__plugin.getPreferences("PipSearchIndex") + "/pypi" - else: - indexUrl = DefaultIndexUrlXml - - self.__searchDialog = PipSearchDialog(self, indexUrl) - self.__searchDialog.show() - - def __pipConfigure(self): - """ - Private slot to open the configuration page. - """ - e5App().getObject("UserInterface").showPreferences("pipPage")
--- a/Plugins/UiExtensionPlugins/PipInterface/PipDialog.py Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,205 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing a dialog showing the output of a pip command. -""" - -from __future__ import unicode_literals -try: - str = unicode # __IGNORE_EXCEPTION__ -except NameError: - pass - -from PyQt5.QtCore import pyqtSlot, Qt, QCoreApplication, QTimer, \ - QProcess -from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton - -from E5Gui import E5MessageBox - -from .Ui_PipDialog import Ui_PipDialog - -import Preferences - - -class PipDialog(QDialog, Ui_PipDialog): - """ - Class implementing a dialog showing the output of a 'python -m pip' - command. - """ - def __init__(self, text, parent=None): - """ - Constructor - - @param text text to be shown by the label - @type str - @param parent reference to the parent widget - @type QWidget - """ - super(PipDialog, self).__init__(parent) - self.setupUi(self) - - self.proc = None - self.__processQueue = [] - self.__ioEncoding = Preferences.getSystem("IOEncoding") - - self.outputGroup.setTitle(text) - - self.show() - QCoreApplication.processEvents() - - def closeEvent(self, e): - """ - Protected slot implementing a close event handler. - - @param e close event - @type QCloseEvent - """ - self.__processQueue = [] - - if self.proc is not None and \ - self.proc.state() != QProcess.NotRunning: - self.proc.terminate() - QTimer.singleShot(2000, self.proc.kill) - self.proc.waitForFinished(3000) - - self.proc = None - - e.accept() - - def __finish(self): - """ - Private slot called when the process finished or the user pressed - the button. - """ - if self.proc is not None and \ - self.proc.state() != QProcess.NotRunning: - self.proc.terminate() - QTimer.singleShot(2000, self.proc.kill) - self.proc.waitForFinished(3000) - - self.proc = None - - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) - self.buttonBox.button(QDialogButtonBox.Close).setFocus( - Qt.OtherFocusReason) - - if self.__processQueue: - cmd, args = self.__processQueue.pop(0) - self.__addOutput("\n\n") - self.startProcess(cmd, args) - - @pyqtSlot(QAbstractButton) - def on_buttonBox_clicked(self, button): - """ - Private slot called by a button of the button box clicked. - - @param button button that was clicked - @type QAbstractButton - """ - if button == self.buttonBox.button(QDialogButtonBox.Close): - self.close() - - def __procFinished(self, exitCode, exitStatus): - """ - Private slot connected to the finished signal. - - @param exitCode exit code of the process - @type int - @param exitStatus exit status of the process - @type QProcess.ExitStatus - """ - self.__finish() - - def startProcess(self, cmd, args, showArgs=True): - """ - Public slot used to start the process. - - @param cmd name of the pip executable to be used - @type str - @param args list of arguments for the process - @type list of str - @keyparam showArgs flag indicating to show the arguments - @type bool - @return flag indicating a successful start of the process - @rtype bool - """ - if len(self.errors.toPlainText()) == 0: - self.errorGroup.hide() - - if showArgs: - self.resultbox.append(cmd + ' ' + ' '.join(args)) - self.resultbox.append('') - - self.proc = QProcess() - self.proc.finished.connect(self.__procFinished) - self.proc.readyReadStandardOutput.connect(self.__readStdout) - self.proc.readyReadStandardError.connect(self.__readStderr) - self.proc.start(cmd, args) - procStarted = self.proc.waitForStarted(5000) - if not procStarted: - self.buttonBox.setFocus() - E5MessageBox.critical( - self, - self.tr('Process Generation Error'), - self.tr( - 'The process {0} could not be started.' - ).format(cmd)) - return procStarted - - def startProcesses(self, processParams): - """ - Public method to issue a list of commands to be executed. - - @param processParams list of tuples containing the command - and arguments - @type list of tuples of (str, list of str) - @return flag indicating a successful start of the first process - @rtype bool - """ - if len(processParams) > 1: - for cmd, args in processParams[1:]: - self.__processQueue.append((cmd, args[:])) - cmd, args = processParams[0] - return self.startProcess(cmd, args) - - 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. - """ - if self.proc is not None: - txt = str(self.proc.readAllStandardOutput(), - self.__ioEncoding, 'replace') - self.__addOutput(txt) - - def __addOutput(self, txt): - """ - Private method to add some text to the output pane. - - @param txt text to be added - @type str - """ - self.resultbox.insertPlainText(txt) - self.resultbox.ensureCursorVisible() - QCoreApplication.processEvents() - - 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. - """ - if self.proc is not None: - s = str(self.proc.readAllStandardError(), - self.__ioEncoding, 'replace') - self.errorGroup.show() - self.errors.insertPlainText(s) - self.errors.ensureCursorVisible() - - QCoreApplication.processEvents()
--- a/Plugins/UiExtensionPlugins/PipInterface/PipDialog.ui Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>PipDialog</class> - <widget class="QDialog" name="PipDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>600</width> - <height>500</height> - </rect> - </property> - <property name="windowTitle"> - <string>pip</string> - </property> - <property name="sizeGripEnabled"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout"> - <item> - <widget class="QGroupBox" name="outputGroup"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>2</verstretch> - </sizepolicy> - </property> - <property name="title"> - <string>Output</string> - </property> - <layout class="QVBoxLayout"> - <item> - <widget class="QTextEdit" name="resultbox"> - <property name="readOnly"> - <bool>true</bool> - </property> - <property name="acceptRichText"> - <bool>false</bool> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="errorGroup"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>1</verstretch> - </sizepolicy> - </property> - <property name="title"> - <string>Errors</string> - </property> - <layout class="QVBoxLayout"> - <item> - <widget class="QTextEdit" name="errors"> - <property name="readOnly"> - <bool>true</bool> - </property> - <property name="acceptRichText"> - <bool>false</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::Close</set> - </property> - </widget> - </item> - </layout> - </widget> - <layoutdefault spacing="6" margin="11"/> - <pixmapfunction>qPixmapFromMimeSource</pixmapfunction> - <tabstops> - <tabstop>resultbox</tabstop> - <tabstop>errors</tabstop> - <tabstop>buttonBox</tabstop> - </tabstops> - <resources/> - <connections/> -</ui>
--- a/Plugins/UiExtensionPlugins/PipInterface/PipFileSelectionDialog.py Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> -# - - -""" -Module implementing a dialog to enter a file to be processed. -""" - -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_PipFileSelectionDialog import Ui_PipFileSelectionDialog - -import Utilities - - -class PipFileSelectionDialog(QDialog, Ui_PipFileSelectionDialog): - """ - Class implementing a dialog to enter a file to be processed. - """ - def __init__(self, pip, mode, install=True, parent=None): - """ - Constructor - - @param pip reference to the pip object - @type Pip - @param mode mode of the dialog - @type str - @param install flag indicating an install action - @type bool - @param parent reference to the parent widget - @type QWidget - """ - super(PipFileSelectionDialog, self).__init__(parent) - self.setupUi(self) - - if mode == "requirements": - self.fileLabel.setText(self.tr("Enter requirements file:")) - self.filePicker.setMode(E5PathPickerModes.OpenFileMode) - self.filePicker.setToolTip(self.tr( - "Press to select the requirements file through a file" - " selection dialog.")) - self.filePicker.setFilters( - self.tr("Text Files (*.txt);;All Files (*)")) - elif mode == "package": - self.fileLabel.setText(self.tr("Enter package file:")) - self.filePicker.setMode(E5PathPickerModes.OpenFileMode) - self.filePicker.setToolTip(self.tr( - "Press to select the package file through a file" - " selection dialog.")) - self.filePicker.setFilters( - self.tr("Python Wheel (*.whl);;" - "Archive Files (*.tar.gz *.zip);;" - "All Files (*)")) - else: - self.fileLabel.setText(self.tr("Enter file name:")) - self.filePicker.setMode(E5PathPickerModes.OpenFileMode) - self.filePicker.setToolTip(self.tr( - "Press to select a file through a file selection dialog.")) - self.filePicker.setFilters(self.tr("All Files (*)")) - self.filePicker.setDefaultDirectory(os.path.expanduser("~")) - - self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) - - self.venvComboBox.addItem(pip.getDefaultEnvironmentString()) - projectVenv = pip.getProjectEnvironmentString() - if projectVenv: - self.venvComboBox.addItem(projectVenv) - self.venvComboBox.addItems(pip.getVirtualenvNames()) - - self.userCheckBox.setVisible(install) - - msh = self.minimumSizeHint() - self.resize(max(self.width(), msh.width()), msh.height()) - - @pyqtSlot(str) - def on_filePicker_textChanged(self, txt): - """ - Private slot to handle entering the name of a file. - - @param txt name of the file - @type str - """ - self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( - bool(txt) and - os.path.exists(Utilities.toNativeSeparators(txt)) - ) - - def getData(self): - """ - Public method to get the entered data. - - @return tuple with the environment name, the name of the - selected file and a flag indicating to install to the - user install directory - @rtype tuple of (str, str, bool) - """ - return ( - self.venvComboBox.currentText(), - self.filePicker.text(), - self.userCheckBox.isChecked() - )
--- a/Plugins/UiExtensionPlugins/PipInterface/PipFileSelectionDialog.ui Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>PipFileSelectionDialog</class> - <widget class="QDialog" name="PipFileSelectionDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>600</width> - <height>170</height> - </rect> - </property> - <property name="windowTitle"> - <string>Select File</string> - </property> - <property name="sizeGripEnabled"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Virtual Environment:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="venvComboBox"> - <property name="toolTip"> - <string>Select the virtual environment to be used</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="fileLabel"> - <property name="text"> - <string>File Name:</string> - </property> - </widget> - </item> - <item> - <widget class="E5PathPicker" name="filePicker" native="true"> - <property name="focusPolicy"> - <enum>Qt::StrongFocus</enum> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="userCheckBox"> - <property name="toolTip"> - <string>Select to install to the Python user install directory</string> - </property> - <property name="text"> - <string>Install into User Directory</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>PipFileSelectionDialog</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>PipFileSelectionDialog</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/PipInterface/PipFreezeDialog.py Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,300 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing a dialog to generate a requirements file. -""" - -from __future__ import unicode_literals -try: - str = unicode # __IGNORE_EXCEPTION__ -except NameError: - pass - -import os - -from PyQt5.QtCore import pyqtSlot, Qt -from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton, \ - QApplication - -from E5Gui import E5MessageBox, E5FileDialog -from E5Gui.E5PathPicker import E5PathPickerModes -from E5Gui.E5Application import e5App - -from .Ui_PipFreezeDialog import Ui_PipFreezeDialog - -import Utilities - - -class PipFreezeDialog(QDialog, Ui_PipFreezeDialog): - """ - Class implementing a dialog to generate a requirements file. - """ - def __init__(self, pip, parent=None): - """ - Constructor - - @param pip reference to the master object - @type Pip - @param parent reference to the parent widget - @type QWidget - """ - super(PipFreezeDialog, self).__init__(parent) - self.setupUi(self) - self.setWindowFlags(Qt.Window) - - self.__refreshButton = self.buttonBox.addButton( - self.tr("&Refresh"), QDialogButtonBox.ActionRole) - - self.requirementsFilePicker.setMode(E5PathPickerModes.SaveFileMode) - self.requirementsFilePicker.setFilters( - self.tr("Text Files (*.txt);;All Files (*)")) - - self.__pip = pip - - self.venvComboBox.addItem(pip.getDefaultEnvironmentString()) - projectVenv = self.__pip.getProjectEnvironmentString() - if projectVenv: - self.venvComboBox.addItem(projectVenv) - self.venvComboBox.addItems(pip.getVirtualenvNames()) - - self.__requirementsEdited = False - self.__requirementsAvailable = False - - self.__updateButtons() - - def closeEvent(self, e): - """ - Protected slot implementing a close event handler. - - @param e close event - @type QCloseEvent - """ - QApplication.restoreOverrideCursor() - e.accept() - - @pyqtSlot(str) - def on_venvComboBox_activated(self, txt): - """ - Private slot handling the selection of a virtual environment. - - @param txt virtual environment - @type str - """ - self.__refresh() - - @pyqtSlot(bool) - def on_localCheckBox_clicked(self, checked): - """ - Private slot handling the switching of the local mode. - - @param checked state of the local check box - @type bool - """ - self.__refresh() - - @pyqtSlot(str) - def on_requirementsFilePicker_textChanged(self, txt): - """ - Private slot handling a change of the requirements file name. - - @param txt name of the requirements file - @type str - """ - self.__updateButtons() - - @pyqtSlot() - def on_requirementsEdit_textChanged(self): - """ - Private slot handling changes of the requirements text. - """ - self.__requirementsEdited = True - - @pyqtSlot(QAbstractButton) - def on_buttonBox_clicked(self, button): - """ - Private slot called by a button of the button box clicked. - - @param button button that was clicked - @type QAbstractButton - """ - if button == self.buttonBox.button(QDialogButtonBox.Close): - self.close() - elif button == self.__refreshButton: - self.__refresh() - - def __refresh(self): - """ - Private slot to refresh the displayed list. - """ - if self.__requirementsEdited: - ok = E5MessageBox.yesNo( - self, - self.tr("Generate Requirements"), - self.tr("""The requirements were changed. Do you want""" - """ to overwrite these changes?""")) - else: - ok = True - if ok: - self.start() - - def start(self): - """ - Public method to start the command. - """ - self.requirementsEdit.clear() - self.__requirementsAvailable = False - - venvName = self.venvComboBox.currentText() - interpreter = self.__pip.getVirtualenvInterpreter(venvName) - if not interpreter: - return - - args = ["-m", "pip", "freeze"] - if self.localCheckBox.isChecked(): - args.append("--local") - if self.requirementsFilePicker.text(): - fileName = Utilities.toNativeSeparators( - self.requirementsFilePicker.text()) - if os.path.exists(fileName): - args.append("--requirement") - args.append(fileName) - - QApplication.setOverrideCursor(Qt.WaitCursor) - success, output = self.__pip.runProcess(args, interpreter) - - if success: - self.requirementsEdit.setPlainText(output) - self.__requirementsAvailable = True - else: - self.requirementsEdit.setPlainText( - self.tr("No output generated by 'pip freeze'.")) - - QApplication.restoreOverrideCursor() - self.__updateButtons() - - self.__requirementsEdited = False - - def __updateButtons(self): - """ - Private method to set the state of the various buttons. - """ - self.saveButton.setEnabled( - self.__requirementsAvailable and - bool(self.requirementsFilePicker.text()) - ) - self.saveToButton.setEnabled(self.__requirementsAvailable) - self.copyButton.setEnabled(self.__requirementsAvailable) - - aw = e5App().getObject("ViewManager").activeWindow() - if aw and self.__requirementsAvailable: - self.insertButton.setEnabled(True) - self.replaceAllButton.setEnabled(True) - self.replaceSelectionButton.setEnabled( - aw.hasSelectedText()) - else: - self.insertButton.setEnabled(False) - self.replaceAllButton.setEnabled(False) - self.replaceSelectionButton.setEnabled(False) - - def __writeToFile(self, fileName): - """ - Private method to write the requirements text to a file. - - @param fileName name of the file to write to - @type str - """ - if os.path.exists(fileName): - ok = E5MessageBox.warning( - self, - self.tr("Generate Requirements"), - self.tr("""The file <b>{0}</b> already exists. Do you want""" - """ to overwrite it?""").format(fileName)) - if not ok: - return - - try: - f = open(fileName, "w") - f.write(self.requirementsEdit.toPlainText()) - f.close() - except (OSError, IOError) as err: - E5MessageBox.critical( - self, - self.tr("Generate Requirements"), - self.tr("""<p>The requirements could not be written""" - """ to <b>{0}</b>.</p><p>Reason: {1}</p>""") - .format(fileName, str(err))) - - @pyqtSlot() - def on_saveButton_clicked(self): - """ - Private slot to save the requirements text to the requirements file. - """ - fileName = self.requirementsFilePicker.text() - self.__writeToFile(fileName) - - @pyqtSlot() - def on_saveToButton_clicked(self): - """ - Private slot to write the requirements text to a new file. - """ - fileName, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( - self, - self.tr("Generate Requirements"), - os.path.expanduser("~"), - self.tr("Text Files (*.txt);;All Files (*)"), - None, - E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite) - ) - if fileName: - ext = os.path.splitext(fileName)[1] - if not ext: - ex = selectedFilter.split("(*")[1].split(")")[0] - if ex: - fileName += ex - self.__writeToFile(fileName) - - @pyqtSlot() - def on_copyButton_clicked(self): - """ - Private slot to copy the requirements text to the clipboard. - """ - txt = self.requirementsEdit.toPlainText() - cb = QApplication.clipboard() - cb.setText(txt) - - @pyqtSlot() - def on_insertButton_clicked(self): - """ - Private slot to insert the requirements text at the cursor position - of the current editor. - """ - aw = e5App().getObject("ViewManager").activeWindow() - if aw: - aw.beginUndoAction() - aw.insert(self.requirementsEdit.toPlainText()) - aw.endUndoAction() - - @pyqtSlot() - def on_replaceSelectionButton_clicked(self): - """ - Private slot to replace the selected text of the current editor - with the requirements text. - """ - aw = e5App().getObject("ViewManager").activeWindow() - if aw: - aw.beginUndoAction() - aw.replaceSelectedText(self.requirementsEdit.toPlainText()) - aw.endUndoAction() - - @pyqtSlot() - def on_replaceAllButton_clicked(self): - """ - Private slot to replace the text of the current editor with the - requirements text. - """ - aw = e5App().getObject("ViewManager").activeWindow() - if aw: - aw.setText(self.requirementsEdit.toPlainText())
--- a/Plugins/UiExtensionPlugins/PipInterface/PipFreezeDialog.ui Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,232 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>PipFreezeDialog</class> - <widget class="QDialog" name="PipFreezeDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>600</width> - <height>550</height> - </rect> - </property> - <property name="windowTitle"> - <string>Generate Requirements</string> - </property> - <property name="toolTip"> - <string>Replace the current selection with the requirements text</string> - </property> - <property name="sizeGripEnabled"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Virtual Environment:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="venvComboBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Select the virtual environment to be used</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QCheckBox" name="localCheckBox"> - <property name="toolTip"> - <string>Select to show requirements for locally-installed packages only</string> - </property> - <property name="text"> - <string>Local packages only</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Requirements File:</string> - </property> - </widget> - </item> - <item> - <widget class="E5PathPicker" name="requirementsFilePicker" native="true"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="focusPolicy"> - <enum>Qt::StrongFocus</enum> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="1"> - <widget class="QPushButton" name="saveButton"> - <property name="toolTip"> - <string>Press to save to the requirements file</string> - </property> - <property name="text"> - <string>Save</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QPushButton" name="saveToButton"> - <property name="toolTip"> - <string>Save to a new file</string> - </property> - <property name="text"> - <string>Save To</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QPushButton" name="copyButton"> - <property name="toolTip"> - <string>Copy the requirements text to the clipboard</string> - </property> - <property name="text"> - <string>Copy</string> - </property> - </widget> - </item> - <item row="3" column="1"> - <widget class="QPushButton" name="insertButton"> - <property name="toolTip"> - <string>Insert the requirements text at the cursor position</string> - </property> - <property name="text"> - <string>Insert</string> - </property> - </widget> - </item> - <item row="4" column="1"> - <widget class="QPushButton" name="replaceSelectionButton"> - <property name="text"> - <string>Replace Selection</string> - </property> - </widget> - </item> - <item row="5" column="1"> - <widget class="QPushButton" name="replaceAllButton"> - <property name="toolTip"> - <string>Replace all text with the requirements text</string> - </property> - <property name="text"> - <string>Replace All</string> - </property> - </widget> - </item> - <item row="6" column="1"> - <spacer name="verticalSpacer"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item row="0" column="0" rowspan="7"> - <widget class="QPlainTextEdit" name="requirementsEdit"> - <property name="tabChangesFocus"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Close</set> - </property> - </widget> - </item> - </layout> - </widget> - <customwidgets> - <customwidget> - <class>E5PathPicker</class> - <extends>QWidget</extends> - <header>E5Gui/E5PathPicker.h</header> - <container>1</container> - </customwidget> - </customwidgets> - <tabstops> - <tabstop>venvComboBox</tabstop> - <tabstop>localCheckBox</tabstop> - <tabstop>requirementsFilePicker</tabstop> - <tabstop>requirementsEdit</tabstop> - <tabstop>saveButton</tabstop> - <tabstop>saveToButton</tabstop> - <tabstop>copyButton</tabstop> - <tabstop>insertButton</tabstop> - <tabstop>replaceSelectionButton</tabstop> - <tabstop>replaceAllButton</tabstop> - </tabstops> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>PipFreezeDialog</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>PipFreezeDialog</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/PipInterface/PipListDialog.py Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,551 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing a dialog to list installed packages. -""" - -from __future__ import unicode_literals -try: - str = unicode # __IGNORE_EXCEPTION__ -except NameError: - pass - -import json - -from PyQt5.QtCore import pyqtSlot, Qt, QProcess, QTimer -from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton, \ - QApplication, QTreeWidgetItem, QHeaderView - -from E5Gui import E5MessageBox - -from .Ui_PipListDialog import Ui_PipListDialog - -import Preferences - - -class PipListDialog(QDialog, Ui_PipListDialog): - """ - Class implementing a dialog to list installed packages. - """ - CommandArguments = { - "list": ["list", "--format=json"], - "uptodate": ["list", "--uptodate", "--format=json"], - "outdated": ["list", "--outdated", "--format=json"], - } - - ShowProcessGeneralMode = 0 - ShowProcessClassifiersMode = 1 - ShowProcessEntryPointsMode = 2 - ShowProcessFilesListMode = 3 - - def __init__(self, pip, mode, indexUrl, title, parent=None): - """ - Constructor - - @param pip reference to the master object - @type Pip - @param mode list command mode (one of 'list', 'uptodate', 'outdated') - @type str - @param indexUrl URL of the pypi index - @type str - @param title title of the dialog - @type str - @param parent reference to the parent widget - @type QWidget - """ - assert mode in PipListDialog.CommandArguments - - super(PipListDialog, self).__init__(parent) - self.setupUi(self) - self.setWindowFlags(Qt.Window) - - self.setWindowTitle(title) - - self.__refreshButton = self.buttonBox.addButton( - self.tr("&Refresh"), QDialogButtonBox.ActionRole) - self.__refreshButton.setEnabled(False) - if mode == "outdated": - self.__upgradeButton = self.buttonBox.addButton( - self.tr("Up&grade"), QDialogButtonBox.ActionRole) - self.__upgradeButton.setEnabled(False) - self.__upgradeAllButton = self.buttonBox.addButton( - self.tr("Upgrade &All"), QDialogButtonBox.ActionRole) - self.__upgradeAllButton.setEnabled(False) - else: - self.__upgradeButton = None - self.__upgradeAllButton = None - self.__uninstallButton = self.buttonBox.addButton( - self.tr("&Uninstall"), QDialogButtonBox.ActionRole) - self.__uninstallButton.setEnabled(False) - - self.__pip = pip - self.__mode = mode - self.__ioEncoding = Preferences.getSystem("IOEncoding") - self.__indexUrl = indexUrl - self.__errors = "" - self.__output = [] - - self.__nothingStrings = { - "list": self.tr("Nothing to show"), - "uptodate": self.tr("All packages outdated"), - "outdated": self.tr("All packages up-to-date"), - } - - self.venvComboBox.addItem(self.__pip.getDefaultEnvironmentString()) - projectVenv = self.__pip.getProjectEnvironmentString() - if projectVenv: - self.venvComboBox.addItem(projectVenv) - self.venvComboBox.addItems(self.__pip.getVirtualenvNames()) - - if mode == "list": - self.infoLabel.setText(self.tr("Installed Packages:")) - self.packageList.setHeaderLabels([ - self.tr("Package"), - self.tr("Version"), - ]) - elif mode == "uptodate": - self.infoLabel.setText(self.tr("Up-to-date Packages:")) - self.packageList.setHeaderLabels([ - self.tr("Package"), - self.tr("Version"), - ]) - elif mode == "outdated": - self.infoLabel.setText(self.tr("Outdated Packages:")) - self.packageList.setHeaderLabels([ - self.tr("Package"), - self.tr("Current Version"), - self.tr("Latest Version"), - self.tr("Package Type"), - ]) - - self.packageList.header().setSortIndicator(0, Qt.AscendingOrder) - - self.__infoLabels = { - "name": self.tr("Name:"), - "version": self.tr("Version:"), - "location": self.tr("Location:"), - "requires": self.tr("Requires:"), - "summary": self.tr("Summary:"), - "home-page": self.tr("Homepage:"), - "author": self.tr("Author:"), - "author-email": self.tr("Author Email:"), - "license": self.tr("License:"), - "metadata-version": self.tr("Metadata Version:"), - "installer": self.tr("Installer:"), - "classifiers": self.tr("Classifiers:"), - "entry-points": self.tr("Entry Points:"), - "files": self.tr("Files:"), - } - self.infoWidget.setHeaderLabels(["Key", "Value"]) - - self.process = QProcess() - self.process.finished.connect(self.__procFinished) - self.process.readyReadStandardOutput.connect(self.__readStdout) - self.process.readyReadStandardError.connect(self.__readStderr) - - self.show() - QApplication.processEvents() - - def __stopProcess(self): - """ - Private slot to stop the running process. - """ - if self.process.state() != QProcess.NotRunning: - self.process.terminate() - QTimer.singleShot(2000, self.process.kill) - self.process.waitForFinished(3000) - - QApplication.restoreOverrideCursor() - - def closeEvent(self, e): - """ - Protected slot implementing a close event handler. - - @param e close event - @type QCloseEvent - """ - self.__stopProcess() - e.accept() - - def __finish(self): - """ - Private slot called when the process finished or the user pressed - the cancel button. - """ - self.__stopProcess() - - self.__processOutput() - - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) - self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) - self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) - self.buttonBox.button(QDialogButtonBox.Close).setFocus( - Qt.OtherFocusReason) - self.__refreshButton.setEnabled(True) - - if self.packageList.topLevelItemCount() == 0: - QTreeWidgetItem(self.packageList, - [self.__nothingStrings[self.__mode]]) - if self.__errors and not self.__errors.startswith("DEPRECATION"): - E5MessageBox.critical( - self, - self.windowTitle(), - self.tr("""<p>The command failed.</p>""" - """<p>Reason: {0}</p>""").format( - self.__errors.replace("\r\n", "<br/>") - .replace("\n", "<br/>").replace("\r", "<br/>") - .replace(" ", " "))) - if self.__upgradeAllButton is not None: - self.__upgradeAllButton.setEnabled(False) - else: - if self.__upgradeAllButton is not None: - self.__upgradeAllButton.setEnabled(True) - - self.packageList.sortItems( - 0, - self.packageList.header().sortIndicatorOrder()) - self.packageList.header().resizeSections( - QHeaderView.ResizeToContents) - self.packageList.header().setStretchLastSection(True) - - @pyqtSlot(QAbstractButton) - def on_buttonBox_clicked(self, button): - """ - Private slot called by a button of the button box clicked. - - @param button button that was clicked - @type QAbstractButton - """ - if button == self.buttonBox.button(QDialogButtonBox.Close): - self.close() - elif button == self.buttonBox.button(QDialogButtonBox.Cancel): - self.__finish() - elif button == self.__refreshButton: - self.__refresh() - elif button == self.__upgradeButton: - self.__upgradePackages() - elif button == self.__upgradeAllButton: - self.__upgradeAllPackages() - elif button == self.__uninstallButton: - self.__uninstallPackages() - - def __procFinished(self, exitCode, exitStatus): - """ - Private slot connected to the finished signal. - - @param exitCode exit code of the process - @type int - @param exitStatus exit status of the process - @type QProcess.ExitStatus - """ - self.__finish() - - def __refresh(self): - """ - Private slot to refresh the displayed list. - """ - self.__stopProcess() - self.start() - - def start(self): - """ - Public method to start the command. - """ - self.packageList.clear() - self.__errors = "" - self.__output = [] - - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) - self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) - self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) - self.__refreshButton.setEnabled(False) - if self.__upgradeAllButton is not None: - self.__upgradeAllButton.setEnabled(False) - QApplication.processEvents() - - QApplication.setOverrideCursor(Qt.WaitCursor) - QApplication.processEvents() - - venvName = self.venvComboBox.currentText() - interpreter = self.__pip.getVirtualenvInterpreter(venvName) - if not interpreter: - return - - args = ["-m", "pip"] + PipListDialog.CommandArguments[self.__mode] - if self.localCheckBox.isChecked(): - args.append("--local") - if self.notRequiredCheckBox.isChecked(): - args.append("--not-required") - if self.userCheckBox.isChecked(): - args.append("--user") - - if self.__indexUrl: - args.append("--index-url") - args.append(self.__indexUrl + "/simple") - - self.process.start(interpreter, args) - procStarted = self.process.waitForStarted(5000) - if not procStarted: - self.buttonBox.setFocus() - self.__stopProcess() - E5MessageBox.critical( - self, - self.tr('Process Generation Error'), - self.tr( - 'The process {0} could not be started.' - ).format(interpreter)) - self.__finish() - - def __processOutput(self): - """ - Private method to process the captured output. - """ - if self.__output: - try: - packageData = json.loads("\n".join(self.__output)) - for package in packageData: - data = [ - package["name"], - package["version"], - ] - if self.__mode == "outdated": - data.extend([ - package["latest_version"], - package["latest_filetype"], - ]) - QTreeWidgetItem(self.packageList, data) - except ValueError as err: - self.__errors += str(err) + "\n" - self.__errors += "received output:\n" - self.__errors += "\n".join(self.__output) - - 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(): - line = str(self.process.readLine(), self.__ioEncoding, - 'replace').strip() - self.__output.append(line) - - 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.__errors += str(self.process.readAllStandardError(), - self.__ioEncoding, 'replace') - - @pyqtSlot(str) - def on_venvComboBox_activated(self, txt): - """ - Private slot handling the selection of a virtual environment. - - @param txt virtual environment - @type str - """ - self.__refresh() - - @pyqtSlot(bool) - def on_localCheckBox_clicked(self, checked): - """ - Private slot handling the switching of the local mode. - - @param checked state of the local check box - @type bool - """ - self.__refresh() - - @pyqtSlot(bool) - def on_notRequiredCheckBox_clicked(self, checked): - """ - Private slot handling the switching of the 'not required' mode. - - @param checked state of the 'not required' check box - @type bool - """ - self.__refresh() - - @pyqtSlot(bool) - def on_userCheckBox_clicked(self, checked): - """ - Private slot handling the switching of the 'user-site' mode. - - @param checked state of the 'user-site' check box - @type bool - """ - self.__refresh() - - @pyqtSlot() - def on_packageList_itemSelectionChanged(self): - """ - Private slot handling the selection of a package. - """ - self.infoWidget.clear() - - if len(self.packageList.selectedItems()) == 1: - itm = self.packageList.selectedItems()[0] - - environment = self.venvComboBox.currentText() - interpreter = self.__pip.getVirtualenvInterpreter(environment) - if not interpreter: - return - - QApplication.setOverrideCursor(Qt.WaitCursor) - - args = ["-m", "pip", "show"] - if self.verboseCheckBox.isChecked(): - args.append("--verbose") - if self.installedFilesCheckBox.isChecked(): - args.append("--files") - args.append(itm.text(0)) - success, output = self.__pip.runProcess(args, interpreter) - - if success and output: - mode = PipListDialog.ShowProcessGeneralMode - for line in output.splitlines(): - line = line.rstrip() - if line != "---": - if mode != PipListDialog.ShowProcessGeneralMode: - if line[0] == " ": - QTreeWidgetItem( - self.infoWidget, - [" ", line.strip()]) - else: - mode = PipListDialog.ShowProcessGeneralMode - if mode == PipListDialog.ShowProcessGeneralMode: - try: - label, info = line.split(": ", 1) - except ValueError: - label = line[:-1] - info = "" - label = label.lower() - if label in self.__infoLabels: - QTreeWidgetItem( - self.infoWidget, - [self.__infoLabels[label], info]) - if label == "files": - mode = PipListDialog.ShowProcessFilesListMode - elif label == "classifiers": - mode = PipListDialog.ShowProcessClassifiersMode - elif label == "entry-points": - mode = PipListDialog.ShowProcessEntryPointsMode - self.infoWidget.scrollToTop() - - header = self.infoWidget.header() - header.setStretchLastSection(False) - header.resizeSections(QHeaderView.ResizeToContents) - if header.sectionSize(0) + header.sectionSize(1) < header.width(): - header.setStretchLastSection(True) - - QApplication.restoreOverrideCursor() - - enable = (len(self.packageList.selectedItems()) > 1 or - (len(self.packageList.selectedItems()) == 1 and - self.packageList.selectedItems()[0].text(0) not in - self.__nothingStrings.values())) - self.__upgradeButton and self.__upgradeButton.setEnabled(enable) - self.__uninstallButton.setEnabled(enable) - - @pyqtSlot(bool) - def on_verboseCheckBox_clicked(self, checked): - """ - Private slot to handle a change of the verbose package information - checkbox. - - @param checked state of the checkbox - @type bool - """ - self.on_packageList_itemSelectionChanged() - - @pyqtSlot(bool) - def on_installedFilesCheckBox_clicked(self, checked): - """ - Private slot to handle a change of the installed files information - checkbox. - - @param checked state of the checkbox - @type bool - """ - self.on_packageList_itemSelectionChanged() - - def __upgradePackages(self): - """ - Private slot to upgrade the selected packages. - """ - packages = [] - for itm in self.packageList.selectedItems(): - packages.append(itm.text(0)) - - if packages: - if "pip" in packages: - self.__upgradePip() - else: - self.__executeUpgradePackages(packages) - - def __upgradeAllPackages(self): - """ - Private slot to upgrade all listed packages. - """ - packages = [] - for index in range(self.packageList.topLevelItemCount()): - itm = self.packageList.topLevelItem(index) - packages.append(itm.text(0)) - - if packages: - if "pip" in packages: - self.__upgradePip() - else: - self.__executeUpgradePackages(packages) - - def __upgradePip(self): - """ - Private slot to upgrade pip itself. - """ - res = self.__pip.upgradePip( - venvName=self.venvComboBox.currentText(), - userSite=self.userCheckBox.isChecked()) - if res: - self.__refresh() - - def __executeUpgradePackages(self, packages): - """ - Private method to execute the pip upgrade command. - - @param packages list of package names to be upgraded - @type list of str - """ - res = self.__pip.upgradePackages( - packages, venvName=self.venvComboBox.currentText(), - userSite=self.userCheckBox.isChecked()) - if res: - self.activateWindow() - self.raise_() - self.__refresh() - - def __uninstallPackages(self): - """ - Private slot to uninstall the selected packages. - """ - packages = [] - for itm in self.packageList.selectedItems(): - packages.append(itm.text(0)) - - if packages: - res = self.__pip.uninstallPackages( - packages, - venvName=self.venvComboBox.currentText()) - if res: - self.activateWindow() - self.raise_() - self.__refresh()
--- a/Plugins/UiExtensionPlugins/PipInterface/PipListDialog.ui Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,253 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>PipListDialog</class> - <widget class="QDialog" name="PipListDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>600</width> - <height>650</height> - </rect> - </property> - <property name="windowTitle"> - <string>Package List</string> - </property> - <property name="sizeGripEnabled"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Virtual Environment:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="venvComboBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Select the virtual environment to be used</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="infoLabel"> - <property name="text"> - <string notr="true">TextLabel</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <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> - <item row="0" column="2"> - <widget class="QCheckBox" name="localCheckBox"> - <property name="toolTip"> - <string>Select to show only locally-installed packages</string> - </property> - <property name="text"> - <string>Local packages only</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="0" column="3"> - <widget class="QCheckBox" name="notRequiredCheckBox"> - <property name="toolTip"> - <string>Select to list packages that are not dependencies of installed packages</string> - </property> - <property name="text"> - <string>Not required Packages</string> - </property> - </widget> - </item> - <item row="1" column="2"> - <widget class="QCheckBox" name="userCheckBox"> - <property name="toolTip"> - <string>Select to show only packages installed to the user-site</string> - </property> - <property name="text"> - <string>User-Site only</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QSplitter" name="splitter"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="childrenCollapsible"> - <bool>false</bool> - </property> - <widget class="QTreeWidget" name="packageList"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>3</verstretch> - </sizepolicy> - </property> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::ExtendedSelection</enum> - </property> - <property name="rootIsDecorated"> - <bool>false</bool> - </property> - <property name="itemsExpandable"> - <bool>false</bool> - </property> - <property name="sortingEnabled"> - <bool>true</bool> - </property> - <column> - <property name="text"> - <string notr="true">1</string> - </property> - </column> - </widget> - <widget class="QWidget" name="widget" native="true"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>1</verstretch> - </sizepolicy> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> - <number>0</number> - </property> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QCheckBox" name="verboseCheckBox"> - <property name="toolTip"> - <string>Select to show verbose package information</string> - </property> - <property name="text"> - <string>Verbose Package Information</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="installedFilesCheckBox"> - <property name="toolTip"> - <string>Select to show information about installed files</string> - </property> - <property name="text"> - <string>Installed Files Information</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QTreeWidget" name="infoWidget"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>1</verstretch> - </sizepolicy> - </property> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="rootIsDecorated"> - <bool>false</bool> - </property> - <property name="itemsExpandable"> - <bool>false</bool> - </property> - <property name="allColumnsShowFocus"> - <bool>true</bool> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - <property name="columnCount"> - <number>2</number> - </property> - <attribute name="headerVisible"> - <bool>false</bool> - </attribute> - <attribute name="headerStretchLastSection"> - <bool>false</bool> - </attribute> - <column> - <property name="text"> - <string notr="true">1</string> - </property> - </column> - <column> - <property name="text"> - <string notr="true">2</string> - </property> - </column> - </widget> - </item> - </layout> - </widget> - </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> - <tabstops> - <tabstop>venvComboBox</tabstop> - <tabstop>localCheckBox</tabstop> - <tabstop>notRequiredCheckBox</tabstop> - <tabstop>userCheckBox</tabstop> - <tabstop>packageList</tabstop> - <tabstop>verboseCheckBox</tabstop> - <tabstop>installedFilesCheckBox</tabstop> - <tabstop>infoWidget</tabstop> - </tabstops> - <resources/> - <connections/> -</ui>
--- a/Plugins/UiExtensionPlugins/PipInterface/PipPackageDetailsDialog.py Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,229 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing a dialog to show details about a package. -""" - -from __future__ import unicode_literals -try: - basestring # __IGNORE_WARNING__ -except NameError: - basestring = str - -from PyQt5.QtCore import Qt, QLocale -from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QTreeWidgetItem, \ - QLabel, QHeaderView - -from .Ui_PipPackageDetailsDialog import Ui_PipPackageDetailsDialog - - -class PipPackageDetailsDialog(QDialog, Ui_PipPackageDetailsDialog): - """ - Class implementing a dialog to show details about a package. - """ - def __init__(self, detailsData, downloadsData, parent=None): - """ - Constructor - - @param detailsData package details - @type dict - @param downloadsData downloads information - @type dict - @param parent reference to the parent widget - @type QWidget - """ - super(PipPackageDetailsDialog, self).__init__(parent) - self.setupUi(self) - self.setWindowFlags(Qt.Window) - - self.__locale = QLocale() - self.__packageTypeMap = { - "sdist": self.tr("Source"), - "bdist_wheel": self.tr("Python Wheel"), - "bdist_egg": self.tr("Python Egg"), - "bdist_wininst": self.tr("MS Windows Installer"), - "bdist_msi": self.tr("MS Windows Installer"), - "bdist_rpm": self.tr("Unix Installer"), - "bdist_deb": self.tr("Unix Installer"), - "bdist_dumb": self.tr("Archive"), - } - - self.__populateDetails(detailsData) - self.__populateDownloadUrls(downloadsData) - self.__populateRequiresProvides(detailsData) - - def __populateDetails(self, detailsData): - """ - Private method to populate the details tab. - - @param detailsData package details - @type dict - """ - self.packageNameLabel.setText( - "<h1>{0} {1}</h1".format(self.__sanitize(detailsData["name"]), - self.__sanitize(detailsData["version"]))) - self.summaryLabel.setText( - self.__sanitize(detailsData["summary"][:240])) - self.descriptionEdit.setPlainText( - self.__sanitize(detailsData["description"])) - self.authorLabel.setText(self.__sanitize(detailsData["author"])) - self.authorEmailLabel.setText( - '<a href="mailto:{0}">{0}</a>'.format( - self.__sanitize(detailsData["author_email"]))) - self.licenseLabel.setText(self.__sanitize(detailsData["license"])) - self.platformLabel.setText(self.__sanitize(detailsData["platform"])) - self.homePageLabel.setText( - '<a href="{0}">{0}</a>'.format( - self.__sanitize(detailsData["home_page"], forUrl=True))) - self.packageUrlLabel.setText( - '<a href="{0}">{0}</a>'.format( - self.__sanitize(detailsData["package_url"], forUrl=True))) - self.releaseUrlLabel.setText( - '<a href="{0}">{0}</a>'.format( - self.__sanitize(detailsData["release_url"], forUrl=True))) - self.docsUrlLabel.setText( - '<a href="{0}">{0}</a>'.format( - self.__sanitize(detailsData["docs_url"], forUrl=True))) - self.downloadsDayLabel.setText(self.__locale.toString( - detailsData["downloads"]["last_day"])) - self.downloadsWeekLabel.setText(self.__locale.toString( - detailsData["downloads"]["last_week"])) - self.downloadsMonthLabel.setText(self.__locale.toString( - detailsData["downloads"]["last_month"])) - self.classifiersList.addItems(detailsData["classifiers"]) - - self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) - self.buttonBox.button(QDialogButtonBox.Close).setFocus( - Qt.OtherFocusReason) - - def __populateDownloadUrls(self, downloadsData): - """ - Private method to populate the download URLs tab. - - @param downloadsData downloads information - @type dict - """ - index = self.infoWidget.indexOf(self.urls) - if downloadsData: - self.infoWidget.setTabEnabled(index, True) - for download in downloadsData: - itm = QTreeWidgetItem(self.downloadUrlsList, [ - "", - self.__packageTypeMap[download["packagetype"]] - if download["packagetype"] in self.__packageTypeMap - else "", - download["python_version"] - if download["python_version"] != "source" - else "", - self.__locale.toString(download["downloads"]), - self.__formatUploadDate(download["upload_time"]), - self.__formatSize(download["size"]), - ]) - if download["has_sig"]: - pgpLink = ' (<a href="{0}">pgp</a>)'.format( - download["url"] + ".asc") - else: - pgpLink = "" - urlLabel = QLabel('<a href="{0}#md5={2}">{1}</a>{3}'.format( - download["url"], download["filename"], - download["md5_digest"], pgpLink)) - urlLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse) - urlLabel.setOpenExternalLinks(True) - self.downloadUrlsList.setItemWidget(itm, 0, urlLabel) - header = self.downloadUrlsList.header() - header.resizeSections(QHeaderView.ResizeToContents) - else: - self.infoWidget.setTabEnabled(index, False) - - def __populateRequiresProvides(self, detailsData): - """ - Private method to populate the requires/provides tab. - - @param detailsData package details - @type dict - """ - populatedItems = 0 - - if "requires" in detailsData: - self.requiredPackagesList.addItems(detailsData["requires"]) - populatedItems += len(detailsData["requires"]) - if "requires_dist" in detailsData: - self.requiredDistributionsList.addItems( - detailsData["requires_dist"]) - populatedItems += len(detailsData["requires_dist"]) - if "provides" in detailsData: - self.providedPackagesList.addItems(detailsData["provides"]) - populatedItems += len(detailsData["provides"]) - if "provides_dist" in detailsData: - self.providedDistributionsList.addItems( - detailsData["provides_dist"]) - populatedItems += len(detailsData["provides_dist"]) - - index = self.infoWidget.indexOf(self.requires) - self.infoWidget.setTabEnabled(index, populatedItems > 0) - - def __sanitize(self, text, forUrl=False): - """ - Private method to clean-up the given text. - - @param text raw text - @type str - @param forUrl flag indicating to sanitize an URL text - @type bool - @return processed text - @rtype str - """ - if text == "UNKNOWN": - text = "" - elif text == "any": - text = self.tr("any") - elif text is None: - text = "" - if forUrl: - if not isinstance(text, basestring) or \ - not text.startswith(("http://", "https://", "ftp://")): - # ignore if the schema is not one of the listed ones - text = "" - - return text - - def __formatUploadDate(self, datetime): - """ - Private method to format the upload date. - - @param datetime upload date and time - @type xmlrpc.DateTime or str - @return formatted date string - @rtype str - """ - if isinstance(datetime, str): - return datetime.split("T")[0] - else: - date = datetime.value.split("T")[0] - return "{0}-{1}-{2}".format(date[:4], date[4:6], date[6:]) - - def __formatSize(self, size): - """ - Private slot to format the size. - - @param size size to be formatted - @type int - @return formatted size - @rtype str - """ - unit = "" - if size < 1024: - unit = self.tr("B") - elif size < 1024 * 1024: - size /= 1024 - unit = self.tr("KB") - elif size < 1024 * 1024 * 1024: - size /= 1024 * 1024 - unit = self.tr("MB") - else: - size /= 1024 * 1024 * 1024 - unit = self.tr("GB") - return self.tr("{0:.1f} {1}", "value, unit").format(size, unit)
--- a/Plugins/UiExtensionPlugins/PipInterface/PipPackageDetailsDialog.ui Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,517 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>PipPackageDetailsDialog</class> - <widget class="QDialog" name="PipPackageDetailsDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>800</width> - <height>700</height> - </rect> - </property> - <property name="windowTitle"> - <string>Package Details</string> - </property> - <property name="sizeGripEnabled"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="packageNameLabel"/> - </item> - <item> - <widget class="QTabWidget" name="infoWidget"> - <property name="currentIndex"> - <number>0</number> - </property> - <widget class="QWidget" name="details"> - <attribute name="title"> - <string>Details</string> - </attribute> - <attribute name="toolTip"> - <string>Lists package informations</string> - </attribute> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="0" column="1"> - <widget class="QLabel" name="summaryLabel"> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string>Description:</string> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - <item row="3" column="1"> - <widget class="QLabel" name="authorEmailLabel"> - <property name="openExternalLinks"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QPlainTextEdit" name="descriptionEdit"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>5</verstretch> - </sizepolicy> - </property> - <property name="tabChangesFocus"> - <bool>true</bool> - </property> - <property name="readOnly"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="label_4"> - <property name="text"> - <string>Author:</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLabel" name="authorLabel"/> - </item> - <item row="3" column="0"> - <widget class="QLabel" name="label_5"> - <property name="text"> - <string>Author Email:</string> - </property> - </widget> - </item> - <item row="7" column="1"> - <widget class="QLabel" name="packageUrlLabel"> - <property name="openExternalLinks"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="4" column="0"> - <widget class="QLabel" name="label_6"> - <property name="text"> - <string>License:</string> - </property> - </widget> - </item> - <item row="4" column="1"> - <widget class="QLabel" name="licenseLabel"/> - </item> - <item row="0" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Summary:</string> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - <item row="5" column="0"> - <widget class="QLabel" name="label_7"> - <property name="text"> - <string>Platform:</string> - </property> - </widget> - </item> - <item row="5" column="1"> - <widget class="QLabel" name="platformLabel"/> - </item> - <item row="6" column="0"> - <widget class="QLabel" name="label_8"> - <property name="text"> - <string>Home Page:</string> - </property> - </widget> - </item> - <item row="6" column="1"> - <widget class="QLabel" name="homePageLabel"> - <property name="openExternalLinks"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="7" column="0"> - <widget class="QLabel" name="label_9"> - <property name="text"> - <string>Package URL:</string> - </property> - </widget> - </item> - <item row="8" column="0"> - <widget class="QLabel" name="label_10"> - <property name="text"> - <string>Release URL:</string> - </property> - </widget> - </item> - <item row="8" column="1"> - <widget class="QLabel" name="releaseUrlLabel"> - <property name="openExternalLinks"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="9" column="0"> - <widget class="QLabel" name="label_11"> - <property name="text"> - <string>Documentation URL:</string> - </property> - </widget> - </item> - <item row="9" column="1"> - <widget class="QLabel" name="docsUrlLabel"> - <property name="openExternalLinks"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="10" column="0"> - <widget class="QLabel" name="label_12"> - <property name="text"> - <string>Downloads:</string> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - <item row="10" column="1"> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="label_13"> - <property name="text"> - <string>Last Day:</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLabel" name="downloadsDayLabel"> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - <item row="0" column="2"> - <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> - <item row="1" column="0"> - <widget class="QLabel" name="label_14"> - <property name="text"> - <string>Last Week:</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLabel" name="downloadsWeekLabel"> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="label_15"> - <property name="text"> - <string>Last Month:</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLabel" name="downloadsMonthLabel"> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - </layout> - </item> - <item row="11" column="0"> - <widget class="QLabel" name="label_16"> - <property name="text"> - <string>Classifiers:</string> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - <item row="11" column="1"> - <widget class="QListWidget" name="classifiersList"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>1</verstretch> - </sizepolicy> - </property> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::NoSelection</enum> - </property> - <property name="sortingEnabled"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="urls"> - <attribute name="title"> - <string>Download URLs</string> - </attribute> - <attribute name="toolTip"> - <string>Lists the download URLs</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QTreeWidget" name="downloadUrlsList"> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::NoSelection</enum> - </property> - <property name="rootIsDecorated"> - <bool>false</bool> - </property> - <property name="itemsExpandable"> - <bool>false</bool> - </property> - <attribute name="headerStretchLastSection"> - <bool>false</bool> - </attribute> - <column> - <property name="text"> - <string>File</string> - </property> - </column> - <column> - <property name="text"> - <string>Type</string> - </property> - </column> - <column> - <property name="text"> - <string>Py Version</string> - </property> - </column> - <column> - <property name="text"> - <string>Downloads</string> - </property> - </column> - <column> - <property name="text"> - <string>Uploaded on</string> - </property> - </column> - <column> - <property name="text"> - <string>Size</string> - </property> - </column> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="requires"> - <attribute name="title"> - <string>Requires/Provides</string> - </attribute> - <attribute name="toolTip"> - <string>Lists required and provided packages</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <item> - <widget class="QGroupBox" name="groupBox"> - <property name="title"> - <string>Requires</string> - </property> - <layout class="QGridLayout" name="gridLayout_4"> - <item row="0" column="0"> - <widget class="QLabel" name="label_17"> - <property name="text"> - <string>Required Packages:</string> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QListWidget" name="requiredPackagesList"> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::NoSelection</enum> - </property> - <property name="sortingEnabled"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_18"> - <property name="text"> - <string>Required Distributions:</string> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QListWidget" name="requiredDistributionsList"> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::NoSelection</enum> - </property> - <property name="sortingEnabled"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="groupBox_2"> - <property name="title"> - <string>Provides</string> - </property> - <layout class="QGridLayout" name="gridLayout_3"> - <item row="0" column="0"> - <widget class="QLabel" name="label_20"> - <property name="text"> - <string>Provided Packages:</string> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QListWidget" name="providedPackagesList"> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::NoSelection</enum> - </property> - <property name="sortingEnabled"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_19"> - <property name="text"> - <string>Provided Distributions:</string> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QListWidget" name="providedDistributionsList"> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::NoSelection</enum> - </property> - <property name="sortingEnabled"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Close</set> - </property> - </widget> - </item> - </layout> - </widget> - <tabstops> - <tabstop>infoWidget</tabstop> - <tabstop>descriptionEdit</tabstop> - <tabstop>classifiersList</tabstop> - <tabstop>downloadUrlsList</tabstop> - <tabstop>requiredPackagesList</tabstop> - <tabstop>requiredDistributionsList</tabstop> - <tabstop>providedPackagesList</tabstop> - <tabstop>providedDistributionsList</tabstop> - </tabstops> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>PipPackageDetailsDialog</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>PipPackageDetailsDialog</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/PipInterface/PipPackagesInputDialog.py Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing a dialog to enter package specifications. -""" - -from __future__ import unicode_literals - -from PyQt5.QtCore import pyqtSlot -from PyQt5.QtWidgets import QDialog, QDialogButtonBox - -from .Ui_PipPackagesInputDialog import Ui_PipPackagesInputDialog - - -class PipPackagesInputDialog(QDialog, Ui_PipPackagesInputDialog): - """ - Class implementing a dialog to enter package specifications. - """ - def __init__(self, pip, title, install=True, parent=None): - """ - Constructor - - @param pip reference to the pip object - @type Pip - @param title dialog title - @type str - @param install flag indicating an install action - @type bool - @param parent reference to the parent widget - @type QWidget - """ - super(PipPackagesInputDialog, self).__init__(parent) - self.setupUi(self) - - self.setWindowTitle(title) - - self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) - - self.venvComboBox.addItem(pip.getDefaultEnvironmentString()) - projectVenv = pip.getProjectEnvironmentString() - if projectVenv: - self.venvComboBox.addItem(projectVenv) - self.venvComboBox.addItems(pip.getVirtualenvNames()) - - self.userCheckBox.setVisible(install) - - msh = self.minimumSizeHint() - self.resize(max(self.width(), msh.width()), msh.height()) - - @pyqtSlot(str) - def on_packagesEdit_textChanged(self, txt): - """ - Private slot handling entering package names. - - @param txt name of the requirements file - @type str - """ - self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(bool(txt)) - - def getData(self): - """ - Public method to get the entered data. - - @return tuple with the environment name, the list of package - specifications and a flag indicating to install to the user - install directory - @rtype tuple of (str, list of str, bool) - """ - packages = [p.strip() for p in self.packagesEdit.text().split()] - - return ( - self.venvComboBox.currentText(), - packages, - self.userCheckBox.isChecked() - )
--- a/Plugins/UiExtensionPlugins/PipInterface/PipPackagesInputDialog.ui Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>PipPackagesInputDialog</class> - <widget class="QDialog" name="PipPackagesInputDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>600</width> - <height>186</height> - </rect> - </property> - <property name="windowTitle"> - <string>Packages </string> - </property> - <property name="sizeGripEnabled"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Virtual Environment:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="venvComboBox"> - <property name="toolTip"> - <string>Select the virtual environment to be used</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Package Specifications (separated by whitespace):</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="packagesEdit"/> - </item> - <item> - <widget class="QCheckBox" name="userCheckBox"> - <property name="toolTip"> - <string>Select to install to the Python user install directory</string> - </property> - <property name="text"> - <string>Install into User Directory</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> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>PipPackagesInputDialog</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>PipPackagesInputDialog</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/PipInterface/PipSearchDialog.py Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,465 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing a dialog to search PyPI. -""" - -from __future__ import unicode_literals - -import textwrap - -from PyQt5.QtCore import pyqtSlot, Qt, QEventLoop, QRegExp -from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton, \ - QApplication, QTreeWidgetItem, QHeaderView, QInputDialog - -from E5Gui import E5MessageBox -try: - from E5Network.E5XmlRpcClient import E5XmlRpcClient -except ImportError: - from .E5XmlRpcClient import E5XmlRpcClient - -from .Ui_PipSearchDialog import Ui_PipSearchDialog - - -class PipSearchDialog(QDialog, Ui_PipSearchDialog): - """ - Class implementing a dialog to search PyPI. - """ - VersionRole = Qt.UserRole + 1 - - Stopwords = { - "a", "and", "are", "as", "at", "be", "but", "by", - "for", "if", "in", "into", "is", "it", - "no", "not", "of", "on", "or", "such", - "that", "the", "their", "then", "there", "these", - "they", "this", "to", "was", "will", - } - - def __init__(self, pip, indexUrl, parent=None): - """ - Constructor - - @param pip reference to the master object - @type Pip - @param indexUrl URL of XML RPC interface to the pypi index - @type str - @param parent reference to the parent widget - @type QWidget - """ - super(PipSearchDialog, self).__init__(parent) - self.setupUi(self) - self.setWindowFlags(Qt.Window) - - self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) - - self.__installButton = self.buttonBox.addButton( - self.tr("&Install"), QDialogButtonBox.ActionRole) - self.__installButton.setEnabled(False) - - self.__installUserButton = self.buttonBox.addButton( - self.tr("Install to &User-Site"), QDialogButtonBox.ActionRole) - self.__installUserButton.setEnabled(False) - - self.__showDetailsButton = self.buttonBox.addButton( - self.tr("&Show Details..."), QDialogButtonBox.ActionRole) - self.__showDetailsButton.setEnabled(False) - - self.__pip = pip - self.__client = E5XmlRpcClient(indexUrl, self) - - self.venvComboBox.addItem(self.__pip.getDefaultEnvironmentString()) - projectVenv = self.__pip.getProjectEnvironmentString() - if projectVenv: - self.venvComboBox.addItem(projectVenv) - self.venvComboBox.addItems(self.__pip.getVirtualenvNames()) - - self.searchEdit.setFocus(Qt.OtherFocusReason) - - self.__canceled = False - self.__detailsData = {} - self.__query = [] - - self.__packageDetailsDialog = None - - def closeEvent(self, e): - """ - Protected slot implementing a close event handler. - - @param e close event - @type QCloseEvent - """ - QApplication.restoreOverrideCursor() - - if self.__packageDetailsDialog is not None: - self.__packageDetailsDialog.close() - - e.accept() - - @pyqtSlot(str) - def on_searchEdit_textChanged(self, txt): - """ - Private slot handling a change of the search term. - - @param txt search term - @type str - """ - self.searchButton.setEnabled(bool(txt)) - - @pyqtSlot() - def on_searchButton_clicked(self): - """ - Private slot handling a press of the search button. - """ - self.__search() - - @pyqtSlot() - def on_resultList_itemSelectionChanged(self): - """ - Private slot handling changes of the selection. - """ - self.__installButton.setEnabled( - len(self.resultList.selectedItems()) > 0) - self.__installUserButton.setEnabled( - len(self.resultList.selectedItems()) > 0) - self.__showDetailsButton.setEnabled( - len(self.resultList.selectedItems()) == 1) - - @pyqtSlot(QAbstractButton) - def on_buttonBox_clicked(self, button): - """ - Private slot called by a button of the button box clicked. - - @param button button that was clicked - @type QAbstractButton - """ - if button == self.buttonBox.button(QDialogButtonBox.Close): - self.close() - elif button == self.buttonBox.button(QDialogButtonBox.Cancel): - self.__client.abort() - self.__canceled = True - elif button == self.__installButton: - self.__install() - elif button == self.__installUserButton: - self.__install(userSite=True) - elif button == self.__showDetailsButton: - self.__showDetails() - - def __search(self): - """ - Private method to perform the search. - """ - self.resultList.clear() - self.infoLabel.clear() - - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) - self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) - self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) - self.searchButton.setEnabled(False) - QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) - - QApplication.setOverrideCursor(Qt.WaitCursor) - QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) - - self.__canceled = False - - self.__query = [term for term in self.searchEdit.text().strip().split() - if term not in PipSearchDialog.Stopwords] - self.__client.call( - "search", - ({"name": self.__query, "summary": self.__query}, "or"), - self.__processSearchResult, - self.__searchError - ) - - def __processSearchResult(self, data): - """ - Private method to process the search result data from PyPI. - - @param data result data with hits in the first element - @type tuple - """ - if data: - packages = self.__transformHits(data[0]) - if packages: - self.infoLabel.setText(self.tr("%n package(s) found.", "", - len(packages))) - wrapper = textwrap.TextWrapper(width=80) - count = 0 - total = 0 - for package in packages: - if self.__canceled: - self.infoLabel.setText( - self.tr("Canceled - only {0} out of %n package(s)" - " shown", "", len(packages)).format(total)) - break - itm = QTreeWidgetItem( - self.resultList, [ - package['name'].strip(), - "{0:4d}".format(package['score']), - "\n".join([ - wrapper.fill(line) for line in - package['summary'].strip().splitlines() - ]) - ]) - itm.setData(0, self.VersionRole, package['version']) - count += 1 - total += 1 - if count == 100: - count = 0 - QApplication.processEvents() - else: - QApplication.restoreOverrideCursor() - E5MessageBox.warning( - self, - self.tr("Search PyPI"), - self.tr("""<p>The package search did not return""" - """ anything.</p>""")) - self.infoLabel.setText( - self.tr("""<p>The package search did not return""" - """ anything.</p>""")) - else: - QApplication.restoreOverrideCursor() - E5MessageBox.warning( - self, - self.tr("Search PyPI"), - self.tr("""<p>The package search did not return anything.""" - """</p>""")) - self.infoLabel.setText( - self.tr("""<p>The package search did not return anything.""" - """</p>""")) - - header = self.resultList.header() - self.resultList.sortItems(1, Qt.DescendingOrder) - header.setStretchLastSection(False) - header.resizeSections(QHeaderView.ResizeToContents) - headerSize = 0 - for col in range(header.count()): - headerSize += header.sectionSize(col) - if headerSize < header.width(): - header.setStretchLastSection(True) - - self.__finish() - - def __finish(self): - """ - Private slot performing the finishing actions. - """ - QApplication.restoreOverrideCursor() - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) - self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) - self.searchButton.setEnabled(True) - self.searchButton.setDefault(True) - self.searchEdit.setFocus(Qt.OtherFocusReason) - - def __searchError(self, errorCode, errorString): - """ - Private method handling a search error. - - @param errorCode code of the error - @type int - @param errorString error message - @type str - """ - self.__finish() - E5MessageBox.warning( - self, - self.tr("Search PyPI"), - self.tr("""<p>The package search failed.</p><p>Reason: {0}</p>""") - .format(errorString)) - self.infoLabel.setText(self.tr("Error: {0}").format(errorString)) - - def __transformHits(self, hits): - """ - Private method to convert the list returned from pypi into a - packages list. - - @param hits list returned from pypi - @type list of dict - @return list of packages - @rtype list of dict - """ - # we only include the record with the highest score - packages = {} - for hit in hits: - name = hit['name'].strip() - summary = (hit['summary'] or "").strip() - version = hit['version'].strip() - score = self.__score(name, summary) - # cleanup the summary - if summary in ["UNKNOWN", "."]: - summary = "" - - if name not in packages: - packages[name] = { - 'name': name, - 'summary': summary, - 'version': [version.strip()], - 'score': score} - else: - if score > packages[name]['score']: - packages[name]['score'] = score - packages[name]['summary'] = summary - packages[name]['version'].append(version.strip()) - - return list(packages.values()) - - def __score(self, name, summary): - """ - Private method to calculate some score for a search result. - - @param name name of the returned package - @type str - @param summary summary text for the package - @type str - @return score value - @rtype int - """ - score = 0 - for queryTerm in self.__query: - if queryTerm.lower() in name.lower(): - score += 4 - if queryTerm.lower() == name.lower(): - score += 4 - - if queryTerm.lower() in summary.lower(): - if QRegExp(r'\b{0}\b'.format(QRegExp.escape(queryTerm)), - Qt.CaseInsensitive).indexIn(summary) != -1: - # word match gets even higher score - score += 2 - else: - score += 1 - - return score - - def __install(self, userSite=False): - """ - Private slot to install the selected packages. - - @param userSite flag indicating to install to the user directory - @type bool - """ - venvName = self.venvComboBox.currentText() - - packages = [] - for itm in self.resultList.selectedItems(): - packages.append(itm.text(0).strip()) - if packages: - self.__pip.installPackages(packages, venvName=venvName, - userSite=userSite) - - def __showDetails(self): - """ - Private slot to show details about the selected package. - """ - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) - self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) - self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) - self.__showDetailsButton.setEnabled(False) - QApplication.setOverrideCursor(Qt.WaitCursor) - QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) - - self.__detailsData = {} - - itm = self.resultList.selectedItems()[0] - packageVersions = itm.data(0, self.VersionRole) - if len(packageVersions) == 1: - packageVersion = packageVersions[0] - elif len(packageVersions) == 0: - packageVersion = "" - else: - packageVersion, ok = QInputDialog.getItem( - self, - self.tr("Show Package Details"), - self.tr("Select the package version:"), - packageVersions, - 0, False) - if not ok: - return - - packageName = itm.text(0) - self.__client.call( - "release_data", - (packageName, packageVersion), - lambda d: self.__getPackageDownloadsData(packageVersion, d), - self.__detailsError - ) - - def __getPackageDownloadsData(self, packageVersion, data): - """ - Private method to store the details data and get downloads - information. - - @param packageVersion version info - @type str - @param data result data with package details in the first - element - @type tuple - """ - if data and data[0]: - self.__detailsData = data[0] - itm = self.resultList.selectedItems()[0] - packageName = itm.text(0) - self.__client.call( - "release_urls", - (packageName, packageVersion), - self.__displayPackageDetails, - self.__detailsError - ) - else: - self.__finish() - E5MessageBox.warning( - self, - self.tr("Search PyPI"), - self.tr("""<p>No package details info available.</p>""")) - - def __displayPackageDetails(self, data): - """ - Private method to display the returned package details. - - @param data result data with downloads information in the first element - @type tuple - """ - from .PipPackageDetailsDialog import PipPackageDetailsDialog - - self.__finish() - self.__showDetailsButton.setEnabled(True) - - if self.__packageDetailsDialog is not None: - self.__packageDetailsDialog.close() - - self.__packageDetailsDialog = \ - PipPackageDetailsDialog(self.__detailsData, data[0], self) - self.__packageDetailsDialog.show() - - def __detailsError(self, errorCode, errorString): - """ - Private method handling a details error. - - @param errorCode code of the error - @type int - @param errorString error message - @type str - """ - self.__finish() - self.__showDetailsButton.setEnabled(True) - E5MessageBox.warning( - self, - self.tr("Search PyPI"), - self.tr("""<p>Package details info could not be retrieved.</p>""" - """<p>Reason: {0}</p>""") - .format(errorString)) - - @pyqtSlot(QTreeWidgetItem, int) - def on_resultList_itemActivated(self, item, column): - """ - Private slot reacting on an item activation. - - @param item reference to the activated item - @type QTreeWidgetItem - @param column activated column - @type int - """ - self.__showDetails()
--- a/Plugins/UiExtensionPlugins/PipInterface/PipSearchDialog.ui Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,138 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>PipSearchDialog</class> - <widget class="QDialog" name="PipSearchDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>700</width> - <height>600</height> - </rect> - </property> - <property name="windowTitle"> - <string>Search PyPI</string> - </property> - <property name="sizeGripEnabled"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Virtual Environment:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="venvComboBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Select the virtual environment to be used</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Query:</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="searchEdit"> - <property name="toolTip"> - <string>Enter the search term</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="searchButton"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="toolTip"> - <string>Press to start the search</string> - </property> - <property name="text"> - <string>Search</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QTreeWidget" name="resultList"> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::ExtendedSelection</enum> - </property> - <property name="rootIsDecorated"> - <bool>false</bool> - </property> - <property name="itemsExpandable"> - <bool>false</bool> - </property> - <property name="sortingEnabled"> - <bool>true</bool> - </property> - <property name="allColumnsShowFocus"> - <bool>true</bool> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - <column> - <property name="text"> - <string>Package</string> - </property> - </column> - <column> - <property name="text"> - <string>Score</string> - </property> - </column> - <column> - <property name="text"> - <string>Description</string> - </property> - </column> - </widget> - </item> - <item> - <widget class="QLabel" name="infoLabel"/> - </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> - <tabstops> - <tabstop>venvComboBox</tabstop> - <tabstop>searchEdit</tabstop> - <tabstop>searchButton</tabstop> - <tabstop>resultList</tabstop> - </tabstops> - <resources/> - <connections/> -</ui>
--- a/Plugins/UiExtensionPlugins/PipInterface/PipSelectionDialog.py Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2018 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing a dialog to select the pip executable to be used. -""" - -from __future__ import unicode_literals - -from PyQt5.QtWidgets import QDialog - -from .Ui_PipSelectionDialog import Ui_PipSelectionDialog - - -class PipSelectionDialog(QDialog, Ui_PipSelectionDialog): - """ - Class implementing a dialog to select the pip executable to be used. - """ - def __init__(self, pip, parent=None): - """ - Constructor - - @param pip reference to the pip object - @type Pip - @param parent reference to the parent widget - @type QWidget - """ - super(PipSelectionDialog, self).__init__(parent) - self.setupUi(self) - - self.venvComboBox.addItem(pip.getDefaultEnvironmentString()) - projectVenv = pip.getProjectEnvironmentString() - if projectVenv: - self.venvComboBox.addItem(projectVenv) - self.venvComboBox.addItems(pip.getVirtualenvNames()) - - msh = self.minimumSizeHint() - self.resize(max(self.width(), msh.width()), msh.height()) - - def getData(self): - """ - Public method to get the entered data. - - @return tuple with the environment name and a flag indicating to - install to the user install directory - @rtype tuple of (str, bool) - """ - return ( - self.venvComboBox.currentText(), - self.userCheckBox.isChecked(), - )
--- a/Plugins/UiExtensionPlugins/PipInterface/PipSelectionDialog.ui Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>PipSelectionDialog</class> - <widget class="QDialog" name="PipSelectionDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>600</width> - <height>130</height> - </rect> - </property> - <property name="windowTitle"> - <string>Select Virtual Environment</string> - </property> - <property name="sizeGripEnabled"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Virtual Environment:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="venvComboBox"> - <property name="toolTip"> - <string>Select the virtual environment to be used</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="userCheckBox"> - <property name="toolTip"> - <string>Select to install to the Python user install directory</string> - </property> - <property name="text"> - <string>Install into User Directory</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> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>PipSelectionDialog</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>PipSelectionDialog</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/PipInterface/__init__.py Mon Feb 18 19:14:05 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Package implementing the various pip dialogs and data. -""" - -from __future__ import unicode_literals - -DefaultPyPiUrl = "https://pypi.org" -DefaultIndexUrlXml = DefaultPyPiUrl + "/pypi" -DefaultIndexUrlPip = DefaultPyPiUrl + "/simple"
--- a/Preferences/ConfigurationDialog.py Mon Feb 18 19:14:05 2019 +0100 +++ b/Preferences/ConfigurationDialog.py Mon Feb 18 19:17:04 2019 +0100 @@ -182,6 +182,9 @@ [self.tr("Notifications"), "preferences-notifications.png", "NotificationsPage", None, None], + "pipPage": + [self.tr("Python Package Management"), "pypi.png", + "PipPage", None, None], "pluginManagerPage": [self.tr("Plugin Manager"), "preferences-pluginmanager.png",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Preferences/ConfigurationPages/PipPage.py Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2015 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Package implementing the pip configuration page. +""" + +from __future__ import unicode_literals + +from .ConfigurationPageBase import ConfigurationPageBase +from .Ui_PipPage import Ui_PipPage + +from PipInterface import DefaultPyPiUrl + +import Preferences + + +class PipPage(ConfigurationPageBase, Ui_PipPage): + """ + Class implementing the pip configuration page. + """ + def __init__(self): + """ + Constructor + + @param plugin reference to the plugin object + @type PipInterfacePlugin + """ + super(PipPage, self).__init__() + self.setupUi(self) + self.setObjectName("PipPage") + + self.indexLabel.setText(self.tr( + '<b>Note:</b> Leave empty to use the default index URL (' + '<a href="{0}">{0}</a>).') + .format(DefaultPyPiUrl)) + + # set initial values + self.indexEdit.setText(Preferences.getPip("PipSearchIndex")) + + def save(self): + """ + Public slot to save the pip configuration. + """ + Preferences.setPip( + "PipSearchIndex", self.indexEdit.text().strip()) + + +def create(dlg): + """ + Module function to create the configuration page. + + @param dlg reference to the configuration dialog + @return reference to the instantiated page (ConfigurationPageBase) + """ + page = PipPage() + return page
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Preferences/ConfigurationPages/PipPage.ui Mon Feb 18 19:17:04 2019 +0100 @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PipPage</class> + <widget class="QWidget" name="PipPage"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>602</width> + <height>389</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QLabel" name="headerLabel"> + <property name="text"> + <string><b>Configure pip</b></string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line9_3"> + <property name="frameShape"> + <enum>QFrame::HLine</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Index URL</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLineEdit" name="indexEdit"> + <property name="toolTip"> + <string>Enter the URL of the package index or leave empty to use the default</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="indexLabel"> + <property name="text"> + <string/> + </property> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>234</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <tabstops> + <tabstop>indexEdit</tabstop> + </tabstops> + <resources/> + <connections/> +</ui>
--- a/Preferences/ProgramsDialog.py Mon Feb 18 19:14:05 2019 +0100 +++ b/Preferences/ProgramsDialog.py Mon Feb 18 19:17:04 2019 +0100 @@ -224,8 +224,16 @@ self.__createProgramEntry( self.tr("conda Manager"), exe, '--version', 'conda', -1) - # 6. do the CORBA and Protobuf programs - # 6a. omniORB + # 6. do the pip program(s) + virtualenvManager = e5App().getObject("VirtualEnvManager") + for venvName in virtualenvManager.getVirtualenvNames(): + interpreter = virtualenvManager.getVirtualenvInterpreter(venvName) + self.__createProgramEntry( + self.tr("PyPI Package Management"), interpreter, '--version', + 'pip', 1, exeModule=["-m", "pip"]) + + # 7. do the CORBA and Protobuf programs + # 7a. omniORB exe = Preferences.getCorba("omniidl") if not exe: exe = "omniidl" @@ -233,7 +241,7 @@ exe += ".exe" self.__createProgramEntry( self.tr("CORBA IDL Compiler"), exe, '-V', 'omniidl', -1) - # 6b. protobuf + # 7b. protobuf exe = Preferences.getProtobuf("protoc") if not exe: exe = "protoc" @@ -241,7 +249,7 @@ exe += ".exe" self.__createProgramEntry( self.tr("Protobuf Compiler"), exe, '--version', 'libprotoc', -1) - # 6c. grpc + # 7c. grpc exe = Preferences.getProtobuf("grpcPython") if not exe: exe = sys.executable @@ -249,7 +257,7 @@ self.tr("gRPC Compiler"), exe, '--version', 'libprotoc', -1, exeModule=['-m', 'grpc_tools.protoc']) - # 7. do the spell checking entry + # 8. do the spell checking entry try: import enchant try: @@ -266,7 +274,7 @@ self.__createEntry( self.tr("Spell Checker - PyEnchant"), text, version) - # 8. do the pygments entry + # 9. do the pygments entry try: import pygments try: @@ -283,7 +291,7 @@ self.__createEntry( self.tr("Source Highlighter - Pygments"), text, version) - # 9. do the plugin related programs + # 10. do the plugin related programs pm = e5App().getObject("PluginManager") for info in pm.getPluginExeDisplayData(): if info["programEntry"]:
--- a/Preferences/__init__.py Mon Feb 18 19:14:05 2019 +0100 +++ b/Preferences/__init__.py Mon Feb 18 19:17:04 2019 +0100 @@ -1587,6 +1587,12 @@ condaDefaults = { "CondaExecutable": "", } + + # defaults for pip + pipDefaults = { + "CurrentEnvironment": "", + "PipSearchIndex": "", # used by the search command + } def readToolGroups(prefClass=Prefs): @@ -3775,6 +3781,30 @@ prefClass.settings.setValue("Conda/" + key, value) +def getPip(key, prefClass=Prefs): + """ + Module function to retrieve the pip related settings. + + @param key the key of the value to get + @param prefClass preferences class used as the storage area + @return the requested pip value + """ + return prefClass.settings.value( + "Pip/" + key, + prefClass.pipDefaults[key]) + + +def setPip(key, value, prefClass=Prefs): + """ + Module function to store the pip related settings. + + @param key the key of the setting to be set + @param value the value to be set + @param prefClass preferences class used as the storage area + """ + prefClass.settings.setValue("Pip/" + key, value) + + def getGeometry(key, prefClass=Prefs): """ Module function to retrieve the display geometry.
--- a/eric6.e4p Mon Feb 18 19:14:05 2019 +0100 +++ b/eric6.e4p Mon Feb 18 19:17:04 2019 +0100 @@ -471,6 +471,16 @@ <Source>Network/IRC/IrcWidget.py</Source> <Source>Network/IRC/__init__.py</Source> <Source>Network/__init__.py</Source> + <Source>PipInterface/Pip.py</Source> + <Source>PipInterface/PipDialog.py</Source> + <Source>PipInterface/PipFileSelectionDialog.py</Source> + <Source>PipInterface/PipFreezeDialog.py</Source> + <Source>PipInterface/PipListDialog.py</Source> + <Source>PipInterface/PipPackageDetailsDialog.py</Source> + <Source>PipInterface/PipPackagesInputDialog.py</Source> + <Source>PipInterface/PipSearchDialog.py</Source> + <Source>PipInterface/PipSelectionDialog.py</Source> + <Source>PipInterface/__init__.py</Source> <Source>PluginManager/PluginDetailsDialog.py</Source> <Source>PluginManager/PluginExceptions.py</Source> <Source>PluginManager/PluginInfoDialog.py</Source> @@ -541,18 +551,6 @@ <Source>Plugins/PluginWizardQRegExp.py</Source> <Source>Plugins/PluginWizardQRegularExpression.py</Source> <Source>Plugins/PluginWizardSetup.py</Source> - <Source>Plugins/UiExtensionPlugins/PipInterface/ConfigurationPage/PipPage.py</Source> - <Source>Plugins/UiExtensionPlugins/PipInterface/ConfigurationPage/__init__.py</Source> - <Source>Plugins/UiExtensionPlugins/PipInterface/Pip.py</Source> - <Source>Plugins/UiExtensionPlugins/PipInterface/PipDialog.py</Source> - <Source>Plugins/UiExtensionPlugins/PipInterface/PipFileSelectionDialog.py</Source> - <Source>Plugins/UiExtensionPlugins/PipInterface/PipFreezeDialog.py</Source> - <Source>Plugins/UiExtensionPlugins/PipInterface/PipListDialog.py</Source> - <Source>Plugins/UiExtensionPlugins/PipInterface/PipPackageDetailsDialog.py</Source> - <Source>Plugins/UiExtensionPlugins/PipInterface/PipPackagesInputDialog.py</Source> - <Source>Plugins/UiExtensionPlugins/PipInterface/PipSearchDialog.py</Source> - <Source>Plugins/UiExtensionPlugins/PipInterface/PipSelectionDialog.py</Source> - <Source>Plugins/UiExtensionPlugins/PipInterface/__init__.py</Source> <Source>Plugins/UiExtensionPlugins/Translator/ConfigurationPage/TranslatorPage.py</Source> <Source>Plugins/UiExtensionPlugins/Translator/ConfigurationPage/__init__.py</Source> <Source>Plugins/UiExtensionPlugins/Translator/Translator.py</Source> @@ -893,6 +891,7 @@ <Source>Preferences/ConfigurationPages/MultiProjectPage.py</Source> <Source>Preferences/ConfigurationPages/NetworkPage.py</Source> <Source>Preferences/ConfigurationPages/NotificationsPage.py</Source> + <Source>Preferences/ConfigurationPages/PipPage.py</Source> <Source>Preferences/ConfigurationPages/PluginManagerPage.py</Source> <Source>Preferences/ConfigurationPages/PrinterPage.py</Source> <Source>Preferences/ConfigurationPages/ProjectBrowserPage.py</Source> @@ -1722,10 +1721,10 @@ <Source>uninstall.py</Source> </Sources> <Forms> - <Form>CondaInterface/CondaNewEnvironmentDataDialog.ui</Form> <Form>CondaInterface/CondaExecDialog.ui</Form> <Form>CondaInterface/CondaExportDialog.ui</Form> <Form>CondaInterface/CondaInfoDialog.ui</Form> + <Form>CondaInterface/CondaNewEnvironmentDataDialog.ui</Form> <Form>CondaInterface/CondaPackageDetailsWidget.ui</Form> <Form>CondaInterface/CondaPackagesWidget.ui</Form> <Form>Cooperation/ChatWidget.ui</Form> @@ -1825,6 +1824,14 @@ <Form>Network/IRC/IrcNetworkWidget.ui</Form> <Form>Network/IRC/IrcServerEditDialog.ui</Form> <Form>Network/IRC/IrcWidget.ui</Form> + <Form>PipInterface/PipDialog.ui</Form> + <Form>PipInterface/PipFileSelectionDialog.ui</Form> + <Form>PipInterface/PipFreezeDialog.ui</Form> + <Form>PipInterface/PipListDialog.ui</Form> + <Form>PipInterface/PipPackageDetailsDialog.ui</Form> + <Form>PipInterface/PipPackagesInputDialog.ui</Form> + <Form>PipInterface/PipSearchDialog.ui</Form> + <Form>PipInterface/PipSelectionDialog.ui</Form> <Form>PluginManager/PluginDetailsDialog.ui</Form> <Form>PluginManager/PluginInfoDialog.ui</Form> <Form>PluginManager/PluginInstallDialog.ui</Form> @@ -1841,15 +1848,6 @@ <Form>Plugins/DocumentationPlugins/Ericapi/EricapiExecDialog.ui</Form> <Form>Plugins/DocumentationPlugins/Ericdoc/EricdocConfigDialog.ui</Form> <Form>Plugins/DocumentationPlugins/Ericdoc/EricdocExecDialog.ui</Form> - <Form>Plugins/UiExtensionPlugins/PipInterface/ConfigurationPage/PipPage.ui</Form> - <Form>Plugins/UiExtensionPlugins/PipInterface/PipDialog.ui</Form> - <Form>Plugins/UiExtensionPlugins/PipInterface/PipFileSelectionDialog.ui</Form> - <Form>Plugins/UiExtensionPlugins/PipInterface/PipFreezeDialog.ui</Form> - <Form>Plugins/UiExtensionPlugins/PipInterface/PipListDialog.ui</Form> - <Form>Plugins/UiExtensionPlugins/PipInterface/PipPackageDetailsDialog.ui</Form> - <Form>Plugins/UiExtensionPlugins/PipInterface/PipPackagesInputDialog.ui</Form> - <Form>Plugins/UiExtensionPlugins/PipInterface/PipSearchDialog.ui</Form> - <Form>Plugins/UiExtensionPlugins/PipInterface/PipSelectionDialog.ui</Form> <Form>Plugins/UiExtensionPlugins/Translator/ConfigurationPage/TranslatorPage.ui</Form> <Form>Plugins/UiExtensionPlugins/Translator/TranslatorWidget.ui</Form> <Form>Plugins/VcsPlugins/vcsGit/ConfigurationPage/GitPage.ui</Form> @@ -2073,6 +2071,7 @@ <Form>Preferences/ConfigurationPages/MultiProjectPage.ui</Form> <Form>Preferences/ConfigurationPages/NetworkPage.ui</Form> <Form>Preferences/ConfigurationPages/NotificationsPage.ui</Form> + <Form>Preferences/ConfigurationPages/PipPage.ui</Form> <Form>Preferences/ConfigurationPages/PluginManagerPage.ui</Form> <Form>Preferences/ConfigurationPages/PrinterPage.ui</Form> <Form>Preferences/ConfigurationPages/ProjectBrowserPage.ui</Form> @@ -2261,14 +2260,14 @@ </Resources> <Others> <Other>.hgignore</Other> + <Other>APIs/Python/zope-2.10.7.api</Other> + <Other>APIs/Python/zope-2.11.2.api</Other> + <Other>APIs/Python/zope-3.3.1.api</Other> <Other>APIs/Python3/PyQt4.bas</Other> <Other>APIs/Python3/PyQt5.bas</Other> <Other>APIs/Python3/QScintilla2.bas</Other> <Other>APIs/Python3/eric6.api</Other> <Other>APIs/Python3/eric6.bas</Other> - <Other>APIs/Python/zope-2.10.7.api</Other> - <Other>APIs/Python/zope-2.11.2.api</Other> - <Other>APIs/Python/zope-3.3.1.api</Other> <Other>APIs/QSS/qss.api</Other> <Other>APIs/Ruby/Ruby-1.8.7.api</Other> <Other>APIs/Ruby/Ruby-1.8.7.bas</Other>