77 """ |
78 """ |
78 Private slot implementing a close event handler. |
79 Private slot implementing a close event handler. |
79 |
80 |
80 @param e close event (QCloseEvent) |
81 @param e close event (QCloseEvent) |
81 """ |
82 """ |
82 if self.process is not None and \ |
83 if self.__hgClient: |
83 self.process.state() != QProcess.NotRunning: |
84 self.__hgClient.cancel() |
84 self.process.terminate() |
85 else: |
85 QTimer.singleShot(2000, self.process.kill) |
86 if self.process is not None and \ |
86 self.process.waitForFinished(3000) |
87 self.process.state() != QProcess.NotRunning: |
|
88 self.process.terminate() |
|
89 QTimer.singleShot(2000, self.process.kill) |
|
90 self.process.waitForFinished(3000) |
87 |
91 |
88 e.accept() |
92 e.accept() |
89 |
93 |
90 def start(self, fn, noEntries=0): |
94 def start(self, fn, noEntries=0): |
91 """ |
95 """ |
143 args.append('--bundle') |
145 args.append('--bundle') |
144 args.append(self.vcs.bundleFile) |
146 args.append(self.vcs.bundleFile) |
145 if not self.projectMode: |
147 if not self.projectMode: |
146 args.append(self.filename) |
148 args.append(self.filename) |
147 |
149 |
148 self.process.setWorkingDirectory(self.repodir) |
150 if self.__hgClient: |
149 |
|
150 self.process.start('hg', args) |
|
151 procStarted = self.process.waitForStarted() |
|
152 if not procStarted: |
|
153 self.inputGroup.setEnabled(False) |
151 self.inputGroup.setEnabled(False) |
154 E5MessageBox.critical(self, |
152 self.inputGroup.hide() |
155 self.trUtf8('Process Generation Error'), |
153 |
156 self.trUtf8( |
154 out, err = self.__hgClient.runcommand(args) |
157 'The process {0} could not be started. ' |
155 |
158 'Ensure, that it is in the search path.' |
156 if out: |
159 ).format('hg')) |
157 for line in out.splitlines(True): |
|
158 self.__processOutputLine(line) |
|
159 |
|
160 if err: |
|
161 self.__showError(err) |
|
162 |
|
163 self.__finish() |
|
164 else: |
|
165 self.process.kill() |
|
166 |
|
167 self.process.setWorkingDirectory(self.repodir) |
|
168 |
|
169 self.process.start('hg', args) |
|
170 procStarted = self.process.waitForStarted() |
|
171 if not procStarted: |
|
172 self.inputGroup.setEnabled(False) |
|
173 E5MessageBox.critical(self, |
|
174 self.trUtf8('Process Generation Error'), |
|
175 self.trUtf8( |
|
176 'The process {0} could not be started. ' |
|
177 'Ensure, that it is in the search path.' |
|
178 ).format('hg')) |
160 |
179 |
161 def __getParents(self, rev): |
180 def __getParents(self, rev): |
162 """ |
181 """ |
163 Private method to get the parents of the currently viewed file/directory. |
182 Private method to get the parents of the currently viewed file/directory. |
164 |
183 |
183 args.append("-r") |
201 args.append("-r") |
184 args.append(rev) |
202 args.append(rev) |
185 if not self.projectMode: |
203 if not self.projectMode: |
186 args.append(self.filename) |
204 args.append(self.filename) |
187 |
205 |
188 process.setWorkingDirectory(self.repodir) |
206 output = "" |
189 process.start('hg', args) |
207 if self.__hgClient: |
190 procStarted = process.waitForStarted() |
208 output, errMsg = self.__hgClient.runcommand(args) |
191 if procStarted: |
209 else: |
192 finished = process.waitForFinished(30000) |
210 process = QProcess() |
193 if finished and process.exitCode() == 0: |
211 process.setWorkingDirectory(self.repodir) |
194 output = \ |
212 process.start('hg', args) |
195 str(process.readAllStandardOutput(), |
213 procStarted = process.waitForStarted() |
196 Preferences.getSystem("IOEncoding"), |
214 if procStarted: |
197 'replace') |
215 finished = process.waitForFinished(30000) |
198 parents = [p for p in output.strip().splitlines()] |
216 if finished and process.exitCode() == 0: |
|
217 output = \ |
|
218 str(process.readAllStandardOutput(), |
|
219 Preferences.getSystem("IOEncoding"), |
|
220 'replace') |
|
221 else: |
|
222 if not finished: |
|
223 errMsg = self.trUtf8("The hg process did not finish within 30s.") |
199 else: |
224 else: |
200 if not finished: |
225 errMsg = self.trUtf8("Could not start the hg executable.") |
201 errMsg = self.trUtf8("The hg process did not finish within 30s.") |
|
202 else: |
|
203 errMsg = self.trUtf8("Could not start the hg executable.") |
|
204 |
226 |
205 if errMsg: |
227 if errMsg: |
206 E5MessageBox.critical(self, |
228 E5MessageBox.critical(self, |
207 self.trUtf8("Mercurial Error"), |
229 self.trUtf8("Mercurial Error"), |
208 errMsg) |
230 errMsg) |
209 |
231 |
|
232 if output: |
|
233 parents = [p for p in output.strip().splitlines()] |
|
234 |
210 return parents |
235 return parents |
211 |
236 |
212 def __procFinished(self, exitCode, exitStatus): |
237 def __procFinished(self, exitCode, exitStatus): |
213 """ |
238 """ |
214 Private slot connected to the finished signal. |
239 Private slot connected to the finished signal. |
215 |
240 |
216 @param exitCode exit code of the process (integer) |
241 @param exitCode exit code of the process (integer) |
217 @param exitStatus exit status of the process (QProcess.ExitStatus) |
242 @param exitStatus exit status of the process (QProcess.ExitStatus) |
|
243 """ |
|
244 self.__finish() |
|
245 |
|
246 def __finish(self): |
|
247 """ |
|
248 Private slot called when the process finished or the user pressed the button. |
218 """ |
249 """ |
219 self.inputGroup.setEnabled(False) |
250 self.inputGroup.setEnabled(False) |
220 self.inputGroup.hide() |
251 self.inputGroup.hide() |
221 |
252 |
222 self.contents.clear() |
253 self.contents.clear() |
322 |
353 |
323 while self.process.canReadLine(): |
354 while self.process.canReadLine(): |
324 s = str(self.process.readLine(), |
355 s = str(self.process.readLine(), |
325 Preferences.getSystem("IOEncoding"), |
356 Preferences.getSystem("IOEncoding"), |
326 'replace') |
357 'replace') |
327 |
358 self.__processOutputLine(s) |
328 if s == "@@@\n": |
359 |
329 self.logEntries.append(self.lastLogEntry) |
360 def __processOutputLine(self, line): |
330 self.lastLogEntry = {} |
361 """ |
331 self.fileCopies = {} |
362 Private method to process the lines of output. |
|
363 |
|
364 @param line output line to be processed (string) |
|
365 """ |
|
366 if line == "@@@\n": |
|
367 self.logEntries.append(self.lastLogEntry) |
|
368 self.lastLogEntry = {} |
|
369 self.fileCopies = {} |
|
370 else: |
|
371 try: |
|
372 key, value = line.split("|", 1) |
|
373 except ValueError: |
|
374 key = "" |
|
375 value = line |
|
376 if key == "change": |
|
377 self.endInitialText = True |
|
378 if key in ("change", "branches", "tags", "parents", "user", |
|
379 "date", "file_copies", "file_adds", "files_mods", |
|
380 "file_dels", "bookmarks"): |
|
381 self.lastLogEntry[key] = value.strip() |
|
382 elif key == "description": |
|
383 self.lastLogEntry[key] = [value.strip()] |
332 else: |
384 else: |
333 try: |
385 if self.endInitialText: |
334 key, value = s.split("|", 1) |
386 self.lastLogEntry["description"].append(value.strip()) |
335 except ValueError: |
|
336 key = "" |
|
337 value = s |
|
338 if key == "change": |
|
339 self.endInitialText = True |
|
340 if key in ("change", "branches", "tags", "parents", "user", |
|
341 "date", "file_copies", "file_adds", "files_mods", |
|
342 "file_dels", "bookmarks"): |
|
343 self.lastLogEntry[key] = value.strip() |
|
344 elif key == "description": |
|
345 self.lastLogEntry[key] = [value.strip()] |
|
346 else: |
387 else: |
347 if self.endInitialText: |
388 self.initialText.append(value) |
348 self.lastLogEntry["description"].append(value.strip()) |
|
349 else: |
|
350 self.initialText.append(value) |
|
351 |
389 |
352 def __readStderr(self): |
390 def __readStderr(self): |
353 """ |
391 """ |
354 Private slot to handle the readyReadStandardError signal. |
392 Private slot to handle the readyReadStandardError signal. |
355 |
393 |
356 It reads the error output of the process and inserts it into the |
394 It reads the error output of the process and inserts it into the |
357 error pane. |
395 error pane. |
358 """ |
396 """ |
359 if self.process is not None: |
397 if self.process is not None: |
360 self.errorGroup.show() |
|
361 s = str(self.process.readAllStandardError(), |
398 s = str(self.process.readAllStandardError(), |
362 Preferences.getSystem("IOEncoding"), |
399 Preferences.getSystem("IOEncoding"), |
363 'replace') |
400 'replace') |
364 self.errors.insertPlainText(s) |
401 self.__showError(s) |
365 self.errors.ensureCursorVisible() |
402 |
|
403 def __showError(self, out): |
|
404 """ |
|
405 Private slot to show some error. |
|
406 |
|
407 @param out error to be shown (string) |
|
408 """ |
|
409 self.errorGroup.show() |
|
410 self.errors.insertPlainText(out) |
|
411 self.errors.ensureCursorVisible() |
366 |
412 |
367 def __sourceChanged(self, url): |
413 def __sourceChanged(self, url): |
368 """ |
414 """ |
369 Private slot to handle the sourceChanged signal of the contents pane. |
415 Private slot to handle the sourceChanged signal of the contents pane. |
370 |
416 |