Plugins/VcsPlugins/vcsMercurial/HgLogDialog.py

changeset 1246
5e9f6df3d1fc
parent 1131
7781e396c903
child 1256
885706dbb69f
equal deleted inserted replaced
1245:f2e75708f0c8 1246:5e9f6df3d1fc
49 if mode in ("log", "incoming", "outgoing"): 49 if mode in ("log", "incoming", "outgoing"):
50 self.mode = mode 50 self.mode = mode
51 else: 51 else:
52 self.mode = "log" 52 self.mode = "log"
53 self.bundle = bundle 53 self.bundle = bundle
54 self.__hgClient = self.vcs.getClient()
54 55
55 self.contents.setHtml( 56 self.contents.setHtml(
56 self.trUtf8('<b>Processing your request, please wait...</b>')) 57 self.trUtf8('<b>Processing your request, please wait...</b>'))
57 58
58 self.process.finished.connect(self.__procFinished) 59 self.process.finished.connect(self.__procFinished)
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 """
107 self.repodir = os.path.dirname(self.repodir) 111 self.repodir = os.path.dirname(self.repodir)
108 if self.repodir == os.sep: 112 if self.repodir == os.sep:
109 return 113 return
110 114
111 self.projectMode = (self.fname == "." and self.dname == self.repodir) 115 self.projectMode = (self.fname == "." and self.dname == self.repodir)
112
113 self.process.kill()
114 116
115 self.activateWindow() 117 self.activateWindow()
116 self.raise_() 118 self.raise_()
117 119
118 args = [] 120 args = []
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
166 @return list of parent revisions (list of strings) 185 @return list of parent revisions (list of strings)
167 """ 186 """
168 errMsg = "" 187 errMsg = ""
169 parents = [] 188 parents = []
170 189
171 process = QProcess()
172 args = [] 190 args = []
173 args.append("parents") 191 args.append("parents")
174 if self.mode == "incoming": 192 if self.mode == "incoming":
175 if self.bundle: 193 if self.bundle:
176 args.append("--repository") 194 args.append("--repository")
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

eric ide

mercurial