/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: Curtis Hovey
  • Date: 2011-08-01 14:46:23 UTC
  • mto: This revision was merged to the branch mainline in revision 741.
  • Revision ID: sinzui.is@verizon.net-20110801144623-ldjf0bu7kyi5bxzu
Updated commit to gtk3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
import time
18
18
 
19
 
import pygtk
20
 
pygtk.require("2.0")
21
 
import gobject
22
 
import gtk
23
 
import pango
 
19
from gi.repository import GObject
 
20
from gi.repository import Gtk
 
21
from gi.repository import Pango
24
22
import re
25
23
 
26
 
from bzrlib import patiencediff, tsort
 
24
from bzrlib import patiencediff
27
25
from bzrlib.errors import NoSuchRevision
28
26
from bzrlib.revision import NULL_REVISION, CURRENT_REVISION
29
27
 
30
 
from colormap import AnnotateColorMap, AnnotateColorSaturation
 
28
from bzrlib.plugins.gtk.annotate.colormap import AnnotateColorSaturation
31
29
from bzrlib.plugins.gtk.revisionview import RevisionView
32
30
from bzrlib.plugins.gtk.window import Window
33
31
 
49
47
        self.all = all
50
48
        self.plain = plain
51
49
        self._branch = branch
52
 
        
 
50
 
53
51
        Window.__init__(self, parent)
54
 
        
55
 
        self.set_icon(self.render_icon(gtk.STOCK_FIND, gtk.ICON_SIZE_BUTTON))
 
52
 
 
53
        self.set_icon(self.render_icon(Gtk.STOCK_FIND, Gtk.IconSize.BUTTON))
56
54
        self.annotate_colormap = AnnotateColorSaturation()
57
55
 
58
56
        self._create()
68
66
        self.revisionview.set_file_id(file_id)
69
67
        self.revision_id = getattr(tree, 'get_revision_id', 
70
68
                                   lambda: CURRENT_REVISION)()
71
 
        
 
69
 
72
70
        # [revision id, line number, author, revno, highlight color, line]
73
 
        self.annomodel = gtk.ListStore(gobject.TYPE_STRING,
74
 
                                       gobject.TYPE_STRING,
75
 
                                       gobject.TYPE_STRING,
76
 
                                       gobject.TYPE_STRING,
77
 
                                       gobject.TYPE_STRING,
78
 
                                       gobject.TYPE_STRING)
79
 
        
 
71
        self.annomodel = Gtk.ListStore(GObject.TYPE_STRING,
 
72
                                       GObject.TYPE_INT,
 
73
                                       GObject.TYPE_STRING,
 
74
                                       GObject.TYPE_STRING,
 
75
                                       GObject.TYPE_STRING,
 
76
                                       GObject.TYPE_STRING)
 
77
 
80
78
        last_seen = None
81
79
        try:
82
80
            branch.lock_read()
86
84
            for revision_id, revno in revno_map.iteritems():
87
85
                self.dotted[revision_id] = '.'.join(str(num) for num in revno)
88
86
            for line_no, (revision, revno, line)\
89
 
                    in enumerate(self._annotate(tree, file_id)):
 
87
                in enumerate(self._annotate(tree, file_id)):
90
88
                if revision.revision_id == last_seen and not self.all:
91
89
                    revno = author = ""
92
90
                else:
102
100
                                       revno,
103
101
                                       None,
104
102
                                       line.rstrip("\r\n")
105
 
                                      ])
 
103
                                       ])
106
104
                self.annotations.append(revision)
107
105
 
108
106
            if not self.plain:
125
123
            # bar?
126
124
            print("gannotate: Line number %d does't exist. Defaulting to "
127
125
                  "line 1." % lineno)
128
 
            return
 
126
            return
129
127
        else:
130
128
            row = lineno - 1
131
129
 
193
191
        self.revisionview = self._create_log_view()
194
192
        self.annoview = self._create_annotate_view()
195
193
 
196
 
        vbox = gtk.VBox(False)
 
194
        vbox = Gtk.VBox(False)
197
195
        vbox.show()
198
196
 
199
 
        sw = gtk.ScrolledWindow()
200
 
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
201
 
        sw.set_shadow_type(gtk.SHADOW_IN)
 
197
        sw = Gtk.ScrolledWindow()
 
198
        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
 
199
        sw.set_shadow_type(Gtk.ShadowType.IN)
202
200
        sw.add(self.annoview)
203
201
        self.annoview.gwindow = self
204
202
        sw.show()
205
203
 
206
 
        swbox = gtk.VBox()
207
 
        swbox.pack_start(sw)
 
204
        swbox = Gtk.VBox()
 
205
        swbox.pack_start(sw, True, True, 0)
208
206
        swbox.show()
209
207
 
210
 
        hbox = gtk.HBox(False, 6)
 
208
        hbox = Gtk.HBox(False, 6)
211
209
        self.back_button = self._create_back_button()
212
210
        hbox.pack_start(self.back_button, expand=False, fill=True)
213
211
        self.forward_button = self._create_forward_button()
218
216
        hbox.pack_start(self.goto_button, expand=False, fill=True)
219
217
        hbox.show()
220
218
        vbox.pack_start(hbox, expand=False, fill=True)
221
 
        
222
 
        self.pane = pane = gtk.VPaned()
 
219
 
 
220
        self.pane = pane = Gtk.VPaned()
223
221
        pane.add1(swbox)
224
222
        pane.add2(self.revisionview)
225
223
        pane.show()
227
225
 
228
226
        self._search = SearchBox()
229
227
        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,
 
228
        accels = Gtk.AccelGroup()
 
229
        accels.connect_group(Gdk.KEY_f, Gdk.EventMask.CONTROL_MASK,
 
230
                             Gtk.ACCEL_LOCKED,
233
231
                             self._search_by_text)
234
 
        accels.connect_group(gtk.keysyms.g, gtk.gdk.CONTROL_MASK,
235
 
                             gtk.ACCEL_LOCKED,
 
232
        accels.connect_group(Gdk.KEY_g, Gdk.EventMask.CONTROL_MASK,
 
233
                             Gtk.ACCEL_LOCKED,
236
234
                             self._search_by_line)
237
235
        self.add_accel_group(accels)
238
236
 
260
258
            else:
261
259
                tree2 = repository.revision_tree(NULL_REVISION)
262
260
        from bzrlib.plugins.gtk.diff import DiffWindow
263
 
        window = DiffWindow()
 
261
        window = DiffWindow(self)
264
262
        window.set_diff("Diff for line %d" % (row+1), tree1, tree2)
265
263
        window.set_file(tree1.id2path(self.file_id))
266
264
        window.show()
267
265
 
268
266
 
269
267
    def _create_annotate_view(self):
270
 
        tv = gtk.TreeView()
 
268
        tv = Gtk.TreeView()
271
269
        tv.set_rules_hint(False)
272
270
        tv.connect("cursor-changed", self._activate_selected_revision)
273
271
        tv.show()
274
272
        tv.connect("row-activated", self.line_diff)
275
273
 
276
 
        cell = gtk.CellRendererText()
 
274
        cell = Gtk.CellRendererText()
277
275
        cell.set_property("xalign", 1.0)
278
276
        cell.set_property("ypad", 0)
279
277
        cell.set_property("family", "Monospace")
280
278
        cell.set_property("cell-background-gdk",
281
 
                          tv.get_style().bg[gtk.STATE_NORMAL])
282
 
        col = gtk.TreeViewColumn()
 
279
                          tv.get_style().bg[Gtk.StateType.NORMAL])
 
280
        col = Gtk.TreeViewColumn()
283
281
        col.set_resizable(False)
284
 
        col.pack_start(cell, expand=True)
 
282
        col.pack_start(cell, True, True, 0)
285
283
        col.add_attribute(cell, "text", LINE_NUM_COL)
286
284
        tv.append_column(col)
287
285
 
288
 
        cell = gtk.CellRendererText()
 
286
        cell = Gtk.CellRendererText()
289
287
        cell.set_property("ypad", 0)
290
 
        cell.set_property("ellipsize", pango.ELLIPSIZE_END)
 
288
        cell.set_property("ellipsize", Pango.EllipsizeMode.END)
291
289
        cell.set_property("cell-background-gdk",
292
 
                          self.get_style().bg[gtk.STATE_NORMAL])
293
 
        col = gtk.TreeViewColumn("Committer")
 
290
                          self.get_style().bg[Gtk.StateType.NORMAL])
 
291
        col = Gtk.TreeViewColumn("Committer")
294
292
        col.set_resizable(True)
295
 
        col.pack_start(cell, expand=True)
 
293
        col.pack_start(cell, True, True, 0)
296
294
        col.add_attribute(cell, "text", COMMITTER_COL)
297
295
        tv.append_column(col)
298
296
 
299
 
        cell = gtk.CellRendererText()
 
297
        cell = Gtk.CellRendererText()
300
298
        cell.set_property("xalign", 1.0)
301
299
        cell.set_property("ypad", 0)
302
300
        cell.set_property("cell-background-gdk",
303
 
                          self.get_style().bg[gtk.STATE_NORMAL])
304
 
        col = gtk.TreeViewColumn("Revno")
 
301
                          self.get_style().bg[Gtk.StateType.NORMAL])
 
302
        col = Gtk.TreeViewColumn("Revno")
305
303
        col.set_resizable(False)
306
 
        col.pack_start(cell, expand=True)
 
304
        col.pack_start(cell, True, True, 0)
307
305
        col.add_attribute(cell, "markup", REVNO_COL)
308
306
        tv.append_column(col)
309
307
 
310
 
        cell = gtk.CellRendererText()
 
308
        cell = Gtk.CellRendererText()
311
309
        cell.set_property("ypad", 0)
312
310
        cell.set_property("family", "Monospace")
313
 
        col = gtk.TreeViewColumn()
 
311
        col = Gtk.TreeViewColumn()
314
312
        col.set_resizable(False)
315
 
        col.pack_start(cell, expand=True)
 
313
        col.pack_start(cell, True, True, 0)
316
314
#        col.add_attribute(cell, "foreground", HIGHLIGHT_COLOR_COL)
317
315
        col.add_attribute(cell, "background", HIGHLIGHT_COLOR_COL)
318
316
        col.add_attribute(cell, "text", TEXT_LINE_COL)
319
317
        tv.append_column(col)
320
318
 
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)
 
319
        # interactive substring search
 
320
        def search_equal_func(model, column, key, iter):
 
321
            return model.get_value(iter, TEXT_LINE_COL).lower().find(key.lower()) == -1
 
322
 
 
323
        tv.set_enable_search(True)
 
324
        tv.set_search_equal_func(search_equal_func)
324
325
 
325
326
        return tv
326
327
 
330
331
        return lv
331
332
 
332
333
    def _create_back_button(self):
333
 
        button = gtk.Button()
 
334
        button = Gtk.Button()
334
335
        button.set_use_stock(True)
335
336
        button.set_label("gtk-go-back")
336
337
        button.connect("clicked", lambda w: self.go_back())
337
 
        button.set_relief(gtk.RELIEF_NONE)
 
338
        button.set_relief(Gtk.ReliefStyle.NONE)
338
339
        button.show()
339
340
        return button
340
341
 
341
342
    def _create_forward_button(self):
342
 
        button = gtk.Button()
 
343
        button = Gtk.Button()
343
344
        button.set_use_stock(True)
344
345
        button.set_label("gtk-go-forward")
345
346
        button.connect("clicked", lambda w: self.go_forward())
346
 
        button.set_relief(gtk.RELIEF_NONE)
 
347
        button.set_relief(Gtk.ReliefStyle.NONE)
347
348
        button.show()
348
349
        button.set_sensitive(False)
349
350
        return button
350
351
 
351
352
    def _create_find_button(self):
352
 
        button = gtk.Button()
 
353
        button = Gtk.Button()
353
354
        button.set_use_stock(True)
354
355
        button.set_label("gtk-find")
355
356
        button.set_tooltip_text("Search for text (Ctrl+F)")
356
357
        button.connect("clicked", self._search_by_text)
357
 
        button.set_relief(gtk.RELIEF_NONE)
 
358
        button.set_relief(Gtk.ReliefStyle.NONE)
358
359
        button.show()
359
360
        button.set_sensitive(True)
360
361
        return button
361
362
 
362
363
    def _create_goto_button(self):
363
 
        button = gtk.Button()
 
364
        button = Gtk.Button()
364
365
        button.set_label("Goto Line")
365
366
        button.set_tooltip_text("Scroll to a line by entering its number (Ctrl+G)")
366
367
        button.connect("clicked", self._search_by_line)
367
 
        button.set_relief(gtk.RELIEF_NONE)
 
368
        button.set_relief(Gtk.ReliefStyle.NONE)
368
369
        button.show()
369
370
        button.set_sensitive(True)
370
371
        return button
449
450
            self.__cache[revision_id] = revision
450
451
        return self.__cache[revision_id]
451
452
 
452
 
class SearchBox(gtk.HBox):
 
453
class SearchBox(Gtk.HBox):
453
454
    """A button box for searching in text or lines of annotations"""
454
455
    def __init__(self):
455
 
        gtk.HBox.__init__(self, False, 6)
 
456
        GObject.GObject.__init__(self, False, 6)
456
457
 
457
458
        # Close button
458
 
        button = gtk.Button()
459
 
        image = gtk.Image()
460
 
        image.set_from_stock('gtk-stop', gtk.ICON_SIZE_BUTTON)
 
459
        button = Gtk.Button()
 
460
        image = Gtk.Image()
 
461
        image.set_from_stock('gtk-stop', Gtk.IconSize.BUTTON)
461
462
        button.set_image(image)
462
 
        button.set_relief(gtk.RELIEF_NONE)
 
463
        button.set_relief(Gtk.ReliefStyle.NONE)
463
464
        button.connect("clicked", lambda w: self.hide_all())
464
465
        self.pack_start(button, expand=False, fill=False)
465
466
 
466
467
        # Search entry
467
 
        label = gtk.Label()
 
468
        label = Gtk.Label()
468
469
        self._label = label
469
470
        self.pack_start(label, expand=False, fill=False)
470
471
 
471
 
        entry = gtk.Entry()
 
472
        entry = Gtk.Entry()
472
473
        self._entry = entry
473
474
        entry.connect("activate", lambda w, d: self._do_search(d),
474
475
                      'forward')
475
476
        self.pack_start(entry, expand=False, fill=False)
476
477
 
477
478
        # Next/previous buttons
478
 
        button = gtk.Button('_Next')
479
 
        image = gtk.Image()
480
 
        image.set_from_stock('gtk-go-forward', gtk.ICON_SIZE_BUTTON)
 
479
        button = Gtk.Button('_Next')
 
480
        image = Gtk.Image()
 
481
        image.set_from_stock('gtk-go-forward', Gtk.IconSize.BUTTON)
481
482
        button.set_image(image)
482
483
        button.connect("clicked", lambda w, d: self._do_search(d),
483
484
                       'forward')
484
485
        self.pack_start(button, expand=False, fill=False)
485
486
 
486
 
        button = gtk.Button('_Previous')
487
 
        image = gtk.Image()
488
 
        image.set_from_stock('gtk-go-back', gtk.ICON_SIZE_BUTTON)
 
487
        button = Gtk.Button('_Previous')
 
488
        image = Gtk.Image()
 
489
        image.set_from_stock('gtk-go-back', Gtk.IconSize.BUTTON)
489
490
        button.set_image(image)
490
491
        button.connect("clicked", lambda w, d: self._do_search(d),
491
492
                       'backward')
492
493
        self.pack_start(button, expand=False, fill=False)
493
494
 
494
495
        # Search options
495
 
        check = gtk.CheckButton('Match case')
 
496
        check = Gtk.CheckButton('Match case')
496
497
        self._match_case = check
497
498
        self.pack_start(check, expand=False, fill=False)
498
499
 
499
 
        check = gtk.CheckButton('Regexp')
 
500
        check = Gtk.CheckButton('Regexp')
500
501
        check.connect("toggled", lambda w: self._set_label())
501
502
        self._regexp = check
502
503
        self.pack_start(check, expand=False, fill=False)
532
533
 
533
534
    def _match(self, model, iterator, column):
534
535
        matching_case = self._match_case.get_active()
535
 
        string, = model.get(iterator, column)
 
536
        cell_value, = model.get(iterator, column)
536
537
        key = self._entry.get_text()
537
 
        if self._regexp.get_active():
 
538
        if column == LINE_NUM_COL:
 
539
            # FIXME: For goto-line there are faster algorithms than searching 
 
540
            # every line til we find the right one! -- mbp 2011-01-27
 
541
            return key.strip() == str(cell_value)
 
542
        elif self._regexp.get_active():
538
543
            if matching_case:
539
 
                match = re.compile(key).search(string, 1)
 
544
                match = re.compile(key).search(cell_value, 1)
540
545
            else:
541
 
                match = re.compile(key, re.I).search(string, 1)
 
546
                match = re.compile(key, re.I).search(cell_value, 1)
542
547
        else:
543
548
            if not matching_case:
544
 
                string = string.lower()
 
549
                cell_value = cell_value.lower()
545
550
                key = key.lower()
546
 
            match = string.find(key) != -1
 
551
            match = cell_value.find(key) != -1
547
552
 
548
553
        return match
549
554