PipInterface: continued with the pip interface widget. pypi

Mon, 18 Feb 2019 19:49:43 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Mon, 18 Feb 2019 19:49:43 +0100
branch
pypi
changeset 6785
058d63c537a4
parent 6784
f5d29245dbb9
child 6792
9dd854f05c83

PipInterface: continued with the pip interface widget.

PipInterface/Pip.py file | annotate | diff | comparison | revisions
PipInterface/PipPackagesWidget.py file | annotate | diff | comparison | revisions
PipInterface/PipPackagesWidget.ui file | annotate | diff | comparison | revisions
Preferences/ConfigurationPages/InterfacePage.py file | annotate | diff | comparison | revisions
Preferences/__init__.py file | annotate | diff | comparison | revisions
UI/UserInterface.py file | annotate | diff | comparison | revisions
eric6.e4p file | annotate | diff | comparison | revisions
--- a/PipInterface/Pip.py	Mon Feb 18 19:17:04 2019 +0100
+++ b/PipInterface/Pip.py	Mon Feb 18 19:49:43 2019 +0100
@@ -28,35 +28,30 @@
 
 import Preferences
 import Globals
-
-import UI.PixmapCache
+##
+##import UI.PixmapCache
 
 
 class Pip(QObject):
     """
     Class implementing the pip GUI logic.
     """
-    def __init__(self, plugin, parent=None):
+    def __init__(self, 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.__project = e5App().getObject("Project")
         
         self.__menus = {}   # dictionary with references to menus
         
-        self.__plugin.currentEnvironmentChanged.connect(
-            self.__handleTearOffMenu)
+##        self.__plugin.currentEnvironmentChanged.connect(
+##            self.__handleTearOffMenu)
     
     def initActions(self):
         """
@@ -79,57 +74,57 @@
         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 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
         ##############################################
@@ -367,16 +362,16 @@
         """
         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 = QMenu()
+##        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.listPackagesAct)
+##        menu.addAction(self.listUptodatePackagesAct)
+##        menu.addAction(self.listOutdatedPackagesAct)
+##        menu.addSeparator()
         menu.addAction(self.installPipAct)
         menu.addSeparator()
         menu.addAction(self.installPackagesAct)
@@ -384,15 +379,15 @@
         menu.addAction(self.installRequirementsAct)
         menu.addSeparator()
         menu.addAction(self.upgradePipAct)
-        menu.addAction(self.upgradePackagesAct)
+##        menu.addAction(self.upgradePackagesAct)
         menu.addSeparator()
-        menu.addAction(self.uninstallPackagesAct)
+##        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.searchPyPIAct)
+##        menu.addSeparator()
         menu.addAction(self.repairPipAct)
         menu.addSeparator()
         menu.addAction(self.editUserConfigAct)
@@ -410,7 +405,7 @@
         """
         Private slot to set the action enabled status.
         """
-        enable = bool(self.__plugin.getPreferences("CurrentEnvironment"))
+        enable = bool(Preferences.getPip("CurrentEnvironment"))
         for act in self.actions:
             if act not in [self.selectEnvironmentAct,
                            self.installPipAct,
@@ -546,17 +541,22 @@
         try:
             venvDirectory = os.environ["VIRTUAL_ENV"]
         except KeyError:
-            venvName = self.__plugin.getPreferences("CurrentEnvironment")
+            venvName = Preferences.getPip("CurrentEnvironment")
             if not venvName:
                 self.__selectPipVirtualenv()
-                venvName = self.__plugin.getPreferences("CurrentEnvironment")
+                venvName = Preferences.getPip("CurrentEnvironment")
             if self.__virtualenvManager.isGlobalEnvironment(venvName):
                 venvDirectory = self.__getUserConfig()
             else:
                 venvDirectory = \
                     self.__virtualenvManager.getVirtualenvDirectory(venvName)
         
-        return os.path.join(venvDirectory, pip)
+        if venvDirectory:
+            config = os.path.join(venvDirectory, pip)
+        else:
+            config = ""
+        
+        return config
     
     def getDefaultEnvironmentString(self):
         """
@@ -574,7 +574,7 @@
         @return string for the project environment
         @rtype str
         """
-        if self.__project.isOpen():
+        if e5App().getObject("Project").isOpen():
             return self.tr("<project>")
         else:
             return ""
@@ -589,12 +589,12 @@
         @rtype str
         """
         if venvName == self.getDefaultEnvironmentString():
-            venvName = self.__plugin.getPreferences("CurrentEnvironment")
+            venvName = Preferences.getPip("CurrentEnvironment")
         elif venvName == self.getProjectEnvironmentString():
-            venvName = self.__project.getDebugProperty("VIRTUALENV")
+            venvName = e5App().getObject("Project").getDebugProperty("VIRTUALENV")
             if not venvName:
                 # fall back to standard if not defined
-                venvName = self.__plugin.getPreferences("CurrentEnvironment")
+                venvName = Preferences.getPip("CurrentEnvironment")
         
         interpreter = self.__virtualenvManager.getVirtualenvInterpreter(
             venvName)
@@ -626,8 +626,7 @@
         """
         environments = self.getVirtualenvNames()
         if environments:
-            currentEnvironment = self.__plugin.getPreferences(
-                "CurrentEnvironment")
+            currentEnvironment = Preferences.getPip("CurrentEnvironment")
             try:
                 index = environments.index(currentEnvironment)
             except ValueError:
@@ -639,8 +638,7 @@
                 environments, index, False)
             
             if ok and environment:
-                self.__plugin.setPreferences("CurrentEnvironment",
-                                             environment)
+                Preferences.getPip("CurrentEnvironment", environment)
         else:
             E5MessageBox.warning(
                 None,
@@ -648,13 +646,14 @@
                 self.tr("""No virtual environments have been configured yet."""
                         """ Please use the Virtualenv Manager to do that."""))
     
+    # TODO: move these three to the widget
     def __listPackages(self):
         """
         Private slot to list all installed packages.
         """
         from .PipListDialog import PipListDialog
         self.__listDialog = PipListDialog(
-            self, "list", self.__plugin.getPreferences("PipSearchIndex"),
+            self, "list", Preferences.getPip("PipSearchIndex"),
             self.tr("Installed Packages"))
         self.__listDialog.show()
         self.__listDialog.start()
@@ -665,7 +664,7 @@
         """
         from .PipListDialog import PipListDialog
         self.__listUptodateDialog = PipListDialog(
-            self, "uptodate", self.__plugin.getPreferences("PipSearchIndex"),
+            self, "uptodate", Preferences.getPip("PipSearchIndex"),
             self.tr("Up-to-date Packages"))
         self.__listUptodateDialog.show()
         self.__listUptodateDialog.start()
@@ -676,7 +675,7 @@
         """
         from .PipListDialog import PipListDialog
         self.__listOutdatedDialog = PipListDialog(
-            self, "outdated", self.__plugin.getPreferences("PipSearchIndex"),
+            self, "outdated", Preferences.getPip("PipSearchIndex"),
             self.tr("Outdated Packages"))
         self.__listOutdatedDialog.show()
         self.__listOutdatedDialog.start()
@@ -704,6 +703,8 @@
         from QScintilla.MiniEditor import MiniEditor
         if virtualenv:
             cfgFile = self.__getVirtualenvConfig()
+            if not cfgFile:
+                return
         else:
             cfgFile = self.__getUserConfig()
         cfgDir = os.path.dirname(cfgFile)
@@ -770,9 +771,8 @@
             commands = [(interpreter, ["-m", "ensurepip", "--user"])]
         else:
             commands = [(interpreter, ["-m", "ensurepip"])]
-        if self.__plugin.getPreferences("PipSearchIndex"):
-            indexUrl = \
-                self.__plugin.getPreferences("PipSearchIndex") + "/simple"
+        if Preferences.getPip("PipSearchIndex"):
+            indexUrl = Preferences.getPip("PipSearchIndex") + "/simple"
             args = ["-m", "pip", "install", "--index-url", indexUrl,
                     "--upgrade"]
         else:
@@ -814,9 +814,8 @@
         if not interpreter:
             return
         
-        if self.__plugin.getPreferences("PipSearchIndex"):
-            indexUrl = \
-                self.__plugin.getPreferences("PipSearchIndex") + "/simple"
+        if Preferences.getPip("PipSearchIndex"):
+            indexUrl = Preferences.getPip("PipSearchIndex") + "/simple"
             args = ["-m", "pip", "install", "--index-url", indexUrl,
                     "--upgrade"]
         else:
@@ -850,9 +849,8 @@
             return
         
         # python -m pip install --ignore-installed pip
-        if self.__plugin.getPreferences("PipSearchIndex"):
-            indexUrl = \
-                self.__plugin.getPreferences("PipSearchIndex") + "/simple"
+        if Preferences.getPip("PipSearchIndex"):
+            indexUrl = Preferences.getPip("PipSearchIndex") + "/simple"
             args = ["-m", "pip", "install", "--index-url", indexUrl,
                     "--ignore-installed"]
         else:
@@ -910,14 +908,13 @@
             return False
         
         if not venvName:
-            venvName = self.__plugin.getPreferences("CurrentEnvironment")
+            venvName = Preferences.getPip("CurrentEnvironment")
         interpreter = self.getVirtualenvInterpreter(venvName)
         if not interpreter:
             return
         
-        if self.__plugin.getPreferences("PipSearchIndex"):
-            indexUrl = \
-                self.__plugin.getPreferences("PipSearchIndex") + "/simple"
+        if Preferences.getPip("PipSearchIndex"):
+            indexUrl = Preferences.getPip("PipSearchIndex") + "/simple"
             args = ["-m", "pip", "install", "--index-url", indexUrl,
                     "--upgrade"]
         else:
@@ -956,14 +953,13 @@
         @type bool
         """
         if not venvName:
-            venvName = self.__plugin.getPreferences("CurrentEnvironment")
+            venvName = Preferences.getPip("CurrentEnvironment")
         interpreter = self.getVirtualenvInterpreter(venvName)
         if not interpreter:
             return
         
-        if self.__plugin.getPreferences("PipSearchIndex"):
-            indexUrl = \
-                self.__plugin.getPreferences("PipSearchIndex") + "/simple"
+        if Preferences.getPip("PipSearchIndex"):
+            indexUrl = Preferences.getPip("PipSearchIndex") + "/simple"
             args = ["-m", "pip", "install", "--index-url", indexUrl]
         else:
             args = ["-m", "pip", "install"]
@@ -1012,9 +1008,8 @@
                 interpreter = self.getVirtualenvInterpreter(venvName)
                 if not interpreter:
                     return
-                if self.__plugin.getPreferences("PipSearchIndex"):
-                    indexUrl = \
-                        self.__plugin.getPreferences("PipSearchIndex") + \
+                if Preferences.getPip("PipSearchIndex"):
+                    indexUrl = Preferences.getPip("PipSearchIndex") + \
                         "/simple"
                     args = ["-m", "pip", "install", "--index-url", indexUrl]
                 else:
@@ -1050,8 +1045,7 @@
                 packages)
             if dlg.exec_() == QDialog.Accepted:
                 if not venvName:
-                    venvName = self.__plugin.getPreferences(
-                        "CurrentEnvironment")
+                    venvName = Preferences.getPip("CurrentEnvironment")
                 interpreter = self.getVirtualenvInterpreter(venvName)
                 if not interpreter:
                     return
@@ -1101,8 +1095,7 @@
                     reqs)
                 if dlg.exec_() == QDialog.Accepted:
                     if not venvName:
-                        venvName = self.__plugin.getPreferences(
-                            "CurrentEnvironment")
+                        venvName = Preferences.getPip("CurrentEnvironment")
                     interpreter = self.getVirtualenvInterpreter(venvName)
                     if not interpreter:
                         return
@@ -1129,8 +1122,8 @@
         """
         from .PipSearchDialog import PipSearchDialog
         
-        if self.__plugin.getPreferences("PipSearchIndex"):
-            indexUrl = self.__plugin.getPreferences("PipSearchIndex") + "/pypi"
+        if Preferences.getPip("PipSearchIndex"):
+            indexUrl = Preferences.getPip("PipSearchIndex") + "/pypi"
         else:
             indexUrl = DefaultIndexUrlXml
         
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PipInterface/PipPackagesWidget.py	Mon Feb 18 19:49:43 2019 +0100
@@ -0,0 +1,159 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2019 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the pip packages management widget.
+"""
+
+from __future__ import unicode_literals
+
+from PyQt5.QtCore import pyqtSlot, Qt
+from PyQt5.QtGui import QCursor
+from PyQt5.QtWidgets import QWidget, QToolButton, QApplication
+
+from .Ui_PipPackagesWidget import Ui_PipPackagesWidget
+
+import UI.PixmapCache
+
+from .Pip import Pip
+
+
+class PipPackagesWidget(QWidget, Ui_PipPackagesWidget):
+    """
+    Class documentation goes here.
+    """
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget
+        @type QWidget
+        """
+        super(PipPackagesWidget, self).__init__(parent)
+        self.setupUi(self)
+        
+        self.pipMenuButton.setObjectName(
+            "navigation_supermenu_button")
+        self.pipMenuButton.setIcon(UI.PixmapCache.getIcon("superMenu"))
+        self.pipMenuButton.setToolTip(self.tr("pip Menu"))
+        self.pipMenuButton.setPopupMode(QToolButton.InstantPopup)
+        self.pipMenuButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
+        self.pipMenuButton.setFocusPolicy(Qt.NoFocus)
+        self.pipMenuButton.setAutoRaise(True)
+        self.pipMenuButton.setShowMenuInside(True)
+        
+        self.searchToggleButton.setIcon(UI.PixmapCache.getIcon("find"))
+        
+        self.__pip = Pip(self)
+        
+        self.__initPipMenu()
+        self.__populateEnvironments()
+        self.__updateActionButtons()
+        
+        self.statusLabel.hide()
+        self.searchWidget.hide()
+        
+    def __initPipMenu(self):
+        """
+        Private method to create the super menu and attach it to the super
+        menu button.
+        """
+        self.__pip.initActions()
+        
+        self.__pipMenu = self.__pip.initMenu()
+        
+        self.pipMenuButton.setMenu(self.__pipMenu)
+    
+    def __populateEnvironments(self):
+        """
+        Private method to get a list of environments and populate the selector.
+        """
+        self.environmentsComboBox.addItem("")
+        projectVenv = self.__pip.getProjectEnvironmentString()
+        if projectVenv:
+            self.environmentsComboBox.addItem(projectVenv)
+        self.environmentsComboBox.addItems(self.__pip.getVirtualenvNames())
+    
+    def __updateActionButtons(self):
+        """
+        Private method to set the state of the action buttons.
+        """
+        # TODO: not yet implemented
+        pass
+    
+    #######################################################################
+    ## Slots handling widget signals below
+    #######################################################################
+    
+    @pyqtSlot(int)
+    def on_environmentsComboBox_currentIndexChanged(self, index):
+        """
+        Private slot handling the selection of a conda environment.
+        
+        @param index index of the selected conda environment
+        @type int
+        """
+        self.packagesList.clear()
+        venvName = self.environmentsComboBox.currentText()
+        if venvName:
+            interpreter = self.__pip.getVirtualenvInterpreter(venvName)
+            if interpreter:
+                QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
+                self.statusLabel.show()
+                self.statusLabel.setText(
+                    self.tr("Getting installed packages..."))
+                QApplication.processEvents()
+                
+                # 1. populate with installed packages
+                pass    # TODO: add code to list installed
+                
+                # 2. update with update information
+                pass    # TODO: add code to list outdated
+                
+                self.packagesList.sortItems(0, Qt.AscendingOrder)
+                for col in range(self.packagesList.columnCount()):
+                    self.packagesList.resizeColumnToContents(col)
+                self.packagesList.setUpdatesEnabled(True)
+                QApplication.restoreOverrideCursor()
+                self.statusLabel.hide()
+        
+        self.__updateActionButtons()
+        self.__updateSearchActionButtons()
+    
+    #######################################################################
+    ## Search widget related methods below
+    #######################################################################
+    
+    def __updateSearchActionButtons(self):
+        """
+        Private method to update the action button states of the search widget.
+        """
+        # TODO: adjust this like search dialog
+        enable = len(self.searchResultList.selectedItems()) == 1
+        self.installButton.setEnabled(
+            enable and self.environmentsComboBox.currentIndex() > 0)
+        self.showDetailsButton.setEnabled(
+            enable and bool(self.searchResultList.selectedItems()[0].parent()))
+    
+    @pyqtSlot(bool)
+    def on_searchToggleButton_toggled(self, checked):
+        """
+        Private slot to togle the search widget.
+        
+        @param checked state of the search widget button
+        @type bool
+        """
+        self.searchWidget.setVisible(checked)
+        
+        if checked:
+            self.searchEdit.setFocus(Qt.OtherFocusReason)
+            self.searchEdit.selectAll()
+            
+            self.__updateSearchActionButtons()
+    
+    #######################################################################
+    ## Menu related methods below
+    #######################################################################
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PipInterface/PipPackagesWidget.ui	Mon Feb 18 19:49:43 2019 +0100
@@ -0,0 +1,486 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PipPackagesWidget</class>
+ <widget class="QWidget" name="PipPackagesWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>500</width>
+    <height>600</height>
+   </rect>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_5">
+   <item>
+    <widget class="QWidget" name="baseWidget" native="true">
+     <layout class="QVBoxLayout" name="verticalLayout_4">
+      <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">
+        <item>
+         <widget class="QComboBox" name="environmentsComboBox"/>
+        </item>
+        <item>
+         <widget class="E5ToolButton" name="pipMenuButton"/>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_6">
+        <item>
+         <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>
+         <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>
+         <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="QLabel" name="statusLabel"/>
+      </item>
+      <item>
+       <widget class="QSplitter" name="splitter">
+        <property name="orientation">
+         <enum>Qt::Vertical</enum>
+        </property>
+        <widget class="QTreeWidget" name="packagesList">
+         <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>
+         <attribute name="headerDefaultSectionSize">
+          <number>150</number>
+         </attribute>
+         <column>
+          <property name="text">
+           <string>Package</string>
+          </property>
+         </column>
+         <column>
+          <property name="text">
+           <string>Installed Version</string>
+          </property>
+         </column>
+         <column>
+          <property name="text">
+           <string>Available Version</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_3">
+          <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_7">
+            <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>
+       <layout class="QHBoxLayout" name="horizontalLayout_2">
+        <item>
+         <spacer name="horizontalSpacer">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QPushButton" name="refreshButton">
+          <property name="toolTip">
+           <string>Press to refresh the lists</string>
+          </property>
+          <property name="text">
+           <string>&amp;Refresh</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="upgradeButton">
+          <property name="toolTip">
+           <string>Press to upgrade the selected packages</string>
+          </property>
+          <property name="text">
+           <string>Up&amp;grade</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="upgradeAllButton">
+          <property name="toolTip">
+           <string>Press to upgrade all listed packages</string>
+          </property>
+          <property name="text">
+           <string>Upgrade &amp;All</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="uninstallButton">
+          <property name="toolTip">
+           <string>Press to uninstall the selected package</string>
+          </property>
+          <property name="text">
+           <string>&amp;Uninstall</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QToolButton" name="searchToggleButton">
+          <property name="toolTip">
+           <string>Toggle to show or hide the search window</string>
+          </property>
+          <property name="checkable">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QWidget" name="searchWidget" native="true">
+     <layout class="QVBoxLayout" name="verticalLayout_2">
+      <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_4">
+        <item>
+         <widget class="QLineEdit" name="searchEdit">
+          <property name="toolTip">
+           <string>Enter the search term</string>
+          </property>
+          <property name="placeholderText">
+           <string>Enter 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>&amp;Search</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <widget class="QWidget" name="searchOptionsWidget" native="true">
+        <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>
+        </layout>
+       </widget>
+      </item>
+      <item>
+       <widget class="QTreeWidget" name="searchResultList">
+        <property name="alternatingRowColors">
+         <bool>true</bool>
+        </property>
+        <property name="selectionMode">
+         <enum>QAbstractItemView::ExtendedSelection</enum>
+        </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="searchInfoLabel"/>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_3">
+        <item>
+         <spacer name="horizontalSpacer_3">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QPushButton" name="installButton">
+          <property name="toolTip">
+           <string>Press to install the selected package</string>
+          </property>
+          <property name="text">
+           <string>&amp;Install</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="installUserSiteButton">
+          <property name="toolTip">
+           <string>Press to install the selected package to the user site</string>
+          </property>
+          <property name="text">
+           <string>Install to &amp;User-Site</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="showDetailsButton">
+          <property name="toolTip">
+           <string>Press to show details for the selected entry</string>
+          </property>
+          <property name="text">
+           <string>Show Details...</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_4">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>E5ToolButton</class>
+   <extends>QToolButton</extends>
+   <header>E5Gui/E5ToolButton.h</header>
+  </customwidget>
+ </customwidgets>
+ <tabstops>
+  <tabstop>environmentsComboBox</tabstop>
+  <tabstop>pipMenuButton</tabstop>
+  <tabstop>packagesList</tabstop>
+  <tabstop>refreshButton</tabstop>
+  <tabstop>upgradeButton</tabstop>
+  <tabstop>upgradeAllButton</tabstop>
+  <tabstop>uninstallButton</tabstop>
+  <tabstop>searchToggleButton</tabstop>
+  <tabstop>searchEdit</tabstop>
+  <tabstop>searchButton</tabstop>
+  <tabstop>searchResultList</tabstop>
+  <tabstop>installButton</tabstop>
+  <tabstop>showDetailsButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
--- a/Preferences/ConfigurationPages/InterfacePage.py	Mon Feb 18 19:17:04 2019 +0100
+++ b/Preferences/ConfigurationPages/InterfacePage.py	Mon Feb 18 19:49:43 2019 +0100
@@ -102,6 +102,7 @@
         # right side
         self.codeDocumentationViewerCheckBox.setChecked(
             Preferences.getUI("ShowCodeDocumentationViewer"))
+        # TODO: add entry for "ShowPyPIPackageManager"
         self.condaCheckBox.setChecked(
             Preferences.getUI("ShowCondaPackageManager"))
         self.cooperationCheckBox.setChecked(
@@ -201,6 +202,7 @@
         Preferences.setUI(
             "ShowCodeDocumentationViewer",
             self.codeDocumentationViewerCheckBox.isChecked())
+        # TODO: add entry for "ShowPyPIPackageManager"
         Preferences.setUI(
             "ShowCondaPackageManager",
             self.condaCheckBox.isChecked())
--- a/Preferences/__init__.py	Mon Feb 18 19:17:04 2019 +0100
+++ b/Preferences/__init__.py	Mon Feb 18 19:49:43 2019 +0100
@@ -171,6 +171,7 @@
         "ShowFileBrowser": True,                # left side
         "ShowSymbolsViewer": True,              # left side
         "ShowCodeDocumentationViewer": True,    # right side
+        "ShowPyPIPackageManager": True,         # right side
         "ShowCondaPackageManager": True,        # right side
         "ShowCooperation": True,                # right side
         "ShowIrc": True,                        # right side
@@ -1996,10 +1997,10 @@
                "LayoutShellEmbedded", "LayoutFileBrowserEmbedded",
                "CheckErrorLog", "NotificationsEnabled", "DynamicOnlineCheck",
                "OpenCrashSessionOnStartup", "CrashSessionEnabled",
-               "ShowCodeDocumentationViewer", "ShowCondaPackageManager",
-               "ShowCooperation", "ShowIrc", "ShowTemplateViewer",
-               "ShowFileBrowser", "ShowSymbolsViewer", "ShowNumbersViewer",
-               "UseNativeMenuBar"]:
+               "ShowCodeDocumentationViewer", "ShowPyPIPackageManager",
+               "ShowCondaPackageManager", "ShowCooperation", "ShowIrc",
+               "ShowTemplateViewer", "ShowFileBrowser", "ShowSymbolsViewer",
+               "ShowNumbersViewer", "UseNativeMenuBar"]:
         return toBool(prefClass.settings.value(
             "UI/" + key, prefClass.uiDefaults[key]))
     elif key in ["TabViewManagerFilenameLength", "CaptionFilenameLength",
--- a/UI/UserInterface.py	Mon Feb 18 19:17:04 2019 +0100
+++ b/UI/UserInterface.py	Mon Feb 18 19:49:43 2019 +0100
@@ -253,6 +253,7 @@
         # Generate an empty project object and multi project object
         from Project.Project import Project
         self.project = Project(self)
+        e5App().registerObject("Project", self.project)
         
         from MultiProject.MultiProject import MultiProject
         self.multiProject = MultiProject(self.project, self)
@@ -578,7 +579,6 @@
         e5App().registerObject("DebugServer", debugServer)
         e5App().registerObject("BackgroundService", self.backgroundService)
         e5App().registerObject("ViewManager", self.viewmanager)
-        e5App().registerObject("Project", self.project)
         e5App().registerObject("ProjectBrowser", self.projectBrowser)
         e5App().registerObject("MultiProject", self.multiProject)
         e5App().registerObject("TaskViewer", self.taskViewer)
@@ -840,6 +840,15 @@
                               UI.PixmapCache.getIcon("debugViewer.png"),
                               self.tr("Debug-Viewer"))
         
+        if Preferences.getUI("ShowPyPIPackageManager"):
+            # Create the PyPI package manager
+            logging.debug("Creating PyPI Package Manager...")
+            from PipInterface.PipPackagesWidget import PipPackagesWidget
+            self.pipWidget = PipPackagesWidget()
+            self.rToolbox.addItem(self.pipWidget,
+                                  UI.PixmapCache.getIcon("pypi"),
+                                  self.tr("PyPI"))
+        
         if Preferences.getUI("ShowCondaPackageManager"):
             # Create the conda package manager
             logging.debug("Creating Conda Package Manager...")
@@ -848,7 +857,7 @@
             self.rToolbox.addItem(self.condaWidget,
                                   UI.PixmapCache.getIcon("miniconda.png"),
                                   self.tr("Conda"))
-
+        
         if Preferences.getUI("ShowCooperation"):
             # Create the chat part of the user interface
             logging.debug("Creating Chat Widget...")
@@ -990,6 +999,15 @@
             self.debugViewer, UI.PixmapCache.getIcon("debugViewer.png"),
             self.tr("Debug-Viewer"))
 
+        if Preferences.getUI("ShowPyPIPackageManager"):
+            # Create the PyPI package manager
+            logging.debug("Creating PyPI Package Manager...")
+            from PipInterface.PipPackagesWidget import PipPackagesWidget
+            self.pipWidget = PipPackagesWidget()
+            self.rightSidebar.addTab(
+                self.pipWidget, UI.PixmapCache.getIcon("pypi"),
+                self.tr("PyPI"))
+        
         if Preferences.getUI("ShowCondaPackageManager"):
             # Create the conda package manager
             logging.debug("Creating Conda Package Manager...")
--- a/eric6.e4p	Mon Feb 18 19:17:04 2019 +0100
+++ b/eric6.e4p	Mon Feb 18 19:49:43 2019 +0100
@@ -478,6 +478,7 @@
     <Source>PipInterface/PipListDialog.py</Source>
     <Source>PipInterface/PipPackageDetailsDialog.py</Source>
     <Source>PipInterface/PipPackagesInputDialog.py</Source>
+    <Source>PipInterface/PipPackagesWidget.py</Source>
     <Source>PipInterface/PipSearchDialog.py</Source>
     <Source>PipInterface/PipSelectionDialog.py</Source>
     <Source>PipInterface/__init__.py</Source>
@@ -1830,6 +1831,7 @@
     <Form>PipInterface/PipListDialog.ui</Form>
     <Form>PipInterface/PipPackageDetailsDialog.ui</Form>
     <Form>PipInterface/PipPackagesInputDialog.ui</Form>
+    <Form>PipInterface/PipPackagesWidget.ui</Form>
     <Form>PipInterface/PipSearchDialog.ui</Form>
     <Form>PipInterface/PipSelectionDialog.ui</Form>
     <Form>PluginManager/PluginDetailsDialog.ui</Form>
@@ -2260,14 +2262,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>

eric ide

mercurial