/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 branchview/treeview.py

  • Committer: Curtis Hovey
  • Date: 2011-08-27 18:35:08 UTC
  • mto: This revision was merged to the branch mainline in revision 741.
  • Revision ID: sinzui.is@verizon.net-20110827183508-ugqbp58na4mtt1no
Updated the pixbuf calls to gtk3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
__copyright__ = "Copyright © 2005 Canonical Ltd."
7
7
__author__    = "Daniel Schierbeck <daniel.schierbeck@gmail.com>"
8
8
 
9
 
import gtk
10
 
import gobject
11
 
import pango
12
 
import treemodel
 
9
from gi.repository import Gtk
 
10
from gi.repository import GObject
 
11
from gi.repository import Pango
 
12
 
13
13
from bzrlib import ui
14
 
 
15
 
from bzrlib.plugins.gtk.ui import ProgressPanel
16
 
from linegraph import linegraph, same_branch
17
 
from graphcell import CellRendererGraph
18
 
from treemodel import TreeModel
19
14
from bzrlib.revision import NULL_REVISION
 
15
 
20
16
from bzrlib.plugins.gtk import lock
21
 
 
22
 
 
23
 
class TreeView(gtk.VBox):
 
17
from bzrlib.plugins.gtk.ui import ProgressPanel
 
18
from bzrlib.plugins.gtk.branchview import treemodel
 
19
from bzrlib.plugins.gtk.branchview.linegraph import linegraph, same_branch
 
20
from bzrlib.plugins.gtk.branchview.graphcell import CellRendererGraph
 
21
 
 
22
 
 
23
class TreeView(Gtk.VBox):
24
24
 
25
25
    __gproperties__ = {
26
 
        'branch': (gobject.TYPE_PYOBJECT,
 
26
        'branch': (GObject.TYPE_PYOBJECT,
27
27
                   'Branch',
28
28
                   'The Bazaar branch being visualized',
29
 
                   gobject.PARAM_CONSTRUCT_ONLY | gobject.PARAM_WRITABLE),
 
29
                   GObject.PARAM_CONSTRUCT_ONLY | GObject.PARAM_WRITABLE),
30
30
 
31
 
        'revision': (gobject.TYPE_PYOBJECT,
 
31
        'revision': (GObject.TYPE_PYOBJECT,
32
32
                     'Revision',
33
33
                     'The currently selected revision',
34
 
                     gobject.PARAM_READWRITE),
 
34
                     GObject.PARAM_READWRITE),
35
35
 
36
 
        'revision-number': (gobject.TYPE_STRING,
 
36
        'revision-number': (GObject.TYPE_STRING,
37
37
                            'Revision number',
38
38
                            'The number of the selected revision',
39
39
                            '',
40
 
                            gobject.PARAM_READABLE),
 
40
                            GObject.PARAM_READABLE),
41
41
 
42
 
        'children': (gobject.TYPE_PYOBJECT,
 
42
        'children': (GObject.TYPE_PYOBJECT,
43
43
                     'Child revisions',
44
44
                     'Children of the currently selected revision',
45
 
                     gobject.PARAM_READABLE),
 
45
                     GObject.PARAM_READABLE),
46
46
 
47
 
        'parents': (gobject.TYPE_PYOBJECT,
 
47
        'parents': (GObject.TYPE_PYOBJECT,
48
48
                    'Parent revisions',
49
49
                    'Parents to the currently selected revision',
50
 
                    gobject.PARAM_READABLE),
 
50
                    GObject.PARAM_READABLE),
51
51
 
52
 
        'revno-column-visible': (gobject.TYPE_BOOLEAN,
 
52
        'revno-column-visible': (GObject.TYPE_BOOLEAN,
53
53
                                 'Revision number column',
54
54
                                 'Show revision number column',
55
55
                                 True,
56
 
                                 gobject.PARAM_READWRITE),
 
56
                                 GObject.PARAM_READWRITE),
57
57
 
58
 
        'graph-column-visible': (gobject.TYPE_BOOLEAN,
 
58
        'graph-column-visible': (GObject.TYPE_BOOLEAN,
59
59
                                 'Graph column',
60
60
                                 'Show graph column',
61
61
                                 True,
62
 
                                 gobject.PARAM_READWRITE),
 
62
                                 GObject.PARAM_READWRITE),
63
63
 
64
 
        'date-column-visible': (gobject.TYPE_BOOLEAN,
 
64
        'date-column-visible': (GObject.TYPE_BOOLEAN,
65
65
                                 'Date',
66
66
                                 'Show date column',
67
67
                                 False,
68
 
                                 gobject.PARAM_READWRITE),
 
68
                                 GObject.PARAM_READWRITE),
69
69
 
70
 
        'compact': (gobject.TYPE_BOOLEAN,
 
70
        'compact': (GObject.TYPE_BOOLEAN,
71
71
                    'Compact view',
72
72
                    'Break ancestry lines to save space',
73
73
                    True,
74
 
                    gobject.PARAM_CONSTRUCT | gobject.PARAM_READWRITE),
 
74
                    GObject.PARAM_CONSTRUCT | GObject.PARAM_READWRITE),
75
75
 
76
 
        'mainline-only': (gobject.TYPE_BOOLEAN,
 
76
        'mainline-only': (GObject.TYPE_BOOLEAN,
77
77
                    'Mainline only',
78
78
                    'Only show the mainline history.',
79
79
                    False,
80
 
                    gobject.PARAM_CONSTRUCT | gobject.PARAM_READWRITE),
 
80
                    GObject.PARAM_CONSTRUCT | GObject.PARAM_READWRITE),
81
81
 
82
82
    }
83
83
 
84
84
    __gsignals__ = {
85
 
        'revision-selected': (gobject.SIGNAL_RUN_FIRST,
86
 
                              gobject.TYPE_NONE,
 
85
        'revision-selected': (GObject.SignalFlags.RUN_FIRST,
 
86
                              None,
87
87
                              ()),
88
 
        'revision-activated': (gobject.SIGNAL_RUN_FIRST,
89
 
                              gobject.TYPE_NONE,
90
 
                              (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)),
91
 
        'tag-added': (gobject.SIGNAL_RUN_FIRST,
92
 
                              gobject.TYPE_NONE,
93
 
                              (gobject.TYPE_STRING, gobject.TYPE_STRING)),
94
 
        'refreshed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
 
88
        'revision-activated': (GObject.SignalFlags.RUN_FIRST,
 
89
                              None,
 
90
                              (GObject.TYPE_PYOBJECT, GObject.TYPE_PYOBJECT)),
 
91
        'tag-added': (GObject.SignalFlags.RUN_FIRST,
 
92
                              None,
 
93
                              (GObject.TYPE_STRING, GObject.TYPE_STRING)),
 
94
        'refreshed': (GObject.SignalFlags.RUN_FIRST, None,
95
95
                              ())
96
96
    }
97
97
 
105
105
        :param broken_line_length: After how much lines to break 
106
106
                                   branches.
107
107
        """
108
 
        gtk.VBox.__init__(self, spacing=0)
 
108
        Gtk.VBox.__init__(self, homogeneous=False, spacing=0)
109
109
 
110
110
        self.progress_widget = ProgressPanel()
111
 
        self.pack_start(self.progress_widget, expand=False, fill=True)
 
111
        self.pack_start(self.progress_widget, False, True, 0)
112
112
        if getattr(ui.ui_factory, "set_progress_bar_widget", None) is not None:
113
113
            # We'are using our own ui, let's tell it to use our widget.
114
114
            ui.ui_factory.set_progress_bar_widget(self.progress_widget)
115
115
 
116
 
        self.scrolled_window = gtk.ScrolledWindow()
117
 
        self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,
118
 
                                        gtk.POLICY_AUTOMATIC)
119
 
        self.scrolled_window.set_shadow_type(gtk.SHADOW_IN)
 
116
        self.scrolled_window = Gtk.ScrolledWindow()
 
117
        self.scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,
 
118
                                        Gtk.PolicyType.AUTOMATIC)
 
119
        self.scrolled_window.set_shadow_type(Gtk.ShadowType.IN)
120
120
        self.scrolled_window.show()
121
 
        self.pack_start(self.scrolled_window, expand=True, fill=True)
 
121
        self.pack_start(self.scrolled_window, True, True, 0)
122
122
 
123
123
        self.scrolled_window.add(self.construct_treeview())
124
124
 
131
131
        self.maxnum = maxnum
132
132
        self.compact = compact
133
133
 
134
 
        gobject.idle_add(self.populate)
 
134
        self.model = treemodel.TreeModel(self.branch, [])
 
135
        GObject.idle_add(self.populate)
135
136
 
136
137
        self.connect("destroy", self._on_destroy)
137
138
 
155
156
        elif property.name == 'branch':
156
157
            return self.branch
157
158
        elif property.name == 'revision':
 
159
            if self.path is None:
 
160
                return None
158
161
            return self.model.get_value(self.model.get_iter(self.path),
159
162
                                        treemodel.REVISION)
160
163
        elif property.name == 'revision-number':
 
164
            if self.path is None:
 
165
                return None
161
166
            return self.model.get_value(self.model.get_iter(self.path),
162
167
                                        treemodel.REVNO)
163
168
        elif property.name == 'children':
 
169
            if self.path is None:
 
170
                return None
164
171
            return self.model.get_value(self.model.get_iter(self.path),
165
172
                                        treemodel.CHILDREN)
166
173
        elif property.name == 'parents':
 
174
            if self.path is None:
 
175
                return None
167
176
            return self.model.get_value(self.model.get_iter(self.path),
168
177
                                        treemodel.PARENTS)
169
178
        else:
202
211
 
203
212
        :param revid: Revision id of revision to display.
204
213
        """
205
 
        self.treeview.set_cursor(self.index[revid])
 
214
        self.treeview.set_cursor(
 
215
            Gtk.TreePath(path=self.index[revid]), None, False)
206
216
        self.treeview.grab_focus()
207
217
 
208
218
    def get_children(self):
232
242
            lock.acquire(self.branch, lock.READ)
233
243
 
234
244
            self.emit('tag-added', tag, revid)
235
 
        
 
245
 
236
246
    def refresh(self):
237
 
        gobject.idle_add(self.populate, self.get_revision())
 
247
        GObject.idle_add(self.populate, self.get_revision())
238
248
 
239
249
    def update(self):
240
250
        try:
298
308
                broken_line_length = 32
299
309
            else:
300
310
                broken_line_length = None
301
 
            
 
311
 
302
312
            show_graph = self.graph_column.get_visible()
303
313
 
304
314
            self.branch.lock_read()
310
320
                                                            self.mainline_only,
311
321
                                                            self.progress_bar)
312
322
 
313
 
            self.model = TreeModel(self.branch, linegraphdata)
 
323
            self.model.line_graph_data = linegraphdata
314
324
            self.graph_cell.columns_len = columns_len
315
 
            width = self.graph_cell.get_size(self.treeview)[2]
 
325
            width = self.graph_cell.get_preferred_width(self.treeview)[1]
316
326
            if width > 500:
317
327
                width = 500
318
328
            self.graph_column.set_fixed_width(width)
321
331
            self.treeview.set_model(self.model)
322
332
 
323
333
            if not revision or revision == NULL_REVISION:
324
 
                self.treeview.set_cursor(0)
 
334
                self.treeview.set_cursor(Gtk.TreePath(path=0), None, False)
325
335
            else:
326
336
                self.set_revision(revision)
327
337
 
331
341
            self.progress_bar.finished()
332
342
 
333
343
    def construct_treeview(self):
334
 
        self.treeview = gtk.TreeView()
 
344
        self.treeview = Gtk.TreeView()
335
345
 
336
346
        self.treeview.set_rules_hint(True)
337
 
        self.treeview.set_search_column(treemodel.REVNO)
338
 
        
339
 
        # Fix old PyGTK bug - by JAM
340
 
        set_tooltip = getattr(self.treeview, 'set_tooltip_column', None)
341
 
        if set_tooltip is not None:
342
 
            set_tooltip(treemodel.MESSAGE)
 
347
        # combined revno/summary interactive search
 
348
        #
 
349
        # the row in a treemodel is considered "matched" if a REVNO *starts*
 
350
        # from the key (that is the key is found in a REVNO at the offset 0)
 
351
        # or if a MESSAGE *contains* the key anywhere (that is, the key is
 
352
        # found case insensitively in a MESSAGE at any offset)
 
353
        def search_equal_func(model, column, key, iter):
 
354
            return (model.get_value(iter, treemodel.REVNO).find(key) != 0
 
355
                and model.get_value(iter, treemodel.MESSAGE).lower().find(key.lower()) == -1)
 
356
 
 
357
        self.treeview.set_search_equal_func(search_equal_func, None)
 
358
        self.treeview.set_enable_search(True)
 
359
 
 
360
        self.treeview.set_tooltip_column(treemodel.MESSAGE)
343
361
 
344
362
        self._prev_cursor_path = None
345
363
        self.treeview.connect("cursor-changed",
355
373
 
356
374
        self.treeview.show()
357
375
 
358
 
        cell = gtk.CellRendererText()
 
376
        cell = Gtk.CellRendererText()
359
377
        cell.set_property("width-chars", 15)
360
 
        cell.set_property("ellipsize", pango.ELLIPSIZE_END)
361
 
        self.revno_column = gtk.TreeViewColumn("Revision No")
362
 
        self.revno_column.set_resizable(False)
363
 
        self.revno_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
364
 
        self.revno_column.set_fixed_width(cell.get_size(self.treeview)[2])
365
 
        self.revno_column.pack_start(cell, expand=True)
 
378
        cell.set_property("ellipsize", Pango.EllipsizeMode.END)
 
379
        self.revno_column = Gtk.TreeViewColumn("Revision No")
 
380
        self.revno_column.set_resizable(True)
 
381
        self.revno_column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
 
382
        self.revno_column.set_fixed_width(
 
383
            cell.get_preferred_width(self.treeview)[1])
 
384
        self.revno_column.pack_start(cell, True)
366
385
        self.revno_column.add_attribute(cell, "text", treemodel.REVNO)
367
386
        self.treeview.append_column(self.revno_column)
368
387
 
369
388
        self.graph_cell = CellRendererGraph()
370
 
        self.graph_column = gtk.TreeViewColumn()
371
 
        self.graph_column.set_resizable(False)
372
 
        self.graph_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
373
 
        self.graph_column.pack_start(self.graph_cell, expand=True)
 
389
        self.graph_column = Gtk.TreeViewColumn()
 
390
        self.graph_column.set_resizable(True)
 
391
        self.graph_column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
 
392
        self.graph_column.pack_start(self.graph_cell, True)
374
393
        self.graph_column.add_attribute(self.graph_cell, "node", treemodel.NODE)
375
394
        self.graph_column.add_attribute(self.graph_cell, "tags", treemodel.TAGS)
376
395
        self.graph_column.add_attribute(self.graph_cell, "in-lines", treemodel.LAST_LINES)
377
396
        self.graph_column.add_attribute(self.graph_cell, "out-lines", treemodel.LINES)
378
397
        self.treeview.append_column(self.graph_column)
379
398
 
380
 
        cell = gtk.CellRendererText()
 
399
        cell = Gtk.CellRendererText()
381
400
        cell.set_property("width-chars", 65)
382
 
        cell.set_property("ellipsize", pango.ELLIPSIZE_END)
383
 
        self.summary_column = gtk.TreeViewColumn("Summary")
384
 
        self.summary_column.set_resizable(False)
 
401
        cell.set_property("ellipsize", Pango.EllipsizeMode.END)
 
402
        self.summary_column = Gtk.TreeViewColumn("Summary")
 
403
        self.summary_column.set_resizable(True)
385
404
        self.summary_column.set_expand(True)
386
 
        self.summary_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
387
 
        self.summary_column.set_fixed_width(cell.get_size(self.treeview)[2])
388
 
        self.summary_column.pack_start(cell, expand=True)
 
405
        self.summary_column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
 
406
        self.summary_column.set_fixed_width(
 
407
            cell.get_preferred_width(self.treeview)[1])
 
408
        self.summary_column.pack_start(cell, True)
389
409
        self.summary_column.add_attribute(cell, "markup", treemodel.SUMMARY)
390
410
        self.treeview.append_column(self.summary_column)
391
411
 
392
 
        cell = gtk.CellRendererText()
 
412
        cell = Gtk.CellRendererText()
393
413
        cell.set_property("width-chars", 15)
394
 
        cell.set_property("ellipsize", pango.ELLIPSIZE_END)
395
 
        self.authors_column = gtk.TreeViewColumn("Author(s)")
 
414
        cell.set_property("ellipsize", Pango.EllipsizeMode.END)
 
415
        self.authors_column = Gtk.TreeViewColumn("Author(s)")
396
416
        self.authors_column.set_resizable(False)
397
 
        self.authors_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
 
417
        self.authors_column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
398
418
        self.authors_column.set_fixed_width(200)
399
 
        self.authors_column.pack_start(cell, expand=True)
 
419
        self.authors_column.pack_start(cell, True)
400
420
        self.authors_column.add_attribute(cell, "text", treemodel.AUTHORS)
401
421
        self.treeview.append_column(self.authors_column)
402
422
 
403
 
        cell = gtk.CellRendererText()
 
423
        cell = Gtk.CellRendererText()
404
424
        cell.set_property("width-chars", 20)
405
 
        cell.set_property("ellipsize", pango.ELLIPSIZE_END)
406
 
        self.date_column = gtk.TreeViewColumn("Date")
 
425
        cell.set_property("ellipsize", Pango.EllipsizeMode.END)
 
426
        self.date_column = Gtk.TreeViewColumn("Date")
407
427
        self.date_column.set_visible(False)
408
 
        self.date_column.set_resizable(False)
409
 
        self.date_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
 
428
        self.date_column.set_resizable(True)
 
429
        self.date_column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
410
430
        self.date_column.set_fixed_width(130)
411
 
        self.date_column.pack_start(cell, expand=True)
 
431
        self.date_column.pack_start(cell, True)
412
432
        self.date_column.add_attribute(cell, "text", treemodel.TIMESTAMP)
413
433
        self.treeview.append_column(self.date_column)
414
 
        
 
434
 
415
435
        return self.treeview
416
 
    
 
436
 
417
437
    def _on_selection_changed(self, treeview):
418
438
        """callback for when the treeview changes."""
419
439
        (path, focus) = treeview.get_cursor()