38 self.buttonBox.button(QDialogButtonBox.Save).setEnabled(False) |
38 self.buttonBox.button(QDialogButtonBox.Save).setEnabled(False) |
39 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) |
39 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) |
40 |
40 |
41 self.process = QProcess() |
41 self.process = QProcess() |
42 self.vcs = vcs |
42 self.vcs = vcs |
|
43 self.__hgClient = self.vcs.getClient() |
43 |
44 |
44 if Utilities.isWindowsPlatform(): |
45 if Utilities.isWindowsPlatform(): |
45 self.contents.setFontFamily("Lucida Console") |
46 self.contents.setFontFamily("Lucida Console") |
46 else: |
47 else: |
47 self.contents.setFontFamily("Monospace") |
48 self.contents.setFontFamily("Monospace") |
62 """ |
63 """ |
63 Private slot implementing a close event handler. |
64 Private slot implementing a close event handler. |
64 |
65 |
65 @param e close event (QCloseEvent) |
66 @param e close event (QCloseEvent) |
66 """ |
67 """ |
67 if self.process is not None and \ |
68 if self.__hgClient: |
68 self.process.state() != QProcess.NotRunning: |
69 self.__hgClient.cancel() |
69 self.process.terminate() |
70 else: |
70 QTimer.singleShot(2000, self.process.kill) |
71 if self.process is not None and \ |
71 self.process.waitForFinished(3000) |
72 self.process.state() != QProcess.NotRunning: |
|
73 self.process.terminate() |
|
74 QTimer.singleShot(2000, self.process.kill) |
|
75 self.process.waitForFinished(3000) |
72 |
76 |
73 e.accept() |
77 e.accept() |
74 |
78 |
75 def __getVersionArg(self, version): |
79 def __getVersionArg(self, version): |
76 """ |
80 """ |
142 self.vcs.addArguments(args, fn) |
144 self.vcs.addArguments(args, fn) |
143 else: |
145 else: |
144 dname, fname = self.vcs.splitPath(fn) |
146 dname, fname = self.vcs.splitPath(fn) |
145 args.append(fn) |
147 args.append(fn) |
146 |
148 |
147 # find the root of the repo |
149 if self.__hgClient: |
148 repodir = dname |
|
149 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): |
|
150 repodir = os.path.dirname(repodir) |
|
151 if repodir == os.sep: |
|
152 return |
|
153 |
|
154 self.process.setWorkingDirectory(repodir) |
|
155 |
|
156 self.process.start('hg', args) |
|
157 procStarted = self.process.waitForStarted() |
|
158 if not procStarted: |
|
159 self.inputGroup.setEnabled(False) |
150 self.inputGroup.setEnabled(False) |
160 E5MessageBox.critical(self, |
151 self.inputGroup.hide() |
161 self.trUtf8('Process Generation Error'), |
152 |
162 self.trUtf8( |
153 out, err = self.__hgClient.runcommand(args) |
163 'The process {0} could not be started. ' |
154 |
164 'Ensure, that it is in the search path.' |
155 if out: |
165 ).format('hg')) |
156 for line in out.splitlines(True): |
|
157 self.__processOutputLine(line) |
|
158 |
|
159 if err: |
|
160 self.__showError(err) |
|
161 |
|
162 self.__finish() |
|
163 else: |
|
164 # find the root of the repo |
|
165 repodir = dname |
|
166 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): |
|
167 repodir = os.path.dirname(repodir) |
|
168 if repodir == os.sep: |
|
169 return |
|
170 |
|
171 self.process.kill() |
|
172 |
|
173 self.process.setWorkingDirectory(repodir) |
|
174 |
|
175 self.process.start('hg', args) |
|
176 procStarted = self.process.waitForStarted() |
|
177 if not procStarted: |
|
178 self.inputGroup.setEnabled(False) |
|
179 E5MessageBox.critical(self, |
|
180 self.trUtf8('Process Generation Error'), |
|
181 self.trUtf8( |
|
182 'The process {0} could not be started. ' |
|
183 'Ensure, that it is in the search path.' |
|
184 ).format('hg')) |
166 |
185 |
167 def __procFinished(self, exitCode, exitStatus): |
186 def __procFinished(self, exitCode, exitStatus): |
168 """ |
187 """ |
169 Private slot connected to the finished signal. |
188 Private slot connected to the finished signal. |
170 |
189 |
171 @param exitCode exit code of the process (integer) |
190 @param exitCode exit code of the process (integer) |
172 @param exitStatus exit status of the process (QProcess.ExitStatus) |
191 @param exitStatus exit status of the process (QProcess.ExitStatus) |
|
192 """ |
|
193 self.__finish() |
|
194 |
|
195 def __finish(self): |
|
196 """ |
|
197 Private slot called when the process finished or the user pressed the button. |
173 """ |
198 """ |
174 self.inputGroup.setEnabled(False) |
199 self.inputGroup.setEnabled(False) |
175 self.inputGroup.hide() |
200 self.inputGroup.hide() |
176 |
201 |
177 if self.paras == 0: |
202 if self.paras == 0: |
199 tc.movePosition(QTextCursor.End) |
224 tc.movePosition(QTextCursor.End) |
200 self.contents.setTextCursor(tc) |
225 self.contents.setTextCursor(tc) |
201 self.contents.setCurrentCharFormat(format) |
226 self.contents.setCurrentCharFormat(format) |
202 self.contents.insertPlainText(txt) |
227 self.contents.insertPlainText(txt) |
203 |
228 |
|
229 def __processOutputLine(self, line): |
|
230 """ |
|
231 Private method to process the lines of output. |
|
232 |
|
233 @param line output line to be processed (string) |
|
234 """ |
|
235 if line.startswith('+'): |
|
236 format = self.cAddedFormat |
|
237 elif line.startswith('-'): |
|
238 format = self.cRemovedFormat |
|
239 elif line.startswith('@@'): |
|
240 format = self.cLineNoFormat |
|
241 else: |
|
242 format = self.cNormalFormat |
|
243 self.__appendText(line, format) |
|
244 self.paras += 1 |
|
245 |
204 def __readStdout(self): |
246 def __readStdout(self): |
205 """ |
247 """ |
206 Private slot to handle the readyReadStandardOutput signal. |
248 Private slot to handle the readyReadStandardOutput signal. |
207 |
249 |
208 It reads the output of the process, formats it and inserts it into |
250 It reads the output of the process, formats it and inserts it into |
212 |
254 |
213 while self.process.canReadLine(): |
255 while self.process.canReadLine(): |
214 line = str(self.process.readLine(), |
256 line = str(self.process.readLine(), |
215 Preferences.getSystem("IOEncoding"), |
257 Preferences.getSystem("IOEncoding"), |
216 'replace') |
258 'replace') |
217 if line.startswith('+'): |
259 self.__processOutputLine(line) |
218 format = self.cAddedFormat |
|
219 elif line.startswith('-'): |
|
220 format = self.cRemovedFormat |
|
221 elif line.startswith('@@'): |
|
222 format = self.cLineNoFormat |
|
223 else: |
|
224 format = self.cNormalFormat |
|
225 self.__appendText(line, format) |
|
226 self.paras += 1 |
|
227 |
260 |
228 def __readStderr(self): |
261 def __readStderr(self): |
229 """ |
262 """ |
230 Private slot to handle the readyReadStandardError signal. |
263 Private slot to handle the readyReadStandardError signal. |
231 |
264 |
232 It reads the error output of the process and inserts it into the |
265 It reads the error output of the process and inserts it into the |
233 error pane. |
266 error pane. |
234 """ |
267 """ |
235 if self.process is not None: |
268 if self.process is not None: |
236 self.errorGroup.show() |
|
237 s = str(self.process.readAllStandardError(), |
269 s = str(self.process.readAllStandardError(), |
238 Preferences.getSystem("IOEncoding"), |
270 Preferences.getSystem("IOEncoding"), |
239 'replace') |
271 'replace') |
240 self.errors.insertPlainText(s) |
272 self.__showError(s) |
241 self.errors.ensureCursorVisible() |
273 |
|
274 def __showError(self, out): |
|
275 """ |
|
276 Private slot to show some error. |
|
277 |
|
278 @param out error to be shown (string) |
|
279 """ |
|
280 self.errorGroup.show() |
|
281 self.errors.insertPlainText(out) |
|
282 self.errors.ensureCursorVisible() |
242 |
283 |
243 def on_buttonBox_clicked(self, button): |
284 def on_buttonBox_clicked(self, button): |
244 """ |
285 """ |
245 Private slot called by a button of the button box clicked. |
286 Private slot called by a button of the button box clicked. |
246 |
287 |