5 |
5 |
6 """ |
6 """ |
7 Module implementing a class to generate the output of the hg diff command. |
7 Module implementing a class to generate the output of the hg diff command. |
8 """ |
8 """ |
9 |
9 |
10 |
|
11 import os |
10 import os |
12 |
11 |
13 from PyQt5.QtCore import pyqtSignal, QProcess, QTimer, QObject |
12 from PyQt5.QtCore import pyqtSignal, QObject |
14 |
13 |
15 |
14 |
16 class HgDiffGenerator(QObject): |
15 class HgDiffGenerator(QObject): |
17 """ |
16 """ |
18 Class implementing the generation of output of the hg diff command. |
17 Class implementing the generation of output of the hg diff command. |
31 super(HgDiffGenerator, self).__init__(parent) |
30 super(HgDiffGenerator, self).__init__(parent) |
32 |
31 |
33 self.vcs = vcs |
32 self.vcs = vcs |
34 |
33 |
35 self.__hgClient = self.vcs.getClient() |
34 self.__hgClient = self.vcs.getClient() |
36 if self.__hgClient: |
|
37 self.process = None |
|
38 else: |
|
39 self.process = QProcess() |
|
40 self.process.finished.connect(self.__finish) |
|
41 self.process.readyReadStandardOutput.connect(self.__readStdout) |
|
42 self.process.readyReadStandardError.connect(self.__readStderr) |
|
43 |
35 |
44 def stopProcess(self): |
36 def stopProcess(self): |
45 """ |
37 """ |
46 Public slot to stop the diff process. |
38 Public slot to stop the diff process. |
47 """ |
39 """ |
48 if self.__hgClient: |
40 if self.__hgClient.isExecuting(): |
49 if self.__hgClient.isExecuting(): |
41 self.__hgClient.cancel() |
50 self.__hgClient.cancel() |
|
51 else: |
|
52 if ( |
|
53 self.process is not None and |
|
54 self.process.state() != QProcess.NotRunning |
|
55 ): |
|
56 self.process.terminate() |
|
57 QTimer.singleShot(2000, self.process.kill) |
|
58 self.process.waitForFinished(3000) |
|
59 |
42 |
60 def __getVersionArg(self, version): |
43 def __getVersionArg(self, version): |
61 """ |
44 """ |
62 Private method to get a hg revision argument for the given revision. |
45 Private method to get a hg revision argument for the given revision. |
63 |
46 |
122 self.__oldFileLine = -1 |
105 self.__oldFileLine = -1 |
123 self.__fileSeparators = [] |
106 self.__fileSeparators = [] |
124 self.__output = [] |
107 self.__output = [] |
125 self.__errors = [] |
108 self.__errors = [] |
126 |
109 |
127 if self.__hgClient: |
110 out, err = self.__hgClient.runcommand(args) |
128 out, err = self.__hgClient.runcommand(args) |
111 |
129 |
112 if err: |
130 if err: |
113 self.__errors = err.splitlines(True) |
131 self.__errors = err.splitlines(True) |
114 |
132 |
115 if out: |
133 if out: |
116 for line in out.splitlines(True): |
134 for line in out.splitlines(True): |
117 self.__processOutputLine(line) |
135 self.__processOutputLine(line) |
118 if self.__hgClient.wasCanceled(): |
136 if self.__hgClient.wasCanceled(): |
119 break |
137 break |
120 |
138 |
121 self.__finish() |
139 self.__finish() |
|
140 else: |
|
141 # find the root of the repo |
|
142 repodir = dname |
|
143 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): |
|
144 repodir = os.path.dirname(repodir) |
|
145 if os.path.splitdrive(repodir)[1] == os.sep: |
|
146 return False |
|
147 |
|
148 self.process.kill() |
|
149 self.process.setWorkingDirectory(repodir) |
|
150 |
|
151 self.process.start('hg', args) |
|
152 procStarted = self.process.waitForStarted(5000) |
|
153 if not procStarted: |
|
154 return False |
|
155 |
122 |
156 return True |
123 return True |
157 |
124 |
158 def __finish(self): |
125 def __finish(self): |
159 """ |
126 """ |
216 line.startswith("+++ ") |
183 line.startswith("+++ ") |
217 ): |
184 ): |
218 self.__processFileLine(line) |
185 self.__processFileLine(line) |
219 |
186 |
220 self.__output.append(line) |
187 self.__output.append(line) |
221 |
|
222 def __readStdout(self): |
|
223 """ |
|
224 Private slot to handle the readyReadStandardOutput signal. |
|
225 |
|
226 It reads the output of the process, formats it and inserts it into |
|
227 the contents pane. |
|
228 """ |
|
229 self.process.setReadChannel(QProcess.StandardOutput) |
|
230 |
|
231 while self.process.canReadLine(): |
|
232 line = str(self.process.readLine(), self.vcs.getEncoding(), |
|
233 'replace') |
|
234 self.__processOutputLine(line) |
|
235 |
|
236 def __readStderr(self): |
|
237 """ |
|
238 Private slot to handle the readyReadStandardError signal. |
|
239 |
|
240 It reads the error output of the process and inserts it into the |
|
241 error pane. |
|
242 """ |
|
243 if self.process is not None: |
|
244 s = str(self.process.readAllStandardError(), |
|
245 self.vcs.getEncoding(), 'replace') |
|
246 self.__errors.append(s) |
|