/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 viz/branchwin.py

  • Committer: Jelmer Vernooij
  • Date: 2007-07-15 15:05:06 UTC
  • Revision ID: jelmer@samba.org-20070715150506-1uemecr5kt7d4kvg
Fix whitespace, add comment.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/python
2
1
# -*- coding: UTF-8 -*-
3
2
"""Branch window.
4
3
 
10
9
__author__    = "Scott James Remnant <scott@ubuntu.com>"
11
10
 
12
11
 
13
 
import os
14
 
 
15
12
import gtk
16
13
import gobject
17
14
import pango
18
15
 
19
16
from bzrlib.osutils import format_date
20
17
 
21
 
from graph import graph
 
18
from graph import distances, graph, same_branch
22
19
from graphcell import CellRendererGraph
23
20
 
24
21
 
36
33
 
37
34
        # Use three-quarters of the screen by default
38
35
        screen = self.get_screen()
39
 
        width = int(screen.get_width() * 0.75)
40
 
        height = int(screen.get_height() * 0.75)
 
36
        monitor = screen.get_monitor_geometry(0)
 
37
        width = int(monitor.width * 0.75)
 
38
        height = int(monitor.height * 0.75)
41
39
        self.set_default_size(width, height)
42
40
 
43
41
        # FIXME AndyFitz!
44
42
        icon = self.render_icon(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
45
43
        self.set_icon(icon)
46
44
 
 
45
        self.accel_group = gtk.AccelGroup()
 
46
        self.add_accel_group(self.accel_group)
 
47
 
47
48
        self.construct()
48
49
 
49
50
    def construct(self):
50
51
        """Construct the window contents."""
 
52
        vbox = gtk.VBox(spacing=0)
 
53
        self.add(vbox)
 
54
 
 
55
        vbox.pack_start(self.construct_navigation(), expand=False, fill=True)
 
56
 
 
57
        paned = gtk.VPaned()
 
58
        paned.pack1(self.construct_top(), resize=True, shrink=False)
 
59
        paned.pack2(self.construct_bottom(), resize=False, shrink=True)
 
60
        paned.show()
 
61
        vbox.pack_start(paned, expand=True, fill=True)
 
62
        vbox.set_focus_child(paned)
 
63
 
 
64
        vbox.show()
 
65
 
 
66
    def construct_top(self):
 
67
        """Construct the top-half of the window."""
51
68
        scrollwin = gtk.ScrolledWindow()
52
69
        scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
53
70
        scrollwin.set_shadow_type(gtk.SHADOW_IN)
54
 
        scrollwin.set_border_width(12)
55
 
        self.add(scrollwin)
56
71
        scrollwin.show()
57
72
 
58
73
        self.treeview = gtk.TreeView()
59
74
        self.treeview.set_rules_hint(True)
60
75
        self.treeview.set_search_column(4)
 
76
        self.treeview.connect("cursor-changed", self._treeview_cursor_cb)
 
77
        self.treeview.connect("row-activated", self._treeview_row_activated_cb)
61
78
        scrollwin.add(self.treeview)
62
79
        self.treeview.show()
63
80
 
64
81
        cell = CellRendererGraph()
65
82
        column = gtk.TreeViewColumn()
66
 
        column.set_resizable(False)
 
83
        column.set_resizable(True)
67
84
        column.pack_start(cell, expand=False)
68
85
        column.add_attribute(cell, "node", 1)
69
86
        column.add_attribute(cell, "in-lines", 2)
96
113
        column.add_attribute(cell, "text", 6)
97
114
        self.treeview.append_column(column)
98
115
 
99
 
    def set_branch(self, branch, start):
 
116
        return scrollwin
 
117
 
 
118
    def construct_navigation(self):
 
119
        """Construct the navigation buttons."""
 
120
        frame = gtk.Frame()
 
121
        frame.set_shadow_type(gtk.SHADOW_OUT)
 
122
        frame.show()
 
123
        
 
124
        hbox = gtk.HBox(spacing=12)
 
125
        frame.add(hbox)
 
126
        hbox.show()
 
127
 
 
128
        self.back_button = gtk.Button(stock=gtk.STOCK_GO_BACK)
 
129
        self.back_button.set_relief(gtk.RELIEF_NONE)
 
130
        self.back_button.add_accelerator("clicked", self.accel_group, ord('['),
 
131
                                         0, 0)
 
132
        self.back_button.connect("clicked", self._back_clicked_cb)
 
133
        hbox.pack_start(self.back_button, expand=False, fill=True)
 
134
        self.back_button.show()
 
135
 
 
136
        self.fwd_button = gtk.Button(stock=gtk.STOCK_GO_FORWARD)
 
137
        self.fwd_button.set_relief(gtk.RELIEF_NONE)
 
138
        self.fwd_button.add_accelerator("clicked", self.accel_group, ord(']'),
 
139
                                        0, 0)
 
140
        self.fwd_button.connect("clicked", self._fwd_clicked_cb)
 
141
        hbox.pack_start(self.fwd_button, expand=False, fill=True)
 
142
        self.fwd_button.show()
 
143
 
 
144
        return frame
 
145
 
 
146
    def construct_bottom(self):
 
147
        """Construct the bottom half of the window."""
 
148
        from bzrlib.plugins.gtk.logview import LogView
 
149
        self.logview = LogView()
 
150
        (width, height) = self.get_size()
 
151
        self.logview.set_size_request(width, int(height / 2.5))
 
152
        self.logview.show()
 
153
        self.logview.set_show_callback(self._show_clicked_cb)
 
154
        self.logview.set_go_callback(self._go_clicked_cb)
 
155
        return self.logview
 
156
 
 
157
    def set_branch(self, branch, start, maxnum):
100
158
        """Set the branch and start position for this window.
101
159
 
102
160
        Creates a new TreeModel and populates it with information about
103
161
        the new branch before updating the window title and model of the
104
162
        treeview itself.
105
163
        """
 
164
        self.branch = branch
 
165
 
106
166
        # [ revision, node, last_lines, lines, message, committer, timestamp ]
107
 
        model = gtk.ListStore(gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,
108
 
                              gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,
109
 
                              str, str, str)
 
167
        self.model = gtk.ListStore(gobject.TYPE_PYOBJECT,
 
168
                                   gobject.TYPE_PYOBJECT,
 
169
                                   gobject.TYPE_PYOBJECT,
 
170
                                   gobject.TYPE_PYOBJECT,
 
171
                                   str, str, str)
 
172
        self.index = {}
 
173
        index = 0
110
174
 
111
175
        last_lines = []
112
 
        for revision, node, lines in graph(branch, start):
 
176
        (self.revisions, colours, self.children, self.parent_ids,
 
177
         merge_sorted) = distances(branch, start)
 
178
        for (index, (revision, node, lines)) in enumerate(graph(
 
179
                self.revisions, colours, merge_sorted)):
 
180
            # FIXME: at this point we should be able to show the graph order
 
181
            # and lines with no message or commit data - and then incrementally
 
182
            # fill the timestamp, committer etc data as desired.
113
183
            message = revision.message.split("\n")[0]
114
184
            if revision.committer is not None:
115
185
                timestamp = format_date(revision.timestamp, revision.timezone)
116
186
            else:
117
187
                timestamp = None
118
 
 
119
 
            model.append([ revision, node, last_lines, lines,
120
 
                           message, revision.committer, timestamp ])
 
188
            self.model.append([revision, node, last_lines, lines,
 
189
                               message, revision.committer, timestamp])
 
190
            self.index[revision] = index
121
191
            last_lines = lines
122
 
 
123
 
        self.set_title(os.path.basename(branch.base) + " - bzrk")
124
 
        self.treeview.set_model(model)
 
192
            if maxnum is not None and index > maxnum:
 
193
                break
 
194
 
 
195
        self.set_title(branch.nick + " - bzrk")
 
196
        self.treeview.set_model(self.model)
 
197
 
 
198
    def _treeview_cursor_cb(self, *args):
 
199
        """Callback for when the treeview cursor changes."""
 
200
        (path, col) = self.treeview.get_cursor()
 
201
        revision = self.model[path][0]
 
202
 
 
203
        self.back_button.set_sensitive(len(self.parent_ids[revision]) > 0)
 
204
        self.fwd_button.set_sensitive(len(self.children[revision]) > 0)
 
205
        self.logview.set_revision(revision)
 
206
 
 
207
    def _back_clicked_cb(self, *args):
 
208
        """Callback for when the back button is clicked."""
 
209
        (path, col) = self.treeview.get_cursor()
 
210
        revision = self.model[path][0]
 
211
        if not len(self.parent_ids[revision]):
 
212
            return
 
213
 
 
214
        for parent_id in self.parent_ids[revision]:
 
215
            parent = self.revisions[parent_id]
 
216
            if same_branch(revision, parent):
 
217
                self.treeview.set_cursor(self.index[parent])
 
218
                break
 
219
        else:
 
220
            next = self.revisions[self.parent_ids[revision][0]]
 
221
            self.treeview.set_cursor(self.index[next])
 
222
        self.treeview.grab_focus()
 
223
 
 
224
    def _fwd_clicked_cb(self, *args):
 
225
        """Callback for when the forward button is clicked."""
 
226
        (path, col) = self.treeview.get_cursor()
 
227
        revision = self.model[path][0]
 
228
        if not len(self.children[revision]):
 
229
            return
 
230
 
 
231
        for child in self.children[revision]:
 
232
            if same_branch(child, revision):
 
233
                self.treeview.set_cursor(self.index[child])
 
234
                break
 
235
        else:
 
236
            prev = list(self.children[revision])[0]
 
237
            self.treeview.set_cursor(self.index[prev])
 
238
        self.treeview.grab_focus()
 
239
 
 
240
    def _go_clicked_cb(self, revid):
 
241
        """Callback for when the go button for a parent is clicked."""
 
242
        self.treeview.set_cursor(self.index[self.revisions[revid]])
 
243
        self.treeview.grab_focus()
 
244
 
 
245
    def show_diff(self, branch, revid, parentid):
 
246
        """Open a new window to show a diff between the given revisions."""
 
247
        from bzrlib.plugins.gtk.diff import DiffWindow
 
248
        window = DiffWindow()
 
249
        rev_tree = branch.repository.revision_tree(revid)
 
250
        parent_tree = branch.repository.revision_tree(parentid)
 
251
        description = revid + " - " + branch.nick
 
252
        window.set_diff(description, rev_tree, parent_tree)
 
253
        window.show()
 
254
 
 
255
    def _show_clicked_cb(self, revid, parentid):
 
256
        """Callback for when the show button for a parent is clicked."""
 
257
        self.show_diff(self.branch, revid, parentid)
 
258
        self.treeview.grab_focus()
 
259
 
 
260
    def _treeview_row_activated_cb(self, widget, path, col):
 
261
        # TODO: more than one parent
 
262
        """Callback for when a treeview row gets activated."""
 
263
        revision = self.model[path][0]
 
264
        if len(self.parent_ids[revision]) == 0:
 
265
            # Ignore revisions without parent
 
266
            return
 
267
        parent_id = self.parent_ids[revision][0]
 
268
        self.show_diff(self.branch, revision.revision_id, parent_id)
 
269
        self.treeview.grab_focus()