12 from PyQt5.QtCore import pyqtSlot, Qt |
12 from PyQt5.QtCore import pyqtSlot, Qt |
13 from PyQt5.QtGui import QCursor |
13 from PyQt5.QtGui import QCursor |
14 from PyQt5.QtWidgets import QWidget, QToolButton, QMenu, QTreeWidgetItem, \ |
14 from PyQt5.QtWidgets import QWidget, QToolButton, QMenu, QTreeWidgetItem, \ |
15 QApplication |
15 QApplication |
16 |
16 |
|
17 from E5Gui import E5MessageBox |
|
18 |
17 from .Ui_CondaPackagesWidget import Ui_CondaPackagesWidget |
19 from .Ui_CondaPackagesWidget import Ui_CondaPackagesWidget |
18 |
20 |
19 import UI.PixmapCache |
21 import UI.PixmapCache |
|
22 |
|
23 import CondaInterface |
20 |
24 |
21 |
25 |
22 class CondaPackagesWidget(QWidget, Ui_CondaPackagesWidget): |
26 class CondaPackagesWidget(QWidget, Ui_CondaPackagesWidget): |
23 """ |
27 """ |
24 Class implementing the conda packages management widget. |
28 Class implementing the conda packages management widget. |
25 """ |
29 """ |
|
30 # Role definition of packages list |
26 PackageVersionRole = Qt.UserRole + 1 |
31 PackageVersionRole = Qt.UserRole + 1 |
27 PackageBuildRole = Qt.UserRole + 2 |
32 PackageBuildRole = Qt.UserRole + 2 |
|
33 |
|
34 # Role definitions of search results list |
|
35 PackageDetailedDataRole = Qt.UserRole + 1 |
28 |
36 |
29 def __init__(self, conda, parent=None): |
37 def __init__(self, conda, parent=None): |
30 """ |
38 """ |
31 Constructor |
39 Constructor |
32 |
40 |
48 self.condaMenuButton.setToolButtonStyle(Qt.ToolButtonIconOnly) |
56 self.condaMenuButton.setToolButtonStyle(Qt.ToolButtonIconOnly) |
49 self.condaMenuButton.setFocusPolicy(Qt.NoFocus) |
57 self.condaMenuButton.setFocusPolicy(Qt.NoFocus) |
50 self.condaMenuButton.setAutoRaise(True) |
58 self.condaMenuButton.setAutoRaise(True) |
51 self.condaMenuButton.setShowMenuInside(True) |
59 self.condaMenuButton.setShowMenuInside(True) |
52 |
60 |
|
61 self.searchToggleButton.setIcon(UI.PixmapCache.getIcon("find.png")) |
|
62 |
|
63 if CondaInterface.condaVersion() >= (4, 4, 0): |
|
64 self.searchOptionsWidget.hide() |
|
65 else: |
|
66 self.platformComboBox.addItems(sorted([ |
|
67 "", "win-32", "win-64", "osx-64", "linux-32", "linux-64", |
|
68 ])) |
|
69 |
53 self.__initCondaMenu() |
70 self.__initCondaMenu() |
54 self.__populateEnvironments() |
71 self.__populateEnvironments() |
55 self.__updateActionButtons() |
72 self.__updateActionButtons() |
|
73 |
|
74 self.searchWidget.hide() |
56 |
75 |
57 self.__conda.condaEnvironmentCreated.connect( |
76 self.__conda.condaEnvironmentCreated.connect( |
58 self.on_refreshButton_clicked) |
77 self.on_refreshButton_clicked) |
59 self.__conda.condaEnvironmentRemoved.connect( |
78 self.__conda.condaEnvironmentRemoved.connect( |
60 self.on_refreshButton_clicked) |
79 self.on_refreshButton_clicked) |
232 prefix = self.environmentsComboBox.itemData( |
253 prefix = self.environmentsComboBox.itemData( |
233 self.environmentsComboBox.currentIndex()) |
254 self.environmentsComboBox.currentIndex()) |
234 ok = self.__conda.uninstallPackages(packages, prefix=prefix) |
255 ok = self.__conda.uninstallPackages(packages, prefix=prefix) |
235 if ok: |
256 if ok: |
236 self.on_refreshButton_clicked() |
257 self.on_refreshButton_clicked() |
|
258 |
|
259 ####################################################################### |
|
260 ## Search widget related methods below |
|
261 ####################################################################### |
|
262 |
|
263 def __updateSearchActionButtons(self): |
|
264 """ |
|
265 Private method to update the action button states of the search widget. |
|
266 """ |
|
267 enable = len(self.searchResultList.selectedItems()) == 1 |
|
268 self.installButton.setEnabled( |
|
269 enable and self.environmentsComboBox.currentIndex() > 0) |
|
270 self.showDetailsButton.setEnabled( |
|
271 enable and bool(self.searchResultList.selectedItems()[0].parent())) |
|
272 |
|
273 def __doSearch(self): |
|
274 """ |
|
275 Private method to search for packages. |
|
276 """ |
|
277 self.searchResultList.clear() |
|
278 pattern = self.searchEdit.text() |
|
279 if pattern: |
|
280 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) |
|
281 QApplication.processEvents() |
|
282 |
|
283 prefix = self.environmentsComboBox.itemData( |
|
284 self.environmentsComboBox.currentIndex()) |
|
285 ok, result = self.__conda.searchPackages( |
|
286 pattern, |
|
287 fullNameOnly=self.fullNameButton.isChecked(), |
|
288 packageSpec=self.packageSpecButton.isChecked(), |
|
289 platform=self.platformComboBox.currentText(), |
|
290 prefix=prefix, |
|
291 ) |
|
292 |
|
293 if result: |
|
294 if ok: |
|
295 self.searchResultList.setUpdatesEnabled(False) |
|
296 for package in result: |
|
297 itm = QTreeWidgetItem(self.searchResultList, [package]) |
|
298 itm.setExpanded(False) |
|
299 for detail in result[package]: |
|
300 version = detail["version"] |
|
301 build = detail["build"] |
|
302 if "subdir" in detail: |
|
303 platform = detail["subdir"] |
|
304 elif "platform" in detail: |
|
305 platform = detail["platform"] |
|
306 else: |
|
307 platform = "" |
|
308 citm = QTreeWidgetItem( |
|
309 itm, ["", version, build, platform]) |
|
310 citm.setData(0, self.PackageDetailedDataRole, |
|
311 detail) |
|
312 |
|
313 self.searchResultList.sortItems(0, Qt.AscendingOrder) |
|
314 self.searchResultList.resizeColumnToContents(0) |
|
315 self.searchResultList.setUpdatesEnabled(True) |
|
316 else: |
|
317 QApplication.restoreOverrideCursor() |
|
318 try: |
|
319 message = result["message"] |
|
320 except KeyError: |
|
321 message = result["error"] |
|
322 E5MessageBox.warning( |
|
323 self, |
|
324 self.tr("Conda Search Package Error"), |
|
325 message) |
|
326 QApplication.restoreOverrideCursor() |
|
327 |
|
328 def __showDetails(self, item): |
|
329 """ |
|
330 Private method to show a dialog with details about a package item. |
|
331 |
|
332 @param item reference to the package item |
|
333 @type QTreeWidgetItem |
|
334 """ |
|
335 details = item.data(0, self.PackageDetailedDataRole) |
|
336 if details: |
|
337 from .CondaPackageDetailsWidget import CondaPackageDetailsDialog |
|
338 dlg = CondaPackageDetailsDialog(details, self) |
|
339 dlg.show() |
|
340 |
|
341 @pyqtSlot(str) |
|
342 def on_searchEdit_textChanged(self, txt): |
|
343 """ |
|
344 Private slot handling changes of the entered search specification. |
|
345 |
|
346 @param txt current search entry |
|
347 @type str |
|
348 """ |
|
349 self.searchButton.setEnabled(bool(txt)) |
|
350 |
|
351 @pyqtSlot() |
|
352 def on_searchEdit_returnPressed(self): |
|
353 """ |
|
354 Private slot handling the user pressing the Return button in the |
|
355 search edit. |
|
356 """ |
|
357 self.__doSearch() |
|
358 |
|
359 @pyqtSlot() |
|
360 def on_searchButton_clicked(self): |
|
361 """ |
|
362 Private slot handling the press of the search button. |
|
363 """ |
|
364 self.__doSearch() |
|
365 |
|
366 @pyqtSlot() |
|
367 def on_installButton_clicked(self): |
|
368 """ |
|
369 Slot documentation goes here. |
|
370 """ |
|
371 # TODO: not implemented yet |
|
372 raise NotImplementedError |
|
373 |
|
374 @pyqtSlot() |
|
375 def on_showDetailsButton_clicked(self): |
|
376 """ |
|
377 Private slot handling the 'Show Details' button. |
|
378 """ |
|
379 item = self.searchResultList.selectedItems()[0] |
|
380 self.__showDetails(item) |
|
381 |
|
382 @pyqtSlot() |
|
383 def on_searchResultList_itemSelectionChanged(self): |
|
384 """ |
|
385 Private slot handling a change of selected search results. |
|
386 """ |
|
387 self.__updateSearchActionButtons() |
|
388 |
|
389 @pyqtSlot(QTreeWidgetItem) |
|
390 def on_searchResultList_itemExpanded(self, item): |
|
391 """ |
|
392 Private slot handling the expansion of an item. |
|
393 |
|
394 @param item reference to the expanded item |
|
395 @type QTreeWidgetItem |
|
396 """ |
|
397 for col in range(1, self.searchResultList.columnCount()): |
|
398 self.searchResultList.resizeColumnToContents(col) |
|
399 |
|
400 @pyqtSlot(QTreeWidgetItem, int) |
|
401 def on_searchResultList_itemDoubleClicked(self, item, column): |
|
402 """ |
|
403 Private slot handling a double click of an item. |
|
404 |
|
405 @param item reference to the item that was double clicked |
|
406 @type QTreeWidgetItem |
|
407 @param column column of the double click |
|
408 @type int |
|
409 """ |
|
410 if item.parent() is not None: |
|
411 self.__showDetails(item) |
|
412 |
|
413 @pyqtSlot(bool) |
|
414 def on_searchToggleButton_toggled(self, checked): |
|
415 """ |
|
416 Private slot to togle the search widget. |
|
417 |
|
418 @param checked state of the search widget button |
|
419 @type bool |
|
420 """ |
|
421 self.searchWidget.setVisible(checked) |
|
422 |
|
423 if checked: |
|
424 self.searchEdit.setFocus(Qt.OtherFocusReason) |
|
425 self.searchEdit.selectAll() |
|
426 |
|
427 self.__updateSearchActionButtons() |