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
1=== modified file 'lib/diffview.py'
2--- lib/diffview.py 2010-03-24 05:23:19 +0000
3+++ lib/diffview.py 2010-08-28 08:52:41 +0000
4@@ -34,6 +34,7 @@
5 CachedTTypeFormater,
6 split_tokens_at_lines,
7 )
8+from PyQt4.QtCore import QEvent
9
10 have_pygments = True
11 try:
12@@ -256,6 +257,10 @@
13
14 config = QBzrGlobalConfig()
15 self.show_intergroup_colors = config.get_user_option("diff_show_intergroup_colors") in ("True", "1")
16+ self.shift = 0
17+ self.slider1_prev = self.browsers[0].verticalScrollBar().minimum()
18+ self.slider2_prev = self.browsers[1].verticalScrollBar().minimum()
19+ self.prevSearchString = True
20
21 def clear(self):
22
23@@ -526,45 +531,137 @@
24 self.browsers[0].scrollToAnchor("top")
25 self.browsers[1].scrollToAnchor("top")
26
27- def _syncSliders(self, slider1, slider2, value):
28- m = slider1.maximum()
29- if m:
30- value = slider2.minimum() + slider2.maximum() * (value - slider1.minimum()) / m
31- self.ignoreUpdate = True
32- slider2.setValue(value)
33- self.ignoreUpdate = False
34+ def _syncSliders(self, slider1, slider2, value, diff):
35+ if not self.shift:
36+ self.ignoreUpdate = True
37+ if diff == 0:
38+ m = slider1.maximum()
39+ if m:
40+ value = slider2.minimum() + slider2.maximum() * (value - slider1.minimum()) / m
41+ slider2.setValue(value)
42+ else:
43+ tmp = slider1.maximum() - slider1.minimum()
44+ if tmp:
45+ diff = (slider2.maximum() - slider2.minimum()) * diff / (tmp)
46+ value += diff
47+ slider2.setValue(value);
48+ self.ignoreUpdate = False
49+ return value
50
51 def updateHandle1(self, value):
52 if not self.ignoreUpdate:
53 slider1 = self.browsers[0].verticalScrollBar()
54 slider2 = self.browsers[1].verticalScrollBar()
55- self._syncSliders(slider1, slider2, value)
56+ self.slider2_prev = self._syncSliders(slider1, slider2, self.slider2_prev , value -
57+ self.slider1_prev)
58+ self.slider1_prev = value
59 self.handle(1).update()
60
61 def updateHandle2(self, value):
62 if not self.ignoreUpdate:
63 slider1 = self.browsers[0].verticalScrollBar()
64 slider2 = self.browsers[1].verticalScrollBar()
65- self._syncSliders(slider2, slider1, value)
66+ self.slider1_prev = self._syncSliders(slider2, slider1, self.slider1_prev, value -
67+ self.slider2_prev)
68+ self.slider2_prev = value
69 self.handle(1).update()
70
71 def syncHorizontalSlider1(self, value):
72 if not self.ignoreUpdate:
73 slider1 = self.browsers[0].horizontalScrollBar()
74 slider2 = self.browsers[1].horizontalScrollBar()
75- self._syncSliders(slider1, slider2, value)
76+ self._syncSliders(slider1, slider2, value, 0)
77 self.handle(1).update()
78
79 def syncHorizontalSlider2(self, value):
80 if not self.ignoreUpdate:
81 slider1 = self.browsers[0].horizontalScrollBar()
82 slider2 = self.browsers[1].horizontalScrollBar()
83- self._syncSliders(slider2, slider1, value)
84+ self._syncSliders(slider2, slider1, value, 0)
85 self.handle(1).update()
86
87 def createHandle(self):
88 return DiffViewHandle(self)
89
90+ def search(self, searchString, dir):
91+ doc = self.docs[1]
92+ if (not searchString == self.prevSearchString):
93+ # Start new search
94+ self.cursors[1].setPosition(0)
95+ self.prevSearchString = searchString
96+
97+ if dir:
98+ found = doc.find(searchString, self.cursors[1])
99+ else:
100+ found = doc.find(searchString, self.cursors[1],
101+ QtGui.QTextDocument.FindBackward)
102+ if (not found.isNull() and not found.atEnd()):
103+ self.browsers[1].setTextCursor(found)
104+ self.cursors[1] = found
105+ self.browsers[1].ensureCursorVisible()
106+
107+ def event(self, event):
108+ if (event.type()==QEvent.KeyPress) and (event.key()==QtCore.Qt.Key_Shift):
109+ self.shift = 1
110+ return True
111+ if (event.type()==QEvent.KeyRelease) and (event.key()==QtCore.Qt.Key_Shift):
112+ self.shift = 0
113+ return True
114+ return QtGui.QSplitter.event(self, event)
115+
116+ # Jump to the next diff
117+ def nextdiff(self):
118+ ly = -1
119+ y = self.browsers[1].verticalScrollBar().value()
120+ half = self.browsers[1].height() / 2
121+ y += half
122+ for ry, ly in [(chr[0], chl[0]) for chr, chl in
123+ zip(self.browsers[0].changes,self.browsers[1].changes)]:
124+ if ly <= y:
125+ continue
126+ break
127+ if ly > 0:
128+ slider1 = self.browsers[0].verticalScrollBar()
129+ slider2 = self.browsers[1].verticalScrollBar()
130+ self.ignoreUpdate = True
131+ slider1.setValue(ry - half)
132+ slider2.setValue(ly - half)
133+ self.slider1_prev = ry - half
134+ self.slider2_prev = ly - half
135+ self.ignoreUpdate = False
136+ self.handle(1).update()
137+
138+ def prevdiff(self):
139+ prev_ly = -1
140+ y = self.browsers[1].verticalScrollBar().value()
141+ half = self.browsers[1].height() / 2
142+ y += half
143+ for ry, ly in [(chr[0], chl[0]) for chr, chl in
144+ zip(self.browsers[0].changes,self.browsers[1].changes)]:
145+ if ly < y:
146+ prev_ly = ly
147+ prev_ry = ry
148+ continue
149+ break
150+ if prev_ly > 0:
151+ slider1 = self.browsers[0].verticalScrollBar()
152+ slider2 = self.browsers[1].verticalScrollBar()
153+ self.ignoreUpdate = True
154+ slider1.setValue(prev_ry - half)
155+ slider2.setValue(prev_ly - half)
156+ self.slider1_prev = prev_ry - half
157+ self.slider2_prev = prev_ly - half
158+ self.ignoreUpdate = False
159+ self.handle(1).update()
160+
161+ def sync_scrl(self):
162+ if not self.ignoreUpdate:
163+ slider1 = self.browsers[0].verticalScrollBar()
164+ slider2 = self.browsers[1].verticalScrollBar()
165+ self.slider1_prev = self._syncSliders(slider2, slider1, self.slider2_prev, 0)
166+ self.handle(1).update()
167+
168+
169
170 class SimpleDiffView(QtGui.QTextBrowser):
171 """Widget to show differences in unidiff format."""
172@@ -690,3 +787,15 @@
173 self.cursor.insertText("\n")
174 self.cursor.endEditBlock()
175 self.update()
176+
177+ def set_search(self, search_text):
178+# self.browsers[1].set_search(search_text)
179+ pass
180+
181+ def scrollTo(self, pos):
182+ pass
183+
184+ def currentIndex(self):
185+ return 0
186+
187+
188
189=== modified file 'lib/diffwindow.py'
190--- lib/diffwindow.py 2010-05-05 12:40:43 +0000
191+++ lib/diffwindow.py 2010-08-28 08:52:41 +0000
192@@ -206,14 +206,59 @@
193 self.click_refresh)
194 self.refresh_button = refresh
195
196+ # Search in diff field
197+ searchgroup = QtGui.QGroupBox("Search", self)
198+ self.searchbox = QtGui.QHBoxLayout(searchgroup)
199+# self.searchbox.setSpacing(3)
200+ self.search_edit = QtGui.QLineEdit()
201+ self.search_edit.setSizePolicy(QtGui.QSizePolicy.Minimum |
202+ QtGui.QSizePolicy.ExpandFlag, QtGui.QSizePolicy.Fixed)
203+ self.search_edit.setMinimumWidth(200)
204+ self.searchbox.addWidget(self.search_edit)
205+
206+ prevsrch_btn = QtGui.QPushButton(gettext('<<'), self)
207+ nextsrch_btn = QtGui.QPushButton(gettext('>>'), self)
208+ prevsrch_btn.setMaximumWidth(30)
209+ nextsrch_btn.setMaximumWidth(30)
210+ QtCore.QObject.connect(prevsrch_btn, QtCore.SIGNAL("clicked(bool)"),
211+ self.prevsrch_click)
212+ QtCore.QObject.connect(nextsrch_btn, QtCore.SIGNAL("clicked(bool)"),
213+ self.nextsrch_click)
214+ self.searchbox.addWidget(prevsrch_btn)
215+ self.searchbox.addWidget(nextsrch_btn)
216+
217+ diffgroup = QtGui.QGroupBox("Diff", self)
218+ diffbox = QtGui.QHBoxLayout(diffgroup)
219+# diffbox.setSpacing(5)
220+ prevdiff_button = QtGui.QPushButton(gettext('<<'), self)
221+ nextdiff_button = QtGui.QPushButton(gettext('>>'), self)
222+ prevdiff_button.setMaximumWidth(30)
223+ nextdiff_button.setMaximumWidth(30)
224+ QtCore.QObject.connect(prevdiff_button, QtCore.SIGNAL("clicked(bool)"),
225+ self.prevdiff_click)
226+ QtCore.QObject.connect(nextdiff_button, QtCore.SIGNAL("clicked(bool)"),
227+ self.nextdiff_click)
228+ sync_scrl_button = QtGui.QPushButton(gettext('>=<'), self)
229+ QtCore.QObject.connect(sync_scrl_button, QtCore.SIGNAL("clicked(bool)"),
230+ self.sync_scrl_click)
231+ sync_scrl_button.setMaximumWidth(35)
232+ diffbox.addWidget(prevdiff_button)
233+ diffbox.addWidget(nextdiff_button)
234+ diffbox.addWidget(sync_scrl_button)
235+
236 hbox = QtGui.QHBoxLayout()
237 hbox.addWidget(diffsidebyside)
238 hbox.addWidget(unidiff)
239 hbox.addWidget(complete)
240 if has_ext_diff():
241 hbox.addWidget(ext_diff_button)
242- hbox.addWidget(self.encoding_selector_left)
243- hbox.addWidget(self.encoding_selector_right)
244+ tmpvbox = QtGui.QVBoxLayout()
245+ tmpvbox.addWidget(self.encoding_selector_left)
246+ tmpvbox.addWidget(self.encoding_selector_right)
247+ tmpvbox.setSpacing(0)
248+ hbox.addLayout(tmpvbox)
249+ hbox.addWidget(searchgroup)
250+ hbox.addWidget(diffgroup)
251 hbox.addWidget(buttonbox)
252 vbox.addLayout(hbox)
253
254@@ -452,3 +497,38 @@
255 def ext_diff_triggered(self, ext_diff):
256 """@param ext_diff: path to external diff executable."""
257 show_diff(self.arg_provider, ext_diff=ext_diff, parent_window = self)
258+
259+ @ui_current_widget
260+ def updateSearch(self, dir):
261+ searchString = unicode(self.search_edit.text())
262+ if (searchString == ""):
263+ return
264+ self.diffview.search(searchString, dir)
265+
266+ def prevdiff_click(self):
267+ self.diffview.prevdiff()
268+
269+ def nextdiff_click(self):
270+ self.diffview.nextdiff()
271+
272+ def prevsrch_click(self):
273+ self.updateSearch(0)
274+
275+ def nextsrch_click(self):
276+ self.updateSearch(1)
277+
278+ def sync_scrl_click(self):
279+ self.diffview.sync_scrl()
280+
281+ def event(self, event):
282+ if (event.type()==QtCore.QEvent.KeyPress):
283+ if (event.key()==QtCore.Qt.Key_Slash) and not (self.search_edit.hasFocus()):
284+ self.search_edit.setFocus()
285+ self.search_edit.selectAll()
286+ return True
287+ if (event.key()==QtCore.Qt.Key_Return) and (self.search_edit.hasFocus()):
288+ self.updateSearch(1)
289+ return True
290+ return QBzrWindow.event(self, event)
291+
292+

Subscribers

People subscribed via source and target branches