10 import struct |
10 import struct |
11 import io |
11 import io |
12 |
12 |
13 from PyQt4.QtCore import QProcess, QProcessEnvironment, QObject, QByteArray, \ |
13 from PyQt4.QtCore import QProcess, QProcessEnvironment, QObject, QByteArray, \ |
14 QCoreApplication |
14 QCoreApplication |
|
15 from PyQt4.QtGui import QDialog |
|
16 |
|
17 from .HgClientPromptDialog import HgClientPromptDialog |
15 |
18 |
16 import Preferences |
19 import Preferences |
17 |
20 |
18 |
21 |
19 class HgClient(QObject): |
22 class HgClient(QObject): |
174 self.__server.waitForReadyRead(10000): |
177 self.__server.waitForReadyRead(10000): |
175 data = bytes(self.__server.read(HgClient.OutputFormatSize)) |
178 data = bytes(self.__server.read(HgClient.OutputFormatSize)) |
176 if not data: |
179 if not data: |
177 return "", "" |
180 return "", "" |
178 |
181 |
|
182 if data.startswith(b" L") and self.__server.bytesAvailable() > 0: |
|
183 # workaround for an issue in the Mercurial command server |
|
184 data = data[1:] + bytes(self.__server.read(1)) |
179 channel, length = struct.unpack(HgClient.OutputFormat, data) |
185 channel, length = struct.unpack(HgClient.OutputFormat, data) |
180 channel = channel.decode(self.__encoding) |
186 channel = channel.decode(self.__encoding) |
181 if channel in "IL": |
187 if channel in "IL": |
182 return channel, length |
188 return channel, length |
183 else: |
189 else: |
231 continue |
237 continue |
232 channel, data = self.__readChannel() |
238 channel, data = self.__readChannel() |
233 |
239 |
234 # input channels |
240 # input channels |
235 if channel in inputChannels: |
241 if channel in inputChannels: |
236 self.__writeDataBlock(inputChannels[channel](data)) |
242 input = inputChannels[channel](data) |
|
243 if channel == "L": |
|
244 # echo the input to the output if it was a prompt |
|
245 outputChannels["o"](input) |
|
246 self.__writeDataBlock(input) |
237 |
247 |
238 # output channels |
248 # output channels |
239 elif channel in outputChannels: |
249 elif channel in outputChannels: |
240 outputChannels[channel](data) |
250 outputChannels[channel](data) |
241 |
251 |
249 "Unexpected but required channel '{0}'.".format(channel)) |
259 "Unexpected but required channel '{0}'.".format(channel)) |
250 |
260 |
251 # optional channels |
261 # optional channels |
252 else: |
262 else: |
253 pass |
263 pass |
|
264 |
|
265 def __prompt(self, size, message): |
|
266 """ |
|
267 Private method to prompt the user for some input. |
|
268 |
|
269 @param size maximum length of the requested input (integer) |
|
270 @param message message sent by the server (string) |
|
271 """ |
|
272 input = "" |
|
273 dlg = HgClientPromptDialog(size, message) |
|
274 if dlg.exec_() == QDialog.Accepted: |
|
275 input = dlg.getInput() + '\n' |
|
276 return input |
254 |
277 |
255 def runcommand(self, args, prompt=None, input=None, output=None, error=None): |
278 def runcommand(self, args, prompt=None, input=None, output=None, error=None): |
256 """ |
279 """ |
257 Public method to execute a command via the command server. |
280 Public method to execute a command via the command server. |
258 |
281 |
289 if prompt is not None: |
312 if prompt is not None: |
290 def func(size): |
313 def func(size): |
291 reply = prompt(size, outputBuffer.getvalue()) |
314 reply = prompt(size, outputBuffer.getvalue()) |
292 return reply |
315 return reply |
293 inputChannels["L"] = func |
316 inputChannels["L"] = func |
|
317 else: |
|
318 def myprompt(size): |
|
319 reply = self.__prompt(size, outputBuffer.getvalue()) |
|
320 return reply |
|
321 inputChannels["L"] = myprompt |
294 if input is not None: |
322 if input is not None: |
295 inputChannels["I"] = input |
323 inputChannels["I"] = input |
296 |
324 |
297 self.__cancel = False |
325 self.__cancel = False |
298 self.__runcommand(args, inputChannels, outputChannels) |
326 self.__runcommand(args, inputChannels, outputChannels) |