Merge lp:~s-dumbie/qbzr/ench_qdiff into lp:qbzr

Proposed by BumbleBee
Status: Work in progress
Proposed branch: lp:~s-dumbie/qbzr/ench_qdiff
Merge into: lp:qbzr
Diff against target: 292 lines (+202/-13)
2 files modified
lib/diffview.py (+120/-11)
lib/diffwindow.py (+82/-2)
To merge this branch: bzr merge lp:~s-dumbie/qbzr/ench_qdiff
Reviewer Review Type Date Requested Status
QBzr Developers Pending
Review via email: mp+33986@code.launchpad.net

Description of the change

Few improvements for diff viewer.
All changes are done to the side by side diff viewer only.

Changed:
*Drop-down encodings lists are now one above another.

Added:
*Now one can scroll only one widow while shift is pressed. After shift
is released
 difference in left and right scrollers positions remains.
*Added the 'Diff' group:
** A button ('>=<') is added to synchronize vertical scrollers.
   When it is pressed left scrollers is moved to the same position as
the right one.
** Added two buttons ('<<' and '>>') to jump to the previous and the
next change respectively.
*Added the 'Search' group:
** The text field for the search string, buttons ('<<' and '>>') for
searching the previous and the next
   occurrence respectively. Search is done in the left window.
Changing the search text make search
   start from the beginning of the text. Otherwise search continues
from the position after the last found text entry.
** Now pressing the '/' button sets focus to the search text field.
** Now pressing 'Enter' while search text field is focused starts
search in the forward direction.

To post a comment you must log in.
Revision history for this message
Alexander Belchenko (bialix) wrote :

Привет, извиняюсь за чересчур длительную задержку с твоим патчем.
Я закончил merge для ветки с переделкой qdiff на toolbar. По всей видимости теперь надо обновить твой патч под использование тулбара?

Теперь изменения касательно encoding drop-down list уже неактуальны.

Поиск по diff тоже уже реализован. Может быть немного не так как у тебя.

Из всего патча остается поддержка раздельного scroll. Можно его выделить в виде отдельного патча на основе текущего состояния qbzr trunk?

Revision history for this message
Alexander Belchenko (bialix) wrote :

As I understand, after I've landed toolbar for qdiff this patch should be significantly reworked. So I mark it as Work In Progress. Please ask if you need any help with updating your patch.

Unmerged revisions

1310. By bumble <bumble@starlight>

Few improvements for diff viewer.
All changes are done to the side by side diff viewer only.

Changed:
*Drop-down encodings lists are now one above another.

Added:
*Now one can scroll only one widow while shift is pressed. After shift
is released
 difference in left and right scrollers positions remains.
*Added the 'Diff' group:
** A button ('>=<') is added to synchronize vertical scrollers.
   When it is pressed left scrollers is moved to the same position as
the right one.
** Added two buttons ('<<' and '>>') to jump to the previous and the
next change respectively.
*Added the 'Search' group:
** The text field for the search string, buttons ('<<' and '>>') for
searching the previous and the next
   occurrence respectively. Search is done in the left window.
Changing the search text make search
   start from the beginning of the text. Otherwise search continues
from the position after the last found text entry.
** Now pressing the '/' button sets focus to the search text field.
** Now pressing 'Enter' while search text field is focused starts
search in the forward direction.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/diffview.py'
--- lib/diffview.py 2010-03-24 05:23:19 +0000
+++ lib/diffview.py 2010-08-28 08:52:41 +0000
@@ -34,6 +34,7 @@
34 CachedTTypeFormater,34 CachedTTypeFormater,
35 split_tokens_at_lines,35 split_tokens_at_lines,
36 )36 )
37from PyQt4.QtCore import QEvent
3738
38have_pygments = True39have_pygments = True
39try:40try:
@@ -256,6 +257,10 @@
256 257
257 config = QBzrGlobalConfig()258 config = QBzrGlobalConfig()
258 self.show_intergroup_colors = config.get_user_option("diff_show_intergroup_colors") in ("True", "1")259 self.show_intergroup_colors = config.get_user_option("diff_show_intergroup_colors") in ("True", "1")
260 self.shift = 0
261 self.slider1_prev = self.browsers[0].verticalScrollBar().minimum()
262 self.slider2_prev = self.browsers[1].verticalScrollBar().minimum()
263 self.prevSearchString = True
259 264
260 def clear(self):265 def clear(self):
261 266
@@ -526,45 +531,137 @@
526 self.browsers[0].scrollToAnchor("top")531 self.browsers[0].scrollToAnchor("top")
527 self.browsers[1].scrollToAnchor("top")532 self.browsers[1].scrollToAnchor("top")
528533
529 def _syncSliders(self, slider1, slider2, value):534 def _syncSliders(self, slider1, slider2, value, diff):
530 m = slider1.maximum()535 if not self.shift:
531 if m:536 self.ignoreUpdate = True
532 value = slider2.minimum() + slider2.maximum() * (value - slider1.minimum()) / m537 if diff == 0:
533 self.ignoreUpdate = True538 m = slider1.maximum()
534 slider2.setValue(value)539 if m:
535 self.ignoreUpdate = False540 value = slider2.minimum() + slider2.maximum() * (value - slider1.minimum()) / m
541 slider2.setValue(value)
542 else:
543 tmp = slider1.maximum() - slider1.minimum()
544 if tmp:
545 diff = (slider2.maximum() - slider2.minimum()) * diff / (tmp)
546 value += diff
547 slider2.setValue(value);
548 self.ignoreUpdate = False
549 return value
536550
537 def updateHandle1(self, value):551 def updateHandle1(self, value):
538 if not self.ignoreUpdate:552 if not self.ignoreUpdate:
539 slider1 = self.browsers[0].verticalScrollBar()553 slider1 = self.browsers[0].verticalScrollBar()
540 slider2 = self.browsers[1].verticalScrollBar()554 slider2 = self.browsers[1].verticalScrollBar()
541 self._syncSliders(slider1, slider2, value)555 self.slider2_prev = self._syncSliders(slider1, slider2, self.slider2_prev , value -
556 self.slider1_prev)
557 self.slider1_prev = value
542 self.handle(1).update()558 self.handle(1).update()
543559
544 def updateHandle2(self, value):560 def updateHandle2(self, value):
545 if not self.ignoreUpdate:561 if not self.ignoreUpdate:
546 slider1 = self.browsers[0].verticalScrollBar()562 slider1 = self.browsers[0].verticalScrollBar()
547 slider2 = self.browsers[1].verticalScrollBar()563 slider2 = self.browsers[1].verticalScrollBar()
548 self._syncSliders(slider2, slider1, value)564 self.slider1_prev = self._syncSliders(slider2, slider1, self.slider1_prev, value -
565 self.slider2_prev)
566 self.slider2_prev = value
549 self.handle(1).update()567 self.handle(1).update()
550568
551 def syncHorizontalSlider1(self, value):569 def syncHorizontalSlider1(self, value):
552 if not self.ignoreUpdate:570 if not self.ignoreUpdate:
553 slider1 = self.browsers[0].horizontalScrollBar()571 slider1 = self.browsers[0].horizontalScrollBar()
554 slider2 = self.browsers[1].horizontalScrollBar()572 slider2 = self.browsers[1].horizontalScrollBar()
555 self._syncSliders(slider1, slider2, value)573 self._syncSliders(slider1, slider2, value, 0)
556 self.handle(1).update()574 self.handle(1).update()
557575
558 def syncHorizontalSlider2(self, value):576 def syncHorizontalSlider2(self, value):
559 if not self.ignoreUpdate:577 if not self.ignoreUpdate:
560 slider1 = self.browsers[0].horizontalScrollBar()578 slider1 = self.browsers[0].horizontalScrollBar()
561 slider2 = self.browsers[1].horizontalScrollBar()579 slider2 = self.browsers[1].horizontalScrollBar()
562 self._syncSliders(slider2, slider1, value)580 self._syncSliders(slider2, slider1, value, 0)
563 self.handle(1).update()581 self.handle(1).update()
564582
565 def createHandle(self):583 def createHandle(self):
566 return DiffViewHandle(self)584 return DiffViewHandle(self)
567585
586 def search(self, searchString, dir):
587 doc = self.docs[1]
588 if (not searchString == self.prevSearchString):
589 # Start new search
590 self.cursors[1].setPosition(0)
591 self.prevSearchString = searchString
592
593 if dir:
594 found = doc.find(searchString, self.cursors[1])
595 else:
596 found = doc.find(searchString, self.cursors[1],
597 QtGui.QTextDocument.FindBackward)
598 if (not found.isNull() and not found.atEnd()):
599 self.browsers[1].setTextCursor(found)
600 self.cursors[1] = found
601 self.browsers[1].ensureCursorVisible()
602
603 def event(self, event):
604 if (event.type()==QEvent.KeyPress) and (event.key()==QtCore.Qt.Key_Shift):
605 self.shift = 1
606 return True
607 if (event.type()==QEvent.KeyRelease) and (event.key()==QtCore.Qt.Key_Shift):
608 self.shift = 0
609 return True
610 return QtGui.QSplitter.event(self, event)
611
612 # Jump to the next diff
613 def nextdiff(self):
614 ly = -1
615 y = self.browsers[1].verticalScrollBar().value()
616 half = self.browsers[1].height() / 2
617 y += half
618 for ry, ly in [(chr[0], chl[0]) for chr, chl in
619 zip(self.browsers[0].changes,self.browsers[1].changes)]:
620 if ly <= y:
621 continue
622 break
623 if ly > 0:
624 slider1 = self.browsers[0].verticalScrollBar()
625 slider2 = self.browsers[1].verticalScrollBar()
626 self.ignoreUpdate = True
627 slider1.setValue(ry - half)
628 slider2.setValue(ly - half)
629 self.slider1_prev = ry - half
630 self.slider2_prev = ly - half
631 self.ignoreUpdate = False
632 self.handle(1).update()
633
634 def prevdiff(self):
635 prev_ly = -1
636 y = self.browsers[1].verticalScrollBar().value()
637 half = self.browsers[1].height() / 2
638 y += half
639 for ry, ly in [(chr[0], chl[0]) for chr, chl in
640 zip(self.browsers[0].changes,self.browsers[1].changes)]:
641 if ly < y:
642 prev_ly = ly
643 prev_ry = ry
644 continue
645 break
646 if prev_ly > 0:
647 slider1 = self.browsers[0].verticalScrollBar()
648 slider2 = self.browsers[1].verticalScrollBar()
649 self.ignoreUpdate = True
650 slider1.setValue(prev_ry - half)
651 slider2.setValue(prev_ly - half)
652 self.slider1_prev = prev_ry - half
653 self.slider2_prev = prev_ly - half
654 self.ignoreUpdate = False
655 self.handle(1).update()
656
657 def sync_scrl(self):
658 if not self.ignoreUpdate:
659 slider1 = self.browsers[0].verticalScrollBar()
660 slider2 = self.browsers[1].verticalScrollBar()
661 self.slider1_prev = self._syncSliders(slider2, slider1, self.slider2_prev, 0)
662 self.handle(1).update()
663
664
568665
569class SimpleDiffView(QtGui.QTextBrowser):666class SimpleDiffView(QtGui.QTextBrowser):
570 """Widget to show differences in unidiff format."""667 """Widget to show differences in unidiff format."""
@@ -690,3 +787,15 @@
690 self.cursor.insertText("\n")787 self.cursor.insertText("\n")
691 self.cursor.endEditBlock()788 self.cursor.endEditBlock()
692 self.update()789 self.update()
790
791 def set_search(self, search_text):
792# self.browsers[1].set_search(search_text)
793 pass
794
795 def scrollTo(self, pos):
796 pass
797
798 def currentIndex(self):
799 return 0
800
801
693802
=== modified file 'lib/diffwindow.py'
--- lib/diffwindow.py 2010-05-05 12:40:43 +0000
+++ lib/diffwindow.py 2010-08-28 08:52:41 +0000
@@ -206,14 +206,59 @@
206 self.click_refresh)206 self.click_refresh)
207 self.refresh_button = refresh207 self.refresh_button = refresh
208208
209 # Search in diff field
210 searchgroup = QtGui.QGroupBox("Search", self)
211 self.searchbox = QtGui.QHBoxLayout(searchgroup)
212# self.searchbox.setSpacing(3)
213 self.search_edit = QtGui.QLineEdit()
214 self.search_edit.setSizePolicy(QtGui.QSizePolicy.Minimum |
215 QtGui.QSizePolicy.ExpandFlag, QtGui.QSizePolicy.Fixed)
216 self.search_edit.setMinimumWidth(200)
217 self.searchbox.addWidget(self.search_edit)
218
219 prevsrch_btn = QtGui.QPushButton(gettext('<<'), self)
220 nextsrch_btn = QtGui.QPushButton(gettext('>>'), self)
221 prevsrch_btn.setMaximumWidth(30)
222 nextsrch_btn.setMaximumWidth(30)
223 QtCore.QObject.connect(prevsrch_btn, QtCore.SIGNAL("clicked(bool)"),
224 self.prevsrch_click)
225 QtCore.QObject.connect(nextsrch_btn, QtCore.SIGNAL("clicked(bool)"),
226 self.nextsrch_click)
227 self.searchbox.addWidget(prevsrch_btn)
228 self.searchbox.addWidget(nextsrch_btn)
229
230 diffgroup = QtGui.QGroupBox("Diff", self)
231 diffbox = QtGui.QHBoxLayout(diffgroup)
232# diffbox.setSpacing(5)
233 prevdiff_button = QtGui.QPushButton(gettext('<<'), self)
234 nextdiff_button = QtGui.QPushButton(gettext('>>'), self)
235 prevdiff_button.setMaximumWidth(30)
236 nextdiff_button.setMaximumWidth(30)
237 QtCore.QObject.connect(prevdiff_button, QtCore.SIGNAL("clicked(bool)"),
238 self.prevdiff_click)
239 QtCore.QObject.connect(nextdiff_button, QtCore.SIGNAL("clicked(bool)"),
240 self.nextdiff_click)
241 sync_scrl_button = QtGui.QPushButton(gettext('>=<'), self)
242 QtCore.QObject.connect(sync_scrl_button, QtCore.SIGNAL("clicked(bool)"),
243 self.sync_scrl_click)
244 sync_scrl_button.setMaximumWidth(35)
245 diffbox.addWidget(prevdiff_button)
246 diffbox.addWidget(nextdiff_button)
247 diffbox.addWidget(sync_scrl_button)
248
209 hbox = QtGui.QHBoxLayout()249 hbox = QtGui.QHBoxLayout()
210 hbox.addWidget(diffsidebyside)250 hbox.addWidget(diffsidebyside)
211 hbox.addWidget(unidiff)251 hbox.addWidget(unidiff)
212 hbox.addWidget(complete)252 hbox.addWidget(complete)
213 if has_ext_diff():253 if has_ext_diff():
214 hbox.addWidget(ext_diff_button)254 hbox.addWidget(ext_diff_button)
215 hbox.addWidget(self.encoding_selector_left)255 tmpvbox = QtGui.QVBoxLayout()
216 hbox.addWidget(self.encoding_selector_right)256 tmpvbox.addWidget(self.encoding_selector_left)
257 tmpvbox.addWidget(self.encoding_selector_right)
258 tmpvbox.setSpacing(0)
259 hbox.addLayout(tmpvbox)
260 hbox.addWidget(searchgroup)
261 hbox.addWidget(diffgroup)
217 hbox.addWidget(buttonbox)262 hbox.addWidget(buttonbox)
218 vbox.addLayout(hbox)263 vbox.addLayout(hbox)
219264
@@ -452,3 +497,38 @@
452 def ext_diff_triggered(self, ext_diff):497 def ext_diff_triggered(self, ext_diff):
453 """@param ext_diff: path to external diff executable."""498 """@param ext_diff: path to external diff executable."""
454 show_diff(self.arg_provider, ext_diff=ext_diff, parent_window = self)499 show_diff(self.arg_provider, ext_diff=ext_diff, parent_window = self)
500
501 @ui_current_widget
502 def updateSearch(self, dir):
503 searchString = unicode(self.search_edit.text())
504 if (searchString == ""):
505 return
506 self.diffview.search(searchString, dir)
507
508 def prevdiff_click(self):
509 self.diffview.prevdiff()
510
511 def nextdiff_click(self):
512 self.diffview.nextdiff()
513
514 def prevsrch_click(self):
515 self.updateSearch(0)
516
517 def nextsrch_click(self):
518 self.updateSearch(1)
519
520 def sync_scrl_click(self):
521 self.diffview.sync_scrl()
522
523 def event(self, event):
524 if (event.type()==QtCore.QEvent.KeyPress):
525 if (event.key()==QtCore.Qt.Key_Slash) and not (self.search_edit.hasFocus()):
526 self.search_edit.setFocus()
527 self.search_edit.selectAll()
528 return True
529 if (event.key()==QtCore.Qt.Key_Return) and (self.search_edit.hasFocus()):
530 self.updateSearch(1)
531 return True
532 return QBzrWindow.event(self, event)
533
534

Subscribers

People subscribed via source and target branches