src/eric7/CondaInterface/CondaExportDialog.py

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

eric ide

mercurial