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

  • Committer: Scott James Remnant
  • Date: 2005-10-17 01:07:49 UTC
  • Revision ID: scott@netsplit.com-20051017010749-15fa95fc2cf09289
Commit the first version of bzrk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
from bzrlib.osutils import format_date
20
20
 
21
 
from graph import distances, graph, same_branch
 
21
from graph import graph
22
22
from graphcell import CellRendererGraph
23
23
 
24
24
 
29
29
    for a particular branch.
30
30
    """
31
31
 
32
 
    def __init__(self, app=None):
 
32
    def __init__(self):
33
33
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
34
34
        self.set_border_width(0)
35
35
        self.set_title("bzrk")
36
36
 
37
 
        self.app = app
38
 
 
39
37
        # Use three-quarters of the screen by default
40
38
        screen = self.get_screen()
41
 
        monitor = screen.get_monitor_geometry(0)
42
 
        width = int(monitor.width * 0.75)
43
 
        height = int(monitor.height * 0.75)
 
39
        width = int(screen.get_width() * 0.75)
 
40
        height = int(screen.get_height() * 0.75)
44
41
        self.set_default_size(width, height)
45
42
 
46
43
        # FIXME AndyFitz!
47
44
        icon = self.render_icon(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
48
45
        self.set_icon(icon)
49
46
 
50
 
        self.accel_group = gtk.AccelGroup()
51
 
        self.add_accel_group(self.accel_group)
52
 
 
53
47
        self.construct()
54
48
 
55
49
    def construct(self):
56
50
        """Construct the window contents."""
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
 
        self.add(paned)
61
 
        paned.show()
62
 
 
63
 
    def construct_top(self):
64
 
        """Construct the top-half of the window."""
65
 
        vbox = gtk.VBox(spacing=6)
66
 
        vbox.set_border_width(12)
67
 
        vbox.show()
68
 
 
69
51
        scrollwin = gtk.ScrolledWindow()
70
52
        scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
71
53
        scrollwin.set_shadow_type(gtk.SHADOW_IN)
72
 
        vbox.pack_start(scrollwin, expand=True, fill=True)
 
54
        scrollwin.set_border_width(12)
 
55
        self.add(scrollwin)
73
56
        scrollwin.show()
74
57
 
75
58
        self.treeview = gtk.TreeView()
76
59
        self.treeview.set_rules_hint(True)
77
60
        self.treeview.set_search_column(4)
78
 
        self.treeview.connect("cursor-changed", self._treeview_cursor_cb)
79
61
        scrollwin.add(self.treeview)
80
62
        self.treeview.show()
81
63
 
114
96
        column.add_attribute(cell, "text", 6)
115
97
        self.treeview.append_column(column)
116
98
 
117
 
        hbox = gtk.HBox(False, spacing=6)
118
 
        vbox.pack_start(hbox, expand=False, fill=False)
119
 
        hbox.show()
120
 
 
121
 
        self.back_button = gtk.Button(stock=gtk.STOCK_GO_BACK)
122
 
        self.back_button.add_accelerator("clicked", self.accel_group, ord('['),
123
 
                                         0, 0)
124
 
        self.back_button.connect("clicked", self._back_clicked_cb)
125
 
        hbox.pack_start(self.back_button, expand=False, fill=True)
126
 
        self.back_button.show()
127
 
 
128
 
        self.fwd_button = gtk.Button(stock=gtk.STOCK_GO_FORWARD)
129
 
        self.fwd_button.add_accelerator("clicked", self.accel_group, ord(']'),
130
 
                                        0, 0)
131
 
        self.fwd_button.connect("clicked", self._fwd_clicked_cb)
132
 
        hbox.pack_start(self.fwd_button, expand=False, fill=True)
133
 
        self.fwd_button.show()
134
 
 
135
 
        return vbox
136
 
 
137
 
    def construct_bottom(self):
138
 
        """Construct the bottom half of the window."""
139
 
        vbox = gtk.VBox(False, spacing=6)
140
 
        vbox.set_border_width(12)
141
 
        (width, height) = self.get_size()
142
 
        vbox.set_size_request(width, int(height / 2.5))
143
 
        vbox.show()
144
 
 
145
 
        self.table = gtk.Table(rows=4, columns=2)
146
 
        self.table.set_row_spacings(6)
147
 
        self.table.set_col_spacings(6)
148
 
        vbox.pack_start(self.table, expand=False, fill=True)
149
 
        self.table.show()
150
 
 
151
 
        align = gtk.Alignment(0.0, 0.5)
152
 
        label = gtk.Label()
153
 
        label.set_markup("<b>Revision:</b>")
154
 
        align.add(label)
155
 
        self.table.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
156
 
        label.show()
157
 
        align.show()
158
 
 
159
 
        align = gtk.Alignment(0.0, 0.5)
160
 
        self.revid_label = gtk.Label()
161
 
        self.revid_label.set_selectable(True)
162
 
        align.add(self.revid_label)
163
 
        self.table.attach(align, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, gtk.FILL)
164
 
        self.revid_label.show()
165
 
        align.show()
166
 
 
167
 
        align = gtk.Alignment(0.0, 0.5)
168
 
        label = gtk.Label()
169
 
        label.set_markup("<b>Committer:</b>")
170
 
        align.add(label)
171
 
        self.table.attach(align, 0, 1, 1, 2, gtk.FILL, gtk.FILL)
172
 
        label.show()
173
 
        align.show()
174
 
 
175
 
        align = gtk.Alignment(0.0, 0.5)
176
 
        self.committer_label = gtk.Label()
177
 
        self.committer_label.set_selectable(True)
178
 
        align.add(self.committer_label)
179
 
        self.table.attach(align, 1, 2, 1, 2, gtk.EXPAND | gtk.FILL, gtk.FILL)
180
 
        self.committer_label.show()
181
 
        align.show()
182
 
 
183
 
        align = gtk.Alignment(0.0, 0.5)
184
 
        label = gtk.Label()
185
 
        label.set_markup("<b>Timestamp:</b>")
186
 
        align.add(label)
187
 
        self.table.attach(align, 0, 1, 2, 3, gtk.FILL, gtk.FILL)
188
 
        label.show()
189
 
        align.show()
190
 
 
191
 
        align = gtk.Alignment(0.0, 0.5)
192
 
        self.timestamp_label = gtk.Label()
193
 
        self.timestamp_label.set_selectable(True)
194
 
        align.add(self.timestamp_label)
195
 
        self.table.attach(align, 1, 2, 2, 3, gtk.EXPAND | gtk.FILL, gtk.FILL)
196
 
        self.timestamp_label.show()
197
 
        align.show()
198
 
 
199
 
        align = gtk.Alignment(0.0, 0.5)
200
 
        label = gtk.Label()
201
 
        label.set_markup("<b>Parents:</b>")
202
 
        align.add(label)
203
 
        self.table.attach(align, 0, 1, 3, 4, gtk.FILL, gtk.FILL)
204
 
        label.show()
205
 
        align.show()
206
 
 
207
 
        self.parents_widgets = []
208
 
 
209
 
        scrollwin = gtk.ScrolledWindow()
210
 
        scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
211
 
        scrollwin.set_shadow_type(gtk.SHADOW_IN)
212
 
        vbox.pack_start(scrollwin, expand=True, fill=True)
213
 
        scrollwin.show()
214
 
 
215
 
        self.message_buffer = gtk.TextBuffer()
216
 
        textview = gtk.TextView(self.message_buffer)
217
 
        textview.set_editable(False)
218
 
        textview.set_wrap_mode(gtk.WRAP_WORD)
219
 
        textview.modify_font(pango.FontDescription("Monospace"))
220
 
        scrollwin.add(textview)
221
 
        textview.show()
222
 
 
223
 
        return vbox
224
 
 
225
99
    def set_branch(self, branch, start):
226
100
        """Set the branch and start position for this window.
227
101
 
229
103
        the new branch before updating the window title and model of the
230
104
        treeview itself.
231
105
        """
232
 
        self.branch = branch
233
 
 
234
106
        # [ revision, node, last_lines, lines, message, committer, timestamp ]
235
 
        self.model = gtk.ListStore(gobject.TYPE_PYOBJECT,
236
 
                                   gobject.TYPE_PYOBJECT,
237
 
                                   gobject.TYPE_PYOBJECT,
238
 
                                   gobject.TYPE_PYOBJECT,
239
 
                                   str, str, str)
240
 
        self.index = {}
241
 
        index = 0
 
107
        model = gtk.ListStore(gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,
 
108
                              gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,
 
109
                              str, str, str)
242
110
 
243
111
        last_lines = []
244
 
        (revids, self.revisions, colours, self.children) \
245
 
                 = distances(branch, start)
246
 
        for revision, node, lines in graph(revids, self.revisions, colours):
 
112
        for revision, node, lines in graph(branch, start):
247
113
            message = revision.message.split("\n")[0]
248
114
            if revision.committer is not None:
249
115
                timestamp = format_date(revision.timestamp, revision.timezone)
250
116
            else:
251
117
                timestamp = None
252
118
 
253
 
            self.model.append([ revision, node, last_lines, lines,
254
 
                                message, revision.committer, timestamp ])
255
 
            self.index[revision] = index
256
 
            index += 1
257
 
 
 
119
            model.append([ revision, node, last_lines, lines,
 
120
                           message, revision.committer, timestamp ])
258
121
            last_lines = lines
259
122
 
260
123
        self.set_title(os.path.basename(branch.base) + " - bzrk")
261
 
        self.treeview.set_model(self.model)
262
 
 
263
 
    def _treeview_cursor_cb(self, *args):
264
 
        """Callback for when the treeview cursor changes."""
265
 
        (path, col) = self.treeview.get_cursor()
266
 
        revision = self.model[path][0]
267
 
 
268
 
        self.back_button.set_sensitive(len(revision.parent_ids) > 0)
269
 
        self.fwd_button.set_sensitive(len(self.children[revision]) > 0)
270
 
 
271
 
        if revision.committer is not None:
272
 
            committer = revision.committer
273
 
            timestamp = format_date(revision.timestamp, revision.timezone)
274
 
            message = revision.message
275
 
        else:
276
 
            committer = ""
277
 
            timestamp = ""
278
 
            message = ""
279
 
 
280
 
        self.revid_label.set_text(revision.revision_id)
281
 
        self.committer_label.set_text(committer)
282
 
        self.timestamp_label.set_text(timestamp)
283
 
        self.message_buffer.set_text(message)
284
 
 
285
 
        for widget in self.parents_widgets:
286
 
            self.table.remove(widget)
287
 
 
288
 
        self.parents_widgets = []
289
 
        self.table.resize(4 + len(revision.parent_ids) - 1, 2)
290
 
        for idx, parent_id in enumerate(revision.parent_ids):
291
 
            self.table.set_row_spacing(idx + 3, 0)
292
 
 
293
 
            align = gtk.Alignment(0.0, 0.0)
294
 
            self.parents_widgets.append(align)
295
 
            self.table.attach(align, 1, 2, idx + 3, idx + 4,
296
 
                              gtk.EXPAND | gtk.FILL, gtk.FILL)
297
 
            align.show()
298
 
 
299
 
            hbox = gtk.HBox(False, 0)
300
 
            align.add(hbox)
301
 
            hbox.show()
302
 
 
303
 
            label = gtk.Label(parent_id)
304
 
            label.set_selectable(True)
305
 
            hbox.pack_start(label, expand=False, fill=True)
306
 
            label.show()
307
 
 
308
 
            image = gtk.Image()
309
 
            image.set_from_stock(gtk.STOCK_JUMP_TO, gtk.ICON_SIZE_MENU)
310
 
            image.show()
311
 
 
312
 
            button = gtk.Button()
313
 
            button.add(image)
314
 
            button.set_relief(gtk.RELIEF_NONE)
315
 
            button.connect("clicked", self._go_clicked_cb, parent_id)
316
 
            hbox.pack_start(button, expand=False, fill=True)
317
 
            button.show()
318
 
 
319
 
            image = gtk.Image()
320
 
            image.set_from_stock(gtk.STOCK_FIND, gtk.ICON_SIZE_MENU)
321
 
            image.show()
322
 
 
323
 
            button = gtk.Button()
324
 
            button.add(image)
325
 
            button.set_relief(gtk.RELIEF_NONE)
326
 
            button.set_sensitive(self.app is not None)
327
 
            button.connect("clicked", self._show_clicked_cb,
328
 
                           revision.revision_id, parent_id)
329
 
            hbox.pack_start(button, expand=False, fill=True)
330
 
            button.show()
331
 
 
332
 
    def _back_clicked_cb(self, *args):
333
 
        """Callback for when the back button is clicked."""
334
 
        (path, col) = self.treeview.get_cursor()
335
 
        revision = self.model[path][0]
336
 
        if not len(revision.parent_ids):
337
 
            return
338
 
 
339
 
        for parent_id in revision.parent_ids:
340
 
            parent = self.revisions[parent_id]
341
 
            if same_branch(revision, parent):
342
 
                self.treeview.set_cursor(self.index[parent])
343
 
                break
344
 
        else:
345
 
            next = self.revisions[revision.parent_ids[0]]
346
 
            self.treeview.set_cursor(self.index[next])
347
 
 
348
 
    def _fwd_clicked_cb(self, *args):
349
 
        """Callback for when the forward button is clicked."""
350
 
        (path, col) = self.treeview.get_cursor()
351
 
        revision = self.model[path][0]
352
 
        if not len(self.children[revision]):
353
 
            return
354
 
 
355
 
        for child in self.children[revision]:
356
 
            if same_branch(child, revision):
357
 
                self.treeview.set_cursor(self.index[child])
358
 
                break
359
 
        else:
360
 
            prev = list(self.children[revision])[0]
361
 
            self.treeview.set_cursor(self.index[prev])
362
 
 
363
 
    def _go_clicked_cb(self, widget, revid):
364
 
        """Callback for when the go button for a parent is clicked."""
365
 
        self.treeview.set_cursor(self.index[self.revisions[revid]])
366
 
 
367
 
    def _show_clicked_cb(self, widget, revid, parentid):
368
 
        """Callback for when the show button for a parent is clicked."""
369
 
        if self.app is not None:
370
 
            self.app.show_diff(self.branch, revid, parentid)
 
124
        self.treeview.set_model(model)