src/eric7/PipInterface/PipFreezeDialog.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9243
73c7abe824f3
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
8 """ 8 """
9 9
10 import os 10 import os
11 11
12 from PyQt6.QtCore import pyqtSlot, Qt 12 from PyQt6.QtCore import pyqtSlot, Qt
13 from PyQt6.QtWidgets import ( 13 from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton, QApplication
14 QDialog, QDialogButtonBox, QAbstractButton, QApplication
15 )
16 14
17 from EricWidgets import EricMessageBox, EricFileDialog 15 from EricWidgets import EricMessageBox, EricFileDialog
18 from EricWidgets.EricPathPicker import EricPathPickerModes 16 from EricWidgets.EricPathPicker import EricPathPickerModes
19 from EricWidgets.EricApplication import ericApp 17 from EricWidgets.EricApplication import ericApp
20 from EricGui.EricOverrideCursor import EricOverrideCursor 18 from EricGui.EricOverrideCursor import EricOverrideCursor
26 24
27 class PipFreezeDialog(QDialog, Ui_PipFreezeDialog): 25 class PipFreezeDialog(QDialog, Ui_PipFreezeDialog):
28 """ 26 """
29 Class implementing a dialog to generate a requirements file. 27 Class implementing a dialog to generate a requirements file.
30 """ 28 """
29
31 def __init__(self, pip, parent=None): 30 def __init__(self, pip, parent=None):
32 """ 31 """
33 Constructor 32 Constructor
34 33
35 @param pip reference to the master object 34 @param pip reference to the master object
36 @type Pip 35 @type Pip
37 @param parent reference to the parent widget 36 @param parent reference to the parent widget
38 @type QWidget 37 @type QWidget
39 """ 38 """
40 super().__init__(parent) 39 super().__init__(parent)
41 self.setupUi(self) 40 self.setupUi(self)
42 self.setWindowFlags(Qt.WindowType.Window) 41 self.setWindowFlags(Qt.WindowType.Window)
43 42
44 self.__refreshButton = self.buttonBox.addButton( 43 self.__refreshButton = self.buttonBox.addButton(
45 self.tr("&Refresh"), QDialogButtonBox.ButtonRole.ActionRole) 44 self.tr("&Refresh"), QDialogButtonBox.ButtonRole.ActionRole
46 45 )
46
47 self.__environmentName = "" 47 self.__environmentName = ""
48 48
49 self.requirementsFilePicker.setMode(EricPathPickerModes.SAVE_FILE_MODE) 49 self.requirementsFilePicker.setMode(EricPathPickerModes.SAVE_FILE_MODE)
50 self.requirementsFilePicker.setFilters( 50 self.requirementsFilePicker.setFilters(
51 self.tr("Text Files (*.txt);;All Files (*)")) 51 self.tr("Text Files (*.txt);;All Files (*)")
52 52 )
53
53 self.__pip = pip 54 self.__pip = pip
54 55
55 self.__requirementsEdited = False 56 self.__requirementsEdited = False
56 self.__requirementsAvailable = False 57 self.__requirementsAvailable = False
57 58
58 self.__updateButtons() 59 self.__updateButtons()
59 60
60 def closeEvent(self, e): 61 def closeEvent(self, e):
61 """ 62 """
62 Protected slot implementing a close event handler. 63 Protected slot implementing a close event handler.
63 64
64 @param e close event 65 @param e close event
65 @type QCloseEvent 66 @type QCloseEvent
66 """ 67 """
67 e.accept() 68 e.accept()
68 69
69 @pyqtSlot() 70 @pyqtSlot()
70 def on_localCheckBox_clicked(self): 71 def on_localCheckBox_clicked(self):
71 """ 72 """
72 Private slot handling the switching of the local mode. 73 Private slot handling the switching of the local mode.
73 """ 74 """
74 self.__refresh() 75 self.__refresh()
75 76
76 @pyqtSlot() 77 @pyqtSlot()
77 def on_userCheckBox_clicked(self): 78 def on_userCheckBox_clicked(self):
78 """ 79 """
79 Private slot handling the switching of the user-site mode. 80 Private slot handling the switching of the user-site mode.
80 """ 81 """
81 self.__refresh() 82 self.__refresh()
82 83
83 @pyqtSlot(str) 84 @pyqtSlot(str)
84 def on_requirementsFilePicker_textChanged(self, txt): 85 def on_requirementsFilePicker_textChanged(self, txt):
85 """ 86 """
86 Private slot handling a change of the requirements file name. 87 Private slot handling a change of the requirements file name.
87 88
88 @param txt name of the requirements file 89 @param txt name of the requirements file
89 @type str 90 @type str
90 """ 91 """
91 self.__updateButtons() 92 self.__updateButtons()
92 93
93 @pyqtSlot() 94 @pyqtSlot()
94 def on_requirementsEdit_textChanged(self): 95 def on_requirementsEdit_textChanged(self):
95 """ 96 """
96 Private slot handling changes of the requirements text. 97 Private slot handling changes of the requirements text.
97 """ 98 """
98 self.__requirementsEdited = True 99 self.__requirementsEdited = True
99 100
100 @pyqtSlot(QAbstractButton) 101 @pyqtSlot(QAbstractButton)
101 def on_buttonBox_clicked(self, button): 102 def on_buttonBox_clicked(self, button):
102 """ 103 """
103 Private slot called by a button of the button box clicked. 104 Private slot called by a button of the button box clicked.
104 105
105 @param button button that was clicked 106 @param button button that was clicked
106 @type QAbstractButton 107 @type QAbstractButton
107 """ 108 """
108 if button == self.buttonBox.button( 109 if button == self.buttonBox.button(QDialogButtonBox.StandardButton.Close):
109 QDialogButtonBox.StandardButton.Close
110 ):
111 self.close() 110 self.close()
112 elif button == self.__refreshButton: 111 elif button == self.__refreshButton:
113 self.__refresh() 112 self.__refresh()
114 113
115 def __refresh(self): 114 def __refresh(self):
116 """ 115 """
117 Private slot to refresh the displayed list. 116 Private slot to refresh the displayed list.
118 """ 117 """
119 ok = ( 118 ok = (
120 EricMessageBox.yesNo( 119 EricMessageBox.yesNo(
121 self, 120 self,
122 self.tr("Generate Requirements"), 121 self.tr("Generate Requirements"),
123 self.tr("""The requirements were changed. Do you want""" 122 self.tr(
124 """ to overwrite these changes?""")) 123 """The requirements were changed. Do you want"""
125 if self.__requirementsEdited else 124 """ to overwrite these changes?"""
126 True 125 ),
126 )
127 if self.__requirementsEdited
128 else True
127 ) 129 )
128 if ok: 130 if ok:
129 self.start(self.__environmentName) 131 self.start(self.__environmentName)
130 132
131 def start(self, venvName): 133 def start(self, venvName):
132 """ 134 """
133 Public method to start the command. 135 Public method to start the command.
134 136
135 @param venvName name of the environment to act upon 137 @param venvName name of the environment to act upon
136 @type str 138 @type str
137 """ 139 """
138 self.requirementsEdit.clear() 140 self.requirementsEdit.clear()
139 self.__requirementsAvailable = False 141 self.__requirementsAvailable = False
140 self.__environmentName = venvName 142 self.__environmentName = venvName
141 143
142 fileName = ( 144 fileName = (
143 Utilities.toNativeSeparators(self.requirementsFilePicker.text()) 145 Utilities.toNativeSeparators(self.requirementsFilePicker.text())
144 if self.requirementsFilePicker.text() else 146 if self.requirementsFilePicker.text()
145 "" 147 else ""
146 ) 148 )
147 149
148 with EricOverrideCursor(): 150 with EricOverrideCursor():
149 specifiers = self.__pip.getFrozenPackages( 151 specifiers = self.__pip.getFrozenPackages(
150 venvName, localPackages=self.localCheckBox.isChecked(), 152 venvName,
151 usersite=self.userCheckBox.isChecked(), requirement=fileName) 153 localPackages=self.localCheckBox.isChecked(),
152 154 usersite=self.userCheckBox.isChecked(),
155 requirement=fileName,
156 )
157
153 if specifiers: 158 if specifiers:
154 self.requirementsEdit.setPlainText( 159 self.requirementsEdit.setPlainText("\n".join(specifiers) + "\n")
155 "\n".join(specifiers) + "\n")
156 self.__requirementsAvailable = True 160 self.__requirementsAvailable = True
157 else: 161 else:
158 self.requirementsEdit.setPlainText(self.tr( 162 self.requirementsEdit.setPlainText(
159 "No package specifiers generated by 'pip freeze'.") 163 self.tr("No package specifiers generated by 'pip freeze'.")
160 ) 164 )
161 165
162 self.__updateButtons() 166 self.__updateButtons()
163 167
164 self.__requirementsEdited = False 168 self.__requirementsEdited = False
165 169
166 def __updateButtons(self): 170 def __updateButtons(self):
167 """ 171 """
168 Private method to set the state of the various buttons. 172 Private method to set the state of the various buttons.
169 """ 173 """
170 self.saveButton.setEnabled( 174 self.saveButton.setEnabled(
171 self.__requirementsAvailable and 175 self.__requirementsAvailable and bool(self.requirementsFilePicker.text())
172 bool(self.requirementsFilePicker.text())
173 ) 176 )
174 self.saveToButton.setEnabled(self.__requirementsAvailable) 177 self.saveToButton.setEnabled(self.__requirementsAvailable)
175 self.copyButton.setEnabled(self.__requirementsAvailable) 178 self.copyButton.setEnabled(self.__requirementsAvailable)
176 179
177 aw = ericApp().getObject("ViewManager").activeWindow() 180 aw = ericApp().getObject("ViewManager").activeWindow()
178 if aw and self.__requirementsAvailable: 181 if aw and self.__requirementsAvailable:
179 self.insertButton.setEnabled(True) 182 self.insertButton.setEnabled(True)
180 self.replaceAllButton.setEnabled(True) 183 self.replaceAllButton.setEnabled(True)
181 self.replaceSelectionButton.setEnabled( 184 self.replaceSelectionButton.setEnabled(aw.hasSelectedText())
182 aw.hasSelectedText())
183 else: 185 else:
184 self.insertButton.setEnabled(False) 186 self.insertButton.setEnabled(False)
185 self.replaceAllButton.setEnabled(False) 187 self.replaceAllButton.setEnabled(False)
186 self.replaceSelectionButton.setEnabled(False) 188 self.replaceSelectionButton.setEnabled(False)
187 189
188 def __writeToFile(self, fileName): 190 def __writeToFile(self, fileName):
189 """ 191 """
190 Private method to write the requirements text to a file. 192 Private method to write the requirements text to a file.
191 193
192 @param fileName name of the file to write to 194 @param fileName name of the file to write to
193 @type str 195 @type str
194 """ 196 """
195 if os.path.exists(fileName): 197 if os.path.exists(fileName):
196 ok = EricMessageBox.warning( 198 ok = EricMessageBox.warning(
197 self, 199 self,
198 self.tr("Generate Requirements"), 200 self.tr("Generate Requirements"),
199 self.tr("""The file <b>{0}</b> already exists. Do you want""" 201 self.tr(
200 """ to overwrite it?""").format(fileName)) 202 """The file <b>{0}</b> already exists. Do you want"""
203 """ to overwrite it?"""
204 ).format(fileName),
205 )
201 if not ok: 206 if not ok:
202 return 207 return
203 208
204 try: 209 try:
205 with open(fileName, "w") as f: 210 with open(fileName, "w") as f:
206 f.write(self.requirementsEdit.toPlainText()) 211 f.write(self.requirementsEdit.toPlainText())
207 except OSError as err: 212 except OSError as err:
208 EricMessageBox.critical( 213 EricMessageBox.critical(
209 self, 214 self,
210 self.tr("Generate Requirements"), 215 self.tr("Generate Requirements"),
211 self.tr("""<p>The requirements could not be written""" 216 self.tr(
212 """ to <b>{0}</b>.</p><p>Reason: {1}</p>""") 217 """<p>The requirements could not be written"""
213 .format(fileName, str(err))) 218 """ to <b>{0}</b>.</p><p>Reason: {1}</p>"""
214 219 ).format(fileName, str(err)),
220 )
221
215 @pyqtSlot() 222 @pyqtSlot()
216 def on_saveButton_clicked(self): 223 def on_saveButton_clicked(self):
217 """ 224 """
218 Private slot to save the requirements text to the requirements file. 225 Private slot to save the requirements text to the requirements file.
219 """ 226 """
220 fileName = self.requirementsFilePicker.text() 227 fileName = self.requirementsFilePicker.text()
221 self.__writeToFile(fileName) 228 self.__writeToFile(fileName)
222 229
223 @pyqtSlot() 230 @pyqtSlot()
224 def on_saveToButton_clicked(self): 231 def on_saveToButton_clicked(self):
225 """ 232 """
226 Private slot to write the requirements text to a new file. 233 Private slot to write the requirements text to a new file.
227 """ 234 """
229 self, 236 self,
230 self.tr("Generate Requirements"), 237 self.tr("Generate Requirements"),
231 os.path.expanduser("~"), 238 os.path.expanduser("~"),
232 self.tr("Text Files (*.txt);;All Files (*)"), 239 self.tr("Text Files (*.txt);;All Files (*)"),
233 None, 240 None,
234 EricFileDialog.DontConfirmOverwrite 241 EricFileDialog.DontConfirmOverwrite,
235 ) 242 )
236 if fileName: 243 if fileName:
237 ext = os.path.splitext(fileName)[1] 244 ext = os.path.splitext(fileName)[1]
238 if not ext: 245 if not ext:
239 ex = selectedFilter.split("(*")[1].split(")")[0] 246 ex = selectedFilter.split("(*")[1].split(")")[0]
240 if ex: 247 if ex:
241 fileName += ex 248 fileName += ex
242 self.__writeToFile(fileName) 249 self.__writeToFile(fileName)
243 250
244 @pyqtSlot() 251 @pyqtSlot()
245 def on_copyButton_clicked(self): 252 def on_copyButton_clicked(self):
246 """ 253 """
247 Private slot to copy the requirements text to the clipboard. 254 Private slot to copy the requirements text to the clipboard.
248 """ 255 """
249 txt = self.requirementsEdit.toPlainText() 256 txt = self.requirementsEdit.toPlainText()
250 cb = QApplication.clipboard() 257 cb = QApplication.clipboard()
251 cb.setText(txt) 258 cb.setText(txt)
252 259
253 @pyqtSlot() 260 @pyqtSlot()
254 def on_insertButton_clicked(self): 261 def on_insertButton_clicked(self):
255 """ 262 """
256 Private slot to insert the requirements text at the cursor position 263 Private slot to insert the requirements text at the cursor position
257 of the current editor. 264 of the current editor.
259 aw = ericApp().getObject("ViewManager").activeWindow() 266 aw = ericApp().getObject("ViewManager").activeWindow()
260 if aw: 267 if aw:
261 aw.beginUndoAction() 268 aw.beginUndoAction()
262 aw.insert(self.requirementsEdit.toPlainText()) 269 aw.insert(self.requirementsEdit.toPlainText())
263 aw.endUndoAction() 270 aw.endUndoAction()
264 271
265 @pyqtSlot() 272 @pyqtSlot()
266 def on_replaceSelectionButton_clicked(self): 273 def on_replaceSelectionButton_clicked(self):
267 """ 274 """
268 Private slot to replace the selected text of the current editor 275 Private slot to replace the selected text of the current editor
269 with the requirements text. 276 with the requirements text.
271 aw = ericApp().getObject("ViewManager").activeWindow() 278 aw = ericApp().getObject("ViewManager").activeWindow()
272 if aw: 279 if aw:
273 aw.beginUndoAction() 280 aw.beginUndoAction()
274 aw.replaceSelectedText(self.requirementsEdit.toPlainText()) 281 aw.replaceSelectedText(self.requirementsEdit.toPlainText())
275 aw.endUndoAction() 282 aw.endUndoAction()
276 283
277 @pyqtSlot() 284 @pyqtSlot()
278 def on_replaceAllButton_clicked(self): 285 def on_replaceAllButton_clicked(self):
279 """ 286 """
280 Private slot to replace the text of the current editor with the 287 Private slot to replace the text of the current editor with the
281 requirements text. 288 requirements text.

eric ide

mercurial