149
148
    def construct_bottom(self):
 
150
149
        """Construct the bottom half of the window."""
 
151
 
        scrollwin = gtk.ScrolledWindow()
 
152
 
        scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
 
153
 
        scrollwin.set_shadow_type(gtk.SHADOW_NONE)
 
 
150
        from bzrlib.plugins.gtk.logview import LogView
 
 
151
        self.logview = LogView()
 
154
152
        (width, height) = self.get_size()
 
155
 
        scrollwin.set_size_request(width, int(height / 2.5))
 
158
 
        vbox = gtk.VBox(False, spacing=6)
 
159
 
        vbox.set_border_width(6)
 
160
 
        scrollwin.add_with_viewport(vbox)
 
163
 
        table = gtk.Table(rows=4, columns=2)
 
164
 
        table.set_row_spacings(6)
 
165
 
        table.set_col_spacings(6)
 
166
 
        vbox.pack_start(table, expand=False, fill=True)
 
169
 
        align = gtk.Alignment(0.0, 0.5)
 
171
 
        label.set_markup("<b>Revision:</b>")
 
173
 
        table.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
 
177
 
        align = gtk.Alignment(0.0, 0.5)
 
178
 
        self.revid_label = gtk.Label()
 
179
 
        self.revid_label.set_selectable(True)
 
180
 
        align.add(self.revid_label)
 
181
 
        table.attach(align, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, gtk.FILL)
 
182
 
        self.revid_label.show()
 
185
 
        align = gtk.Alignment(0.0, 0.5)
 
187
 
        label.set_markup("<b>Committer:</b>")
 
189
 
        table.attach(align, 0, 1, 1, 2, gtk.FILL, gtk.FILL)
 
193
 
        align = gtk.Alignment(0.0, 0.5)
 
194
 
        self.committer_label = gtk.Label()
 
195
 
        self.committer_label.set_selectable(True)
 
196
 
        align.add(self.committer_label)
 
197
 
        table.attach(align, 1, 2, 1, 2, gtk.EXPAND | gtk.FILL, gtk.FILL)
 
198
 
        self.committer_label.show()
 
201
 
        align = gtk.Alignment(0.0, 0.5)
 
203
 
        label.set_markup("<b>Branch nick:</b>")
 
205
 
        table.attach(align, 0, 1, 2, 3, gtk.FILL, gtk.FILL)
 
209
 
        align = gtk.Alignment(0.0, 0.5)
 
210
 
        self.branchnick_label = gtk.Label()
 
211
 
        self.branchnick_label.set_selectable(True)
 
212
 
        align.add(self.branchnick_label)
 
213
 
        table.attach(align, 1, 2, 2, 3, gtk.EXPAND | gtk.FILL, gtk.FILL)
 
214
 
        self.branchnick_label.show()
 
217
 
        align = gtk.Alignment(0.0, 0.5)
 
219
 
        label.set_markup("<b>Timestamp:</b>")
 
221
 
        table.attach(align, 0, 1, 3, 4, gtk.FILL, gtk.FILL)
 
225
 
        align = gtk.Alignment(0.0, 0.5)
 
226
 
        self.timestamp_label = gtk.Label()
 
227
 
        self.timestamp_label.set_selectable(True)
 
228
 
        align.add(self.timestamp_label)
 
229
 
        table.attach(align, 1, 2, 3, 4, gtk.EXPAND | gtk.FILL, gtk.FILL)
 
230
 
        self.timestamp_label.show()
 
233
 
        self.parents_table = gtk.Table(rows=1, columns=2)
 
234
 
        self.parents_table.set_row_spacings(3)
 
235
 
        self.parents_table.set_col_spacings(6)
 
236
 
        self.parents_table.show()
 
237
 
        vbox.pack_start(self.parents_table, expand=False, fill=True)
 
238
 
        self.parents_widgets = []
 
241
 
        label.set_markup("<b>Parents:</b>")
 
242
 
        align = gtk.Alignment(0.0, 0.5)
 
244
 
        self.parents_table.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
 
248
 
        self.message_buffer = gtk.TextBuffer()
 
249
 
        textview = gtk.TextView(self.message_buffer)
 
250
 
        textview.set_editable(False)
 
251
 
        textview.set_wrap_mode(gtk.WRAP_WORD)
 
252
 
        textview.modify_font(pango.FontDescription("Monospace"))
 
253
 
        vbox.pack_start(textview, expand=True, fill=True)
 
 
153
        self.logview.set_size_request(width, int(height / 2.5))
 
 
155
        self.logview.set_show_callback(self._show_clicked_cb)
 
 
156
        self.logview.set_go_callback(self._go_clicked_cb)
 
258
159
    def set_branch(self, branch, start, maxnum):
 
259
160
        """Set the branch and start position for this window.
 
 
304
209
        self.back_button.set_sensitive(len(self.parent_ids[revision]) > 0)
 
305
210
        self.fwd_button.set_sensitive(len(self.children[revision]) > 0)
 
307
 
        if revision.committer is not None:
 
309
 
            committer = revision.committer
 
310
 
            timestamp = format_date(revision.timestamp, revision.timezone)
 
311
 
            message = revision.message
 
313
 
                branchnick = revision.properties['branch-nick']
 
323
 
        self.revid_label.set_text(revision.revision_id)
 
324
 
        self.branchnick_label.set_text(branchnick)
 
326
 
        self.committer_label.set_text(committer)
 
327
 
        self.timestamp_label.set_text(timestamp)
 
328
 
        self.message_buffer.set_text(message)
 
330
 
        for widget in self.parents_widgets:
 
331
 
            self.parents_table.remove(widget)
 
333
 
        self.parents_widgets = []
 
334
 
        self.parents_table.resize(max(len(self.parent_ids[revision]), 1), 2)
 
336
 
        for idx, parent_id in enumerate(self.parent_ids[revision]):
 
337
 
            align = gtk.Alignment(0.0, 0.0)
 
338
 
            self.parents_widgets.append(align)
 
339
 
            self.parents_table.attach(align, 1, 2, idx, idx + 1,
 
340
 
                                      gtk.EXPAND | gtk.FILL, gtk.FILL)
 
343
 
            hbox = gtk.HBox(False, spacing=6)
 
348
 
            image.set_from_stock(
 
349
 
                gtk.STOCK_FIND, gtk.ICON_SIZE_SMALL_TOOLBAR)
 
352
 
            button = gtk.Button()
 
354
 
            button.set_sensitive(self.app is not None)
 
355
 
            button.connect("clicked", self._show_clicked_cb,
 
356
 
                           revision.revision_id, parent_id)
 
357
 
            hbox.pack_start(button, expand=False, fill=True)
 
360
 
            button = gtk.Button(parent_id)
 
361
 
            button.connect("clicked", self._go_clicked_cb, parent_id)
 
362
 
            hbox.pack_start(button, expand=False, fill=True)
 
 
212
        if self.branch.supports_tags():
 
 
213
            tagdict = self.branch.tags.get_reverse_tag_dict()
 
 
214
            if tagdict.has_key(revision.revision_id):
 
 
215
                tags = tagdict[revision.revision_id]
 
 
216
        self.logview.set_revision(revision, tags)
 
366
218
    def _back_clicked_cb(self, *args):
 
367
219
        """Callback for when the back button is clicked."""
 
 
396
248
            self.treeview.set_cursor(self.index[prev])
 
397
249
        self.treeview.grab_focus()
 
399
 
    def _go_clicked_cb(self, widget, revid):
 
 
251
    def _go_clicked_cb(self, revid):
 
400
252
        """Callback for when the go button for a parent is clicked."""
 
401
253
        self.treeview.set_cursor(self.index[self.revisions[revid]])
 
402
254
        self.treeview.grab_focus()
 
404
 
    def _show_clicked_cb(self, widget, revid, parentid):
 
 
256
    def show_diff(self, branch, revid, parentid):
 
 
257
        """Open a new window to show a diff between the given revisions."""
 
 
258
        from bzrlib.plugins.gtk.diff import DiffWindow
 
 
259
        window = DiffWindow()
 
 
260
        (parent_tree, rev_tree) = branch.repository.revision_trees([parentid, 
 
 
262
        description = revid + " - " + branch.nick
 
 
263
        window.set_diff(description, rev_tree, parent_tree)
 
 
266
    def _show_clicked_cb(self, revid, parentid):
 
405
267
        """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)
 
 
268
        self.show_diff(self.branch, revid, parentid)
 
408
269
        self.treeview.grab_focus()
 
 
271
    def _treeview_row_mouseclick(self, widget, event):
 
 
272
        from bzrlib.plugins.gtk.revisionmenu import RevisionPopupMenu
 
 
273
        if event.button == 3:
 
 
274
            menu = RevisionPopupMenu(self.branch.repository, 
 
 
275
                [x.revision_id for x in self.selected_revisions()],
 
 
277
            menu.popup(None, None, None, event.button, event.get_time())
 
 
279
    def selected_revision(self, path):
 
 
280
        return self.model[path][0]
 
 
282
    def selected_revisions(self):
 
 
283
        return [self.selected_revision(path) for path in \
 
 
284
                self.treeview.get_selection().get_selected_rows()[1]]
 
410
286
    def _treeview_row_activated_cb(self, widget, path, col):
 
411
287
        # TODO: more than one parent
 
412
288
        """Callback for when a treeview row gets activated."""
 
413
 
        revision = self.model[path][0]
 
 
289
        revision = self.selected_revision(path)
 
 
290
        if len(self.parent_ids[revision]) == 0:
 
 
291
            # Ignore revisions without parent
 
414
293
        parent_id = self.parent_ids[revision][0]
 
415
 
        if self.app is not None:
 
416
 
            self.app.show_diff(self.branch, revision.revision_id, parent_id)
 
 
294
        self.show_diff(self.branch, revision.revision_id, parent_id)
 
417
295
        self.treeview.grab_focus()