src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnLogBrowserDialog.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
10 import re 10 import re
11 import os 11 import os
12 12
13 from PyQt6.QtCore import pyqtSlot, Qt, QTimer, QDate, QProcess, QPoint 13 from PyQt6.QtCore import pyqtSlot, Qt, QTimer, QDate, QProcess, QPoint
14 from PyQt6.QtWidgets import ( 14 from PyQt6.QtWidgets import (
15 QHeaderView, QLineEdit, QWidget, QApplication, QDialogButtonBox, 15 QHeaderView,
16 QTreeWidgetItem 16 QLineEdit,
17 QWidget,
18 QApplication,
19 QDialogButtonBox,
20 QTreeWidgetItem,
17 ) 21 )
18 22
19 from EricWidgets import EricMessageBox 23 from EricWidgets import EricMessageBox
20 from EricGui.EricOverrideCursor import EricOverrideCursorProcess 24 from EricGui.EricOverrideCursor import EricOverrideCursorProcess
21 25
28 32
29 class SvnLogBrowserDialog(QWidget, Ui_SvnLogBrowserDialog): 33 class SvnLogBrowserDialog(QWidget, Ui_SvnLogBrowserDialog):
30 """ 34 """
31 Class implementing a dialog to browse the log history. 35 Class implementing a dialog to browse the log history.
32 """ 36 """
37
33 def __init__(self, vcs, parent=None): 38 def __init__(self, vcs, parent=None):
34 """ 39 """
35 Constructor 40 Constructor
36 41
37 @param vcs reference to the vcs object 42 @param vcs reference to the vcs object
38 @param parent parent widget (QWidget) 43 @param parent parent widget (QWidget)
39 """ 44 """
40 super().__init__(parent) 45 super().__init__(parent)
41 self.setupUi(self) 46 self.setupUi(self)
42 47
43 self.__position = QPoint() 48 self.__position = QPoint()
44 49
45 self.buttonBox.button( 50 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False)
46 QDialogButtonBox.StandardButton.Close).setEnabled(False) 51 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(True)
47 self.buttonBox.button( 52
48 QDialogButtonBox.StandardButton.Cancel).setDefault(True)
49
50 self.upButton.setIcon(UI.PixmapCache.getIcon("1uparrow")) 53 self.upButton.setIcon(UI.PixmapCache.getIcon("1uparrow"))
51 self.downButton.setIcon(UI.PixmapCache.getIcon("1downarrow")) 54 self.downButton.setIcon(UI.PixmapCache.getIcon("1downarrow"))
52 55
53 self.filesTree.headerItem().setText(self.filesTree.columnCount(), "") 56 self.filesTree.headerItem().setText(self.filesTree.columnCount(), "")
54 self.filesTree.header().setSortIndicator( 57 self.filesTree.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder)
55 0, Qt.SortOrder.AscendingOrder) 58
56
57 self.vcs = vcs 59 self.vcs = vcs
58 60
59 self.__initData() 61 self.__initData()
60 62
61 self.fromDate.setDisplayFormat("yyyy-MM-dd") 63 self.fromDate.setDisplayFormat("yyyy-MM-dd")
62 self.toDate.setDisplayFormat("yyyy-MM-dd") 64 self.toDate.setDisplayFormat("yyyy-MM-dd")
63 self.__resetUI() 65 self.__resetUI()
64 66
65 self.__messageRole = Qt.ItemDataRole.UserRole 67 self.__messageRole = Qt.ItemDataRole.UserRole
66 self.__changesRole = Qt.ItemDataRole.UserRole + 1 68 self.__changesRole = Qt.ItemDataRole.UserRole + 1
67 69
68 self.__process = EricOverrideCursorProcess() 70 self.__process = EricOverrideCursorProcess()
69 self.__process.finished.connect(self.__procFinished) 71 self.__process.finished.connect(self.__procFinished)
70 self.__process.readyReadStandardOutput.connect(self.__readStdout) 72 self.__process.readyReadStandardOutput.connect(self.__readStdout)
71 self.__process.readyReadStandardError.connect(self.__readStderr) 73 self.__process.readyReadStandardError.connect(self.__readStderr)
72 74
73 self.rx_sep1 = re.compile('\\-+\\s*') 75 self.rx_sep1 = re.compile("\\-+\\s*")
74 self.rx_sep2 = re.compile('=+\\s*') 76 self.rx_sep2 = re.compile("=+\\s*")
75 self.rx_rev1 = re.compile( 77 self.rx_rev1 = re.compile(r"rev ([0-9]+): ([^|]*) \| ([^|]*) \| ([0-9]+) .*")
76 r'rev ([0-9]+): ([^|]*) \| ([^|]*) \| ([0-9]+) .*')
77 # "rev" followed by one or more decimals followed by a colon followed 78 # "rev" followed by one or more decimals followed by a colon followed
78 # anything up to " | " (twice) followed by one or more decimals 79 # anything up to " | " (twice) followed by one or more decimals
79 # followed by anything 80 # followed by anything
80 self.rx_rev2 = re.compile( 81 self.rx_rev2 = re.compile(r"r([0-9]+) \| ([^|]*) \| ([^|]*) \| ([0-9]+) .*")
81 r'r([0-9]+) \| ([^|]*) \| ([^|]*) \| ([0-9]+) .*')
82 # "r" followed by one or more decimals followed by " | " followed 82 # "r" followed by one or more decimals followed by " | " followed
83 # anything up to " | " (twice) followed by one or more decimals 83 # anything up to " | " (twice) followed by one or more decimals
84 # followed by anything 84 # followed by anything
85 self.rx_flags1 = re.compile( 85 self.rx_flags1 = re.compile(
86 r""" ([ADM])\s(.*)\s+\(\w+\s+(.*):([0-9]+)\)\s*""") 86 r""" ([ADM])\s(.*)\s+\(\w+\s+(.*):([0-9]+)\)\s*"""
87 )
87 # three blanks followed by A or D or M followed by path followed by 88 # three blanks followed by A or D or M followed by path followed by
88 # path copied from followed by copied from revision 89 # path copied from followed by copied from revision
89 self.rx_flags2 = re.compile(' ([ADM]) (.*)\\s*') 90 self.rx_flags2 = re.compile(" ([ADM]) (.*)\\s*")
90 # three blanks followed by A or D or M followed by path 91 # three blanks followed by A or D or M followed by path
91 92
92 self.flags = { 93 self.flags = {
93 'A': self.tr('Added'), 94 "A": self.tr("Added"),
94 'D': self.tr('Deleted'), 95 "D": self.tr("Deleted"),
95 'M': self.tr('Modified'), 96 "M": self.tr("Modified"),
96 'R': self.tr('Replaced'), 97 "R": self.tr("Replaced"),
97 } 98 }
98 self.intercept = False 99 self.intercept = False
99 100
100 self.__logTreeNormalFont = self.logTree.font() 101 self.__logTreeNormalFont = self.logTree.font()
101 self.__logTreeNormalFont.setBold(False) 102 self.__logTreeNormalFont.setBold(False)
102 self.__logTreeBoldFont = self.logTree.font() 103 self.__logTreeBoldFont = self.logTree.font()
103 self.__logTreeBoldFont.setBold(True) 104 self.__logTreeBoldFont.setBold(True)
104 105
105 self.__finishCallbacks = [] 106 self.__finishCallbacks = []
106 107
107 def __addFinishCallback(self, callback): 108 def __addFinishCallback(self, callback):
108 """ 109 """
109 Private method to add a method to be called once the process finished. 110 Private method to add a method to be called once the process finished.
110 111
111 The callback methods are invoke in a FIFO style and are consumed. If 112 The callback methods are invoke in a FIFO style and are consumed. If
112 a callback method needs to be called again, it must be added again. 113 a callback method needs to be called again, it must be added again.
113 114
114 @param callback callback method 115 @param callback callback method
115 @type function 116 @type function
116 """ 117 """
117 if callback not in self.__finishCallbacks: 118 if callback not in self.__finishCallbacks:
118 self.__finishCallbacks.append(callback) 119 self.__finishCallbacks.append(callback)
119 120
120 def __initData(self): 121 def __initData(self):
121 """ 122 """
122 Private method to (re-)initialize some data. 123 Private method to (re-)initialize some data.
123 """ 124 """
124 self.__maxDate = QDate() 125 self.__maxDate = QDate()
125 self.__minDate = QDate() 126 self.__minDate = QDate()
126 self.__filterLogsEnabled = True 127 self.__filterLogsEnabled = True
127 128
128 self.buf = [] # buffer for stdout 129 self.buf = [] # buffer for stdout
129 self.diff = None 130 self.diff = None
130 self.__started = False 131 self.__started = False
131 self.__lastRev = 0 132 self.__lastRev = 0
132 133
133 def closeEvent(self, e): 134 def closeEvent(self, e):
134 """ 135 """
135 Protected slot implementing a close event handler. 136 Protected slot implementing a close event handler.
136 137
137 @param e close event (QCloseEvent) 138 @param e close event (QCloseEvent)
138 """ 139 """
139 if ( 140 if (
140 self.__process is not None and 141 self.__process is not None
141 self.__process.state() != QProcess.ProcessState.NotRunning 142 and self.__process.state() != QProcess.ProcessState.NotRunning
142 ): 143 ):
143 self.__process.terminate() 144 self.__process.terminate()
144 QTimer.singleShot(2000, self.__process.kill) 145 QTimer.singleShot(2000, self.__process.kill)
145 self.__process.waitForFinished(3000) 146 self.__process.waitForFinished(3000)
146 147
147 self.__position = self.pos() 148 self.__position = self.pos()
148 149
149 e.accept() 150 e.accept()
150 151
151 def show(self): 152 def show(self):
152 """ 153 """
153 Public slot to show the dialog. 154 Public slot to show the dialog.
154 """ 155 """
155 if not self.__position.isNull(): 156 if not self.__position.isNull():
156 self.move(self.__position) 157 self.move(self.__position)
157 self.__resetUI() 158 self.__resetUI()
158 159
159 super().show() 160 super().show()
160 161
161 def __resetUI(self): 162 def __resetUI(self):
162 """ 163 """
163 Private method to reset the user interface. 164 Private method to reset the user interface.
164 """ 165 """
165 self.fromDate.setDate(QDate.currentDate()) 166 self.fromDate.setDate(QDate.currentDate())
166 self.toDate.setDate(QDate.currentDate()) 167 self.toDate.setDate(QDate.currentDate())
167 self.fieldCombo.setCurrentIndex(self.fieldCombo.findText( 168 self.fieldCombo.setCurrentIndex(self.fieldCombo.findText(self.tr("Message")))
168 self.tr("Message"))) 169 self.limitSpinBox.setValue(self.vcs.getPlugin().getPreferences("LogLimit"))
169 self.limitSpinBox.setValue(self.vcs.getPlugin().getPreferences( 170 self.stopCheckBox.setChecked(
170 "LogLimit")) 171 self.vcs.getPlugin().getPreferences("StopLogOnCopy")
171 self.stopCheckBox.setChecked(self.vcs.getPlugin().getPreferences( 172 )
172 "StopLogOnCopy")) 173
173
174 self.logTree.clear() 174 self.logTree.clear()
175 175
176 self.nextButton.setEnabled(True) 176 self.nextButton.setEnabled(True)
177 self.limitSpinBox.setEnabled(True) 177 self.limitSpinBox.setEnabled(True)
178 178
179 def __resizeColumnsLog(self): 179 def __resizeColumnsLog(self):
180 """ 180 """
181 Private method to resize the log tree columns. 181 Private method to resize the log tree columns.
182 """ 182 """
183 self.logTree.header().resizeSections( 183 self.logTree.header().resizeSections(QHeaderView.ResizeMode.ResizeToContents)
184 QHeaderView.ResizeMode.ResizeToContents)
185 self.logTree.header().setStretchLastSection(True) 184 self.logTree.header().setStretchLastSection(True)
186 185
187 def __resortLog(self): 186 def __resortLog(self):
188 """ 187 """
189 Private method to resort the log tree. 188 Private method to resort the log tree.
190 """ 189 """
191 self.logTree.sortItems( 190 self.logTree.sortItems(
192 self.logTree.sortColumn(), 191 self.logTree.sortColumn(), self.logTree.header().sortIndicatorOrder()
193 self.logTree.header().sortIndicatorOrder()) 192 )
194 193
195 def __resizeColumnsFiles(self): 194 def __resizeColumnsFiles(self):
196 """ 195 """
197 Private method to resize the changed files tree columns. 196 Private method to resize the changed files tree columns.
198 """ 197 """
199 self.filesTree.header().resizeSections( 198 self.filesTree.header().resizeSections(QHeaderView.ResizeMode.ResizeToContents)
200 QHeaderView.ResizeMode.ResizeToContents)
201 self.filesTree.header().setStretchLastSection(True) 199 self.filesTree.header().setStretchLastSection(True)
202 200
203 def __resortFiles(self): 201 def __resortFiles(self):
204 """ 202 """
205 Private method to resort the changed files tree. 203 Private method to resort the changed files tree.
206 """ 204 """
207 sortColumn = self.filesTree.sortColumn() 205 sortColumn = self.filesTree.sortColumn()
206 self.filesTree.sortItems(1, self.filesTree.header().sortIndicatorOrder())
208 self.filesTree.sortItems( 207 self.filesTree.sortItems(
209 1, self.filesTree.header().sortIndicatorOrder()) 208 sortColumn, self.filesTree.header().sortIndicatorOrder()
210 self.filesTree.sortItems( 209 )
211 sortColumn, self.filesTree.header().sortIndicatorOrder()) 210
212
213 def __generateLogItem(self, author, date, message, revision, changedPaths): 211 def __generateLogItem(self, author, date, message, revision, changedPaths):
214 """ 212 """
215 Private method to generate a log tree entry. 213 Private method to generate a log tree entry.
216 214
217 @param author author info (string) 215 @param author author info (string)
218 @param date date info (string) 216 @param date date info (string)
219 @param message text of the log message (list of strings) 217 @param message text of the log message (list of strings)
220 @param revision revision info (string) 218 @param revision revision info (string)
221 @param changedPaths list of dictionary objects containing 219 @param changedPaths list of dictionary objects containing
223 @return reference to the generated item (QTreeWidgetItem) 221 @return reference to the generated item (QTreeWidgetItem)
224 """ 222 """
225 msg = [] 223 msg = []
226 for line in message: 224 for line in message:
227 msg.append(line.strip()) 225 msg.append(line.strip())
228 226
229 itm = QTreeWidgetItem(self.logTree) 227 itm = QTreeWidgetItem(self.logTree)
230 itm.setData(0, Qt.ItemDataRole.DisplayRole, int(revision)) 228 itm.setData(0, Qt.ItemDataRole.DisplayRole, int(revision))
231 itm.setData(1, Qt.ItemDataRole.DisplayRole, author) 229 itm.setData(1, Qt.ItemDataRole.DisplayRole, author)
232 itm.setData(2, Qt.ItemDataRole.DisplayRole, date) 230 itm.setData(2, Qt.ItemDataRole.DisplayRole, date)
233 itm.setData(3, Qt.ItemDataRole.DisplayRole, " ".join(msg)) 231 itm.setData(3, Qt.ItemDataRole.DisplayRole, " ".join(msg))
234 232
235 itm.setData(0, self.__messageRole, message) 233 itm.setData(0, self.__messageRole, message)
236 itm.setData(0, self.__changesRole, changedPaths) 234 itm.setData(0, self.__changesRole, changedPaths)
237 235
238 itm.setTextAlignment(0, Qt.AlignmentFlag.AlignRight) 236 itm.setTextAlignment(0, Qt.AlignmentFlag.AlignRight)
239 itm.setTextAlignment(1, Qt.AlignmentFlag.AlignLeft) 237 itm.setTextAlignment(1, Qt.AlignmentFlag.AlignLeft)
240 itm.setTextAlignment(2, Qt.AlignmentFlag.AlignLeft) 238 itm.setTextAlignment(2, Qt.AlignmentFlag.AlignLeft)
241 itm.setTextAlignment(3, Qt.AlignmentFlag.AlignLeft) 239 itm.setTextAlignment(3, Qt.AlignmentFlag.AlignLeft)
242 itm.setTextAlignment(4, Qt.AlignmentFlag.AlignLeft) 240 itm.setTextAlignment(4, Qt.AlignmentFlag.AlignLeft)
243 241
244 try: 242 try:
245 self.__lastRev = int(revision) 243 self.__lastRev = int(revision)
246 except ValueError: 244 except ValueError:
247 self.__lastRev = 0 245 self.__lastRev = 0
248 246
249 return itm 247 return itm
250 248
251 def __generateFileItem(self, action, path, copyFrom, copyRev): 249 def __generateFileItem(self, action, path, copyFrom, copyRev):
252 """ 250 """
253 Private method to generate a changed files tree entry. 251 Private method to generate a changed files tree entry.
254 252
255 @param action indicator for the change action ("A", "D" or "M") 253 @param action indicator for the change action ("A", "D" or "M")
256 @param path path of the file in the repository (string) 254 @param path path of the file in the repository (string)
257 @param copyFrom path the file was copied from (None, string) 255 @param copyFrom path the file was copied from (None, string)
258 @param copyRev revision the file was copied from (None, string) 256 @param copyRev revision the file was copied from (None, string)
259 @return reference to the generated item (QTreeWidgetItem) 257 @return reference to the generated item (QTreeWidgetItem)
260 """ 258 """
261 itm = QTreeWidgetItem(self.filesTree, [ 259 itm = QTreeWidgetItem(
262 self.flags[action], 260 self.filesTree,
263 path, 261 [
264 copyFrom, 262 self.flags[action],
265 copyRev, 263 path,
266 ]) 264 copyFrom,
267 265 copyRev,
266 ],
267 )
268
268 itm.setTextAlignment(3, Qt.AlignmentFlag.AlignRight) 269 itm.setTextAlignment(3, Qt.AlignmentFlag.AlignRight)
269 270
270 return itm 271 return itm
271 272
272 def __getLogEntries(self, startRev=None): 273 def __getLogEntries(self, startRev=None):
273 """ 274 """
274 Private method to retrieve log entries from the repository. 275 Private method to retrieve log entries from the repository.
275 276
276 @param startRev revision number to start from (integer, string) 277 @param startRev revision number to start from (integer, string)
277 """ 278 """
278 self.buttonBox.button( 279 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False)
279 QDialogButtonBox.StandardButton.Close).setEnabled(False) 280 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(True)
280 self.buttonBox.button( 281 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(True)
281 QDialogButtonBox.StandardButton.Cancel).setEnabled(True)
282 self.buttonBox.button(
283 QDialogButtonBox.StandardButton.Cancel).setDefault(True)
284 QApplication.processEvents() 282 QApplication.processEvents()
285 283
286 self.intercept = False 284 self.intercept = False
287 self.__process.kill() 285 self.__process.kill()
288 286
289 self.buf = [] 287 self.buf = []
290 self.cancelled = False 288 self.cancelled = False
291 self.errors.clear() 289 self.errors.clear()
292 290
293 args = [] 291 args = []
294 args.append('log') 292 args.append("log")
295 self.vcs.addArguments(args, self.vcs.options['global']) 293 self.vcs.addArguments(args, self.vcs.options["global"])
296 self.vcs.addArguments(args, self.vcs.options['log']) 294 self.vcs.addArguments(args, self.vcs.options["log"])
297 args.append('--verbose') 295 args.append("--verbose")
298 args.append('--limit') 296 args.append("--limit")
299 args.append('{0:d}'.format(self.limitSpinBox.value())) 297 args.append("{0:d}".format(self.limitSpinBox.value()))
300 if startRev is not None: 298 if startRev is not None:
301 args.append('--revision') 299 args.append("--revision")
302 args.append('{0}:0'.format(startRev)) 300 args.append("{0}:0".format(startRev))
303 if self.stopCheckBox.isChecked(): 301 if self.stopCheckBox.isChecked():
304 args.append('--stop-on-copy') 302 args.append("--stop-on-copy")
305 args.append(self.fname) 303 args.append(self.fname)
306 304
307 self.__process.setWorkingDirectory(self.dname) 305 self.__process.setWorkingDirectory(self.dname)
308 306
309 self.inputGroup.setEnabled(True) 307 self.inputGroup.setEnabled(True)
310 self.inputGroup.show() 308 self.inputGroup.show()
311 309
312 self.__process.start('svn', args) 310 self.__process.start("svn", args)
313 procStarted = self.__process.waitForStarted(5000) 311 procStarted = self.__process.waitForStarted(5000)
314 if not procStarted: 312 if not procStarted:
315 self.inputGroup.setEnabled(False) 313 self.inputGroup.setEnabled(False)
316 self.inputGroup.hide() 314 self.inputGroup.hide()
317 EricMessageBox.critical( 315 EricMessageBox.critical(
318 self, 316 self,
319 self.tr('Process Generation Error'), 317 self.tr("Process Generation Error"),
320 self.tr( 318 self.tr(
321 'The process {0} could not be started. ' 319 "The process {0} could not be started. "
322 'Ensure, that it is in the search path.' 320 "Ensure, that it is in the search path."
323 ).format('svn')) 321 ).format("svn"),
324 322 )
323
325 def start(self, fn, isFile=False): 324 def start(self, fn, isFile=False):
326 """ 325 """
327 Public slot to start the svn log command. 326 Public slot to start the svn log command.
328 327
329 @param fn filename to show the log for (string) 328 @param fn filename to show the log for (string)
330 @param isFile flag indicating log for a file is to be shown 329 @param isFile flag indicating log for a file is to be shown
331 (boolean) 330 (boolean)
332 """ 331 """
333 self.sbsCheckBox.setEnabled(isFile) 332 self.sbsCheckBox.setEnabled(isFile)
334 self.sbsCheckBox.setVisible(isFile) 333 self.sbsCheckBox.setVisible(isFile)
335 334
336 self.errorGroup.hide() 335 self.errorGroup.hide()
337 QApplication.processEvents() 336 QApplication.processEvents()
338 337
339 self.__initData() 338 self.__initData()
340 339
341 self.filename = fn 340 self.filename = fn
342 self.dname, self.fname = self.vcs.splitPath(fn) 341 self.dname, self.fname = self.vcs.splitPath(fn)
343 342
344 self.activateWindow() 343 self.activateWindow()
345 self.raise_() 344 self.raise_()
346 345
347 self.logTree.clear() 346 self.logTree.clear()
348 self.__started = True 347 self.__started = True
349 self.__getLogEntries() 348 self.__getLogEntries()
350 349
351 def __procFinished(self, exitCode, exitStatus): 350 def __procFinished(self, exitCode, exitStatus):
352 """ 351 """
353 Private slot connected to the finished signal. 352 Private slot connected to the finished signal.
354 353
355 @param exitCode exit code of the process (integer) 354 @param exitCode exit code of the process (integer)
356 @param exitStatus exit status of the process (QProcess.ExitStatus) 355 @param exitStatus exit status of the process (QProcess.ExitStatus)
357 """ 356 """
358 self.__processBuffer() 357 self.__processBuffer()
359 self.__finish() 358 self.__finish()
360 359
361 def __finish(self): 360 def __finish(self):
362 """ 361 """
363 Private slot called when the process finished or the user pressed the 362 Private slot called when the process finished or the user pressed the
364 button. 363 button.
365 """ 364 """
366 if ( 365 if (
367 self.__process is not None and 366 self.__process is not None
368 self.__process.state() != QProcess.ProcessState.NotRunning 367 and self.__process.state() != QProcess.ProcessState.NotRunning
369 ): 368 ):
370 self.__process.terminate() 369 self.__process.terminate()
371 QTimer.singleShot(2000, self.__process.kill) 370 QTimer.singleShot(2000, self.__process.kill)
372 self.__process.waitForFinished(3000) 371 self.__process.waitForFinished(3000)
373 372
374 self.buttonBox.button( 373 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True)
375 QDialogButtonBox.StandardButton.Close).setEnabled(True) 374 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(False)
376 self.buttonBox.button( 375 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True)
377 QDialogButtonBox.StandardButton.Cancel).setEnabled(False) 376
378 self.buttonBox.button(
379 QDialogButtonBox.StandardButton.Close).setDefault(True)
380
381 self.inputGroup.setEnabled(False) 377 self.inputGroup.setEnabled(False)
382 self.inputGroup.hide() 378 self.inputGroup.hide()
383 379
384 while self.__finishCallbacks: 380 while self.__finishCallbacks:
385 self.__finishCallbacks.pop(0)() 381 self.__finishCallbacks.pop(0)()
386 382
387 def __processBuffer(self): 383 def __processBuffer(self):
388 """ 384 """
389 Private method to process the buffered output of the svn log command. 385 Private method to process the buffered output of the svn log command.
390 """ 386 """
391 noEntries = 0 387 noEntries = 0
392 log = {"message": []} 388 log = {"message": []}
393 changedPaths = [] 389 changedPaths = []
394 for s in self.buf: 390 for s in self.buf:
395 match = ( 391 match = (
396 self.rx_rev1.fullmatch(s) or 392 self.rx_rev1.fullmatch(s)
397 self.rx_rev2.fullmatch(s) or 393 or self.rx_rev2.fullmatch(s)
398 self.rx_flags1.fullmatch(s) or 394 or self.rx_flags1.fullmatch(s)
399 self.rx_flags2.fullmatch(s) or 395 or self.rx_flags2.fullmatch(s)
400 self.rx_sep1.fullmatch(s) or 396 or self.rx_sep1.fullmatch(s)
401 self.rx_sep2.fullmatch(s) 397 or self.rx_sep2.fullmatch(s)
402 ) 398 )
403 if match is None: 399 if match is None:
404 if s.strip().endswith(":") or not s.strip(): 400 if s.strip().endswith(":") or not s.strip():
405 continue 401 continue
406 else: 402 else:
414 log["revision"] = match.group(1) 410 log["revision"] = match.group(1)
415 log["author"] = match.group(2) 411 log["author"] = match.group(2)
416 log["date"] = " ".join(match.group(3).split()[:2]) 412 log["date"] = " ".join(match.group(3).split()[:2])
417 # number of lines is ignored 413 # number of lines is ignored
418 elif match.re is self.rx_flags1: 414 elif match.re is self.rx_flags1:
419 changedPaths.append({ 415 changedPaths.append(
420 "action": match.group(1).strip(), 416 {
421 "path": match.group(2).strip(), 417 "action": match.group(1).strip(),
422 "copyfrom_path": match.group(3).strip(), 418 "path": match.group(2).strip(),
423 "copyfrom_revision": match.group(4).strip(), 419 "copyfrom_path": match.group(3).strip(),
424 }) 420 "copyfrom_revision": match.group(4).strip(),
421 }
422 )
425 elif match.re is self.rx_flags2: 423 elif match.re is self.rx_flags2:
426 changedPaths.append({ 424 changedPaths.append(
427 "action": match.group(1).strip(), 425 {
428 "path": match.group(2).strip(), 426 "action": match.group(1).strip(),
429 "copyfrom_path": "", 427 "path": match.group(2).strip(),
430 "copyfrom_revision": "", 428 "copyfrom_path": "",
431 }) 429 "copyfrom_revision": "",
432 elif ( 430 }
433 (match.re is self.rx_sep1 or match.re is self.rx_sep2) and 431 )
434 len(log) > 1 432 elif (match.re is self.rx_sep1 or match.re is self.rx_sep2) and len(
435 ): 433 log
434 ) > 1:
436 self.__generateLogItem( 435 self.__generateLogItem(
437 log["author"], log["date"], log["message"], 436 log["author"],
438 log["revision"], changedPaths) 437 log["date"],
438 log["message"],
439 log["revision"],
440 changedPaths,
441 )
439 dt = QDate.fromString(log["date"], Qt.DateFormat.ISODate) 442 dt = QDate.fromString(log["date"], Qt.DateFormat.ISODate)
440 if ( 443 if not self.__maxDate.isValid() and not self.__minDate.isValid():
441 not self.__maxDate.isValid() and
442 not self.__minDate.isValid()
443 ):
444 self.__maxDate = dt 444 self.__maxDate = dt
445 self.__minDate = dt 445 self.__minDate = dt
446 else: 446 else:
447 if self.__maxDate < dt: 447 if self.__maxDate < dt:
448 self.__maxDate = dt 448 self.__maxDate = dt
449 if self.__minDate > dt: 449 if self.__minDate > dt:
450 self.__minDate = dt 450 self.__minDate = dt
451 noEntries += 1 451 noEntries += 1
452 log = {"message": []} 452 log = {"message": []}
453 changedPaths = [] 453 changedPaths = []
454 454
455 self.__resizeColumnsLog() 455 self.__resizeColumnsLog()
456 self.__resortLog() 456 self.__resortLog()
457 457
458 if self.__started: 458 if self.__started:
459 self.logTree.setCurrentItem(self.logTree.topLevelItem(0)) 459 self.logTree.setCurrentItem(self.logTree.topLevelItem(0))
460 self.__started = False 460 self.__started = False
461 461
462 if noEntries < self.limitSpinBox.value() and not self.cancelled: 462 if noEntries < self.limitSpinBox.value() and not self.cancelled:
463 self.nextButton.setEnabled(False) 463 self.nextButton.setEnabled(False)
464 self.limitSpinBox.setEnabled(False) 464 self.limitSpinBox.setEnabled(False)
465 465
466 self.__filterLogsEnabled = False 466 self.__filterLogsEnabled = False
467 self.fromDate.setMinimumDate(self.__minDate) 467 self.fromDate.setMinimumDate(self.__minDate)
468 self.fromDate.setMaximumDate(self.__maxDate) 468 self.fromDate.setMaximumDate(self.__maxDate)
469 self.fromDate.setDate(self.__minDate) 469 self.fromDate.setDate(self.__minDate)
470 self.toDate.setMinimumDate(self.__minDate) 470 self.toDate.setMinimumDate(self.__minDate)
471 self.toDate.setMaximumDate(self.__maxDate) 471 self.toDate.setMaximumDate(self.__maxDate)
472 self.toDate.setDate(self.__maxDate) 472 self.toDate.setDate(self.__maxDate)
473 self.__filterLogsEnabled = True 473 self.__filterLogsEnabled = True
474 self.__filterLogs() 474 self.__filterLogs()
475 475
476 def __readStdout(self): 476 def __readStdout(self):
477 """ 477 """
478 Private slot to handle the readyReadStandardOutput signal. 478 Private slot to handle the readyReadStandardOutput signal.
479 479
480 It reads the output of the process and inserts it into a buffer. 480 It reads the output of the process and inserts it into a buffer.
481 """ 481 """
482 self.__process.setReadChannel(QProcess.ProcessChannel.StandardOutput) 482 self.__process.setReadChannel(QProcess.ProcessChannel.StandardOutput)
483 483
484 while self.__process.canReadLine(): 484 while self.__process.canReadLine():
485 line = str(self.__process.readLine(), 485 line = str(
486 Preferences.getSystem("IOEncoding"), 486 self.__process.readLine(),
487 'replace') 487 Preferences.getSystem("IOEncoding"),
488 "replace",
489 )
488 self.buf.append(line) 490 self.buf.append(line)
489 491
490 def __readStderr(self): 492 def __readStderr(self):
491 """ 493 """
492 Private slot to handle the readyReadStandardError signal. 494 Private slot to handle the readyReadStandardError signal.
493 495
494 It reads the error output of the process and inserts it into the 496 It reads the error output of the process and inserts it into the
495 error pane. 497 error pane.
496 """ 498 """
497 if self.__process is not None: 499 if self.__process is not None:
498 self.errorGroup.show() 500 self.errorGroup.show()
499 s = str(self.__process.readAllStandardError(), 501 s = str(
500 Preferences.getSystem("IOEncoding"), 502 self.__process.readAllStandardError(),
501 'replace') 503 Preferences.getSystem("IOEncoding"),
504 "replace",
505 )
502 self.errors.insertPlainText(s) 506 self.errors.insertPlainText(s)
503 self.errors.ensureCursorVisible() 507 self.errors.ensureCursorVisible()
504 508
505 def __diffRevisions(self, rev1, rev2): 509 def __diffRevisions(self, rev1, rev2):
506 """ 510 """
507 Private method to do a diff of two revisions. 511 Private method to do a diff of two revisions.
508 512
509 @param rev1 first revision number (integer) 513 @param rev1 first revision number (integer)
510 @param rev2 second revision number (integer) 514 @param rev2 second revision number (integer)
511 """ 515 """
512 if self.sbsCheckBox.isEnabled() and self.sbsCheckBox.isChecked(): 516 if self.sbsCheckBox.isEnabled() and self.sbsCheckBox.isChecked():
513 self.vcs.vcsSbsDiff(self.filename, 517 self.vcs.vcsSbsDiff(self.filename, revisions=(str(rev1), str(rev2)))
514 revisions=(str(rev1), str(rev2)))
515 else: 518 else:
516 if self.diff is None: 519 if self.diff is None:
517 from .SvnDiffDialog import SvnDiffDialog 520 from .SvnDiffDialog import SvnDiffDialog
521
518 self.diff = SvnDiffDialog(self.vcs) 522 self.diff = SvnDiffDialog(self.vcs)
519 self.diff.show() 523 self.diff.show()
520 self.diff.raise_() 524 self.diff.raise_()
521 self.diff.start(self.filename, [rev1, rev2]) 525 self.diff.start(self.filename, [rev1, rev2])
522 526
523 def on_buttonBox_clicked(self, button): 527 def on_buttonBox_clicked(self, button):
524 """ 528 """
525 Private slot called by a button of the button box clicked. 529 Private slot called by a button of the button box clicked.
526 530
527 @param button button that was clicked (QAbstractButton) 531 @param button button that was clicked (QAbstractButton)
528 """ 532 """
529 if button == self.buttonBox.button( 533 if button == self.buttonBox.button(QDialogButtonBox.StandardButton.Close):
530 QDialogButtonBox.StandardButton.Close
531 ):
532 self.close() 534 self.close()
533 elif button == self.buttonBox.button( 535 elif button == self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel):
534 QDialogButtonBox.StandardButton.Cancel
535 ):
536 self.cancelled = True 536 self.cancelled = True
537 self.__finish() 537 self.__finish()
538 538
539 @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) 539 @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem)
540 def on_logTree_currentItemChanged(self, current, previous): 540 def on_logTree_currentItemChanged(self, current, previous):
541 """ 541 """
542 Private slot called, when the current item of the log tree changes. 542 Private slot called, when the current item of the log tree changes.
543 543
544 @param current reference to the new current item (QTreeWidgetItem) 544 @param current reference to the new current item (QTreeWidgetItem)
545 @param previous reference to the old current item (QTreeWidgetItem) 545 @param previous reference to the old current item (QTreeWidgetItem)
546 """ 546 """
547 if current is not None: 547 if current is not None:
548 self.messageEdit.clear() 548 self.messageEdit.clear()
549 for line in current.data(0, self.__messageRole): 549 for line in current.data(0, self.__messageRole):
550 self.messageEdit.append(line.strip()) 550 self.messageEdit.append(line.strip())
551 551
552 self.filesTree.clear() 552 self.filesTree.clear()
553 changes = current.data(0, self.__changesRole) 553 changes = current.data(0, self.__changesRole)
554 if len(changes) > 0: 554 if len(changes) > 0:
555 for change in changes: 555 for change in changes:
556 self.__generateFileItem( 556 self.__generateFileItem(
557 change["action"], change["path"], 557 change["action"],
558 change["path"],
558 change["copyfrom_path"], 559 change["copyfrom_path"],
559 change["copyfrom_revision"]) 560 change["copyfrom_revision"],
561 )
560 self.__resizeColumnsFiles() 562 self.__resizeColumnsFiles()
561 self.__resortFiles() 563 self.__resortFiles()
562 564
563 self.diffPreviousButton.setEnabled( 565 self.diffPreviousButton.setEnabled(
564 current != self.logTree.topLevelItem( 566 current != self.logTree.topLevelItem(self.logTree.topLevelItemCount() - 1)
565 self.logTree.topLevelItemCount() - 1)) 567 )
566 568
567 # Highlight the current entry using a bold font 569 # Highlight the current entry using a bold font
568 for col in range(self.logTree.columnCount()): 570 for col in range(self.logTree.columnCount()):
569 current and current.setFont(col, self.__logTreeBoldFont) 571 current and current.setFont(col, self.__logTreeBoldFont)
570 previous and previous.setFont(col, self.__logTreeNormalFont) 572 previous and previous.setFont(col, self.__logTreeNormalFont)
571 573
572 # set the state of the up and down buttons 574 # set the state of the up and down buttons
573 self.upButton.setEnabled( 575 self.upButton.setEnabled(
574 current is not None and 576 current is not None and self.logTree.indexOfTopLevelItem(current) > 0
575 self.logTree.indexOfTopLevelItem(current) > 0) 577 )
576 self.downButton.setEnabled( 578 self.downButton.setEnabled(current is not None and int(current.text(0)) > 1)
577 current is not None and 579
578 int(current.text(0)) > 1)
579
580 @pyqtSlot() 580 @pyqtSlot()
581 def on_logTree_itemSelectionChanged(self): 581 def on_logTree_itemSelectionChanged(self):
582 """ 582 """
583 Private slot called, when the selection has changed. 583 Private slot called, when the selection has changed.
584 """ 584 """
585 self.diffRevisionsButton.setEnabled( 585 self.diffRevisionsButton.setEnabled(len(self.logTree.selectedItems()) == 2)
586 len(self.logTree.selectedItems()) == 2) 586
587
588 @pyqtSlot() 587 @pyqtSlot()
589 def on_nextButton_clicked(self): 588 def on_nextButton_clicked(self):
590 """ 589 """
591 Private slot to handle the Next button. 590 Private slot to handle the Next button.
592 """ 591 """
593 if self.__lastRev > 1: 592 if self.__lastRev > 1:
594 self.__getLogEntries(self.__lastRev - 1) 593 self.__getLogEntries(self.__lastRev - 1)
595 594
596 @pyqtSlot() 595 @pyqtSlot()
597 def on_diffPreviousButton_clicked(self): 596 def on_diffPreviousButton_clicked(self):
598 """ 597 """
599 Private slot to handle the Diff to Previous button. 598 Private slot to handle the Diff to Previous button.
600 """ 599 """
601 itm = self.logTree.currentItem() 600 itm = self.logTree.currentItem()
602 if itm is None: 601 if itm is None:
603 self.diffPreviousButton.setEnabled(False) 602 self.diffPreviousButton.setEnabled(False)
604 return 603 return
605 rev2 = int(itm.text(0)) 604 rev2 = int(itm.text(0))
606 605
607 itm = self.logTree.topLevelItem( 606 itm = self.logTree.topLevelItem(self.logTree.indexOfTopLevelItem(itm) + 1)
608 self.logTree.indexOfTopLevelItem(itm) + 1)
609 if itm is None: 607 if itm is None:
610 self.diffPreviousButton.setEnabled(False) 608 self.diffPreviousButton.setEnabled(False)
611 return 609 return
612 rev1 = int(itm.text(0)) 610 rev1 = int(itm.text(0))
613 611
614 self.__diffRevisions(rev1, rev2) 612 self.__diffRevisions(rev1, rev2)
615 613
616 @pyqtSlot() 614 @pyqtSlot()
617 def on_diffRevisionsButton_clicked(self): 615 def on_diffRevisionsButton_clicked(self):
618 """ 616 """
619 Private slot to handle the Compare Revisions button. 617 Private slot to handle the Compare Revisions button.
620 """ 618 """
621 items = self.logTree.selectedItems() 619 items = self.logTree.selectedItems()
622 if len(items) != 2: 620 if len(items) != 2:
623 self.diffRevisionsButton.setEnabled(False) 621 self.diffRevisionsButton.setEnabled(False)
624 return 622 return
625 623
626 rev2 = int(items[0].text(0)) 624 rev2 = int(items[0].text(0))
627 rev1 = int(items[1].text(0)) 625 rev1 = int(items[1].text(0))
628 626
629 self.__diffRevisions(min(rev1, rev2), max(rev1, rev2)) 627 self.__diffRevisions(min(rev1, rev2), max(rev1, rev2))
630 628
631 @pyqtSlot(QDate) 629 @pyqtSlot(QDate)
632 def on_fromDate_dateChanged(self, date): 630 def on_fromDate_dateChanged(self, date):
633 """ 631 """
634 Private slot called, when the from date changes. 632 Private slot called, when the from date changes.
635 633
636 @param date new date (QDate) 634 @param date new date (QDate)
637 """ 635 """
638 self.__filterLogs() 636 self.__filterLogs()
639 637
640 @pyqtSlot(QDate) 638 @pyqtSlot(QDate)
641 def on_toDate_dateChanged(self, date): 639 def on_toDate_dateChanged(self, date):
642 """ 640 """
643 Private slot called, when the from date changes. 641 Private slot called, when the from date changes.
644 642
645 @param date new date (QDate) 643 @param date new date (QDate)
646 """ 644 """
647 self.__filterLogs() 645 self.__filterLogs()
648 646
649 @pyqtSlot(int) 647 @pyqtSlot(int)
650 def on_fieldCombo_activated(self, index): 648 def on_fieldCombo_activated(self, index):
651 """ 649 """
652 Private slot called, when a new filter field is selected. 650 Private slot called, when a new filter field is selected.
653 651
654 @param index index of the selected entry 652 @param index index of the selected entry
655 @type int 653 @type int
656 """ 654 """
657 self.__filterLogs() 655 self.__filterLogs()
658 656
659 @pyqtSlot(str) 657 @pyqtSlot(str)
660 def on_rxEdit_textChanged(self, txt): 658 def on_rxEdit_textChanged(self, txt):
661 """ 659 """
662 Private slot called, when a filter expression is entered. 660 Private slot called, when a filter expression is entered.
663 661
664 @param txt filter expression (string) 662 @param txt filter expression (string)
665 """ 663 """
666 self.__filterLogs() 664 self.__filterLogs()
667 665
668 def __filterLogs(self): 666 def __filterLogs(self):
669 """ 667 """
670 Private method to filter the log entries. 668 Private method to filter the log entries.
671 """ 669 """
672 if self.__filterLogsEnabled: 670 if self.__filterLogsEnabled:
678 searchRx = re.compile(self.rxEdit.text(), re.IGNORECASE) 676 searchRx = re.compile(self.rxEdit.text(), re.IGNORECASE)
679 elif txt == self.tr("Revision"): 677 elif txt == self.tr("Revision"):
680 fieldIndex = 0 678 fieldIndex = 0
681 txt = self.rxEdit.text() 679 txt = self.rxEdit.text()
682 if txt.startswith("^"): 680 if txt.startswith("^"):
683 searchRx = re.compile( 681 searchRx = re.compile(r"^\s*{0}".format(txt[1:]), re.IGNORECASE)
684 r"^\s*{0}".format(txt[1:]), re.IGNORECASE)
685 else: 682 else:
686 searchRx = re.compile(txt, re.IGNORECASE) 683 searchRx = re.compile(txt, re.IGNORECASE)
687 else: 684 else:
688 fieldIndex = 3 685 fieldIndex = 3
689 searchRx = re.compile(self.rxEdit.text(), re.IGNORECASE) 686 searchRx = re.compile(self.rxEdit.text(), re.IGNORECASE)
690 687
691 currentItem = self.logTree.currentItem() 688 currentItem = self.logTree.currentItem()
692 for topIndex in range(self.logTree.topLevelItemCount()): 689 for topIndex in range(self.logTree.topLevelItemCount()):
693 topItem = self.logTree.topLevelItem(topIndex) 690 topItem = self.logTree.topLevelItem(topIndex)
694 if ( 691 if (
695 topItem.text(2) <= to_ and 692 topItem.text(2) <= to_
696 topItem.text(2) >= from_ and 693 and topItem.text(2) >= from_
697 searchRx.match(topItem.text(fieldIndex)) is not None 694 and searchRx.match(topItem.text(fieldIndex)) is not None
698 ): 695 ):
699 topItem.setHidden(False) 696 topItem.setHidden(False)
700 if topItem is currentItem: 697 if topItem is currentItem:
701 self.on_logTree_currentItemChanged(topItem, None) 698 self.on_logTree_currentItemChanged(topItem, None)
702 else: 699 else:
703 topItem.setHidden(True) 700 topItem.setHidden(True)
704 if topItem is currentItem: 701 if topItem is currentItem:
705 self.messageEdit.clear() 702 self.messageEdit.clear()
706 self.filesTree.clear() 703 self.filesTree.clear()
707 704
708 @pyqtSlot(bool) 705 @pyqtSlot(bool)
709 def on_stopCheckBox_clicked(self, checked): 706 def on_stopCheckBox_clicked(self, checked):
710 """ 707 """
711 Private slot called, when the stop on copy/move checkbox is clicked. 708 Private slot called, when the stop on copy/move checkbox is clicked.
712 709
713 @param checked flag indicating the checked state (boolean) 710 @param checked flag indicating the checked state (boolean)
714 """ 711 """
715 self.vcs.getPlugin().setPreferences("StopLogOnCopy", 712 self.vcs.getPlugin().setPreferences(
716 self.stopCheckBox.isChecked()) 713 "StopLogOnCopy", self.stopCheckBox.isChecked()
714 )
717 self.nextButton.setEnabled(True) 715 self.nextButton.setEnabled(True)
718 self.limitSpinBox.setEnabled(True) 716 self.limitSpinBox.setEnabled(True)
719 717
720 @pyqtSlot() 718 @pyqtSlot()
721 def on_upButton_clicked(self): 719 def on_upButton_clicked(self):
722 """ 720 """
723 Private slot to move the current item up one entry. 721 Private slot to move the current item up one entry.
724 """ 722 """
725 itm = self.logTree.itemAbove(self.logTree.currentItem()) 723 itm = self.logTree.itemAbove(self.logTree.currentItem())
726 if itm: 724 if itm:
727 self.logTree.setCurrentItem(itm) 725 self.logTree.setCurrentItem(itm)
728 726
729 @pyqtSlot() 727 @pyqtSlot()
730 def on_downButton_clicked(self): 728 def on_downButton_clicked(self):
731 """ 729 """
732 Private slot to move the current item down one entry. 730 Private slot to move the current item down one entry.
733 """ 731 """
736 self.logTree.setCurrentItem(itm) 734 self.logTree.setCurrentItem(itm)
737 else: 735 else:
738 # load the next bunch and try again 736 # load the next bunch and try again
739 self.__addFinishCallback(self.on_downButton_clicked) 737 self.__addFinishCallback(self.on_downButton_clicked)
740 self.on_nextButton_clicked() 738 self.on_nextButton_clicked()
741 739
742 def on_passwordCheckBox_toggled(self, isOn): 740 def on_passwordCheckBox_toggled(self, isOn):
743 """ 741 """
744 Private slot to handle the password checkbox toggled. 742 Private slot to handle the password checkbox toggled.
745 743
746 @param isOn flag indicating the status of the check box (boolean) 744 @param isOn flag indicating the status of the check box (boolean)
747 """ 745 """
748 if isOn: 746 if isOn:
749 self.input.setEchoMode(QLineEdit.EchoMode.Password) 747 self.input.setEchoMode(QLineEdit.EchoMode.Password)
750 else: 748 else:
751 self.input.setEchoMode(QLineEdit.EchoMode.Normal) 749 self.input.setEchoMode(QLineEdit.EchoMode.Normal)
752 750
753 @pyqtSlot() 751 @pyqtSlot()
754 def on_sendButton_clicked(self): 752 def on_sendButton_clicked(self):
755 """ 753 """
756 Private slot to send the input to the subversion process. 754 Private slot to send the input to the subversion process.
757 """ 755 """
758 inputTxt = self.input.text() 756 inputTxt = self.input.text()
759 inputTxt += os.linesep 757 inputTxt += os.linesep
760 758
761 if self.passwordCheckBox.isChecked(): 759 if self.passwordCheckBox.isChecked():
762 self.errors.insertPlainText(os.linesep) 760 self.errors.insertPlainText(os.linesep)
763 self.errors.ensureCursorVisible() 761 self.errors.ensureCursorVisible()
764 else: 762 else:
765 self.errors.insertPlainText(inputTxt) 763 self.errors.insertPlainText(inputTxt)
766 self.errors.ensureCursorVisible() 764 self.errors.ensureCursorVisible()
767 self.errorGroup.show() 765 self.errorGroup.show()
768 766
769 self.__process.write(strToQByteArray(inputTxt)) 767 self.__process.write(strToQByteArray(inputTxt))
770 768
771 self.passwordCheckBox.setChecked(False) 769 self.passwordCheckBox.setChecked(False)
772 self.input.clear() 770 self.input.clear()
773 771
774 def on_input_returnPressed(self): 772 def on_input_returnPressed(self):
775 """ 773 """
776 Private slot to handle the press of the return key in the input field. 774 Private slot to handle the press of the return key in the input field.
777 """ 775 """
778 self.intercept = True 776 self.intercept = True
779 self.on_sendButton_clicked() 777 self.on_sendButton_clicked()
780 778
781 def keyPressEvent(self, evt): 779 def keyPressEvent(self, evt):
782 """ 780 """
783 Protected slot to handle a key press event. 781 Protected slot to handle a key press event.
784 782
785 @param evt the key press event (QKeyEvent) 783 @param evt the key press event (QKeyEvent)
786 """ 784 """
787 if self.intercept: 785 if self.intercept:
788 self.intercept = False 786 self.intercept = False
789 evt.accept() 787 evt.accept()

eric ide

mercurial