1
# -*- coding: UTF-8 -*-
4
This module contains the code to manage the branch information window,
5
which contains both the revision graph and details panes.
8
__copyright__ = "Copyright © 2005 Canonical Ltd."
9
__author__ = "Scott James Remnant <scott@ubuntu.com>"
17
from bzrlib.osutils import format_date
19
from linegraph import linegraph, same_branch
20
from graphcell import CellRendererGraph
21
from treemodel import TreeModel
22
from treeview import TreeView
24
class BranchWindow(gtk.Window):
27
This object represents and manages a single window containing information
28
for a particular branch.
31
def __init__(self, branch, start, maxnum, parent=None):
32
gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
33
self.set_border_width(0)
39
self.set_title(branch.nick + " - revision history")
43
self.connect('key-press-event', self._on_key_pressed)
45
# Use three-quarters of the screen by default
46
screen = self.get_screen()
47
monitor = screen.get_monitor_geometry(0)
48
width = int(monitor.width * 0.75)
49
height = int(monitor.height * 0.75)
50
self.set_default_size(width, height)
53
icon = self.render_icon(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
56
self.accel_group = gtk.AccelGroup()
57
self.add_accel_group(self.accel_group)
62
"""Construct the window contents."""
63
vbox = gtk.VBox(spacing=0)
66
vbox.pack_start(self.construct_navigation(), expand=False, fill=True)
67
vbox.pack_start(self.construct_loading_msg(), expand=False, fill=True)
70
paned.pack1(self.construct_top(), resize=True, shrink=False)
71
paned.pack2(self.construct_bottom(), resize=False, shrink=True)
73
vbox.pack_start(paned, expand=True, fill=True)
74
vbox.set_focus_child(paned)
78
def construct_loading_msg(self):
79
image_loading = gtk.image_new_from_stock(gtk.STOCK_REFRESH,
83
label_loading = gtk.Label(_("Please wait, loading ancestral graph..."))
84
label_loading.set_alignment(0.0, 0.5)
87
self.loading_msg_box = gtk.HBox()
88
self.loading_msg_box.set_spacing(5)
89
self.loading_msg_box.set_border_width(5)
90
self.loading_msg_box.pack_start(image_loading, False, False)
91
self.loading_msg_box.pack_start(label_loading, True, True)
92
self.loading_msg_box.show()
94
return self.loading_msg_box
96
def construct_top(self):
97
"""Construct the top-half of the window."""
98
self.treeview = TreeView(self.branch, self.start, self.maxnum)
100
self.treeview.connect("revision-selected",
101
self._treeselection_changed_cb)
103
self.treeview.connect('revisions-loaded',
104
lambda x: self.loading_msg_box.hide())
110
def construct_navigation(self):
111
"""Construct the navigation buttons."""
113
frame.set_shadow_type(gtk.SHADOW_OUT)
116
hbox = gtk.HBox(spacing=12)
120
self.back_button = gtk.Button(stock=gtk.STOCK_GO_BACK)
121
self.back_button.set_relief(gtk.RELIEF_NONE)
122
self.back_button.add_accelerator("clicked", self.accel_group, ord('['),
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()
128
self.fwd_button = gtk.Button(stock=gtk.STOCK_GO_FORWARD)
129
self.fwd_button.set_relief(gtk.RELIEF_NONE)
130
self.fwd_button.add_accelerator("clicked", self.accel_group, ord(']'),
132
self.fwd_button.connect("clicked", self._fwd_clicked_cb)
133
hbox.pack_start(self.fwd_button, expand=False, fill=True)
134
self.fwd_button.show()
138
def construct_bottom(self):
139
"""Construct the bottom half of the window."""
140
from bzrlib.plugins.gtk.logview import LogView
141
self.logview = LogView(None, True, [], True)
142
(width, height) = self.get_size()
143
self.logview.set_size_request(width, int(height / 2.5))
145
self.logview.set_show_callback(self._show_clicked_cb)
146
self.logview.set_go_callback(self._go_clicked_cb)
149
def _on_key_pressed(self, widget, event):
150
""" Key press event handler. """
151
keyname = gtk.gdk.keyval_name(event.keyval)
152
func = getattr(self, '_on_key_press_' + keyname, None)
156
def _on_key_press_w(self, event):
157
if event.state & gtk.gdk.CONTROL_MASK:
159
if self._parent is None:
162
def _on_key_press_q(self, event):
163
if event.state & gtk.gdk.CONTROL_MASK:
166
def _treeselection_changed_cb(self, selection, *args):
167
"""callback for when the treeview changes."""
168
revision = self.treeview.get_revision()
169
parents = self.treeview.get_parents()
170
children = self.treeview.get_children()
172
if revision is not None:
173
self.back_button.set_sensitive(len(parents) > 0)
174
self.fwd_button.set_sensitive(len(children) > 0)
176
if self.branch.supports_tags():
177
tagdict = self.branch.tags.get_reverse_tag_dict()
178
if tagdict.has_key(revision.revision_id):
179
tags = tagdict[revision.revision_id]
180
self.logview.set_revision(revision, tags, children)
182
def _back_clicked_cb(self, *args):
183
"""Callback for when the back button is clicked."""
186
def _fwd_clicked_cb(self, *args):
187
"""Callback for when the forward button is clicked."""
188
self.treeview.forward()
190
def _go_clicked_cb(self, revid):
191
"""Callback for when the go button for a parent is clicked."""
192
self.treeview.set_revision(revid)
194
def _show_clicked_cb(self, revid, parentid):
195
"""Callback for when the show button for a parent is clicked."""
196
self.treeview.show_diff(self.branch, revid, parentid)
197
self.treeview.grab_focus()