* Scott Scriven <[EMAIL PROTECTED]> wrote:
> The changes are available in my branch:
> 
>   lp:~toykeeper/bzr-gtk/bzr-vis-enhancements/

And, if people prefer a merge directive, it's attached.

A few changes are included, but they're all related:

  - Added an optional diff panel to vis.
  - Made vis remember its window size, panel sizes, and toolbar 
    state.
  - Removed some redundant screen redrawing vis.
  - Fixed overflowing labels/buttons in vis.


-- Scott
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: [EMAIL PROTECTED]
# target_branch: https://code.launchpad.net/~bzr-gtk/bzr-gtk/trunk
# testament_sha1: 890fb27ec71013aa98051752412ed977a2642caf
# timestamp: 2008-07-12 03:34:50 -0600
# source_branch: https://code.launchpad.net/~bzr-gtk/bzr-gtk/trunk
# base_revision_id: [EMAIL PROTECTED]
# 
# Begin patch
=== modified file 'NEWS'
--- NEWS	2008-07-01 21:56:25 +0000
+++ NEWS	2008-07-11 17:36:56 +0000
@@ -11,6 +11,12 @@
 
   * Add "Send Merge Directive" button in bzr viz. (Jelmer Vernooij)
 
+  * Added an optional diff panel to bzr vis.  (Scott Scriven)
+
+  * Made bzr vis remember whether the toolbar is visible.  (Scott Scriven)
+
+  * Made bzr vis remember window and panel sizes.  (Scott Scriven)
+
  BUG FIXES
 
   * Replace _() calls by _i18n() calls. (Vincent Ladeuil, #187283)
@@ -30,6 +36,10 @@
 
   * List network drives in Olive. (Kevin Light, #244308)
 
+  * Removed some redundant screen redrawing in bzr vis.  (Scott Scriven)
+
+  * Fixed overflowing labels in bzr vis.  (Scott Scriven)
+
  CHANGES
 
   * Moved notify icon code to separate script. (Jelmer Vernooij)

=== modified file 'branchview/treeview.py'
--- branchview/treeview.py	2008-06-30 20:11:24 +0000
+++ branchview/treeview.py	2008-07-10 06:23:54 +0000
@@ -325,6 +325,7 @@
         if set_tooltip is not None:
             set_tooltip(treemodel.MESSAGE)
 
+        self._prev_cursor_path = None
         self.treeview.connect("cursor-changed",
                 self._on_selection_changed)
 
@@ -400,7 +401,8 @@
     def _on_selection_changed(self, treeview):
         """callback for when the treeview changes."""
         (path, focus) = treeview.get_cursor()
-        if path is not None:
+        if (path is not None) and (path != self._prev_cursor_path):
+            self._prev_cursor_path = path # avoid emitting twice per click
             self.iter = self.model.get_iter(path)
             self.emit('revision-selected')
 

=== modified file 'diff.py'
--- diff.py	2008-05-22 02:33:40 +0000
+++ diff.py	2008-07-10 07:33:13 +0000
@@ -330,9 +330,10 @@
         # text view
 
     def set_diff_text_sections(self, sections):
-        self.diff_view = DiffFileView()
+        if not hasattr(self, 'diff_view'):
+            self.diff_view = DiffFileView()
+            self.pack2(self.diff_view)
         self.diff_view.show()
-        self.pack2(self.diff_view)
         for oldname, newname, patch in sections:
             self.diff_view._diffs[newname] = str(patch)
             if newname is None:
@@ -346,8 +347,9 @@
         Compares the two trees and populates the window with the
         differences.
         """
-        self.diff_view = DiffView()
-        self.pack2(self.diff_view)
+        if not hasattr(self, 'diff_view'):
+            self.diff_view = DiffView()
+            self.pack2(self.diff_view)
         self.diff_view.show()
         self.diff_view.set_trees(rev_tree, parent_tree)
         self.rev_tree = rev_tree
@@ -380,6 +382,7 @@
                 self.model.append(titer, [ path, path ])
 
         self.treeview.expand_all()
+        self.diff_view.show_diff(None)
 
     def set_file(self, file_path):
         """Select the current file to display"""

=== modified file 'revisionview.py'
--- revisionview.py	2008-06-29 19:18:34 +0000
+++ revisionview.py	2008-07-11 15:46:32 +0000
@@ -509,7 +509,7 @@
         table.resize(max(len(revids), 1), 2)
 
         for idx, revid in enumerate(revids):
-            align = gtk.Alignment(0.0, 0.0)
+            align = gtk.Alignment(0.0, 0.0, 1, 1)
             widgets.append(align)
             table.attach(align, 1, 2, idx, idx + 1,
                                       gtk.EXPAND | gtk.FILL, gtk.FILL)
@@ -532,12 +532,16 @@
                 hbox.pack_start(button, expand=False, fill=True)
                 button.show()
 
-            button = gtk.Button(revid)
+            button = gtk.Button()
+            revid_label = gtk.Label(str(revid))
+            revid_label.set_ellipsize(pango.ELLIPSIZE_MIDDLE)
+            revid_label.set_alignment(0.0, 0.5)
+            button.add(revid_label)
             button.connect("clicked",
                     lambda w, r: self.set_revision(self._repository.get_revision(r)), revid)
             button.set_use_underline(False)
-            hbox.pack_start(button, expand=False, fill=True)
-            button.show()
+            hbox.pack_start(button, expand=True, fill=True)
+            button.show_all()
 
     def _create_general(self):
         vbox = gtk.VBox(False, 6)
@@ -566,102 +570,91 @@
         self.table.set_col_spacings(6)
         self.table.show()
 
-        align = gtk.Alignment(1.0, 0.5)
+        row = 0
+
         label = gtk.Label()
+        label.set_alignment(1.0, 0.5)
         label.set_markup("<b>Revision Id:</b>")
-        align.add(label)
-        self.table.attach(align, 0, 1, 0, 1, gtk.FILL, gtk.FILL)
-        align.show()
+        self.table.attach(label, 0, 1, row, row+1, gtk.FILL, gtk.FILL)
         label.show()
 
-        align = gtk.Alignment(0.0, 0.5)
         revision_id = gtk.Label()
+        revision_id.set_ellipsize(pango.ELLIPSIZE_MIDDLE)
+        revision_id.set_alignment(0.0, 0.5)
         revision_id.set_selectable(True)
         self.connect('notify::revision', 
                 lambda w, p: revision_id.set_text(self._revision.revision_id))
-        align.add(revision_id)
-        self.table.attach(align, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, gtk.FILL)
-        align.show()
+        self.table.attach(revision_id, 1, 2, row, row+1, gtk.EXPAND | gtk.FILL, gtk.FILL)
         revision_id.show()
 
-        align = gtk.Alignment(1.0, 0.5)
+        row += 1
         self.author_label = gtk.Label()
+        self.author_label.set_alignment(1.0, 0.5)
         self.author_label.set_markup("<b>Author:</b>")
-        align.add(self.author_label)
-        self.table.attach(align, 0, 1, 1, 2, gtk.FILL, gtk.FILL)
-        align.show()
+        self.table.attach(self.author_label, 0, 1, row, row+1, gtk.FILL, gtk.FILL)
         self.author_label.show()
 
-        align = gtk.Alignment(0.0, 0.5)
         self.author = gtk.Label()
+        self.author.set_ellipsize(pango.ELLIPSIZE_END)
+        self.author.set_alignment(0.0, 0.5)
         self.author.set_selectable(True)
-        align.add(self.author)
-        self.table.attach(align, 1, 2, 1, 2, gtk.EXPAND | gtk.FILL, gtk.FILL)
-        align.show()
+        self.table.attach(self.author, 1, 2, row, row+1, gtk.EXPAND | gtk.FILL, gtk.FILL)
         self.author.show()
         self.author.hide()
 
-        align = gtk.Alignment(1.0, 0.5)
+        row += 1
         label = gtk.Label()
+        label.set_alignment(1.0, 0.5)
         label.set_markup("<b>Committer:</b>")
-        align.add(label)
-        self.table.attach(align, 0, 1, 2, 3, gtk.FILL, gtk.FILL)
-        align.show()
+        self.table.attach(label, 0, 1, row, row+1, gtk.FILL, gtk.FILL)
         label.show()
 
-        align = gtk.Alignment(0.0, 0.5)
         self.committer = gtk.Label()
+        self.committer.set_ellipsize(pango.ELLIPSIZE_END)
+        self.committer.set_alignment(0.0, 0.5)
         self.committer.set_selectable(True)
-        align.add(self.committer)
-        self.table.attach(align, 1, 2, 2, 3, gtk.EXPAND | gtk.FILL, gtk.FILL)
-        align.show()
+        self.table.attach(self.committer, 1, 2, row, row+1, gtk.EXPAND | gtk.FILL, gtk.FILL)
         self.committer.show()
 
-        align = gtk.Alignment(0.0, 0.5)
+        row += 1
         label = gtk.Label()
+        label.set_alignment(1.0, 0.5)
         label.set_markup("<b>Branch nick:</b>")
-        align.add(label)
-        self.table.attach(align, 0, 1, 3, 4, gtk.FILL, gtk.FILL)
+        self.table.attach(label, 0, 1, row, row+1, gtk.FILL, gtk.FILL)
         label.show()
-        align.show()
 
-        align = gtk.Alignment(0.0, 0.5)
         self.branchnick_label = gtk.Label()
+        self.branchnick_label.set_ellipsize(pango.ELLIPSIZE_MIDDLE)
+        self.branchnick_label.set_alignment(0.0, 0.5)
         self.branchnick_label.set_selectable(True)
-        align.add(self.branchnick_label)
-        self.table.attach(align, 1, 2, 3, 4, gtk.EXPAND | gtk.FILL, gtk.FILL)
+        self.table.attach(self.branchnick_label, 1, 2, row, row+1, gtk.EXPAND | gtk.FILL, gtk.FILL)
         self.branchnick_label.show()
-        align.show()
 
-        align = gtk.Alignment(1.0, 0.5)
+        row += 1
         label = gtk.Label()
+        label.set_alignment(1.0, 0.5)
         label.set_markup("<b>Timestamp:</b>")
-        align.add(label)
-        self.table.attach(align, 0, 1, 4, 5, gtk.FILL, gtk.FILL)
-        align.show()
+        self.table.attach(label, 0, 1, row, row+1, gtk.FILL, gtk.FILL)
         label.show()
 
-        align = gtk.Alignment(0.0, 0.5)
         self.timestamp = gtk.Label()
+        self.timestamp.set_ellipsize(pango.ELLIPSIZE_END)
+        self.timestamp.set_alignment(0.0, 0.5)
         self.timestamp.set_selectable(True)
-        align.add(self.timestamp)
-        self.table.attach(align, 1, 2, 4, 5, gtk.EXPAND | gtk.FILL, gtk.FILL)
-        align.show()
+        self.table.attach(self.timestamp, 1, 2, row, row+1, gtk.EXPAND | gtk.FILL, gtk.FILL)
         self.timestamp.show()
 
-        align = gtk.Alignment(1.0, 0.5)
+        row += 1
         self.tags_label = gtk.Label()
+        self.tags_label.set_alignment(1.0, 0.5)
         self.tags_label.set_markup("<b>Tags:</b>")
-        align.add(self.tags_label)
-        align.show()
-        self.table.attach(align, 0, 1, 5, 6, gtk.FILL, gtk.FILL)
+        self.table.attach(self.tags_label, 0, 1, row, row+1, gtk.FILL, gtk.FILL)
         self.tags_label.show()
 
-        align = gtk.Alignment(0.0, 0.5)
         self.tags_list = gtk.Label()
-        align.add(self.tags_list)
-        self.table.attach(align, 1, 2, 5, 6, gtk.EXPAND | gtk.FILL, gtk.FILL)
-        align.show()
+        self.tags_list.set_ellipsize(pango.ELLIPSIZE_MIDDLE)
+        self.tags_list.set_alignment(0.0, 0.5)
+        self.table.attach(self.tags_list, 1, 2, row, row+1, gtk.EXPAND | gtk.FILL, gtk.FILL)
         self.tags_list.show()
 
         self.connect('notify::revision', self._add_tags)

=== modified file 'viz/branchwin.py'
--- viz/branchwin.py	2008-07-01 21:54:21 +0000
+++ viz/branchwin.py	2008-07-11 17:25:46 +0000
@@ -48,6 +48,8 @@
         self.maxnum      = maxnum
         self.config      = GlobalConfig()
 
+        self._sizes      = {} # window and widget sizes
+
         if self.config.get_user_option('viz-compact-view') == 'yes':
             self.compact_view = True
         else:
@@ -60,7 +62,13 @@
         monitor = screen.get_monitor_geometry(0)
         width = int(monitor.width * 0.75)
         height = int(monitor.height * 0.75)
+        # user-configured window size
+        size = self._load_size('viz-window-size')
+        if size:
+            width, height = size
         self.set_default_size(width, height)
+        self.set_size_request(width/3, height/3)
+        self.connect("size-allocate", self._on_size_allocate, 'viz-window-size')
 
         # FIXME AndyFitz!
         icon = self.render_icon(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)
@@ -104,13 +112,15 @@
         self.add(vbox)
 
         self.paned = gtk.VPaned()
-        self.paned.pack1(self.construct_top(), resize=True, shrink=False)
-        self.paned.pack2(self.construct_bottom(), resize=False, shrink=True)
+        self.paned.pack1(self.construct_top(), resize=False, shrink=True)
+        self.paned.pack2(self.construct_bottom(), resize=True, shrink=False)
         self.paned.show()
 
-        vbox.pack_start(self.construct_menubar(), expand=False, fill=True)
-        vbox.pack_start(self.construct_navigation(), expand=False, fill=True)
-        
+        nav = self.construct_navigation()
+        menubar = self.construct_menubar()
+        vbox.pack_start(menubar, expand=False, fill=True)
+        vbox.pack_start(nav, expand=False, fill=True)
+
         vbox.pack_start(self.paned, expand=True, fill=True)
         vbox.set_focus_child(self.paned)
 
@@ -161,14 +171,24 @@
 
         view_menu_toolbar = gtk.CheckMenuItem("Show Toolbar")
         view_menu_toolbar.set_active(True)
+        if self.config.get_user_option('viz-toolbar-visible') == 'False':
+            view_menu_toolbar.set_active(False)
+            self.toolbar.hide()
         view_menu_toolbar.connect('toggled', self._toolbar_visibility_changed)
 
         view_menu_compact = gtk.CheckMenuItem("Show Compact Graph")
         view_menu_compact.set_active(self.compact_view)
         view_menu_compact.connect('activate', self._brokenlines_toggled_cb)
 
+        view_menu_diffs = gtk.CheckMenuItem("Show Diffs")
+        view_menu_diffs.set_active(True)
+        if self.config.get_user_option('viz-show-diffs') == 'False':
+            view_menu_diffs.set_active(False)
+        view_menu_diffs.connect('toggled', self._diff_visibility_changed)
+
         view_menu.add(view_menu_toolbar)
         view_menu.add(view_menu_compact)
+        view_menu.add(view_menu_diffs)
         view_menu.add(gtk.SeparatorMenuItem())
 
         self.mnu_show_revno_column = gtk.CheckMenuItem("Show Revision _Number Column")
@@ -275,6 +295,15 @@
         align = gtk.Alignment(0.0, 0.0, 1.0, 1.0)
         align.set_padding(5, 0, 0, 0)
         align.add(self.treeview)
+        # user-configured size
+        size = self._load_size('viz-graph-size')
+        if size:
+            width, height = size
+            align.set_size_request(width, height)
+        else:
+            (width, height) = self.get_size()
+            align.set_size_request(width, int(height / 2.5))
+        align.connect('size-allocate', self._on_size_allocate, 'viz-graph-size')
         align.show()
 
         return align
@@ -302,15 +331,34 @@
 
     def construct_bottom(self):
         """Construct the bottom half of the window."""
+        self.bottom_hpaned = gtk.HPaned()
+        (width, height) = self.get_size()
+        self.bottom_hpaned.set_size_request(20, 20) # shrinkable
+
         from bzrlib.plugins.gtk.revisionview import RevisionView
         self.revisionview = RevisionView(branch=self.branch)
-        (width, height) = self.get_size()
-        self.revisionview.set_size_request(width, int(height / 2.5))
+        self.revisionview.set_size_request(width/3, int(height / 2.5))
+        # user-configured size
+        size = self._load_size('viz-revisionview-size')
+        if size:
+            width, height = size
+            self.revisionview.set_size_request(width, height)
+        self.revisionview.connect('size-allocate', self._on_size_allocate, 'viz-revisionview-size')
         self.revisionview.show()
         self.revisionview.set_show_callback(self._show_clicked_cb)
         self.revisionview.connect('notify::revision', self._go_clicked_cb)
         self.treeview.connect('tag-added', lambda w, t, r: self.revisionview.update_tags())
-        return self.revisionview
+        self.bottom_hpaned.pack1(self.revisionview)
+
+        from bzrlib.plugins.gtk.diff import DiffWidget
+        self.diff = DiffWidget()
+        self.bottom_hpaned.pack2(self.diff)
+
+        self.bottom_hpaned.show_all()
+        if self.config.get_user_option('viz-show-diffs') == 'False':
+            self.diff.hide()
+
+        return self.bottom_hpaned
 
     def _tag_selected_cb(self, menuitem, revid):
         self.treeview.set_revision_id(revid)
@@ -367,7 +415,9 @@
 
             self.revisionview.set_revision(revision)
             self.revisionview.set_children(children)
-    
+
+            self.update_diff_panel(revision, parents)
+
     def _tree_revision_activated(self, widget, path, col):
         # TODO: more than one parent
         """Callback for when a treeview row gets activated."""
@@ -439,9 +489,23 @@
 
     def _toolbar_visibility_changed(self, col):
         if col.get_active():
-            self.toolbar.show() 
+            self.toolbar.show()
         else:
             self.toolbar.hide()
+        self.config.set_user_option('viz-toolbar-visible', col.get_active())
+
+    def _diff_visibility_changed(self, col):
+        if col.get_active():
+            self.diff.show()
+            # make sure the diff isn't zero-width
+            alloc = self.diff.get_allocation()
+            if alloc.width < 10:
+                width, height = self.get_size()
+                self.revisionview.set_size_request(width/3, int(height / 2.5))
+        else:
+            self.diff.hide()
+        self.config.set_user_option('viz-show-diffs', str(col.get_active()))
+        self.update_diff_panel()
 
     def _show_about_cb(self, w):
         dialog = AboutDialog()
@@ -473,6 +537,34 @@
 
         self.go_menu_tags.show_all()
 
+    def _load_size(self, name):
+        """Read and parse 'name' from self.config.
+        The value is a string, formatted as WIDTHxHEIGHT
+        Returns None, or (width, height)
+        """
+        size = self.config.get_user_option(name)
+        if size:
+            width, height = [int(num) for num in size.split('x')]
+            # avoid writing config every time we start
+            self._sizes[name] = (width, height)
+            return width, height
+        return None
+
+    def _on_size_allocate(self, widget, allocation, name):
+        """When window has been resized, save the new size."""
+        width, height = 0, 0
+        if name in self._sizes:
+            width, height = self._sizes[name]
+
+        size_changed = (width != allocation.width) or \
+                (height != allocation.height)
+
+        if size_changed:
+            width, height = allocation.width, allocation.height
+            self._sizes[name] = (width, height)
+            value = '%sx%s' % (width, height)
+            self.config.set_user_option(name, value)
+
     def show_diff(self, revid=None, parentid=None):
         """Open a new window to show a diff between the given revisions."""
         from bzrlib.plugins.gtk.diff import DiffWindow
@@ -489,3 +581,25 @@
         window.show()
 
 
+    def update_diff_panel(self, revision=None, parents=None):
+        """Show the current revision in the diff panel."""
+        if self.config.get_user_option('viz-show-diffs') == 'False':
+            return
+
+        if not revision: # default to selected row
+            revision = self.treeview.get_revision()
+        if (not revision) or (revision == NULL_REVISION):
+            return
+
+        if not parents: # default to selected row's parents
+            parents  = self.treeview.get_parents()
+        if len(parents) == 0:
+            parent_id = None
+        else:
+            parent_id = parents[0]
+
+        rev_tree    = self.branch.repository.revision_tree(revision.revision_id)
+        parent_tree = self.branch.repository.revision_tree(parent_id)
+
+        self.diff.set_diff(rev_tree, parent_tree)
+        self.diff.show_all()

# Begin bundle
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
Wr/9/+LuSKcKEgVTSntg
-- 
bzr-gtk mailing list
[email protected]
Modify settings or unsubscribe at: 
https://lists.canonical.com/mailman/listinfo/bzr-gtk

Reply via email to