6 """ |
6 """ |
7 Module implementing a dialog to show some summary information of the working |
7 Module implementing a dialog to show some summary information of the working |
8 directory state. |
8 directory state. |
9 """ |
9 """ |
10 |
10 |
11 |
|
12 import os |
11 import os |
13 |
12 |
14 from PyQt5.QtCore import pyqtSlot, QProcess, QTimer |
13 from PyQt5.QtCore import pyqtSlot |
15 from PyQt5.QtWidgets import QDialog, QDialogButtonBox |
14 from PyQt5.QtWidgets import QDialog, QDialogButtonBox |
16 |
|
17 from E5Gui import E5MessageBox |
|
18 |
|
19 from .HgUtilities import prepareProcess |
|
20 |
15 |
21 from .Ui_HgSummaryDialog import Ui_HgSummaryDialog |
16 from .Ui_HgSummaryDialog import Ui_HgSummaryDialog |
22 |
17 |
23 |
18 |
24 class HgSummaryDialog(QDialog, Ui_HgSummaryDialog): |
19 class HgSummaryDialog(QDialog, Ui_HgSummaryDialog): |
42 self.tr("Press to refresh the summary display")) |
37 self.tr("Press to refresh the summary display")) |
43 self.refreshButton.setEnabled(False) |
38 self.refreshButton.setEnabled(False) |
44 |
39 |
45 self.vcs = vcs |
40 self.vcs = vcs |
46 self.vcs.committed.connect(self.__committed) |
41 self.vcs.committed.connect(self.__committed) |
47 |
|
48 self.process = QProcess() |
|
49 prepareProcess(self.process, language="C") |
|
50 self.process.finished.connect(self.__procFinished) |
|
51 self.process.readyReadStandardOutput.connect(self.__readStdout) |
|
52 self.process.readyReadStandardError.connect(self.__readStderr) |
|
53 |
|
54 def closeEvent(self, e): |
|
55 """ |
|
56 Protected slot implementing a close event handler. |
|
57 |
|
58 @param e close event (QCloseEvent) |
|
59 """ |
|
60 if ( |
|
61 self.process is not None and |
|
62 self.process.state() != QProcess.NotRunning |
|
63 ): |
|
64 self.process.terminate() |
|
65 QTimer.singleShot(2000, self.process.kill) |
|
66 self.process.waitForFinished(3000) |
|
67 |
|
68 e.accept() |
|
69 |
42 |
70 def start(self, path, mq=False, largefiles=False): |
43 def start(self, path, mq=False, largefiles=False): |
71 """ |
44 """ |
72 Public slot to start the hg summary command. |
45 Public slot to start the hg summary command. |
73 |
46 |
97 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): |
70 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): |
98 repodir = os.path.dirname(repodir) |
71 repodir = os.path.dirname(repodir) |
99 if os.path.splitdrive(repodir)[1] == os.sep: |
72 if os.path.splitdrive(repodir)[1] == os.sep: |
100 return |
73 return |
101 |
74 |
102 if self.process: |
75 client = self.vcs.getClient() |
103 self.process.kill() |
76 output, error = client.runcommand(args) |
104 |
77 if error: |
105 self.process.setWorkingDirectory(repodir) |
78 self.__showError(error) |
106 |
79 else: |
107 self.__buffer = [] |
80 self.__processOutput(output.splitlines()) |
108 |
|
109 self.process.start('hg', args) |
|
110 procStarted = self.process.waitForStarted(5000) |
|
111 if not procStarted: |
|
112 E5MessageBox.critical( |
|
113 self, |
|
114 self.tr('Process Generation Error'), |
|
115 self.tr( |
|
116 'The process {0} could not be started. ' |
|
117 'Ensure, that it is in the search path.' |
|
118 ).format('hg')) |
|
119 |
|
120 def __finish(self): |
|
121 """ |
|
122 Private slot called when the process finished or the user pressed |
|
123 the button. |
|
124 """ |
|
125 if ( |
|
126 self.process is not None and |
|
127 self.process.state() != QProcess.NotRunning |
|
128 ): |
|
129 self.process.terminate() |
|
130 QTimer.singleShot(2000, self.process.kill) |
|
131 self.process.waitForFinished(3000) |
|
132 |
81 |
133 self.refreshButton.setEnabled(True) |
82 self.refreshButton.setEnabled(True) |
134 |
83 |
135 def on_buttonBox_clicked(self, button): |
84 def on_buttonBox_clicked(self, button): |
136 """ |
85 """ |
141 if button == self.buttonBox.button(QDialogButtonBox.Close): |
90 if button == self.buttonBox.button(QDialogButtonBox.Close): |
142 self.close() |
91 self.close() |
143 elif button == self.refreshButton: |
92 elif button == self.refreshButton: |
144 self.on_refreshButton_clicked() |
93 self.on_refreshButton_clicked() |
145 |
94 |
146 def __procFinished(self, exitCode, exitStatus): |
95 @pyqtSlot() |
147 """ |
96 def on_refreshButton_clicked(self): |
148 Private slot connected to the finished signal. |
97 """ |
149 |
98 Private slot to refresh the status display. |
150 @param exitCode exit code of the process (integer) |
99 """ |
151 @param exitStatus exit status of the process (QProcess.ExitStatus) |
100 self.start(self.__path, mq=self.__mq) |
152 """ |
101 |
153 self.__processOutput(self.__buffer) |
102 def __committed(self): |
154 self.__finish() |
103 """ |
155 |
104 Private slot called after the commit has finished. |
156 def __readStdout(self): |
105 """ |
157 """ |
106 if self.isVisible(): |
158 Private slot to handle the readyReadStandardOutput signal. |
107 self.on_refreshButton_clicked() |
159 |
|
160 It reads the output of the process, formats it and inserts it into |
|
161 the contents pane. |
|
162 """ |
|
163 if self.process is not None: |
|
164 self.process.setReadChannel(QProcess.StandardOutput) |
|
165 |
|
166 while self.process.canReadLine(): |
|
167 line = str(self.process.readLine(), self.vcs.getEncoding(), |
|
168 'replace') |
|
169 self.__buffer.append(line) |
|
170 |
|
171 def __readStderr(self): |
|
172 """ |
|
173 Private slot to handle the readyReadStandardError signal. |
|
174 |
|
175 It reads the error output of the process and inserts it into the |
|
176 error pane. |
|
177 """ |
|
178 if self.process is not None: |
|
179 s = str(self.process.readAllStandardError(), |
|
180 self.vcs.getEncoding(), 'replace') |
|
181 self.__showError(s) |
|
182 |
108 |
183 def __showError(self, out): |
109 def __showError(self, out): |
184 """ |
110 """ |
185 Private slot to show some error. |
111 Private slot to show some error. |
186 |
112 |
187 @param out error to be shown (string) |
113 @param out error to be shown (string) |
188 """ |
114 """ |
189 self.errorGroup.show() |
115 self.errorGroup.show() |
190 self.errors.insertPlainText(out) |
116 self.errors.insertPlainText(out) |
191 self.errors.ensureCursorVisible() |
117 self.errors.ensureCursorVisible() |
192 |
|
193 @pyqtSlot() |
|
194 def on_refreshButton_clicked(self): |
|
195 """ |
|
196 Private slot to refresh the status display. |
|
197 """ |
|
198 self.start(self.__path, mq=self.__mq) |
|
199 |
|
200 def __committed(self): |
|
201 """ |
|
202 Private slot called after the commit has finished. |
|
203 """ |
|
204 if self.isVisible(): |
|
205 self.on_refreshButton_clicked() |
|
206 |
118 |
207 def __processOutput(self, output): |
119 def __processOutput(self, output): |
208 """ |
120 """ |
209 Private method to process the output into nice readable text. |
121 Private method to process the output into nice readable text. |
210 |
122 |