/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
301 by Daniel Schierbeck
Initial work on extracting the TreeView from the branch window.
1
# -*- coding: UTF-8 -*-
2
"""Revision history view.
3
4
"""
5
6
__copyright__ = "Copyright © 2005 Canonical Ltd."
7
__author__    = "Daniel Schierbeck <daniel.schierbeck@gmail.com>"
8
314 by Daniel Schierbeck
Moved branch locking into treeview.
9
import sys
10
import string
301 by Daniel Schierbeck
Initial work on extracting the TreeView from the branch window.
11
import gtk
12
import gobject
13
import pango
14
import re
303 by Daniel Schierbeck
Made basic signaling work.
15
import treemodel
301 by Daniel Schierbeck
Initial work on extracting the TreeView from the branch window.
16
17
from linegraph import linegraph, same_branch
18
from graphcell import CellRendererGraph
19
from treemodel import TreeModel
20
303 by Daniel Schierbeck
Made basic signaling work.
21
class TreeView(gtk.ScrolledWindow):
301 by Daniel Schierbeck
Initial work on extracting the TreeView from the branch window.
22
307 by Daniel Schierbeck
Made load notification work again.
23
    __gsignals__ = {
24
            'revisions-loaded': (gobject.SIGNAL_RUN_FIRST, 
25
                                 gobject.TYPE_NONE,
308 by Daniel Schierbeck
Made Show Diff work again.
26
                                 ()),
27
            'revision-selected': (gobject.SIGNAL_RUN_FIRST,
28
                                  gobject.TYPE_NONE,
29
                                  ())
307 by Daniel Schierbeck
Made load notification work again.
30
    }
31
316 by Daniel Schierbeck
Removed viz.TreeView.set_branch()
32
    def __init__(self, branch, start, maxnum):
322 by Jelmer Vernooij
Add docstrings.
33
        """Create a new TreeView.
34
35
        :param branch: Branch object for branch to show.
36
        :param start: Revision id of top revision.
37
        :param maxnum: Maximum number of revisions to display, 
38
                       None for no limit.
39
        """
301 by Daniel Schierbeck
Initial work on extracting the TreeView from the branch window.
40
        gtk.ScrolledWindow.__init__(self)
41
303 by Daniel Schierbeck
Made basic signaling work.
42
        self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
301 by Daniel Schierbeck
Initial work on extracting the TreeView from the branch window.
43
        self.set_shadow_type(gtk.SHADOW_IN)
44
303 by Daniel Schierbeck
Made basic signaling work.
45
        self.construct_treeview()
46
316 by Daniel Schierbeck
Removed viz.TreeView.set_branch()
47
        self.branch = branch
48
        self.branch.lock_read()
49
50
        gobject.idle_add(self.populate, start, maxnum)
51
303 by Daniel Schierbeck
Made basic signaling work.
52
        self.revision = None
53
        self.children = None
54
        self.parents  = None
55
314 by Daniel Schierbeck
Moved branch locking into treeview.
56
        self.connect('destroy', lambda w: self.branch.unlock())
57
303 by Daniel Schierbeck
Made basic signaling work.
58
    def get_revision(self):
322 by Jelmer Vernooij
Add docstrings.
59
        """Return revision id of currently selected revision, or None."""
303 by Daniel Schierbeck
Made basic signaling work.
60
        return self.revision
61
305 by Daniel Schierbeck
Moved revision selection to the new view.
62
    def set_revision(self, revid):
322 by Jelmer Vernooij
Add docstrings.
63
        """Change the currently selected revision.
64
65
        :param revid: Revision id of revision to display.
66
        """
305 by Daniel Schierbeck
Moved revision selection to the new view.
67
        self.treeview.set_cursor(self.index[revid])
68
        self.treeview.grab_focus()
69
303 by Daniel Schierbeck
Made basic signaling work.
70
    def get_children(self):
322 by Jelmer Vernooij
Add docstrings.
71
        """Return the children of the currently selected revision.
72
73
        :return: list of revision ids.
74
        """
303 by Daniel Schierbeck
Made basic signaling work.
75
        return self.children
76
77
    def get_parents(self):
322 by Jelmer Vernooij
Add docstrings.
78
        """Return the parents of the currently selected revision.
79
80
        :return: list of revision ids.
81
        """
303 by Daniel Schierbeck
Made basic signaling work.
82
        return self.parents
316 by Daniel Schierbeck
Removed viz.TreeView.set_branch()
83
        
304 by Daniel Schierbeck
Made forward/back buttons work again.
84
    def back(self):
322 by Jelmer Vernooij
Add docstrings.
85
        """Signal handler for the Back button."""
304 by Daniel Schierbeck
Made forward/back buttons work again.
86
        (path, col) = self.treeview.get_cursor()
87
        revision = self.model[path][treemodel.REVISION]
88
        parents = self.model[path][treemodel.PARENTS]
89
        if not len(parents):
90
            return
91
92
        for parent_id in parents:
93
            parent_index = self.index[parent_id]
94
            parent = self.model[parent_index][treemodel.REVISION]
95
            if same_branch(revision, parent):
96
                self.treeview.set_cursor(parent_index)
97
                break
98
        else:
99
            self.treeview.set_cursor(self.index[parents[0]])
100
        self.treeview.grab_focus()
101
102
    def forward(self):
322 by Jelmer Vernooij
Add docstrings.
103
        """Signal handler for the Forward button."""
304 by Daniel Schierbeck
Made forward/back buttons work again.
104
        (path, col) = self.treeview.get_cursor()
105
        revision = self.model[path][treemodel.REVISION]
106
        children = self.model[path][treemodel.CHILDREN]
107
        if not len(children):
108
            return
109
110
        for child_id in children:
111
            child_index = self.index[child_id]
112
            child = self.model[child_index][treemodel.REVISION]
113
            if same_branch(child, revision):
114
                self.treeview.set_cursor(child_index)
115
                break
116
        else:
117
            self.treeview.set_cursor(self.index[children[0]])
118
        self.treeview.grab_focus()
119
120
    def populate(self, start, maxnum):
322 by Jelmer Vernooij
Add docstrings.
121
        """Fill the treeview with contents.
122
123
        :param start: Revision id of revision to start with.
124
        :param maxnum: Maximum number of revisions to display, or None 
125
                       for no limit.
126
        """
304 by Daniel Schierbeck
Made forward/back buttons work again.
127
        (linegraphdata, index, columns_len) = linegraph(self.branch,
128
                                                        start,
129
                                                        maxnum)
130
131
        self.model = TreeModel(self.branch, linegraphdata)
132
        self.graph_cell.columns_len = columns_len
133
        width = self.graph_cell.get_size(self.treeview)[2]
134
        self.graph_column.set_fixed_width(width)
135
        self.graph_column.set_max_width(width)
136
        self.index = index
137
        self.treeview.set_model(self.model)
138
        self.treeview.set_cursor(0)
307 by Daniel Schierbeck
Made load notification work again.
139
        self.emit('revisions-loaded')
304 by Daniel Schierbeck
Made forward/back buttons work again.
140
141
        return False
142
306 by Daniel Schierbeck
Made clicking a row work again.
143
    def show_diff(self, branch, revid, parentid):
144
        """Open a new window to show a diff between the given revisions."""
145
        from bzrlib.plugins.gtk.diff import DiffWindow
146
        window = DiffWindow(parent=self)
147
        (parent_tree, rev_tree) = branch.repository.revision_trees([parentid, 
148
                                                                   revid])
149
        description = revid + " - " + branch.nick
150
        window.set_diff(description, rev_tree, parent_tree)
151
        window.show()
152
301 by Daniel Schierbeck
Initial work on extracting the TreeView from the branch window.
153
    def construct_treeview(self):
154
        self.treeview = gtk.TreeView()
155
156
        self.treeview.set_rules_hint(True)
157
        self.treeview.set_search_column(4)
158
303 by Daniel Schierbeck
Made basic signaling work.
159
        self.treeview.get_selection().connect("changed",
301 by Daniel Schierbeck
Initial work on extracting the TreeView from the branch window.
160
                self._on_selection_changed)
161
162
        self.treeview.connect("row-activated", 
163
                self._on_revision_activated)
164
165
        self.treeview.connect("button-release-event", 
166
                self._on_revision_selected)
167
168
        self.treeview.set_property('fixed-height-mode', True)
169
170
        self.add(self.treeview)
171
        self.treeview.show()
172
173
        cell = gtk.CellRendererText()
174
        cell.set_property("width-chars", 15)
175
        cell.set_property("ellipsize", pango.ELLIPSIZE_END)
176
        column = gtk.TreeViewColumn("Revision No")
177
        column.set_resizable(True)
178
        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
179
        column.set_fixed_width(cell.get_size(self.treeview)[2])
180
        column.pack_start(cell, expand=True)
181
        column.add_attribute(cell, "text", treemodel.REVNO)
182
        self.treeview.append_column(column)
183
184
        self.graph_cell = CellRendererGraph()
185
        self.graph_column = gtk.TreeViewColumn()
186
        self.graph_column.set_resizable(True)
187
        self.graph_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
188
        self.graph_column.pack_start(self.graph_cell, expand=False)
189
        self.graph_column.add_attribute(self.graph_cell, "node", treemodel.NODE)
190
        self.graph_column.add_attribute(self.graph_cell, "in-lines", treemodel.LAST_LINES)
191
        self.graph_column.add_attribute(self.graph_cell, "out-lines", treemodel.LINES)
192
        self.treeview.append_column(self.graph_column)
193
194
        cell = gtk.CellRendererText()
195
        cell.set_property("width-chars", 65)
196
        cell.set_property("ellipsize", pango.ELLIPSIZE_END)
197
        column = gtk.TreeViewColumn("Message")
198
        column.set_resizable(True)
199
        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
200
        column.set_fixed_width(cell.get_size(self.treeview)[2])
201
        column.pack_start(cell, expand=True)
202
        column.add_attribute(cell, "text", treemodel.MESSAGE)
203
        self.treeview.append_column(column)
204
205
        cell = gtk.CellRendererText()
206
        cell.set_property("width-chars", 15)
207
        cell.set_property("ellipsize", pango.ELLIPSIZE_END)
208
        column = gtk.TreeViewColumn("Committer")
209
        column.set_resizable(True)
210
        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
211
        column.set_fixed_width(cell.get_size(self.treeview)[2])
212
        column.pack_start(cell, expand=True)
213
        column.add_attribute(cell, "text", treemodel.COMMITER)
214
        self.treeview.append_column(column)
215
216
    def _on_selection_changed(self, selection, *args):
303 by Daniel Schierbeck
Made basic signaling work.
217
        """callback for when the treeview changes."""
301 by Daniel Schierbeck
Initial work on extracting the TreeView from the branch window.
218
        (model, selected_rows) = selection.get_selected_rows()
219
        if len(selected_rows) > 0:
220
            iter = self.model.get_iter(selected_rows[0])
303 by Daniel Schierbeck
Made basic signaling work.
221
            self.revision = self.model.get_value(iter, treemodel.REVISION)
222
            self.parents = self.model.get_value(iter, treemodel.PARENTS)
223
            self.children = self.model.get_value(iter, treemodel.CHILDREN)
301 by Daniel Schierbeck
Initial work on extracting the TreeView from the branch window.
224
310 by Daniel Schierbeck
Moved to using custom signal for handling revision selections.
225
            self.emit('revision-selected')
226
301 by Daniel Schierbeck
Initial work on extracting the TreeView from the branch window.
227
    def _on_revision_selected(self, widget, event):
228
        from bzrlib.plugins.gtk.revisionmenu import RevisionPopupMenu
229
        if event.button == 3:
230
            menu = RevisionPopupMenu(self.branch.repository, 
312 by Daniel Schierbeck
Made right-clicking work again.
231
                [self.get_revision().revision_id],
301 by Daniel Schierbeck
Initial work on extracting the TreeView from the branch window.
232
                self.branch)
233
            menu.popup(None, None, None, event.button, event.get_time())
234
235
    def _on_revision_activated(self, widget, path, col):
236
        # TODO: more than one parent
237
        """Callback for when a treeview row gets activated."""
238
        revision_id = self.model[path][treemodel.REVID]
239
        parents = self.model[path][treemodel.PARENTS]
240
        if len(parents) == 0:
241
            # Ignore revisions without parent
242
            return
243
        parent_id = parents[0]
244
        self.show_diff(self.branch, revision_id, parent_id)
245
        self.treeview.grab_focus()