28 def sbsdiff(a, b, linenumberwidth=4): |
28 def sbsdiff(a, b, linenumberwidth=4): |
29 """ |
29 """ |
30 Compare two sequences of lines; generate the delta for display side by |
30 Compare two sequences of lines; generate the delta for display side by |
31 side. |
31 side. |
32 |
32 |
33 @param a first sequence of lines (list of strings) |
33 @param a first sequence of lines |
34 @param b second sequence of lines (list of strings) |
34 @type list of str |
35 @param linenumberwidth width (in characters) of the linenumbers (integer) |
35 @param b second sequence of lines |
|
36 @type list of str |
|
37 @param linenumberwidth width (in characters) of the linenumbers |
|
38 @type int |
36 @yield tuples of differences. Each tuple is composed of strings as follows. |
39 @yield tuples of differences. Each tuple is composed of strings as follows. |
37 <ul> |
40 <ul> |
38 <li>opcode -- one of e, d, i, r for equal, delete, insert, |
41 <li>opcode -- one of e, d, i, r for equal, delete, insert, |
39 replace</li> |
42 replace</li> |
40 <li>lineno a -- linenumber of sequence a</li> |
43 <li>lineno a -- linenumber of sequence a</li> |
47 |
50 |
48 def removeMarkers(line): |
51 def removeMarkers(line): |
49 """ |
52 """ |
50 Internal function to remove all diff markers. |
53 Internal function to remove all diff markers. |
51 |
54 |
52 @param line line to work on (string) |
55 @param line line to work on |
53 @return line without diff markers (string) |
56 @type str |
|
57 @return line without diff markers |
|
58 @rtype str |
54 """ |
59 """ |
55 return ( |
60 return ( |
56 line.replace("\0+", "") |
61 line.replace("\0+", "") |
57 .replace("\0-", "") |
62 .replace("\0-", "") |
58 .replace("\0^", "") |
63 .replace("\0^", "") |
102 def __init__(self, files=None, parent=None): |
107 def __init__(self, files=None, parent=None): |
103 """ |
108 """ |
104 Constructor |
109 Constructor |
105 |
110 |
106 @param files list of files to compare and their label |
111 @param files list of files to compare and their label |
107 @type list of two tuples of (str, str) |
112 @type list of tuples of (str, str) |
108 @param parent parent widget |
113 @param parent parent widget |
109 @type QWidget |
114 @type QWidget |
110 """ |
115 """ |
111 super().__init__(parent) |
116 super().__init__(parent) |
112 self.setupUi(self) |
117 self.setupUi(self) |
198 |
203 |
199 def show(self, filename=None): |
204 def show(self, filename=None): |
200 """ |
205 """ |
201 Public slot to show the dialog. |
206 Public slot to show the dialog. |
202 |
207 |
203 @param filename name of a file to use as the first file (string) |
208 @param filename name of a file to use as the first file |
|
209 @type str |
204 """ |
210 """ |
205 if filename: |
211 if filename: |
206 self.file1Picker.setText(filename) |
212 self.file1Picker.setText(filename) |
207 super().show() |
213 super().show() |
208 |
214 |
209 def __appendText(self, pane, linenumber, line, charFormat, interLine=False): |
215 def __appendText(self, pane, linenumber, line, charFormat, interLine=False): |
210 """ |
216 """ |
211 Private method to append text to the end of the contents pane. |
217 Private method to append text to the end of the contents pane. |
212 |
218 |
213 @param pane text edit widget to append text to (QTextedit) |
219 @param pane text edit widget to append text to |
214 @param linenumber number of line to insert (string) |
220 @type QTextedit |
215 @param line text to insert (string) |
221 @param linenumber number of line to insert |
216 @param charFormat text format to be used (QTextCharFormat) |
222 @type str |
217 @param interLine flag indicating interline changes (boolean) |
223 @param line text to insert |
|
224 @type str |
|
225 @param charFormat text format to be used |
|
226 @type QTextCharFormat |
|
227 @param interLine flag indicating interline changes |
|
228 @type bool |
218 """ |
229 """ |
219 tc = pane.textCursor() |
230 tc = pane.textCursor() |
220 tc.movePosition(QTextCursor.MoveOperation.End) |
231 tc.movePosition(QTextCursor.MoveOperation.End) |
221 pane.setTextCursor(tc) |
232 pane.setTextCursor(tc) |
222 pane.setCurrentCharFormat(charFormat) |
233 pane.setCurrentCharFormat(charFormat) |
241 |
252 |
242 def on_buttonBox_clicked(self, button): |
253 def on_buttonBox_clicked(self, button): |
243 """ |
254 """ |
244 Private slot called by a button of the button box clicked. |
255 Private slot called by a button of the button box clicked. |
245 |
256 |
246 @param button button that was clicked (QAbstractButton) |
257 @param button button that was clicked |
|
258 @type QAbstractButton |
247 """ |
259 """ |
248 if button == self.diffButton: |
260 if button == self.diffButton: |
249 self.on_diffButton_clicked() |
261 self.on_diffButton_clicked() |
250 |
262 |
251 @pyqtSlot() |
263 @pyqtSlot() |
289 |
301 |
290 def compare(self, lines1, lines2, name1="", name2=""): |
302 def compare(self, lines1, lines2, name1="", name2=""): |
291 """ |
303 """ |
292 Public method to compare two lists of text. |
304 Public method to compare two lists of text. |
293 |
305 |
294 @param lines1 text to compare against (string or list of strings) |
306 @param lines1 text to compare against |
295 @param lines2 text to compare (string or list of strings) |
307 @type str or list of str |
296 @param name1 name to be shown for the first text (string) |
308 @param lines2 text to compare |
297 @param name2 name to be shown for the second text (string) |
309 @type str or list of str) |
|
310 @param name1 name to be shown for the first text |
|
311 @type str |
|
312 @param name2 name to be shown for the second text |
|
313 @type str |
298 """ |
314 """ |
299 if name1 == "" or name2 == "": |
315 if name1 == "" or name2 == "": |
300 self.filesGroup.hide() |
316 self.filesGroup.hide() |
301 else: |
317 else: |
302 self.file1Picker.setText(name1) |
318 self.file1Picker.setText(name1) |
315 |
331 |
316 def __compare(self, lines1, lines2): |
332 def __compare(self, lines1, lines2): |
317 """ |
333 """ |
318 Private method to compare two lists of text. |
334 Private method to compare two lists of text. |
319 |
335 |
320 @param lines1 text to compare against (list of strings) |
336 @param lines1 text to compare against |
321 @param lines2 text to compare (list of strings) |
337 @type list of str |
|
338 @param lines2 text to compare |
|
339 @type list of str |
322 """ |
340 """ |
323 self.contents_1.clear() |
341 self.contents_1.clear() |
324 self.contents_2.clear() |
342 self.contents_2.clear() |
325 |
343 |
326 self.__generateFormats() |
344 self.__generateFormats() |
402 def __scrollBarMoved(self, value): |
420 def __scrollBarMoved(self, value): |
403 """ |
421 """ |
404 Private slot to enable the buttons and set the current diff position |
422 Private slot to enable the buttons and set the current diff position |
405 depending on scrollbar position. |
423 depending on scrollbar position. |
406 |
424 |
407 @param value scrollbar position (integer) |
425 @param value scrollbar position |
|
426 @type int |
408 """ |
427 """ |
409 tPos = value / self.fontHeight + 1 |
428 tPos = value / self.fontHeight + 1 |
410 bPos = (value + self.vsb1.pageStep()) / self.fontHeight + 1 |
429 bPos = (value + self.vsb1.pageStep()) / self.fontHeight + 1 |
411 |
430 |
412 self.currentDiffPos = -1 |
431 self.currentDiffPos = -1 |
467 @pyqtSlot(bool) |
486 @pyqtSlot(bool) |
468 def on_synchronizeCheckBox_toggled(self, sync): |
487 def on_synchronizeCheckBox_toggled(self, sync): |
469 """ |
488 """ |
470 Private slot to connect or disconnect the scrollbars of the displays. |
489 Private slot to connect or disconnect the scrollbars of the displays. |
471 |
490 |
472 @param sync flag indicating synchronisation status (boolean) |
491 @param sync flag indicating synchronisation status |
|
492 @type bool |
473 """ |
493 """ |
474 if sync: |
494 if sync: |
475 self.hsb2.setValue(self.hsb1.value()) |
495 self.hsb2.setValue(self.hsb1.value()) |
476 self.hsb1.valueChanged.connect(self.hsb2.setValue) |
496 self.hsb1.valueChanged.connect(self.hsb2.setValue) |
477 self.hsb2.valueChanged.connect(self.hsb1.setValue) |
497 self.hsb2.valueChanged.connect(self.hsb1.setValue) |
488 def __init__(self, files=None, parent=None): |
508 def __init__(self, files=None, parent=None): |
489 """ |
509 """ |
490 Constructor |
510 Constructor |
491 |
511 |
492 @param files list of files to compare and their label |
512 @param files list of files to compare and their label |
493 (list of two tuples of two strings) |
513 @type list of [(str, str), (str, str)] |
494 @param parent reference to the parent widget (QWidget) |
514 @param parent reference to the parent widget |
|
515 @type QWidget |
495 """ |
516 """ |
496 super().__init__(parent) |
517 super().__init__(parent) |
497 |
518 |
498 self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) |
519 self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) |
499 |
520 |
505 |
526 |
506 def eventFilter(self, obj, event): |
527 def eventFilter(self, obj, event): |
507 """ |
528 """ |
508 Public method to filter events. |
529 Public method to filter events. |
509 |
530 |
510 @param obj reference to the object the event is meant for (QObject) |
531 @param obj reference to the object the event is meant for |
511 @param event reference to the event object (QEvent) |
532 @type QObject |
512 @return flag indicating, whether the event was handled (boolean) |
533 @param event reference to the event object |
|
534 @type QEvent |
|
535 @return flag indicating, whether the event was handled |
|
536 @rtype bool |
513 """ |
537 """ |
514 if event.type() == QEvent.Type.Close: |
538 if event.type() == QEvent.Type.Close: |
515 QApplication.exit() |
539 QApplication.exit() |
516 return True |
540 return True |
517 |
541 |