24 |
28 |
25 class GitDescribeDialog(QDialog, Ui_GitDescribeDialog): |
29 class GitDescribeDialog(QDialog, Ui_GitDescribeDialog): |
26 """ |
30 """ |
27 Class implementing a dialog to show the results of the git describe action. |
31 Class implementing a dialog to show the results of the git describe action. |
28 """ |
32 """ |
|
33 |
29 def __init__(self, vcs, parent=None): |
34 def __init__(self, vcs, parent=None): |
30 """ |
35 """ |
31 Constructor |
36 Constructor |
32 |
37 |
33 @param vcs reference to the vcs object |
38 @param vcs reference to the vcs object |
34 @param parent reference to the parent widget (QWidget) |
39 @param parent reference to the parent widget (QWidget) |
35 """ |
40 """ |
36 super().__init__(parent) |
41 super().__init__(parent) |
37 self.setupUi(self) |
42 self.setupUi(self) |
38 self.setWindowFlags(Qt.WindowType.Window) |
43 self.setWindowFlags(Qt.WindowType.Window) |
39 |
44 |
40 self.buttonBox.button( |
45 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False) |
41 QDialogButtonBox.StandardButton.Close).setEnabled(False) |
46 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(True) |
42 self.buttonBox.button( |
47 |
43 QDialogButtonBox.StandardButton.Cancel).setDefault(True) |
|
44 |
|
45 self.process = QProcess() |
48 self.process = QProcess() |
46 self.vcs = vcs |
49 self.vcs = vcs |
47 |
50 |
48 self.tagList.headerItem().setText(self.tagList.columnCount(), "") |
51 self.tagList.headerItem().setText(self.tagList.columnCount(), "") |
49 self.tagList.header().setSortIndicator(1, Qt.SortOrder.AscendingOrder) |
52 self.tagList.header().setSortIndicator(1, Qt.SortOrder.AscendingOrder) |
50 |
53 |
51 self.process.finished.connect(self.__procFinished) |
54 self.process.finished.connect(self.__procFinished) |
52 self.process.readyReadStandardOutput.connect(self.__readStdout) |
55 self.process.readyReadStandardOutput.connect(self.__readStdout) |
53 self.process.readyReadStandardError.connect(self.__readStderr) |
56 self.process.readyReadStandardError.connect(self.__readStderr) |
54 |
57 |
55 self.show() |
58 self.show() |
56 QCoreApplication.processEvents() |
59 QCoreApplication.processEvents() |
57 |
60 |
58 def closeEvent(self, e): |
61 def closeEvent(self, e): |
59 """ |
62 """ |
60 Protected slot implementing a close event handler. |
63 Protected slot implementing a close event handler. |
61 |
64 |
62 @param e close event (QCloseEvent) |
65 @param e close event (QCloseEvent) |
63 """ |
66 """ |
64 if ( |
67 if ( |
65 self.process is not None and |
68 self.process is not None |
66 self.process.state() != QProcess.ProcessState.NotRunning |
69 and self.process.state() != QProcess.ProcessState.NotRunning |
67 ): |
70 ): |
68 self.process.terminate() |
71 self.process.terminate() |
69 QTimer.singleShot(2000, self.process.kill) |
72 QTimer.singleShot(2000, self.process.kill) |
70 self.process.waitForFinished(3000) |
73 self.process.waitForFinished(3000) |
71 |
74 |
72 e.accept() |
75 e.accept() |
73 |
76 |
74 def start(self, path, commits): |
77 def start(self, path, commits): |
75 """ |
78 """ |
76 Public slot to start the tag/branch list command. |
79 Public slot to start the tag/branch list command. |
77 |
80 |
78 @param path name of directory to be listed (string) |
81 @param path name of directory to be listed (string) |
79 @param commits list of commits to be described (list of string) |
82 @param commits list of commits to be described (list of string) |
80 """ |
83 """ |
81 self.tagList.clear() |
84 self.tagList.clear() |
82 self.errorGroup.hide() |
85 self.errorGroup.hide() |
83 |
86 |
84 self.intercept = False |
87 self.intercept = False |
85 self.activateWindow() |
88 self.activateWindow() |
86 |
89 |
87 self.__commits = commits[:] |
90 self.__commits = commits[:] |
88 self.__tagInfoLines = [] |
91 self.__tagInfoLines = [] |
89 |
92 |
90 dname, fname = self.vcs.splitPath(path) |
93 dname, fname = self.vcs.splitPath(path) |
91 |
94 |
92 # find the root of the repo |
95 # find the root of the repo |
93 self.repodir = dname |
96 self.repodir = dname |
94 while not os.path.isdir(os.path.join(self.repodir, self.vcs.adminDir)): |
97 while not os.path.isdir(os.path.join(self.repodir, self.vcs.adminDir)): |
95 self.repodir = os.path.dirname(self.repodir) |
98 self.repodir = os.path.dirname(self.repodir) |
96 if os.path.splitdrive(self.repodir)[1] == os.sep: |
99 if os.path.splitdrive(self.repodir)[1] == os.sep: |
97 return |
100 return |
98 |
101 |
99 args = self.vcs.initCommand("describe") |
102 args = self.vcs.initCommand("describe") |
100 args.append('--abbrev={0}'.format( |
103 args.append( |
101 self.vcs.getPlugin().getPreferences("CommitIdLength"))) |
104 "--abbrev={0}".format(self.vcs.getPlugin().getPreferences("CommitIdLength")) |
|
105 ) |
102 if commits: |
106 if commits: |
103 args.extend(commits) |
107 args.extend(commits) |
104 else: |
108 else: |
105 args.append('--dirty') |
109 args.append("--dirty") |
106 |
110 |
107 self.process.kill() |
111 self.process.kill() |
108 self.process.setWorkingDirectory(self.repodir) |
112 self.process.setWorkingDirectory(self.repodir) |
109 |
113 |
110 self.process.start('git', args) |
114 self.process.start("git", args) |
111 procStarted = self.process.waitForStarted(5000) |
115 procStarted = self.process.waitForStarted(5000) |
112 if not procStarted: |
116 if not procStarted: |
113 self.inputGroup.setEnabled(False) |
117 self.inputGroup.setEnabled(False) |
114 self.inputGroup.hide() |
118 self.inputGroup.hide() |
115 EricMessageBox.critical( |
119 EricMessageBox.critical( |
116 self, |
120 self, |
117 self.tr('Process Generation Error'), |
121 self.tr("Process Generation Error"), |
118 self.tr( |
122 self.tr( |
119 'The process {0} could not be started. ' |
123 "The process {0} could not be started. " |
120 'Ensure, that it is in the search path.' |
124 "Ensure, that it is in the search path." |
121 ).format('git')) |
125 ).format("git"), |
|
126 ) |
122 else: |
127 else: |
123 self.inputGroup.setEnabled(True) |
128 self.inputGroup.setEnabled(True) |
124 self.inputGroup.show() |
129 self.inputGroup.show() |
125 |
130 |
126 def __finish(self): |
131 def __finish(self): |
127 """ |
132 """ |
128 Private slot called when the process finished or the user pressed |
133 Private slot called when the process finished or the user pressed |
129 the button. |
134 the button. |
130 """ |
135 """ |
131 if ( |
136 if ( |
132 self.process is not None and |
137 self.process is not None |
133 self.process.state() != QProcess.ProcessState.NotRunning |
138 and self.process.state() != QProcess.ProcessState.NotRunning |
134 ): |
139 ): |
135 self.process.terminate() |
140 self.process.terminate() |
136 QTimer.singleShot(2000, self.process.kill) |
141 QTimer.singleShot(2000, self.process.kill) |
137 self.process.waitForFinished(3000) |
142 self.process.waitForFinished(3000) |
138 |
143 |
139 self.inputGroup.setEnabled(False) |
144 self.inputGroup.setEnabled(False) |
140 self.inputGroup.hide() |
145 self.inputGroup.hide() |
141 |
146 |
142 self.buttonBox.button( |
147 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True) |
143 QDialogButtonBox.StandardButton.Close).setEnabled(True) |
148 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(False) |
144 self.buttonBox.button( |
149 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True) |
145 QDialogButtonBox.StandardButton.Cancel).setEnabled(False) |
150 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setFocus( |
146 self.buttonBox.button( |
151 Qt.FocusReason.OtherFocusReason |
147 QDialogButtonBox.StandardButton.Close).setDefault(True) |
152 ) |
148 self.buttonBox.button( |
153 |
149 QDialogButtonBox.StandardButton.Close).setFocus( |
|
150 Qt.FocusReason.OtherFocusReason) |
|
151 |
|
152 self.__resizeColumns() |
154 self.__resizeColumns() |
153 self.__resort() |
155 self.__resort() |
154 |
156 |
155 def on_buttonBox_clicked(self, button): |
157 def on_buttonBox_clicked(self, button): |
156 """ |
158 """ |
157 Private slot called by a button of the button box clicked. |
159 Private slot called by a button of the button box clicked. |
158 |
160 |
159 @param button button that was clicked (QAbstractButton) |
161 @param button button that was clicked (QAbstractButton) |
160 """ |
162 """ |
161 if button == self.buttonBox.button( |
163 if button == self.buttonBox.button(QDialogButtonBox.StandardButton.Close): |
162 QDialogButtonBox.StandardButton.Close |
|
163 ): |
|
164 self.close() |
164 self.close() |
165 elif button == self.buttonBox.button( |
165 elif button == self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel): |
166 QDialogButtonBox.StandardButton.Cancel |
|
167 ): |
|
168 self.__finish() |
166 self.__finish() |
169 |
167 |
170 def __procFinished(self, exitCode, exitStatus): |
168 def __procFinished(self, exitCode, exitStatus): |
171 """ |
169 """ |
172 Private slot connected to the finished signal. |
170 Private slot connected to the finished signal. |
173 |
171 |
174 @param exitCode exit code of the process (integer) |
172 @param exitCode exit code of the process (integer) |
175 @param exitStatus exit status of the process (QProcess.ExitStatus) |
173 @param exitStatus exit status of the process (QProcess.ExitStatus) |
176 """ |
174 """ |
177 if self.__tagInfoLines: |
175 if self.__tagInfoLines: |
178 if self.__commits: |
176 if self.__commits: |
179 for commit, tagInfo in zip(self.__commits, |
177 for commit, tagInfo in zip(self.__commits, self.__tagInfoLines): |
180 self.__tagInfoLines): |
|
181 QTreeWidgetItem(self.tagList, [commit, tagInfo]) |
178 QTreeWidgetItem(self.tagList, [commit, tagInfo]) |
182 else: |
179 else: |
183 for tagInfo in self.__tagInfoLines: |
180 for tagInfo in self.__tagInfoLines: |
184 QTreeWidgetItem(self.tagList, ["", tagInfo]) |
181 QTreeWidgetItem(self.tagList, ["", tagInfo]) |
185 |
182 |
186 self.__finish() |
183 self.__finish() |
187 |
184 |
188 def __resort(self): |
185 def __resort(self): |
189 """ |
186 """ |
190 Private method to resort the tree. |
187 Private method to resort the tree. |
191 """ |
188 """ |
192 self.tagList.sortItems( |
189 self.tagList.sortItems( |
193 self.tagList.sortColumn(), |
190 self.tagList.sortColumn(), self.tagList.header().sortIndicatorOrder() |
194 self.tagList.header().sortIndicatorOrder()) |
191 ) |
195 |
192 |
196 def __resizeColumns(self): |
193 def __resizeColumns(self): |
197 """ |
194 """ |
198 Private method to resize the list columns. |
195 Private method to resize the list columns. |
199 """ |
196 """ |
200 self.tagList.header().resizeSections( |
197 self.tagList.header().resizeSections(QHeaderView.ResizeMode.ResizeToContents) |
201 QHeaderView.ResizeMode.ResizeToContents) |
|
202 self.tagList.header().setStretchLastSection(True) |
198 self.tagList.header().setStretchLastSection(True) |
203 |
199 |
204 def __readStdout(self): |
200 def __readStdout(self): |
205 """ |
201 """ |
206 Private slot to handle the readyReadStdout signal. |
202 Private slot to handle the readyReadStdout signal. |
207 |
203 |
208 It reads the output of the process, formats it and inserts it into |
204 It reads the output of the process, formats it and inserts it into |
209 the contents pane. |
205 the contents pane. |
210 """ |
206 """ |
211 self.process.setReadChannel(QProcess.ProcessChannel.StandardOutput) |
207 self.process.setReadChannel(QProcess.ProcessChannel.StandardOutput) |
212 |
208 |
213 while self.process.canReadLine(): |
209 while self.process.canReadLine(): |
214 s = str(self.process.readLine(), |
210 s = str( |
215 Preferences.getSystem("IOEncoding"), |
211 self.process.readLine(), Preferences.getSystem("IOEncoding"), "replace" |
216 'replace') |
212 ) |
217 self.__tagInfoLines.append(s.strip()) |
213 self.__tagInfoLines.append(s.strip()) |
218 |
214 |
219 def __readStderr(self): |
215 def __readStderr(self): |
220 """ |
216 """ |
221 Private slot to handle the readyReadStderr signal. |
217 Private slot to handle the readyReadStderr signal. |
222 |
218 |
223 It reads the error output of the process and inserts it into the |
219 It reads the error output of the process and inserts it into the |
224 error pane. |
220 error pane. |
225 """ |
221 """ |
226 if self.process is not None: |
222 if self.process is not None: |
227 s = str(self.process.readAllStandardError(), |
223 s = str( |
228 Preferences.getSystem("IOEncoding"), |
224 self.process.readAllStandardError(), |
229 'replace') |
225 Preferences.getSystem("IOEncoding"), |
|
226 "replace", |
|
227 ) |
230 self.errorGroup.show() |
228 self.errorGroup.show() |
231 self.errors.insertPlainText(s) |
229 self.errors.insertPlainText(s) |
232 self.errors.ensureCursorVisible() |
230 self.errors.ensureCursorVisible() |
233 |
231 |
234 def on_passwordCheckBox_toggled(self, isOn): |
232 def on_passwordCheckBox_toggled(self, isOn): |
235 """ |
233 """ |
236 Private slot to handle the password checkbox toggled. |
234 Private slot to handle the password checkbox toggled. |
237 |
235 |
238 @param isOn flag indicating the status of the check box (boolean) |
236 @param isOn flag indicating the status of the check box (boolean) |
239 """ |
237 """ |
240 if isOn: |
238 if isOn: |
241 self.input.setEchoMode(QLineEdit.EchoMode.Password) |
239 self.input.setEchoMode(QLineEdit.EchoMode.Password) |
242 else: |
240 else: |
243 self.input.setEchoMode(QLineEdit.EchoMode.Normal) |
241 self.input.setEchoMode(QLineEdit.EchoMode.Normal) |
244 |
242 |
245 @pyqtSlot() |
243 @pyqtSlot() |
246 def on_sendButton_clicked(self): |
244 def on_sendButton_clicked(self): |
247 """ |
245 """ |
248 Private slot to send the input to the git process. |
246 Private slot to send the input to the git process. |
249 """ |
247 """ |
250 inputTxt = self.input.text() |
248 inputTxt = self.input.text() |
251 inputTxt += os.linesep |
249 inputTxt += os.linesep |
252 |
250 |
253 if self.passwordCheckBox.isChecked(): |
251 if self.passwordCheckBox.isChecked(): |
254 self.errors.insertPlainText(os.linesep) |
252 self.errors.insertPlainText(os.linesep) |
255 self.errors.ensureCursorVisible() |
253 self.errors.ensureCursorVisible() |
256 else: |
254 else: |
257 self.errors.insertPlainText(inputTxt) |
255 self.errors.insertPlainText(inputTxt) |
258 self.errors.ensureCursorVisible() |
256 self.errors.ensureCursorVisible() |
259 |
257 |
260 self.process.write(strToQByteArray(inputTxt)) |
258 self.process.write(strToQByteArray(inputTxt)) |
261 |
259 |
262 self.passwordCheckBox.setChecked(False) |
260 self.passwordCheckBox.setChecked(False) |
263 self.input.clear() |
261 self.input.clear() |
264 |
262 |
265 def on_input_returnPressed(self): |
263 def on_input_returnPressed(self): |
266 """ |
264 """ |
267 Private slot to handle the press of the return key in the input field. |
265 Private slot to handle the press of the return key in the input field. |
268 """ |
266 """ |
269 self.intercept = True |
267 self.intercept = True |
270 self.on_sendButton_clicked() |
268 self.on_sendButton_clicked() |
271 |
269 |
272 def keyPressEvent(self, evt): |
270 def keyPressEvent(self, evt): |
273 """ |
271 """ |
274 Protected slot to handle a key press event. |
272 Protected slot to handle a key press event. |
275 |
273 |
276 @param evt the key press event (QKeyEvent) |
274 @param evt the key press event (QKeyEvent) |
277 """ |
275 """ |
278 if self.intercept: |
276 if self.intercept: |
279 self.intercept = False |
277 self.intercept = False |
280 evt.accept() |
278 evt.accept() |
281 return |
279 return |
282 |
280 |
283 super().keyPressEvent(evt) |
281 super().keyPressEvent(evt) |