/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: Aaron Bentley
  • Date: 2007-01-17 06:42:55 UTC
  • mto: This revision was merged to the branch mainline in revision 129.
  • Revision ID: aaron.bentley@utoronto.ca-20070117064255-x4gznz5e0lyjq3gk
Remove usused span selector

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
29
26
    for a particular branch.
30
27
    """
31
28
 
32
 
    def __init__(self):
 
29
    def __init__(self, app=None):
33
30
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
34
31
        self.set_border_width(0)
35
32
        self.set_title("bzrk")
36
33
 
 
34
        self.app = app
 
35
 
37
36
        # Use three-quarters of the screen by default
38
37
        screen = self.get_screen()
39
 
        width = int(screen.get_width() * 0.75)
40
 
        height = int(screen.get_height() * 0.75)
 
38
        monitor = screen.get_monitor_geometry(0)
 
39
        width = int(monitor.width * 0.75)
 
40
        height = int(monitor.height * 0.75)
41
41
        self.set_default_size(width, height)
42
42
 
43
43
        # FIXME AndyFitz!
51
51
 
52
52
    def construct(self):
53
53
        """Construct the window contents."""
 
54
        vbox = gtk.VBox(spacing=0)
 
55
        self.add(vbox)
 
56
 
 
57
        vbox.pack_start(self.construct_navigation(), expand=False, fill=True)
 
58
 
54
59
        paned = gtk.VPaned()
55
60
        paned.pack1(self.construct_top(), resize=True, shrink=False)
56
 
        paned.pack2(self.construct_bottom(), resize=True, shrink=True)
57
 
        self.add(paned)
 
61
        paned.pack2(self.construct_bottom(), resize=False, shrink=True)
58
62
        paned.show()
 
63
        vbox.pack_start(paned, expand=True, fill=True)
 
64
        vbox.set_focus_child(paned)
 
65
 
 
66
        vbox.show()
59
67
 
60
68
    def construct_top(self):
61
69
        """Construct the top-half of the window."""
62
 
        vbox = gtk.VBox(spacing=6)
63
 
        vbox.set_border_width(12)
64
 
        vbox.show()
65
 
 
66
70
        scrollwin = gtk.ScrolledWindow()
67
71
        scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
68
72
        scrollwin.set_shadow_type(gtk.SHADOW_IN)
69
 
        #scrollwin.set_border_width(12)
70
 
        vbox.pack_start(scrollwin, expand=True, fill=True)
71
73
        scrollwin.show()
72
74
 
73
75
        self.treeview = gtk.TreeView()
74
76
        self.treeview.set_rules_hint(True)
75
77
        self.treeview.set_search_column(4)
76
78
        self.treeview.connect("cursor-changed", self._treeview_cursor_cb)
 
79
        self.treeview.connect("row-activated", self._treeview_row_activated_cb)
77
80
        scrollwin.add(self.treeview)
78
81
        self.treeview.show()
79
82
 
80
83
        cell = CellRendererGraph()
81
84
        column = gtk.TreeViewColumn()
82
 
        column.set_resizable(False)
 
85
        column.set_resizable(True)
83
86
        column.pack_start(cell, expand=False)
84
87
        column.add_attribute(cell, "node", 1)
85
88
        column.add_attribute(cell, "in-lines", 2)
112
115
        column.add_attribute(cell, "text", 6)
113
116
        self.treeview.append_column(column)
114
117
 
115
 
        hbox = gtk.HBox(False, spacing=6)
116
 
        vbox.pack_start(hbox, expand=False, fill=False)
 
118
        return scrollwin
 
119
 
 
120
    def construct_navigation(self):
 
121
        """Construct the navigation buttons."""
 
122
        frame = gtk.Frame()
 
123
        frame.set_shadow_type(gtk.SHADOW_OUT)
 
124
        frame.show()
 
125
        
 
126
        hbox = gtk.HBox(spacing=12)
 
127
        frame.add(hbox)
117
128
        hbox.show()
118
129
 
119
130
        self.back_button = gtk.Button(stock=gtk.STOCK_GO_BACK)
 
131
        self.back_button.set_relief(gtk.RELIEF_NONE)
120
132
        self.back_button.add_accelerator("clicked", self.accel_group, ord('['),
121
133
                                         0, 0)
122
134
        self.back_button.connect("clicked", self._back_clicked_cb)
124
136
        self.back_button.show()
125
137
 
126
138
        self.fwd_button = gtk.Button(stock=gtk.STOCK_GO_FORWARD)
 
139
        self.fwd_button.set_relief(gtk.RELIEF_NONE)
127
140
        self.fwd_button.add_accelerator("clicked", self.accel_group, ord(']'),
128
141
                                        0, 0)
129
142
        self.fwd_button.connect("clicked", self._fwd_clicked_cb)
130
143
        hbox.pack_start(self.fwd_button, expand=False, fill=True)
131
144
        self.fwd_button.show()
132
145
 
133
 
        return vbox
 
146
        return frame
134
147
 
135
148
    def construct_bottom(self):
136
149
        """Construct the bottom half of the window."""
137
 
        label = gtk.Label("test")
138
 
        label.show()
139
 
 
140
 
        return label
141
 
 
142
 
    def set_branch(self, branch, start):
 
150
        scrollwin = gtk.ScrolledWindow()
 
151
        scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
 
152
        scrollwin.set_shadow_type(gtk.SHADOW_NONE)
 
153
        (width, height) = self.get_size()
 
154
        scrollwin.set_size_request(width, int(height / 2.5))
 
155
        scrollwin.show()
 
156
 
 
157
        vbox = gtk.VBox(False, spacing=6)
 
158
        vbox.set_border_width(6)
 
159
        scrollwin.add_with_viewport(vbox)
 
160
        vbox.show()
 
161
 
 
162
        table = gtk.Table(rows=4, columns=2)
 
163
        table.set_row_spacings(6)
 
164
        table.set_col_spacings(6)
 
165
        vbox.pack_start(table, expand=False, fill=True)
 
166
        table.show()
 
167
 
 
168
        align = gtk.Alignment(0.0, 0.5)
 
169
        label = gtk.Label()
 
170
        label.set_markup("<b>Revision:</b>")
 
171
        align.add(label)
 
172
        table.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
 
173
        label.show()
 
174
        align.show()
 
175
 
 
176
        align = gtk.Alignment(0.0, 0.5)
 
177
        self.revid_label = gtk.Label()
 
178
        self.revid_label.set_selectable(True)
 
179
        align.add(self.revid_label)
 
180
        table.attach(align, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, gtk.FILL)
 
181
        self.revid_label.show()
 
182
        align.show()
 
183
 
 
184
        align = gtk.Alignment(0.0, 0.5)
 
185
        label = gtk.Label()
 
186
        label.set_markup("<b>Committer:</b>")
 
187
        align.add(label)
 
188
        table.attach(align, 0, 1, 1, 2, gtk.FILL, gtk.FILL)
 
189
        label.show()
 
190
        align.show()
 
191
 
 
192
        align = gtk.Alignment(0.0, 0.5)
 
193
        self.committer_label = gtk.Label()
 
194
        self.committer_label.set_selectable(True)
 
195
        align.add(self.committer_label)
 
196
        table.attach(align, 1, 2, 1, 2, gtk.EXPAND | gtk.FILL, gtk.FILL)
 
197
        self.committer_label.show()
 
198
        align.show()
 
199
 
 
200
        align = gtk.Alignment(0.0, 0.5)
 
201
        label = gtk.Label()
 
202
        label.set_markup("<b>Branch nick:</b>")
 
203
        align.add(label)
 
204
        table.attach(align, 0, 1, 2, 3, gtk.FILL, gtk.FILL)
 
205
        label.show()
 
206
        align.show()
 
207
 
 
208
        align = gtk.Alignment(0.0, 0.5)
 
209
        self.branchnick_label = gtk.Label()
 
210
        self.branchnick_label.set_selectable(True)
 
211
        align.add(self.branchnick_label)
 
212
        table.attach(align, 1, 2, 2, 3, gtk.EXPAND | gtk.FILL, gtk.FILL)
 
213
        self.branchnick_label.show()
 
214
        align.show()
 
215
 
 
216
        align = gtk.Alignment(0.0, 0.5)
 
217
        label = gtk.Label()
 
218
        label.set_markup("<b>Timestamp:</b>")
 
219
        align.add(label)
 
220
        table.attach(align, 0, 1, 3, 4, gtk.FILL, gtk.FILL)
 
221
        label.show()
 
222
        align.show()
 
223
 
 
224
        align = gtk.Alignment(0.0, 0.5)
 
225
        self.timestamp_label = gtk.Label()
 
226
        self.timestamp_label.set_selectable(True)
 
227
        align.add(self.timestamp_label)
 
228
        table.attach(align, 1, 2, 3, 4, gtk.EXPAND | gtk.FILL, gtk.FILL)
 
229
        self.timestamp_label.show()
 
230
        align.show()
 
231
 
 
232
        self.parents_table = gtk.Table(rows=1, columns=2)
 
233
        self.parents_table.set_row_spacings(3)
 
234
        self.parents_table.set_col_spacings(6)
 
235
        self.parents_table.show()
 
236
        vbox.pack_start(self.parents_table, expand=False, fill=True)
 
237
        self.parents_widgets = []
 
238
 
 
239
        label = gtk.Label()
 
240
        label.set_markup("<b>Parents:</b>")
 
241
        align = gtk.Alignment(0.0, 0.5)
 
242
        align.add(label)
 
243
        self.parents_table.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
 
244
        label.show()
 
245
        align.show()
 
246
 
 
247
        self.message_buffer = gtk.TextBuffer()
 
248
        textview = gtk.TextView(self.message_buffer)
 
249
        textview.set_editable(False)
 
250
        textview.set_wrap_mode(gtk.WRAP_WORD)
 
251
        textview.modify_font(pango.FontDescription("Monospace"))
 
252
        vbox.pack_start(textview, expand=True, fill=True)
 
253
        textview.show()
 
254
 
 
255
        return scrollwin
 
256
 
 
257
    def set_branch(self, branch, start, maxnum):
143
258
        """Set the branch and start position for this window.
144
259
 
145
260
        Creates a new TreeModel and populates it with information about
146
261
        the new branch before updating the window title and model of the
147
262
        treeview itself.
148
263
        """
 
264
        self.branch = branch
 
265
 
149
266
        # [ revision, node, last_lines, lines, message, committer, timestamp ]
150
267
        self.model = gtk.ListStore(gobject.TYPE_PYOBJECT,
151
268
                                   gobject.TYPE_PYOBJECT,
156
273
        index = 0
157
274
 
158
275
        last_lines = []
159
 
        (revids, self.revisions, colours, self.children) \
160
 
                 = distances(branch, start)
161
 
        for revision, node, lines in graph(revids, self.revisions, colours):
 
276
        (self.revisions, colours, self.children, self.parent_ids,
 
277
         merge_sorted) = distances(branch, start)
 
278
        for (index, (revision, node, lines)) in enumerate(graph(
 
279
                self.revisions, colours, merge_sorted)):
 
280
            # FIXME: at this point we should be able to show the graph order
 
281
            # and lines with no message or commit data - and then incrementally
 
282
            # fill the timestamp, committer etc data as desired.
162
283
            message = revision.message.split("\n")[0]
163
284
            if revision.committer is not None:
164
285
                timestamp = format_date(revision.timestamp, revision.timezone)
165
286
            else:
166
287
                timestamp = None
167
 
 
168
 
            self.model.append([ revision, node, last_lines, lines,
169
 
                                message, revision.committer, timestamp ])
 
288
            self.model.append([revision, node, last_lines, lines,
 
289
                               message, revision.committer, timestamp])
170
290
            self.index[revision] = index
171
 
            index += 1
172
 
 
173
291
            last_lines = lines
 
292
            if maxnum is not None and index > maxnum:
 
293
                break
174
294
 
175
 
        self.set_title(os.path.basename(branch.base) + " - bzrk")
 
295
        self.set_title(branch.nick + " - bzrk")
176
296
        self.treeview.set_model(self.model)
177
297
 
178
298
    def _treeview_cursor_cb(self, *args):
180
300
        (path, col) = self.treeview.get_cursor()
181
301
        revision = self.model[path][0]
182
302
 
183
 
        self.back_button.set_sensitive(len(self.children[revision]) > 0)
184
 
        self.fwd_button.set_sensitive(len(revision.parent_ids) > 0)
 
303
        self.back_button.set_sensitive(len(self.parent_ids[revision]) > 0)
 
304
        self.fwd_button.set_sensitive(len(self.children[revision]) > 0)
 
305
 
 
306
        if revision.committer is not None:
 
307
            branchnick = ""
 
308
            committer = revision.committer
 
309
            timestamp = format_date(revision.timestamp, revision.timezone)
 
310
            message = revision.message
 
311
            try:
 
312
                branchnick = revision.properties['branch-nick']
 
313
            except KeyError:
 
314
                pass
 
315
 
 
316
        else:
 
317
            committer = ""
 
318
            timestamp = ""
 
319
            message = ""
 
320
            branchnick = ""
 
321
 
 
322
        self.revid_label.set_text(revision.revision_id)
 
323
        self.branchnick_label.set_text(branchnick)
 
324
 
 
325
        self.committer_label.set_text(committer)
 
326
        self.timestamp_label.set_text(timestamp)
 
327
        self.message_buffer.set_text(message)
 
328
 
 
329
        for widget in self.parents_widgets:
 
330
            self.parents_table.remove(widget)
 
331
 
 
332
        self.parents_widgets = []
 
333
        self.parents_table.resize(max(len(self.parent_ids[revision]), 1), 2)
 
334
        
 
335
        for idx, parent_id in enumerate(self.parent_ids[revision]):
 
336
            align = gtk.Alignment(0.0, 0.0)
 
337
            self.parents_widgets.append(align)
 
338
            self.parents_table.attach(align, 1, 2, idx, idx + 1,
 
339
                                      gtk.EXPAND | gtk.FILL, gtk.FILL)
 
340
            align.show()
 
341
 
 
342
            hbox = gtk.HBox(False, spacing=6)
 
343
            align.add(hbox)
 
344
            hbox.show()
 
345
 
 
346
            image = gtk.Image()
 
347
            image.set_from_stock(
 
348
                gtk.STOCK_FIND, gtk.ICON_SIZE_SMALL_TOOLBAR)
 
349
            image.show()
 
350
 
 
351
            button = gtk.Button()
 
352
            button.add(image)
 
353
            button.set_sensitive(self.app is not None)
 
354
            button.connect("clicked", self._show_clicked_cb,
 
355
                           revision.revision_id, parent_id)
 
356
            hbox.pack_start(button, expand=False, fill=True)
 
357
            button.show()
 
358
 
 
359
            button = gtk.Button(parent_id)
 
360
            button.set_use_underline(False)
 
361
            button.connect("clicked", self._go_clicked_cb, parent_id)
 
362
            hbox.pack_start(button, expand=False, fill=True)
 
363
            button.show()
 
364
 
185
365
 
186
366
    def _back_clicked_cb(self, *args):
187
367
        """Callback for when the back button is clicked."""
188
368
        (path, col) = self.treeview.get_cursor()
189
369
        revision = self.model[path][0]
 
370
        if not len(self.parent_ids[revision]):
 
371
            return
 
372
 
 
373
        for parent_id in self.parent_ids[revision]:
 
374
            parent = self.revisions[parent_id]
 
375
            if same_branch(revision, parent):
 
376
                self.treeview.set_cursor(self.index[parent])
 
377
                break
 
378
        else:
 
379
            next = self.revisions[self.parent_ids[revision][0]]
 
380
            self.treeview.set_cursor(self.index[next])
 
381
        self.treeview.grab_focus()
 
382
 
 
383
    def _fwd_clicked_cb(self, *args):
 
384
        """Callback for when the forward button is clicked."""
 
385
        (path, col) = self.treeview.get_cursor()
 
386
        revision = self.model[path][0]
190
387
        if not len(self.children[revision]):
191
388
            return
192
389
 
197
394
        else:
198
395
            prev = list(self.children[revision])[0]
199
396
            self.treeview.set_cursor(self.index[prev])
200
 
 
201
 
    def _fwd_clicked_cb(self, *args):
202
 
        """Callback for when the forward button is clicked."""
203
 
        (path, col) = self.treeview.get_cursor()
 
397
        self.treeview.grab_focus()
 
398
 
 
399
    def _go_clicked_cb(self, widget, revid):
 
400
        """Callback for when the go button for a parent is clicked."""
 
401
        self.treeview.set_cursor(self.index[self.revisions[revid]])
 
402
        self.treeview.grab_focus()
 
403
 
 
404
    def _show_clicked_cb(self, widget, revid, parentid):
 
405
        """Callback for when the show button for a parent is clicked."""
 
406
        if self.app is not None:
 
407
            self.app.show_diff(self.branch, revid, parentid)
 
408
        self.treeview.grab_focus()
 
409
 
 
410
    def _treeview_row_activated_cb(self, widget, path, col):
 
411
        # TODO: more than one parent
 
412
        """Callback for when a treeview row gets activated."""
204
413
        revision = self.model[path][0]
205
 
        if not len(revision.parent_ids):
 
414
        if len(self.parent_ids[revision]) == 0:
 
415
            # Ignore revisions without parent
206
416
            return
207
 
 
208
 
        for parent_id in revision.parent_ids:
209
 
            parent = self.revisions[parent_id]
210
 
            if same_branch(revision, parent):
211
 
                self.treeview.set_cursor(self.index[parent])
212
 
                break
213
 
        else:
214
 
            next = self.revisions[revision.parent_ids[0]]
215
 
            self.treeview.set_cursor(self.index[next])
216
 
 
 
417
        parent_id = self.parent_ids[revision][0]
 
418
        if self.app is not None:
 
419
            self.app.show_diff(self.branch, revision.revision_id, parent_id)
 
420
        self.treeview.grab_focus()