/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz

« back to all changes in this revision

Viewing changes to annotate/gannotate.py

  • Committer: matkor
  • Date: 2007-08-23 10:17:40 UTC
  • mto: This revision was merged to the branch mainline in revision 265.
  • Revision ID: matkor@laptop-hp-20070823101740-s17kf9qa383wiuje
Code for "branch update" menuitem and toolbox. Typo fix

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
import time
18
18
 
19
 
from gi.repository import GObject
20
 
from gi.repository import Gdk
21
 
from gi.repository import Gtk
22
 
from gi.repository import Pango
 
19
import pygtk
 
20
pygtk.require("2.0")
 
21
import gobject
 
22
import gtk
 
23
import pango
23
24
import re
24
25
 
25
 
from bzrlib import patiencediff
 
26
from bzrlib import patiencediff, tsort
26
27
from bzrlib.errors import NoSuchRevision
27
28
from bzrlib.revision import NULL_REVISION, CURRENT_REVISION
28
29
 
29
 
from bzrlib.plugins.gtk.annotate.colormap import AnnotateColorSaturation
30
 
from bzrlib.plugins.gtk.i18n import _i18n
31
 
from bzrlib.plugins.gtk.revisionview import RevisionView
32
 
from bzrlib.plugins.gtk.window import Window
 
30
from colormap import AnnotateColorMap, AnnotateColorSaturation
 
31
from bzrlib.plugins.gtk.logview import LogView
33
32
 
34
33
 
35
34
(
42
41
) = range(6)
43
42
 
44
43
 
45
 
class GAnnotateWindow(Window):
 
44
class GAnnotateWindow(gtk.Window):
46
45
    """Annotate window."""
47
46
 
48
 
    def __init__(self, all=False, plain=False, parent=None, branch=None):
 
47
    def __init__(self, all=False, plain=False):
49
48
        self.all = all
50
49
        self.plain = plain
51
 
        self._branch = branch
52
 
 
53
 
        super(GAnnotateWindow, self).__init__(parent=parent)
54
 
 
55
 
        self.set_icon(
56
 
            self.render_icon_pixbuf(Gtk.STOCK_FIND, Gtk.IconSize.BUTTON))
 
50
        
 
51
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
 
52
        
 
53
        self.set_icon(self.render_icon(gtk.STOCK_FIND, gtk.ICON_SIZE_BUTTON))
57
54
        self.annotate_colormap = AnnotateColorSaturation()
58
55
 
59
56
        self._create()
66
63
        self.branch = branch
67
64
        self.tree = tree
68
65
        self.file_id = file_id
69
 
        self.revisionview.set_file_id(file_id)
70
66
        self.revision_id = getattr(tree, 'get_revision_id', 
71
67
                                   lambda: CURRENT_REVISION)()
72
 
 
 
68
        
73
69
        # [revision id, line number, author, revno, highlight color, line]
74
 
        self.annomodel = Gtk.ListStore(GObject.TYPE_STRING,
75
 
                                       GObject.TYPE_INT,
76
 
                                       GObject.TYPE_STRING,
77
 
                                       GObject.TYPE_STRING,
78
 
                                       GObject.TYPE_STRING,
79
 
                                       GObject.TYPE_STRING)
80
 
 
 
70
        self.annomodel = gtk.ListStore(gobject.TYPE_STRING,
 
71
                                       gobject.TYPE_STRING,
 
72
                                       gobject.TYPE_STRING,
 
73
                                       gobject.TYPE_STRING,
 
74
                                       gobject.TYPE_STRING,
 
75
                                       gobject.TYPE_STRING)
 
76
        
81
77
        last_seen = None
82
78
        try:
83
79
            branch.lock_read()
84
80
            branch.repository.lock_read()
85
 
            self.dotted = {}
86
 
            revno_map = self.branch.get_revision_id_to_revno_map()
87
 
            for revision_id, revno in revno_map.iteritems():
88
 
                self.dotted[revision_id] = '.'.join(str(num) for num in revno)
89
81
            for line_no, (revision, revno, line)\
90
 
                in enumerate(self._annotate(tree, file_id)):
 
82
                    in enumerate(self._annotate(tree, file_id)):
91
83
                if revision.revision_id == last_seen and not self.all:
92
 
                    revno = author = ""
 
84
                    revno = committer = ""
93
85
                else:
94
86
                    last_seen = revision.revision_id
95
 
                    author = ", ".join(revision.get_apparent_authors())
 
87
                    committer = revision.properties.get('author',
 
88
                        revision.committer)
96
89
 
97
90
                if revision.revision_id not in self.revisions:
98
91
                    self.revisions[revision.revision_id] = revision
99
92
 
100
93
                self.annomodel.append([revision.revision_id,
101
94
                                       line_no + 1,
102
 
                                       author,
 
95
                                       committer,
103
96
                                       revno,
104
97
                                       None,
105
98
                                       line.rstrip("\r\n")
106
 
                                       ])
 
99
                                      ])
107
100
                self.annotations.append(revision)
108
101
 
109
102
            if not self.plain:
115
108
 
116
109
        self.annoview.set_model(self.annomodel)
117
110
        self.annoview.grab_focus()
118
 
        my_revno = self.dotted.get(self.revision_id, 'current')
119
 
        title = '%s (%s) - gannotate' % (self.tree.id2path(file_id), my_revno)
120
 
        self.set_title(title)
121
111
 
122
112
    def jump_to_line(self, lineno):
123
113
        if lineno > len(self.annomodel) or lineno < 1:
126
116
            # bar?
127
117
            print("gannotate: Line number %d does't exist. Defaulting to "
128
118
                  "line 1." % lineno)
129
 
            return
 
119
            return
130
120
        else:
131
121
            row = lineno - 1
132
122
 
133
 
        tree_path = Gtk.TreePath(path=row)
134
 
        self.annoview.set_cursor(tree_path, None, False)
135
 
        self.annoview.scroll_to_cell(tree_path, use_align=True)
 
123
        self.annoview.set_cursor(row)
 
124
        self.annoview.scroll_to_cell(row, use_align=True)
 
125
 
 
126
    def _dotted_revnos(self, repository, revision_id):
 
127
        """Return a dict of revision_id -> dotted revno
 
128
        
 
129
        :param repository: The repository to get the graph from
 
130
        :param revision_id: The last revision for which this info is needed
 
131
        """
 
132
        graph = repository.get_revision_graph(revision_id)
 
133
        dotted = {}
 
134
        for n, revision_id, d, revno, e in tsort.merge_sort(graph, 
 
135
            revision_id, generate_revno=True):
 
136
            dotted[revision_id] = '.'.join(str(num) for num in revno)
 
137
        return dotted
136
138
 
137
139
    def _annotate(self, tree, file_id):
138
140
        current_revision = FakeRevision(CURRENT_REVISION)
140
142
        current_revision.timestamp = time.time()
141
143
        current_revision.message = '[Not yet committed]'
142
144
        current_revision.parent_ids = tree.get_parent_ids()
143
 
        current_revision.properties['branch-nick'] = self.branch._get_nick(local=True)
 
145
        current_revision.properties['branch-nick'] = self.branch.nick
144
146
        current_revno = '%d?' % (self.branch.revno() + 1)
145
147
        repository = self.branch.repository
146
148
        if self.revision_id == CURRENT_REVISION:
147
149
            revision_id = self.branch.last_revision()
148
150
        else:
149
151
            revision_id = self.revision_id
 
152
        dotted = self._dotted_revnos(repository, revision_id)
150
153
        revision_cache = RevisionCache(repository, self.revisions)
151
154
        for origin, text in tree.annotate_iter(file_id):
152
155
            rev_id = origin
156
159
            else:
157
160
                try:
158
161
                    revision = revision_cache.get_revision(rev_id)
159
 
                    revno = self.dotted.get(rev_id, 'merge')
 
162
                    revno = dotted.get(rev_id, 'merge')
160
163
                    if len(revno) > 15:
161
164
                        revno = 'merge'
162
165
                except NoSuchRevision:
168
171
    def _highlight_annotation(self, model, path, iter, now):
169
172
        revision_id, = model.get(iter, REVISION_ID_COL)
170
173
        revision = self.revisions[revision_id]
171
 
        # XXX sinzui 2011-08-12: What does get_color return?
172
 
        color = self.annotate_colormap.get_color(revision, now)
173
 
        model.set_value(iter, HIGHLIGHT_COLOR_COL, color)
 
174
        model.set(iter, HIGHLIGHT_COLOR_COL,
 
175
                  self.annotate_colormap.get_color(revision, now))
174
176
 
175
177
    def _selected_revision(self):
176
178
        (path, col) = self.annoview.get_cursor()
180
182
 
181
183
    def _activate_selected_revision(self, w):
182
184
        rev_id = self._selected_revision()
183
 
        if not rev_id or rev_id == NULL_REVISION:
 
185
        if rev_id is None:
184
186
            return
185
187
        selected = self.revisions[rev_id]
186
 
        self.revisionview.set_revision(selected)
 
188
        self.logview.set_revision(selected)
187
189
        if (len(selected.parent_ids) != 0 and selected.parent_ids[0] not in
188
190
            self._no_back):
189
191
            enable_back = True
192
194
        self.back_button.set_sensitive(enable_back)
193
195
 
194
196
    def _create(self):
195
 
        self.revisionview = self._create_log_view()
 
197
        self.logview = self._create_log_view()
196
198
        self.annoview = self._create_annotate_view()
197
199
 
198
 
        vbox = Gtk.VBox(homogeneous=False, spacing=0)
 
200
        vbox = gtk.VBox(False)
199
201
        vbox.show()
200
202
 
201
 
        sw = Gtk.ScrolledWindow()
202
 
        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
203
 
        sw.set_shadow_type(Gtk.ShadowType.IN)
 
203
        sw = gtk.ScrolledWindow()
 
204
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
 
205
        sw.set_shadow_type(gtk.SHADOW_IN)
204
206
        sw.add(self.annoview)
205
207
        self.annoview.gwindow = self
206
208
        sw.show()
207
209
 
208
 
        swbox = Gtk.VBox()
209
 
        swbox.pack_start(sw, True, True, 0)
 
210
        swbox = gtk.VBox()
 
211
        swbox.pack_start(sw)
210
212
        swbox.show()
211
213
 
212
 
        hbox = Gtk.HBox(homogeneous=False, spacing=6)
 
214
        hbox = gtk.HBox(False, 6)
213
215
        self.back_button = self._create_back_button()
214
 
        hbox.pack_start(self.back_button, False, True, 0)
 
216
        hbox.pack_start(self.back_button, expand=False, fill=True)
215
217
        self.forward_button = self._create_forward_button()
216
 
        hbox.pack_start(self.forward_button, False, True, 0)
217
 
        self.find_button = self._create_find_button()
218
 
        hbox.pack_start(self.find_button, False, True, 0)
219
 
        self.goto_button = self._create_goto_button()
220
 
        hbox.pack_start(self.goto_button, False, True, 0)
 
218
        hbox.pack_start(self.forward_button, expand=False, fill=True)
221
219
        hbox.show()
222
 
        vbox.pack_start(hbox, False, True, 0)
223
 
 
224
 
        self.pane = pane = Gtk.Paned.new(Gtk.Orientation.VERTICAL)
 
220
        vbox.pack_start(hbox, expand=False, fill=True)
 
221
        
 
222
        self.pane = pane = gtk.VPaned()
225
223
        pane.add1(swbox)
226
 
        pane.add2(self.revisionview)
 
224
        pane.add2(self.logview)
227
225
        pane.show()
228
 
        vbox.pack_start(pane, True, True, 0)
 
226
        vbox.pack_start(pane, expand=True, fill=True)
229
227
 
230
228
        self._search = SearchBox()
231
 
        swbox.pack_start(self._search, False, True, 0)
232
 
        accels = Gtk.AccelGroup()
233
 
        accels.connect(Gdk.KEY_f, Gdk.ModifierType.CONTROL_MASK,
234
 
                             Gtk.AccelFlags.LOCKED,
 
229
        swbox.pack_start(self._search, expand=False, fill=True)
 
230
        accels = gtk.AccelGroup()
 
231
        accels.connect_group(gtk.keysyms.f, gtk.gdk.CONTROL_MASK,
 
232
                             gtk.ACCEL_LOCKED,
235
233
                             self._search_by_text)
236
 
        accels.connect(Gdk.KEY_g, Gdk.ModifierType.CONTROL_MASK,
237
 
                             Gtk.AccelFlags.LOCKED,
 
234
        accels.connect_group(gtk.keysyms.g, gtk.gdk.CONTROL_MASK,
 
235
                             gtk.ACCEL_LOCKED,
238
236
                             self._search_by_line)
239
237
        self.add_accel_group(accels)
240
238
 
241
239
        self.add(vbox)
242
240
 
243
 
    def _search_by_text(self, *ignored): # (accel_group, window, key, modifiers):
 
241
    def _search_by_text(self, accel_group, window, key, modifiers):
244
242
        self._search.show_for('text')
245
243
        self._search.set_target(self.annoview, TEXT_LINE_COL)
246
244
 
247
 
    def _search_by_line(self, *ignored): # accel_group, window, key, modifiers):
 
245
    def _search_by_line(self, accel_group, window, key, modifiers):
248
246
        self._search.show_for('line')
249
247
        self._search.set_target(self.annoview, LINE_NUM_COL)
250
248
 
251
 
    def line_diff(self, tv, path, tvc):
252
 
        row = path.get_indices()[0]
 
249
    def row_diff(self, tv, path, tvc):
 
250
        row = path[0]
253
251
        revision = self.annotations[row]
254
252
        repository = self.branch.repository
255
253
        if revision.revision_id == CURRENT_REVISION:
262
260
            else:
263
261
                tree2 = repository.revision_tree(NULL_REVISION)
264
262
        from bzrlib.plugins.gtk.diff import DiffWindow
265
 
        window = DiffWindow(self)
266
 
        window.set_diff("Diff for line %d" % (row+1), tree1, tree2)
 
263
        window = DiffWindow()
 
264
        window.set_diff("Diff for row %d" % (row+1), tree1, tree2)
267
265
        window.set_file(tree1.id2path(self.file_id))
268
266
        window.show()
269
267
 
270
268
 
271
269
    def _create_annotate_view(self):
272
 
        tv = Gtk.TreeView()
 
270
        tv = gtk.TreeView()
273
271
        tv.set_rules_hint(False)
274
272
        tv.connect("cursor-changed", self._activate_selected_revision)
275
273
        tv.show()
276
 
        tv.connect("row-activated", self.line_diff)
 
274
        tv.connect("row-activated", self.row_diff)
277
275
 
278
 
        cell = Gtk.CellRendererText()
 
276
        cell = gtk.CellRendererText()
279
277
        cell.set_property("xalign", 1.0)
280
278
        cell.set_property("ypad", 0)
281
279
        cell.set_property("family", "Monospace")
282
 
        cell.set_property(
283
 
            "cell-background-rgba",
284
 
            tv.get_style_context().get_background_color(Gtk.StateType.NORMAL))
285
 
        col = Gtk.TreeViewColumn()
 
280
        cell.set_property("cell-background-gdk",
 
281
                          tv.get_style().bg[gtk.STATE_NORMAL])
 
282
        col = gtk.TreeViewColumn()
286
283
        col.set_resizable(False)
287
 
        col.pack_start(cell, True)
 
284
        col.pack_start(cell, expand=True)
288
285
        col.add_attribute(cell, "text", LINE_NUM_COL)
289
286
        tv.append_column(col)
290
287
 
291
 
        style_context = self.get_style_context()
292
 
 
293
 
        cell = Gtk.CellRendererText()
 
288
        cell = gtk.CellRendererText()
294
289
        cell.set_property("ypad", 0)
295
 
        cell.set_property("ellipsize", Pango.EllipsizeMode.END)
296
 
        cell.set_property(
297
 
            "cell-background-rgba",
298
 
            style_context.get_background_color(Gtk.StateType.NORMAL))
299
 
        col = Gtk.TreeViewColumn("Committer")
 
290
        cell.set_property("ellipsize", pango.ELLIPSIZE_END)
 
291
        cell.set_property("cell-background-gdk",
 
292
                          self.get_style().bg[gtk.STATE_NORMAL])
 
293
        col = gtk.TreeViewColumn("Committer")
300
294
        col.set_resizable(True)
301
 
        col.pack_start(cell, True)
 
295
        col.pack_start(cell, expand=True)
302
296
        col.add_attribute(cell, "text", COMMITTER_COL)
303
297
        tv.append_column(col)
304
298
 
305
 
        cell = Gtk.CellRendererText()
 
299
        cell = gtk.CellRendererText()
306
300
        cell.set_property("xalign", 1.0)
307
301
        cell.set_property("ypad", 0)
308
 
        cell.set_property(
309
 
            "cell-background-rgba",
310
 
            style_context.get_background_color(Gtk.StateType.NORMAL))
311
 
        col = Gtk.TreeViewColumn("Revno")
 
302
        cell.set_property("cell-background-gdk",
 
303
                          self.get_style().bg[gtk.STATE_NORMAL])
 
304
        col = gtk.TreeViewColumn("Revno")
312
305
        col.set_resizable(False)
313
 
        col.pack_start(cell, True)
 
306
        col.pack_start(cell, expand=True)
314
307
        col.add_attribute(cell, "markup", REVNO_COL)
315
308
        tv.append_column(col)
316
309
 
317
 
        cell = Gtk.CellRendererText()
 
310
        cell = gtk.CellRendererText()
318
311
        cell.set_property("ypad", 0)
319
312
        cell.set_property("family", "Monospace")
320
 
        col = Gtk.TreeViewColumn()
 
313
        col = gtk.TreeViewColumn()
321
314
        col.set_resizable(False)
322
 
        col.pack_start(cell, True)
 
315
        col.pack_start(cell, expand=True)
323
316
#        col.add_attribute(cell, "foreground", HIGHLIGHT_COLOR_COL)
324
317
        col.add_attribute(cell, "background", HIGHLIGHT_COLOR_COL)
325
318
        col.add_attribute(cell, "text", TEXT_LINE_COL)
326
319
        tv.append_column(col)
327
320
 
328
 
        # interactive substring search
329
 
        def search_equal_func(model, column, key, iter):
330
 
            return model.get_value(iter, TEXT_LINE_COL).lower().find(key.lower()) == -1
331
 
 
332
 
        tv.set_enable_search(True)
333
 
        tv.set_search_equal_func(search_equal_func, None)
 
321
        # FIXME: Now that C-f is now used for search by text we
 
322
        # may as well disable the auto search.
 
323
        tv.set_search_column(LINE_NUM_COL)
334
324
 
335
325
        return tv
336
326
 
337
327
    def _create_log_view(self):
338
 
        lv = RevisionView(self._branch)
 
328
        lv = LogView()
339
329
        lv.show()
340
330
        return lv
341
331
 
342
332
    def _create_back_button(self):
343
 
        button = Gtk.Button()
 
333
        button = gtk.Button()
344
334
        button.set_use_stock(True)
345
335
        button.set_label("gtk-go-back")
346
336
        button.connect("clicked", lambda w: self.go_back())
347
 
        button.set_relief(Gtk.ReliefStyle.NONE)
 
337
        button.set_relief(gtk.RELIEF_NONE)
348
338
        button.show()
349
339
        return button
350
340
 
351
341
    def _create_forward_button(self):
352
 
        button = Gtk.Button()
 
342
        button = gtk.Button()
353
343
        button.set_use_stock(True)
354
344
        button.set_label("gtk-go-forward")
355
345
        button.connect("clicked", lambda w: self.go_forward())
356
 
        button.set_relief(Gtk.ReliefStyle.NONE)
 
346
        button.set_relief(gtk.RELIEF_NONE)
357
347
        button.show()
358
348
        button.set_sensitive(False)
359
349
        return button
360
350
 
361
 
    def _create_find_button(self):
362
 
        button = Gtk.Button()
363
 
        button.set_use_stock(True)
364
 
        button.set_label("gtk-find")
365
 
        button.set_tooltip_text("Search for text (Ctrl+F)")
366
 
        button.connect("clicked", self._search_by_text)
367
 
        button.set_relief(Gtk.ReliefStyle.NONE)
368
 
        button.show()
369
 
        button.set_sensitive(True)
370
 
        return button
371
 
 
372
 
    def _create_goto_button(self):
373
 
        button = Gtk.Button()
374
 
        button.set_label("Goto Line")
375
 
        button.set_tooltip_text("Scroll to a line by entering its number (Ctrl+G)")
376
 
        button.connect("clicked", self._search_by_line)
377
 
        button.set_relief(Gtk.ReliefStyle.NONE)
378
 
        button.show()
379
 
        button.set_sensitive(True)
380
 
        return button
381
 
 
382
351
    def go_back(self):
383
352
        last_tree = self.tree
384
353
        rev_id = self._selected_revision()
403
372
        rev_id = self._selected_revision()
404
373
        if self.file_id in target_tree:
405
374
            offset = self.get_scroll_offset(target_tree)
406
 
            path, col = self.annoview.get_cursor()
407
 
            (row,) = path.get_indices()
 
375
            (row,), col = self.annoview.get_cursor()
408
376
            self.annotate(target_tree, self.branch, self.file_id)
409
377
            new_row = row+offset
410
378
            if new_row < 0:
411
379
                new_row = 0
412
 
            new_path = Gtk.TreePath(path=new_row)
413
 
            self.annoview.set_cursor(new_path, None, False)
 
380
            self.annoview.set_cursor(new_row)
414
381
            return True
415
382
        else:
416
383
            return False
418
385
    def get_scroll_offset(self, tree):
419
386
        old = self.tree.get_file(self.file_id)
420
387
        new = tree.get_file(self.file_id)
421
 
        path, col = self.annoview.get_cursor()
422
 
        (row,) = path.get_indices()
 
388
        (row,), col = self.annoview.get_cursor()
423
389
        matcher = patiencediff.PatienceSequenceMatcher(None, old.readlines(),
424
390
                                                       new.readlines())
425
391
        for i, j, n in matcher.get_matching_blocks():
427
393
                return j - i
428
394
 
429
395
 
430
 
class FakeRevision(object):
 
396
 
 
397
class FakeRevision:
431
398
    """ A fake revision.
432
399
 
433
400
    For when a revision is referenced but not present.
442
409
        self.timezone = 0
443
410
        self.properties = {}
444
411
 
445
 
    def get_apparent_authors(self):
446
 
        return [self.committer]
447
 
 
448
412
 
449
413
class RevisionCache(object):
450
414
    """A caching revision source"""
451
 
 
452
415
    def __init__(self, real_source, seed_cache=None):
453
416
        self.__real_source = real_source
454
417
        if seed_cache is None:
462
425
            self.__cache[revision_id] = revision
463
426
        return self.__cache[revision_id]
464
427
 
465
 
 
466
 
class SearchBox(Gtk.HBox):
 
428
class SearchBox(gtk.HBox):
467
429
    """A button box for searching in text or lines of annotations"""
468
430
    def __init__(self):
469
 
        super(SearchBox, self).__init__(homogeneous=False, spacing=6)
 
431
        gtk.HBox.__init__(self, False, 6)
470
432
 
471
433
        # Close button
472
 
        button = Gtk.Button()
473
 
        image = Gtk.Image()
474
 
        image.set_from_stock('gtk-stop', Gtk.IconSize.BUTTON)
 
434
        button = gtk.Button()
 
435
        image = gtk.Image()
 
436
        image.set_from_stock('gtk-stop', gtk.ICON_SIZE_BUTTON)
475
437
        button.set_image(image)
476
 
        button.set_relief(Gtk.ReliefStyle.NONE)
477
 
        button.connect("clicked", lambda w: self.hide())
478
 
        self.pack_start(button, False, False, 0)
 
438
        button.set_relief(gtk.RELIEF_NONE)
 
439
        button.connect("clicked", lambda w: self.hide_all())
 
440
        self.pack_start(button, expand=False, fill=False)
479
441
 
480
442
        # Search entry
481
 
        label = Gtk.Label()
 
443
        label = gtk.Label()
482
444
        self._label = label
483
 
        self.pack_start(label, False, False, 0)
 
445
        self.pack_start(label, expand=False, fill=False)
484
446
 
485
 
        entry = Gtk.Entry()
 
447
        entry = gtk.Entry()
486
448
        self._entry = entry
487
449
        entry.connect("activate", lambda w, d: self._do_search(d),
488
450
                      'forward')
489
 
        self.pack_start(entry, False, False, 0)
 
451
        self.pack_start(entry, expand=False, fill=False)
490
452
 
491
453
        # Next/previous buttons
492
 
        button = Gtk.Button(_i18n('_Next'), use_underline=True)
493
 
        image = Gtk.Image()
494
 
        image.set_from_stock('gtk-go-forward', Gtk.IconSize.BUTTON)
 
454
        button = gtk.Button('_Next')
 
455
        image = gtk.Image()
 
456
        image.set_from_stock('gtk-go-forward', gtk.ICON_SIZE_BUTTON)
495
457
        button.set_image(image)
496
458
        button.connect("clicked", lambda w, d: self._do_search(d),
497
459
                       'forward')
498
 
        self.pack_start(button, False, False, 0)
 
460
        self.pack_start(button, expand=False, fill=False)
499
461
 
500
 
        button = Gtk.Button(_i18n('_Previous'), use_underline=True)
501
 
        image = Gtk.Image()
502
 
        image.set_from_stock('gtk-go-back', Gtk.IconSize.BUTTON)
 
462
        button = gtk.Button('_Previous')
 
463
        image = gtk.Image()
 
464
        image.set_from_stock('gtk-go-back', gtk.ICON_SIZE_BUTTON)
503
465
        button.set_image(image)
504
466
        button.connect("clicked", lambda w, d: self._do_search(d),
505
467
                       'backward')
506
 
        self.pack_start(button, False, False, 0)
 
468
        self.pack_start(button, expand=False, fill=False)
507
469
 
508
470
        # Search options
509
 
        check = Gtk.CheckButton('Match case')
 
471
        check = gtk.CheckButton('Match case')
510
472
        self._match_case = check
511
 
        self.pack_start(check, False, False, 0)
 
473
        self.pack_start(check, expand=False, fill=False)
512
474
 
513
 
        check = Gtk.CheckButton('Regexp')
 
475
        check = gtk.CheckButton('Regexp')
514
476
        check.connect("toggled", lambda w: self._set_label())
515
477
        self._regexp = check
516
 
        self.pack_start(check, False, False, 0)
 
478
        self.pack_start(check, expand=False, fill=False)
517
479
 
518
480
        self._view = None
519
481
        self._column = None
546
508
 
547
509
    def _match(self, model, iterator, column):
548
510
        matching_case = self._match_case.get_active()
549
 
        cell_value, = model.get(iterator, column)
 
511
        string, = model.get(iterator, column)
550
512
        key = self._entry.get_text()
551
 
        if column == LINE_NUM_COL:
552
 
            # FIXME: For goto-line there are faster algorithms than searching 
553
 
            # every line til we find the right one! -- mbp 2011-01-27
554
 
            return key.strip() == str(cell_value)
555
 
        elif self._regexp.get_active():
 
513
        if self._regexp.get_active():
556
514
            if matching_case:
557
 
                match = re.compile(key).search(cell_value, 1)
 
515
                match = re.compile(key).search(string, 1)
558
516
            else:
559
 
                match = re.compile(key, re.I).search(cell_value, 1)
 
517
                match = re.compile(key, re.I).search(string, 1)
560
518
        else:
561
519
            if not matching_case:
562
 
                cell_value = cell_value.lower()
 
520
                string = string.lower()
563
521
                key = key.lower()
564
 
            match = cell_value.find(key) != -1
 
522
            match = string.find(key) != -1
565
523
 
566
524
        return match
567
525
 
599
557
        for row in iterate(model, start):
600
558
            if self._match(model, row, self._column):
601
559
                path = model.get_path(row)
602
 
                self._view.set_cursor(path, None, False)
 
560
                self._view.set_cursor(path)
603
561
                self._view.scroll_to_cell(path, use_align=True)
604
562
                break