eric7/VirtualEnv/VirtualenvManagerWidgets.py

branch
eric7
changeset 8610
c9cd21bcbe33
child 8611
0b1a09e47e98
equal deleted inserted replaced
8609:fd6b68a0a2df 8610:c9cd21bcbe33
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2018 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a dialog to manage the list of defined virtual
8 environments.
9 """
10
11 from PyQt6.QtCore import pyqtSlot, Qt
12 from PyQt6.QtWidgets import (
13 QWidget, QDialog, QDialogButtonBox, QTreeWidgetItem, QHeaderView,
14 QVBoxLayout
15 )
16
17 from EricWidgets.EricPathPicker import EricPathPickerModes
18
19 from .Ui_VirtualenvManagerWidget import Ui_VirtualenvManagerWidget
20
21 import Utilities
22 import UI.PixmapCache
23
24
25 class VirtualenvManagerWidget(QWidget, Ui_VirtualenvManagerWidget):
26 """
27 Class implementing a widget to manage the list of defined virtual
28 environments.
29 """
30 IsGlobalRole = Qt.ItemDataRole.UserRole + 1
31 IsCondaRole = Qt.ItemDataRole.UserRole + 2
32 IsRemoteRole = Qt.ItemDataRole.UserRole + 3
33 ExecPathRole = Qt.ItemDataRole.UserRole + 4
34
35 def __init__(self, manager, parent=None):
36 """
37 Constructor
38
39 @param manager reference to the virtual environment manager
40 @type VirtualenvManager
41 @param parent reference to the parent widget
42 @type QWidget
43 """
44 super().__init__(parent)
45 self.setupUi(self)
46
47 self.__manager = manager
48
49 self.addButton.setIcon(UI.PixmapCache.getIcon("plus"))
50 self.newButton.setIcon(UI.PixmapCache.getIcon("new"))
51 self.editButton.setIcon(UI.PixmapCache.getIcon("edit"))
52 self.removeButton.setIcon(UI.PixmapCache.getIcon("minus"))
53 self.removeAllButton.setIcon(UI.PixmapCache.getIcon("minus_3"))
54 self.deleteButton.setIcon(UI.PixmapCache.getIcon("fileDelete"))
55 self.deleteAllButton.setIcon(UI.PixmapCache.getIcon("fileDeleteList"))
56 self.saveButton.setIcon(UI.PixmapCache.getIcon("fileSave"))
57
58 baseDir = self.__manager.getVirtualEnvironmentsBaseDir()
59 if not baseDir:
60 baseDir = Utilities.getHomeDir()
61
62 self.envBaseDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
63 self.envBaseDirectoryPicker.setWindowTitle(
64 self.tr("Virtualenv Base Directory"))
65 self.envBaseDirectoryPicker.setText(baseDir)
66
67 self.__populateVenvList()
68 self.__updateButtons()
69
70 self.venvList.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder)
71
72 self.__manager.virtualEnvironmentsListChanged.connect(self.__refresh)
73
74 def __updateButtons(self):
75 """
76 Private method to update the enabled state of the various buttons.
77 """
78 selectedItemsCount = len(self.venvList.selectedItems())
79 topLevelItemCount = self.venvList.topLevelItemCount()
80
81 deletableSelectedItemCount = 0
82 for itm in self.venvList.selectedItems():
83 if (
84 itm.text(0) != "<default>" and
85 bool(itm.text(1)) and
86 not itm.data(0, VirtualenvManagerWidget.IsGlobalRole) and
87 not itm.data(0, VirtualenvManagerWidget.IsRemoteRole)
88 ):
89 deletableSelectedItemCount += 1
90
91 deletableItemCount = 0
92 for index in range(topLevelItemCount):
93 itm = self.venvList.topLevelItem(index)
94 if (
95 itm.text(0) != "<default>" and
96 bool(itm.text(1)) and
97 not itm.data(0, VirtualenvManagerWidget.IsRemoteRole)
98 ):
99 deletableItemCount += 1
100
101 canBeRemoved = (
102 selectedItemsCount == 1 and
103 self.venvList.selectedItems()[0].text(0) != "<default>"
104 )
105 canAllBeRemoved = (
106 topLevelItemCount == 1 and
107 self.venvList.topLevelItem(0).text(0) != "<default>"
108 )
109
110 self.editButton.setEnabled(selectedItemsCount == 1)
111
112 self.removeButton.setEnabled(selectedItemsCount > 1 or canBeRemoved)
113 self.removeAllButton.setEnabled(
114 topLevelItemCount > 1 or canAllBeRemoved)
115
116 self.deleteButton.setEnabled(deletableSelectedItemCount)
117 self.deleteAllButton.setEnabled(deletableItemCount)
118
119 @pyqtSlot()
120 def on_addButton_clicked(self):
121 """
122 Private slot to add a new entry.
123 """
124 from .VirtualenvAddEditDialog import VirtualenvAddEditDialog
125 dlg = VirtualenvAddEditDialog(
126 self.__manager,
127 baseDir=self.envBaseDirectoryPicker.text()
128 )
129 if dlg.exec() == QDialog.DialogCode.Accepted:
130 (venvName, venvDirectory, venvInterpreter, isGlobal, isConda,
131 isRemote, execPath) = dlg.getData()
132
133 self.__manager.addVirtualEnv(
134 venvName, venvDirectory, venvInterpreter, isGlobal, isConda,
135 isRemote, execPath)
136
137 @pyqtSlot()
138 def on_newButton_clicked(self):
139 """
140 Private slot to create a new virtual environment.
141 """
142 self.__manager.createVirtualEnv(
143 baseDir=self.envBaseDirectoryPicker.text())
144
145 @pyqtSlot()
146 def on_editButton_clicked(self):
147 """
148 Private slot to edit the selected entry.
149 """
150 selectedItem = self.venvList.selectedItems()[0]
151 oldVenvName = selectedItem.text(0)
152
153 from .VirtualenvAddEditDialog import VirtualenvAddEditDialog
154 dlg = VirtualenvAddEditDialog(
155 self.__manager, selectedItem.text(0),
156 selectedItem.text(1), selectedItem.text(2),
157 selectedItem.data(0, VirtualenvManagerWidget.IsGlobalRole),
158 selectedItem.data(0, VirtualenvManagerWidget.IsCondaRole),
159 selectedItem.data(0, VirtualenvManagerWidget.IsRemoteRole),
160 selectedItem.data(0, VirtualenvManagerWidget.ExecPathRole),
161 baseDir=self.envBaseDirectoryPicker.text()
162 )
163 if dlg.exec() == QDialog.DialogCode.Accepted:
164 (venvName, venvDirectory, venvInterpreter, isGlobal, isConda,
165 isRemote, execPath) = dlg.getData()
166 if venvName != oldVenvName:
167 self.__manager.renameVirtualEnv(
168 oldVenvName, venvName, venvDirectory, venvInterpreter,
169 isGlobal, isConda, isRemote, execPath)
170 else:
171 self.__manager.setVirtualEnv(
172 venvName, venvDirectory, venvInterpreter, isGlobal,
173 isConda, isRemote, execPath)
174
175 @pyqtSlot()
176 def on_removeButton_clicked(self):
177 """
178 Private slot to remove all selected entries from the list but keep
179 their directories.
180 """
181 selectedVenvs = []
182 for itm in self.venvList.selectedItems():
183 selectedVenvs.append(itm.text(0))
184
185 if selectedVenvs:
186 self.__manager.removeVirtualEnvs(selectedVenvs)
187
188 @pyqtSlot()
189 def on_removeAllButton_clicked(self):
190 """
191 Private slot to remove all entries from the list but keep their
192 directories.
193 """
194 venvNames = []
195 for index in range(self.venvList.topLevelItemCount()):
196 itm = self.venvList.topLevelItem(index)
197 venvNames.append(itm.text(0))
198
199 if venvNames:
200 self.__manager.removeVirtualEnvs(venvNames)
201
202 @pyqtSlot()
203 def on_deleteButton_clicked(self):
204 """
205 Private slot to delete all selected entries from the list and disk.
206 """
207 selectedVenvs = []
208 for itm in self.venvList.selectedItems():
209 selectedVenvs.append(itm.text(0))
210
211 if selectedVenvs:
212 self.__manager.deleteVirtualEnvs(selectedVenvs)
213
214 @pyqtSlot()
215 def on_deleteAllButton_clicked(self):
216 """
217 Private slot to delete all entries from the list and disk.
218 """
219 venvNames = []
220 for index in range(self.venvList.topLevelItemCount()):
221 itm = self.venvList.topLevelItem(index)
222 venvNames.append(itm.text(0))
223
224 if venvNames:
225 self.__manager.deleteVirtualEnvs(venvNames)
226
227 @pyqtSlot()
228 def on_venvList_itemSelectionChanged(self):
229 """
230 Private slot handling a change of the selected items.
231 """
232 self.__updateButtons()
233
234 @pyqtSlot()
235 def __refresh(self):
236 """
237 Private slot to refresh the list of shown items.
238 """
239 # 1. remember selected entries
240 selectedVenvs = []
241 for itm in self.venvList.selectedItems():
242 selectedVenvs.append(itm.text(0))
243
244 # 2. clear the list
245 self.venvList.clear()
246
247 # 3. re-populate the list
248 self.__populateVenvList()
249
250 # 4. re-establish selection
251 for venvName in selectedVenvs:
252 itms = self.venvList.findItems(
253 venvName, Qt.MatchFlag.MatchExactly, 0)
254 if itms:
255 itms[0].setSelected(True)
256
257 def __populateVenvList(self):
258 """
259 Private method to populate the list of virtual environments.
260 """
261 environments = self.__manager.getEnvironmentEntries()
262 for venvName in environments:
263 itm = QTreeWidgetItem(self.venvList, [
264 venvName,
265 environments[venvName]["path"],
266 environments[venvName]["interpreter"],
267 ])
268 itm.setData(0, VirtualenvManagerWidget.IsGlobalRole,
269 environments[venvName]["is_global"])
270 itm.setData(0, VirtualenvManagerWidget.IsCondaRole,
271 environments[venvName]["is_conda"])
272 itm.setData(0, VirtualenvManagerWidget.IsRemoteRole,
273 environments[venvName]["is_remote"])
274 itm.setData(0, VirtualenvManagerWidget.ExecPathRole,
275 environments[venvName]["exec_path"])
276
277 # show remote environments with underlined font
278 if environments[venvName]["is_remote"]:
279 font = itm.font(0)
280 font.setUnderline(True)
281 for column in range(itm.columnCount()):
282 itm.setFont(column, font)
283 else:
284 # local environments
285
286 # show global environments with bold font
287 if environments[venvName]["is_global"]:
288 font = itm.font(0)
289 font.setBold(True)
290 for column in range(itm.columnCount()):
291 itm.setFont(column, font)
292
293 # show Anaconda environments with italic font
294 if environments[venvName]["is_conda"]:
295 font = itm.font(0)
296 font.setItalic(True)
297 for column in range(itm.columnCount()):
298 itm.setFont(column, font)
299
300 self.__resizeSections()
301
302 def __resizeSections(self):
303 """
304 Private method to resize the sections of the environment list to their
305 contents.
306 """
307 self.venvList.header().resizeSections(
308 QHeaderView.ResizeMode.ResizeToContents)
309 self.venvList.header().setStretchLastSection(True)
310
311 @pyqtSlot()
312 def on_saveButton_clicked(self):
313 """
314 Private slot to save the base directory name.
315 """
316 baseDir = self.envBaseDirectoryPicker.text()
317 self.__manager.setVirtualEnvironmentsBaseDir(baseDir)
318
319
320 class VirtualenvManagerDialog(QDialog):
321 """
322 Class implementing the virtual environments manager dialog variant.
323 """
324 def __init__(self, manager, parent=None):
325 """
326 Constructor
327
328 @param manager reference to the virtual environment manager
329 @type VirtualenvManager
330 @param parent reference to the parent widget
331 @type QWidget
332 """
333 super().__init__(parent)
334 self.setSizeGripEnabled(True)
335
336 self.__layout = QVBoxLayout(self)
337 self.setLayout(self.__layout)
338
339 self.cw = VirtualenvManagerWidget(manager, self)
340 self.__layout.addWidget(self.cw)
341
342 self.buttonBox = QDialogButtonBox(
343 QDialogButtonBox.StandardButton.Close,
344 Qt.Orientation.Horizontal,
345 self)
346 self.__layout.addWidget(self.buttonBox)
347
348 self.resize(700, 500)
349 self.setWindowTitle(self.tr("Manage Virtual Environments"))
350
351 self.buttonBox.accepted.connect(self.accept)
352 self.buttonBox.rejected.connect(self.reject)
353
354 # TODO: add a VirtualenvManagerWindow class and am associated script

eric ide

mercurial