src/eric7/PipInterface/PipPackagesWidget.py

branch
eric7-maintenance
changeset 9654
7328efba128b
parent 9549
67295777d9fe
parent 9653
e67609152c5e
child 9725
b9a29a7aa820
equal deleted inserted replaced
9555:88f10deec960 9654:7328efba128b
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 2
3 # Copyright (c) 2019 - 2022 Detlev Offenbach <detlev@die-offenbachs.de> 3 # Copyright (c) 2019 - 2023 Detlev Offenbach <detlev@die-offenbachs.de>
4 # 4 #
5 5
6 """ 6 """
7 Module implementing the pip packages management widget. 7 Module implementing the pip packages management widget.
8 """ 8 """
199 self.refreshButton.setIcon(EricPixmapCache.getIcon("reload")) 199 self.refreshButton.setIcon(EricPixmapCache.getIcon("reload"))
200 self.upgradeButton.setIcon(EricPixmapCache.getIcon("1uparrow")) 200 self.upgradeButton.setIcon(EricPixmapCache.getIcon("1uparrow"))
201 self.upgradeAllButton.setIcon(EricPixmapCache.getIcon("2uparrow")) 201 self.upgradeAllButton.setIcon(EricPixmapCache.getIcon("2uparrow"))
202 self.uninstallButton.setIcon(EricPixmapCache.getIcon("minus")) 202 self.uninstallButton.setIcon(EricPixmapCache.getIcon("minus"))
203 self.showPackageDetailsButton.setIcon(EricPixmapCache.getIcon("info")) 203 self.showPackageDetailsButton.setIcon(EricPixmapCache.getIcon("info"))
204 self.searchToggleButton.setIcon(EricPixmapCache.getIcon("find")) 204 self.searchToggleButton_1.setIcon(EricPixmapCache.getIcon("find"))
205 self.searchToggleButton_2.setIcon(EricPixmapCache.getIcon("find"))
205 self.searchButton.setIcon(EricPixmapCache.getIcon("findNext")) 206 self.searchButton.setIcon(EricPixmapCache.getIcon("findNext"))
206 self.searchMoreButton.setIcon(EricPixmapCache.getIcon("plus")) 207 self.searchMoreButton.setIcon(EricPixmapCache.getIcon("plus"))
207 self.installButton.setIcon(EricPixmapCache.getIcon("plus")) 208 self.installButton.setIcon(EricPixmapCache.getIcon("plus"))
208 self.installUserSiteButton.setIcon(EricPixmapCache.getIcon("addUser")) 209 self.installUserSiteButton.setIcon(EricPixmapCache.getIcon("addUser"))
209 self.showDetailsButton.setIcon(EricPixmapCache.getIcon("info")) 210 self.showDetailsButton.setIcon(EricPixmapCache.getIcon("info"))
480 @type str 481 @type str
481 """ 482 """
482 if name != self.__selectedEnvironment: 483 if name != self.__selectedEnvironment:
483 if not name: 484 if not name:
484 self.environmentPathLabel.setPath("") 485 self.environmentPathLabel.setPath("")
486 self.searchNameEdit.clear()
487 self.searchNameEdit.setEnabled(False)
485 else: 488 else:
486 self.environmentPathLabel.setPath( 489 self.environmentPathLabel.setPath(
487 self.__pip.getVirtualenvInterpreter(name) 490 self.__pip.getVirtualenvInterpreter(name)
488 ) 491 )
492 self.searchNameEdit.setEnabled(True)
489 493
490 if self.viewToggleButton.isChecked(): 494 if self.viewToggleButton.isChecked():
491 self.__refreshDependencyTree() 495 self.__refreshDependencyTree()
492 else: 496 else:
493 self.__refreshPackagesList() 497 self.__refreshPackagesList()
540 544
541 if success and output: 545 if success and output:
542 mode = self.ShowProcessGeneralMode 546 mode = self.ShowProcessGeneralMode
543 for line in output.splitlines(): 547 for line in output.splitlines():
544 line = line.rstrip() 548 line = line.rstrip()
545 if line != "---": 549 if line and line != "---":
546 if mode != self.ShowProcessGeneralMode: 550 if mode != self.ShowProcessGeneralMode:
547 if line[0] == " ": 551 if line[0] == " ":
548 QTreeWidgetItem(infoWidget, [" ", line.strip()]) 552 QTreeWidgetItem(infoWidget, [" ", line.strip()])
549 else: 553 else:
550 mode = self.ShowProcessGeneralMode 554 mode = self.ShowProcessGeneralMode
789 def __updateSearchButton(self): 793 def __updateSearchButton(self):
790 """ 794 """
791 Private method to update the state of the search button. 795 Private method to update the state of the search button.
792 """ 796 """
793 self.searchButton.setEnabled( 797 self.searchButton.setEnabled(
794 bool(self.searchEditName.text()) and self.__isPipAvailable() 798 bool(self.searchNameEdit.text()) and self.__isPipAvailable()
795 ) 799 )
796 800
797 def __updateSearchMoreButton(self, enable): 801 def __updateSearchMoreButton(self, enable):
798 """ 802 """
799 Private method to update the state of the search more button. 803 Private method to update the state of the search more button.
800 804
801 @param enable flag indicating the desired enable state 805 @param enable flag indicating the desired enable state
802 @type bool 806 @type bool
803 """ 807 """
804 self.searchMoreButton.setEnabled( 808 self.searchMoreButton.setEnabled(
805 enable and bool(self.searchEditName.text()) and self.__isPipAvailable() 809 enable and bool(self.searchNameEdit.text()) and self.__isPipAvailable()
806 ) 810 )
807 811
808 @pyqtSlot(bool) 812 @pyqtSlot(bool)
809 def on_searchToggleButton_toggled(self, checked): 813 def on_searchToggleButton_1_toggled(self, checked):
810 """ 814 """
811 Private slot to togle the search widget. 815 Private slot to toggle the search widget.
812 816
813 @param checked state of the search widget button 817 @param checked state of the search widget button
814 @type bool 818 @type bool
815 """ 819 """
816 self.searchWidget.setVisible(checked) 820 self.searchWidget.setVisible(checked)
821 self.searchToggleButton_2.setChecked(checked)
817 822
818 if checked: 823 if checked:
819 self.searchEditName.setFocus(Qt.FocusReason.OtherFocusReason) 824 self.searchNameEdit.setFocus(Qt.FocusReason.OtherFocusReason)
820 self.searchEditName.selectAll() 825 self.searchNameEdit.selectAll()
821 826
822 self.__updateSearchActionButtons() 827 self.__updateSearchActionButtons()
823 self.__updateSearchButton() 828 self.__updateSearchButton()
824 self.__updateSearchMoreButton(False) 829 self.__updateSearchMoreButton(False)
825 830
831 @pyqtSlot(bool)
832 def on_searchToggleButton_2_toggled(self, checked):
833 """
834 Private slot to toggle the search widget.
835
836 @param checked state of the search widget button
837 @type bool
838 """
839 self.searchToggleButton_1.setChecked(checked)
840
826 @pyqtSlot(str) 841 @pyqtSlot(str)
827 def on_searchEditName_textChanged(self, txt): 842 def on_searchNameEdit_textChanged(self, txt):
828 """ 843 """
829 Private slot handling a change of the search term. 844 Private slot handling a change of the search term.
830 845
831 @param txt search term 846 @param txt search term
832 @type str 847 @type str
833 """ 848 """
834 self.__updateSearchButton() 849 self.__updateSearchButton()
835 850
836 @pyqtSlot() 851 @pyqtSlot()
837 def on_searchEditName_returnPressed(self): 852 def on_searchNameEdit_returnPressed(self):
838 """ 853 """
839 Private slot initiating a search via a press of the Return key. 854 Private slot initiating a search via a press of the Return key.
840 """ 855 """
841 if bool(self.searchEditName.text()) and self.__isPipAvailable(): 856 if bool(self.searchNameEdit.text()) and self.__isPipAvailable():
842 self.__searchFirst() 857 self.__searchFirst()
843 858
844 @pyqtSlot() 859 @pyqtSlot()
845 def on_searchButton_clicked(self): 860 def on_searchButton_clicked(self):
846 """ 861 """
882 """ 897 """
883 self.__lastSearchPage = page 898 self.__lastSearchPage = page
884 899
885 self.searchButton.setEnabled(False) 900 self.searchButton.setEnabled(False)
886 901
887 searchTerm = self.searchEditName.text().strip() 902 searchTerm = self.searchNameEdit.text().strip()
888 searchTerm = bytes(QUrl.toPercentEncoding(searchTerm)).decode() 903 searchTerm = bytes(QUrl.toPercentEncoding(searchTerm)).decode()
889 urlQuery = QUrlQuery() 904 urlQuery = QUrlQuery()
890 urlQuery.addQueryItem("q", searchTerm) 905 urlQuery.addQueryItem("q", searchTerm)
891 urlQuery.addQueryItem("page", str(page)) 906 urlQuery.addQueryItem("page", str(page))
892 url = QUrl(self.__pip.getIndexUrlSearch()) 907 url = QUrl(self.__pip.getIndexUrlSearch())
966 else: 981 else:
967 EricMessageBox.warning( 982 EricMessageBox.warning(
968 self, 983 self,
969 self.tr("Search PyPI"), 984 self.tr("Search PyPI"),
970 self.tr( 985 self.tr(
971 """<p>There were no more results for""" """ <b>{0}</b>.</p>""" 986 """<p>There were no more results for <b>{0}</b>.</p>"""
972 ).format(searchTerm), 987 ).format(searchTerm),
973 ) 988 )
974 lastItem = None 989 lastItem = None
975 990
976 wrapper = textwrap.TextWrapper(width=80) 991 wrapper = textwrap.TextWrapper(width=80)
1017 Private slot performing the search finishing actions. 1032 Private slot performing the search finishing actions.
1018 """ 1033 """
1019 self.__updateSearchActionButtons() 1034 self.__updateSearchActionButtons()
1020 self.__updateSearchButton() 1035 self.__updateSearchButton()
1021 1036
1022 self.searchEditName.setFocus(Qt.FocusReason.OtherFocusReason) 1037 self.searchNameEdit.setFocus(Qt.FocusReason.OtherFocusReason)
1023 1038
1024 @pyqtSlot() 1039 @pyqtSlot()
1025 def on_installButton_clicked(self): 1040 def on_installButton_clicked(self):
1026 """ 1041 """
1027 Private slot to handle pressing the Install button.. 1042 Private slot to handle pressing the Install button..
1235 self.__showLicensesDialogAct = self.__pipMenu.addAction( 1250 self.__showLicensesDialogAct = self.__pipMenu.addAction(
1236 self.tr("Show Licenses..."), self.__showLicensesDialog 1251 self.tr("Show Licenses..."), self.__showLicensesDialog
1237 ) 1252 )
1238 self.__pipMenu.addSeparator() 1253 self.__pipMenu.addSeparator()
1239 self.__checkVulnerabilityAct = self.__pipMenu.addAction( 1254 self.__checkVulnerabilityAct = self.__pipMenu.addAction(
1240 self.tr("Check Vulnerabilities"), self.__updateVulnerabilityData 1255 self.tr("Check Vulnerabilities"), self.__checkVulnerability
1241 ) 1256 )
1242 # updateVulnerabilityDbAct 1257 # updateVulnerabilityDbAct
1243 self.__pipMenu.addAction( 1258 self.__pipMenu.addAction(
1244 self.tr("Update Vulnerability Database"), self.__updateVulnerabilityDbCache 1259 self.tr("Update Vulnerability Database"), self.__updateVulnerabilityDbCache
1245 ) 1260 )
1454 cfgDir = os.path.dirname(cfgFile) 1469 cfgDir = os.path.dirname(cfgFile)
1455 if not cfgDir: 1470 if not cfgDir:
1456 EricMessageBox.critical( 1471 EricMessageBox.critical(
1457 None, 1472 None,
1458 self.tr("Edit Configuration"), 1473 self.tr("Edit Configuration"),
1459 self.tr("""No valid configuration path determined.""" """ Aborting"""), 1474 self.tr("""No valid configuration path determined. Aborting"""),
1460 ) 1475 )
1461 return 1476 return
1462 1477
1463 try: 1478 try:
1464 if not os.path.isdir(cfgDir): 1479 if not os.path.isdir(cfgDir):
1465 os.makedirs(cfgDir) 1480 os.makedirs(cfgDir)
1466 except OSError: 1481 except OSError:
1467 EricMessageBox.critical( 1482 EricMessageBox.critical(
1468 None, 1483 None,
1469 self.tr("Edit Configuration"), 1484 self.tr("Edit Configuration"),
1470 self.tr("""No valid configuration path determined.""" """ Aborting"""), 1485 self.tr("""No valid configuration path determined. Aborting"""),
1471 ) 1486 )
1472 return 1487 return
1473 1488
1474 if not os.path.exists(cfgFile): 1489 if not os.path.exists(cfgFile):
1475 with contextlib.suppress(OSError), open(cfgFile, "w") as f: 1490 with contextlib.suppress(OSError), open(cfgFile, "w") as f:
1478 # check, if the destination is writeable 1493 # check, if the destination is writeable
1479 if not os.access(cfgFile, os.W_OK): 1494 if not os.access(cfgFile, os.W_OK):
1480 EricMessageBox.critical( 1495 EricMessageBox.critical(
1481 None, 1496 None,
1482 self.tr("Edit Configuration"), 1497 self.tr("Edit Configuration"),
1483 self.tr("""No valid configuration path determined.""" """ Aborting"""), 1498 self.tr("""No valid configuration path determined. Aborting"""),
1484 ) 1499 )
1485 return 1500 return
1486 1501
1487 self.__editor = MiniEditor(cfgFile, "Properties") 1502 self.__editor = MiniEditor(cfgFile, "Properties")
1488 self.__editor.show() 1503 self.__editor.show()
1545 self.__updateVulnerabilityData(clearFirst=True) 1560 self.__updateVulnerabilityData(clearFirst=True)
1546 1561
1547 self.packagesList.header().setSectionHidden( 1562 self.packagesList.header().setSectionHidden(
1548 PipPackagesWidget.VulnerabilityColumn, not checked 1563 PipPackagesWidget.VulnerabilityColumn, not checked
1549 ) 1564 )
1565
1566 @pyqtSlot()
1567 def __checkVulnerability(self):
1568 """
1569 Private slot to update and show the vulnerability data (called from the menu).
1570 """
1571 self.vulnerabilityCheckBox.setChecked(True)
1572 self.on_vulnerabilityCheckBox_clicked(True)
1550 1573
1551 @pyqtSlot() 1574 @pyqtSlot()
1552 def __clearVulnerabilityInfo(self): 1575 def __clearVulnerabilityInfo(self):
1553 """ 1576 """
1554 Private slot to clear the vulnerability info. 1577 Private slot to clear the vulnerability info.

eric ide

mercurial