src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnDialog.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
21 21
22 22
23 class SvnDialog(QDialog, Ui_SvnDialog): 23 class SvnDialog(QDialog, Ui_SvnDialog):
24 """ 24 """
25 Class implementing a dialog starting a process and showing its output. 25 Class implementing a dialog starting a process and showing its output.
26 26
27 It starts a QProcess and displays a dialog that 27 It starts a QProcess and displays a dialog that
28 shows the output of the process. The dialog is modal, 28 shows the output of the process. The dialog is modal,
29 which causes a synchronized execution of the process. 29 which causes a synchronized execution of the process.
30 """ 30 """
31
31 def __init__(self, text, parent=None): 32 def __init__(self, text, parent=None):
32 """ 33 """
33 Constructor 34 Constructor
34 35
35 @param text text to be shown by the label (string) 36 @param text text to be shown by the label (string)
36 @param parent parent widget (QWidget) 37 @param parent parent widget (QWidget)
37 """ 38 """
38 super().__init__(parent) 39 super().__init__(parent)
39 self.setupUi(self) 40 self.setupUi(self)
40 self.setWindowFlags(Qt.WindowType.Window) 41 self.setWindowFlags(Qt.WindowType.Window)
41 42
42 self.buttonBox.button( 43 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False)
43 QDialogButtonBox.StandardButton.Close).setEnabled(False) 44 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(True)
44 self.buttonBox.button( 45
45 QDialogButtonBox.StandardButton.Cancel).setDefault(True)
46
47 self.process = None 46 self.process = None
48 self.username = '' 47 self.username = ""
49 self.password = '' 48 self.password = ""
50 49
51 self.outputGroup.setTitle(text) 50 self.outputGroup.setTitle(text)
52 51
53 def __finish(self): 52 def __finish(self):
54 """ 53 """
55 Private slot called when the process finished or the user pressed the 54 Private slot called when the process finished or the user pressed the
56 button. 55 button.
57 """ 56 """
58 if ( 57 if (
59 self.process is not None and 58 self.process is not None
60 self.process.state() != QProcess.ProcessState.NotRunning 59 and self.process.state() != QProcess.ProcessState.NotRunning
61 ): 60 ):
62 self.process.terminate() 61 self.process.terminate()
63 QTimer.singleShot(2000, self.process.kill) 62 QTimer.singleShot(2000, self.process.kill)
64 self.process.waitForFinished(3000) 63 self.process.waitForFinished(3000)
65 64
66 self.buttonBox.button( 65 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True)
67 QDialogButtonBox.StandardButton.Close).setEnabled(True) 66 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(False)
68 self.buttonBox.button( 67 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True)
69 QDialogButtonBox.StandardButton.Cancel).setEnabled(False) 68
70 self.buttonBox.button(
71 QDialogButtonBox.StandardButton.Close).setDefault(True)
72
73 self.inputGroup.setEnabled(False) 69 self.inputGroup.setEnabled(False)
74 self.inputGroup.hide() 70 self.inputGroup.hide()
75 71
76 self.process = None 72 self.process = None
77 73
78 self.buttonBox.button( 74 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True)
79 QDialogButtonBox.StandardButton.Close).setEnabled(True) 75 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(False)
80 self.buttonBox.button( 76 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True)
81 QDialogButtonBox.StandardButton.Cancel).setEnabled(False) 77 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setFocus(
82 self.buttonBox.button( 78 Qt.FocusReason.OtherFocusReason
83 QDialogButtonBox.StandardButton.Close).setDefault(True) 79 )
84 self.buttonBox.button( 80
85 QDialogButtonBox.StandardButton.Close).setFocus(
86 Qt.FocusReason.OtherFocusReason)
87
88 if ( 81 if (
89 Preferences.getVCS("AutoClose") and 82 Preferences.getVCS("AutoClose")
90 self.normal and 83 and self.normal
91 self.errors.toPlainText() == "" 84 and self.errors.toPlainText() == ""
92 ): 85 ):
93 self.accept() 86 self.accept()
94 87
95 def on_buttonBox_clicked(self, button): 88 def on_buttonBox_clicked(self, button):
96 """ 89 """
97 Private slot called by a button of the button box clicked. 90 Private slot called by a button of the button box clicked.
98 91
99 @param button button that was clicked (QAbstractButton) 92 @param button button that was clicked (QAbstractButton)
100 """ 93 """
101 if button == self.buttonBox.button( 94 if button == self.buttonBox.button(QDialogButtonBox.StandardButton.Close):
102 QDialogButtonBox.StandardButton.Close
103 ):
104 self.close() 95 self.close()
105 elif button == self.buttonBox.button( 96 elif button == self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel):
106 QDialogButtonBox.StandardButton.Cancel
107 ):
108 self.__finish() 97 self.__finish()
109 98
110 def __procFinished(self, exitCode, exitStatus): 99 def __procFinished(self, exitCode, exitStatus):
111 """ 100 """
112 Private slot connected to the finished signal. 101 Private slot connected to the finished signal.
113 102
114 @param exitCode exit code of the process (integer) 103 @param exitCode exit code of the process (integer)
115 @param exitStatus exit status of the process (QProcess.ExitStatus) 104 @param exitStatus exit status of the process (QProcess.ExitStatus)
116 """ 105 """
117 self.normal = ( 106 self.normal = exitStatus == QProcess.ExitStatus.NormalExit and exitCode == 0
118 exitStatus == QProcess.ExitStatus.NormalExit and
119 exitCode == 0
120 )
121 self.__finish() 107 self.__finish()
122 108
123 def startProcess(self, args, workingDir=None, setLanguage=False): 109 def startProcess(self, args, workingDir=None, setLanguage=False):
124 """ 110 """
125 Public slot used to start the process. 111 Public slot used to start the process.
126 112
127 @param args list of arguments for the process (list of strings) 113 @param args list of arguments for the process (list of strings)
128 @param workingDir working directory for the process (string) 114 @param workingDir working directory for the process (string)
129 @param setLanguage flag indicating to set the language to "C" (boolean) 115 @param setLanguage flag indicating to set the language to "C" (boolean)
130 @return flag indicating a successful start of the process 116 @return flag indicating a successful start of the process
131 """ 117 """
132 self.errorGroup.hide() 118 self.errorGroup.hide()
133 self.normal = False 119 self.normal = False
134 self.intercept = False 120 self.intercept = False
135 121
136 self.__hasAddOrDelete = False 122 self.__hasAddOrDelete = False
137 123
138 self.process = QProcess() 124 self.process = QProcess()
139 if setLanguage: 125 if setLanguage:
140 env = QProcessEnvironment.systemEnvironment() 126 env = QProcessEnvironment.systemEnvironment()
141 env.insert("LANG", "C") 127 env.insert("LANG", "C")
142 self.process.setProcessEnvironment(env) 128 self.process.setProcessEnvironment(env)
145 for arg in args: 131 for arg in args:
146 if lastWasPwd: 132 if lastWasPwd:
147 lastWasPwd = True 133 lastWasPwd = True
148 continue 134 continue
149 nargs.append(arg) 135 nargs.append(arg)
150 if arg == '--password': 136 if arg == "--password":
151 lastWasPwd = True 137 lastWasPwd = True
152 nargs.append('*****') 138 nargs.append("*****")
153 139
154 self.resultbox.append(' '.join(nargs)) 140 self.resultbox.append(" ".join(nargs))
155 self.resultbox.append('') 141 self.resultbox.append("")
156 142
157 self.process.finished.connect(self.__procFinished) 143 self.process.finished.connect(self.__procFinished)
158 self.process.readyReadStandardOutput.connect(self.__readStdout) 144 self.process.readyReadStandardOutput.connect(self.__readStdout)
159 self.process.readyReadStandardError.connect(self.__readStderr) 145 self.process.readyReadStandardError.connect(self.__readStderr)
160 146
161 if workingDir: 147 if workingDir:
162 self.process.setWorkingDirectory(workingDir) 148 self.process.setWorkingDirectory(workingDir)
163 self.process.start('svn', args) 149 self.process.start("svn", args)
164 procStarted = self.process.waitForStarted(5000) 150 procStarted = self.process.waitForStarted(5000)
165 if not procStarted: 151 if not procStarted:
166 self.buttonBox.setFocus() 152 self.buttonBox.setFocus()
167 self.inputGroup.setEnabled(False) 153 self.inputGroup.setEnabled(False)
168 self.inputGroup.hide() 154 self.inputGroup.hide()
169 EricMessageBox.critical( 155 EricMessageBox.critical(
170 self, 156 self,
171 self.tr('Process Generation Error'), 157 self.tr("Process Generation Error"),
172 self.tr( 158 self.tr(
173 'The process {0} could not be started. ' 159 "The process {0} could not be started. "
174 'Ensure, that it is in the search path.' 160 "Ensure, that it is in the search path."
175 ).format('svn')) 161 ).format("svn"),
162 )
176 else: 163 else:
177 self.inputGroup.setEnabled(True) 164 self.inputGroup.setEnabled(True)
178 self.inputGroup.show() 165 self.inputGroup.show()
179 return procStarted 166 return procStarted
180 167
181 def normalExit(self): 168 def normalExit(self):
182 """ 169 """
183 Public method to check for a normal process termination. 170 Public method to check for a normal process termination.
184 171
185 @return flag indicating normal process termination (boolean) 172 @return flag indicating normal process termination (boolean)
186 """ 173 """
187 return self.normal 174 return self.normal
188 175
189 def __readStdout(self): 176 def __readStdout(self):
190 """ 177 """
191 Private slot to handle the readyReadStdout signal. 178 Private slot to handle the readyReadStdout signal.
192 179
193 It reads the output of the process, formats it and inserts it into 180 It reads the output of the process, formats it and inserts it into
194 the contents pane. 181 the contents pane.
195 """ 182 """
196 if self.process is not None: 183 if self.process is not None:
197 s = str(self.process.readAllStandardOutput(), 184 s = str(
198 Preferences.getSystem("IOEncoding"), 185 self.process.readAllStandardOutput(),
199 'replace') 186 Preferences.getSystem("IOEncoding"),
187 "replace",
188 )
200 self.resultbox.insertPlainText(s) 189 self.resultbox.insertPlainText(s)
201 self.resultbox.ensureCursorVisible() 190 self.resultbox.ensureCursorVisible()
202 if not self.__hasAddOrDelete and len(s) > 0: 191 if not self.__hasAddOrDelete and len(s) > 0:
203 # check the output 192 # check the output
204 for line in s.split(os.linesep): 193 for line in s.split(os.linesep):
205 if ( 194 if ".epj" in line or ".e4p" in line:
206 '.epj' in line or
207 '.e4p' in line
208 ):
209 self.__hasAddOrDelete = True 195 self.__hasAddOrDelete = True
210 break 196 break
211 if line and line[0:2].strip() in ['A', 'D']: 197 if line and line[0:2].strip() in ["A", "D"]:
212 self.__hasAddOrDelete = True 198 self.__hasAddOrDelete = True
213 break 199 break
214 200
215 def __readStderr(self): 201 def __readStderr(self):
216 """ 202 """
217 Private slot to handle the readyReadStderr signal. 203 Private slot to handle the readyReadStderr signal.
218 204
219 It reads the error output of the process and inserts it into the 205 It reads the error output of the process and inserts it into the
220 error pane. 206 error pane.
221 """ 207 """
222 if self.process is not None: 208 if self.process is not None:
223 self.errorGroup.show() 209 self.errorGroup.show()
224 s = str(self.process.readAllStandardError(), 210 s = str(
225 Preferences.getSystem("IOEncoding"), 211 self.process.readAllStandardError(),
226 'replace') 212 Preferences.getSystem("IOEncoding"),
213 "replace",
214 )
227 self.errors.insertPlainText(s) 215 self.errors.insertPlainText(s)
228 self.errors.ensureCursorVisible() 216 self.errors.ensureCursorVisible()
229 217
230 def on_passwordCheckBox_toggled(self, isOn): 218 def on_passwordCheckBox_toggled(self, isOn):
231 """ 219 """
232 Private slot to handle the password checkbox toggled. 220 Private slot to handle the password checkbox toggled.
233 221
234 @param isOn flag indicating the status of the check box (boolean) 222 @param isOn flag indicating the status of the check box (boolean)
235 """ 223 """
236 if isOn: 224 if isOn:
237 self.input.setEchoMode(QLineEdit.EchoMode.Password) 225 self.input.setEchoMode(QLineEdit.EchoMode.Password)
238 else: 226 else:
239 self.input.setEchoMode(QLineEdit.EchoMode.Normal) 227 self.input.setEchoMode(QLineEdit.EchoMode.Normal)
240 228
241 @pyqtSlot() 229 @pyqtSlot()
242 def on_sendButton_clicked(self): 230 def on_sendButton_clicked(self):
243 """ 231 """
244 Private slot to send the input to the subversion process. 232 Private slot to send the input to the subversion process.
245 """ 233 """
246 inputTxt = self.input.text() 234 inputTxt = self.input.text()
247 inputTxt += os.linesep 235 inputTxt += os.linesep
248 236
249 if self.passwordCheckBox.isChecked(): 237 if self.passwordCheckBox.isChecked():
250 self.errors.insertPlainText(os.linesep) 238 self.errors.insertPlainText(os.linesep)
251 self.errors.ensureCursorVisible() 239 self.errors.ensureCursorVisible()
252 else: 240 else:
253 self.errors.insertPlainText(inputTxt) 241 self.errors.insertPlainText(inputTxt)
254 self.errors.ensureCursorVisible() 242 self.errors.ensureCursorVisible()
255 243
256 self.process.write(strToQByteArray(inputTxt)) 244 self.process.write(strToQByteArray(inputTxt))
257 245
258 self.passwordCheckBox.setChecked(False) 246 self.passwordCheckBox.setChecked(False)
259 self.input.clear() 247 self.input.clear()
260 248
261 def on_input_returnPressed(self): 249 def on_input_returnPressed(self):
262 """ 250 """
263 Private slot to handle the press of the return key in the input field. 251 Private slot to handle the press of the return key in the input field.
264 """ 252 """
265 self.intercept = True 253 self.intercept = True
266 self.on_sendButton_clicked() 254 self.on_sendButton_clicked()
267 255
268 def keyPressEvent(self, evt): 256 def keyPressEvent(self, evt):
269 """ 257 """
270 Protected slot to handle a key press event. 258 Protected slot to handle a key press event.
271 259
272 @param evt the key press event (QKeyEvent) 260 @param evt the key press event (QKeyEvent)
273 """ 261 """
274 if self.intercept: 262 if self.intercept:
275 self.intercept = False 263 self.intercept = False
276 evt.accept() 264 evt.accept()
277 return 265 return
278 super().keyPressEvent(evt) 266 super().keyPressEvent(evt)
279 267
280 def hasAddOrDelete(self): 268 def hasAddOrDelete(self):
281 """ 269 """
282 Public method to check, if the last action contained an add or delete. 270 Public method to check, if the last action contained an add or delete.
283 271
284 @return flag indicating the presence of an add or delete (boolean) 272 @return flag indicating the presence of an add or delete (boolean)
285 """ 273 """
286 return self.__hasAddOrDelete 274 return self.__hasAddOrDelete

eric ide

mercurial