[Pkg-bazaar-commits] ./bzr-gtk/unstable r3: Split the display in two with a pane, we'll use the bottom half to show
Scott James Remnant
scott at netsplit.com
Fri Apr 10 07:15:00 UTC 2009
------------------------------------------------------------
revno: 3
committer: Scott James Remnant <scott at netsplit.com>
timestamp: Mon 2005-10-17 05:26:00 +0100
message:
Split the display in two with a pane, we'll use the bottom half to show
information about the current revision. Add a Back and Forward button
which figure out which revision is logically the next of previous and
moves the cursor to it. Handle the cursor-changed event to enable/disable
the buttons (and soon update the bottom pane).
Further split up graph.py so we can stash the internal lists to do the
above; also it may allow us in future to produce partial graphs.
modified:
branchwin.py
graph.py
-------------- next part --------------
=== modified file 'branchwin.py'
--- a/branchwin.py 2005-10-17 01:07:49 +0000
+++ b/branchwin.py 2005-10-17 04:26:00 +0000
@@ -18,7 +18,7 @@
from bzrlib.osutils import format_date
-from graph import graph
+from graph import distances, graph, same_branch
from graphcell import CellRendererGraph
@@ -44,20 +44,36 @@
icon = self.render_icon(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
self.set_icon(icon)
+ self.accel_group = gtk.AccelGroup()
+ self.add_accel_group(self.accel_group)
+
self.construct()
def construct(self):
"""Construct the window contents."""
+ paned = gtk.VPaned()
+ paned.pack1(self.construct_top(), resize=True, shrink=False)
+ paned.pack2(self.construct_bottom(), resize=True, shrink=True)
+ self.add(paned)
+ paned.show()
+
+ def construct_top(self):
+ """Construct the top-half of the window."""
+ vbox = gtk.VBox(spacing=6)
+ vbox.set_border_width(12)
+ vbox.show()
+
scrollwin = gtk.ScrolledWindow()
scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
scrollwin.set_shadow_type(gtk.SHADOW_IN)
- scrollwin.set_border_width(12)
- self.add(scrollwin)
+ #scrollwin.set_border_width(12)
+ vbox.pack_start(scrollwin, expand=True, fill=True)
scrollwin.show()
self.treeview = gtk.TreeView()
self.treeview.set_rules_hint(True)
self.treeview.set_search_column(4)
+ self.treeview.connect("cursor-changed", self._treeview_cursor_cb)
scrollwin.add(self.treeview)
self.treeview.show()
@@ -96,6 +112,33 @@
column.add_attribute(cell, "text", 6)
self.treeview.append_column(column)
+ hbox = gtk.HBox(False, spacing=6)
+ vbox.pack_start(hbox, expand=False, fill=False)
+ hbox.show()
+
+ self.back_button = gtk.Button(stock=gtk.STOCK_GO_BACK)
+ self.back_button.add_accelerator("clicked", self.accel_group, ord('['),
+ 0, 0)
+ self.back_button.connect("clicked", self._back_clicked_cb)
+ hbox.pack_start(self.back_button, expand=False, fill=True)
+ self.back_button.show()
+
+ self.fwd_button = gtk.Button(stock=gtk.STOCK_GO_FORWARD)
+ self.fwd_button.add_accelerator("clicked", self.accel_group, ord(']'),
+ 0, 0)
+ self.fwd_button.connect("clicked", self._fwd_clicked_cb)
+ hbox.pack_start(self.fwd_button, expand=False, fill=True)
+ self.fwd_button.show()
+
+ return vbox
+
+ def construct_bottom(self):
+ """Construct the bottom half of the window."""
+ label = gtk.Label("test")
+ label.show()
+
+ return label
+
def set_branch(self, branch, start):
"""Set the branch and start position for this window.
@@ -104,21 +147,70 @@
treeview itself.
"""
# [ revision, node, last_lines, lines, message, committer, timestamp ]
- model = gtk.ListStore(gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,
- gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,
- str, str, str)
+ self.model = gtk.ListStore(gobject.TYPE_PYOBJECT,
+ gobject.TYPE_PYOBJECT,
+ gobject.TYPE_PYOBJECT,
+ gobject.TYPE_PYOBJECT,
+ str, str, str)
+ self.index = {}
+ index = 0
last_lines = []
- for revision, node, lines in graph(branch, start):
+ (revids, self.revisions, colours, self.children) \
+ = distances(branch, start)
+ for revision, node, lines in graph(revids, self.revisions, colours):
message = revision.message.split("\n")[0]
if revision.committer is not None:
timestamp = format_date(revision.timestamp, revision.timezone)
else:
timestamp = None
- model.append([ revision, node, last_lines, lines,
- message, revision.committer, timestamp ])
+ self.model.append([ revision, node, last_lines, lines,
+ message, revision.committer, timestamp ])
+ self.index[revision] = index
+ index += 1
+
last_lines = lines
self.set_title(os.path.basename(branch.base) + " - bzrk")
- self.treeview.set_model(model)
+ self.treeview.set_model(self.model)
+
+ def _treeview_cursor_cb(self, *args):
+ """Callback for when the treeview cursor changes."""
+ (path, col) = self.treeview.get_cursor()
+ revision = self.model[path][0]
+
+ self.back_button.set_sensitive(len(self.children[revision]) > 0)
+ self.fwd_button.set_sensitive(len(revision.parent_ids) > 0)
+
+ def _back_clicked_cb(self, *args):
+ """Callback for when the back button is clicked."""
+ (path, col) = self.treeview.get_cursor()
+ revision = self.model[path][0]
+ if not len(self.children[revision]):
+ return
+
+ for child in self.children[revision]:
+ if same_branch(child, revision):
+ self.treeview.set_cursor(self.index[child])
+ break
+ else:
+ prev = list(self.children[revision])[0]
+ self.treeview.set_cursor(self.index[prev])
+
+ def _fwd_clicked_cb(self, *args):
+ """Callback for when the forward button is clicked."""
+ (path, col) = self.treeview.get_cursor()
+ revision = self.model[path][0]
+ if not len(revision.parent_ids):
+ return
+
+ for parent_id in revision.parent_ids:
+ parent = self.revisions[parent_id]
+ if same_branch(revision, parent):
+ self.treeview.set_cursor(self.index[parent])
+ break
+ else:
+ next = self.revisions[revision.parent_ids[0]]
+ self.treeview.set_cursor(self.index[next])
+
=== modified file 'graph.py'
--- a/graph.py 2005-10-17 03:23:43 +0000
+++ b/graph.py 2005-10-17 04:26:00 +0000
@@ -30,35 +30,17 @@
self.message = self.revision_id
-def graph(branch, start):
- """Produce a directed graph of a bzr branch.
+def distances(branch, start):
+ """Sort the revisions.
Traverses the branch revision tree starting at start and produces an
ordered list of revisions such that a revision always comes after
- any revision it is the parent of. It also tries to make a reasonably
- not-too-stupid decision whether a parent revision is on the same
- logical branch, as that information is not available with bzr.
-
- For each revision it then yields a tuple of (revision, node, lines).
- If the revision is only referenced in the branch and not present in the
- store, revision will be a DummyRevision object, otherwise it is the bzr
- Revision object with the meta-data for the revision.
-
- Node is a tuple of (column, colour) with column being a zero-indexed
- column number of the graph that this revision represents and colour
- being a zero-indexed colour (which doesn't specify any actual colour
- in particular) to draw the node in.
-
- Lines is a list of tuples which represent lines you should draw away
- from the revision, if you also need to draw lines into the revision
- you should use the lines list from the previous iteration. Each
- typle in the list is in the form (start, end, colour) with start and
- end being zero-indexed column numbers and colour as in node.
-
- It's up to you how to actually draw the nodes and lines (straight,
- curved, kinked, etc.) and to pick the actual colours for each index.
+ any revision it is the parent of.
+
+ Returns a tuple of (revids, revisions, colours, children)
"""
revisions = { start: branch.get_revision(start) }
+ children = { revisions[start]: set() }
distances = { start: 0 }
colours = { start: 0 }
last_colour = 0
@@ -82,6 +64,7 @@
# Get the parent from the cache, or put it in the cache
try:
parent = revisions[parent_id]
+ children[parent].add(revision)
except KeyError:
try:
parent = revisions[parent_id] \
@@ -89,6 +72,8 @@
except NoSuchRevision:
parent = revisions[parent_id] = DummyRevision(parent_id)
+ children[parent] = set([ revision ])
+
# Penalise revisions a little at a fork if we think they're on
# the same branch -- this makes the few few (at least) revisions
# of a branch appear straight after the fork
@@ -104,12 +89,33 @@
todo.add(parent_id)
- # Now iterate the revisions again, but this time in list order rather
- # than traversing the tree, and build up the graph lines. We do this
- # by keeping a list of "hanging parents", which can only be removed
- # once we encounter the revision being hung.
- hanging = [ start ]
- for revid in sorted(distances, key=distances.get):
+ return ( sorted(distances, key=distances.get), revisions, colours,
+ children )
+
+def graph(revids, revisions, colours):
+ """Produce a directed graph of a bzr branch.
+
+ For each revision it then yields a tuple of (revision, node, lines).
+ If the revision is only referenced in the branch and not present in the
+ store, revision will be a DummyRevision object, otherwise it is the bzr
+ Revision object with the meta-data for the revision.
+
+ Node is a tuple of (column, colour) with column being a zero-indexed
+ column number of the graph that this revision represents and colour
+ being a zero-indexed colour (which doesn't specify any actual colour
+ in particular) to draw the node in.
+
+ Lines is a list of tuples which represent lines you should draw away
+ from the revision, if you also need to draw lines into the revision
+ you should use the lines list from the previous iteration. Each
+ typle in the list is in the form (start, end, colour) with start and
+ end being zero-indexed column numbers and colour as in node.
+
+ It's up to you how to actually draw the nodes and lines (straight,
+ curved, kinked, etc.) and to pick the actual colours for each index.
+ """
+ hanging = revids[:1]
+ for revid in revids:
lines = []
node = None
More information about the Pkg-bazaar-commits
mailing list