Commit be078d24 authored by Kai Willadsen's avatar Kai Willadsen

Fix sensitivity of prev/next diff in VC and DirDiff (closes bgo#650181)

Common code for finding the previous/next differing rows was moved to
the tree module, and both VCView and DirDiff now use that approach.
Previous/next diff is updated on tree cursor movement and used to set
sensitivity of the corresponding actions.

Currently there is no attempt to minimise the number of tree
traversals done when the cursor moves. In some situations of very large
trees with few changes, this may mean that scrolling through the tree
with the keyboard will be very slow. There are certainly tricks that
can be done with invalidation of the prev/next validity (TODO-ed in the
code) that should improve the situation.
parent 24ad00b1
......@@ -73,6 +73,7 @@
<property name="hover_expand">False</property>
<signal handler="on_row_activated" last_modification_time="Sat, 03 Aug 2002 23:32:49 GMT" name="row_activated"/>
<signal handler="on_button_press_event" last_modification_time="Sat, 30 Aug 2003 12:42:19 GMT" name="button_press_event"/>
<signal handler="on_treeview_cursor_changed" name="cursor-changed" swapped="no"/>
<signal handler="on_treeview_popup_menu" name="popup-menu"/>
</object>
</child>
......
### Copyright (C) 2002-2006 Stephen Kennedy <stevek@gnome.org>
### Copyright (C) 2009-2010 Kai Willadsen <kai.willadsen@gmail.com>
### Copyright (C) 2009-2011 Kai Willadsen <kai.willadsen@gmail.com>
### This program is free software; you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
......@@ -264,6 +264,7 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
self.focus_in_events.append(handler_id)
handler_id = treeview.connect("focus-out-event", self.on_treeview_focus_out_event)
self.focus_out_events.append(handler_id)
self.prev_path, self.next_path = None, None
self.on_treeview_focus_out_event(None, None)
self.treeview_focussed = None
......@@ -322,8 +323,6 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
self._create_filter_menu_button(ui)
self.ui_manager = ui
# FIXME: Add real sensitivity handling
self.emit("next-diff-changed", True, True)
if self.treeview_focussed:
self.scheduler.add_task(self.treeview_focussed.grab_focus)
self.scheduler.add_task(self.on_treeview_cursor_changed)
......@@ -702,6 +701,19 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
pane = self._get_focused_pane()
if pane is None:
return
cursor_path, cursor_col = self.treeview[pane].get_cursor()
if not cursor_path:
self.emit("next-diff-changed", False, False)
else:
# TODO: Only recalculate when needed;
# not self.prev_path < cursor_path < self.next_path is a start,
# but fails when we move off a changed row.
prev_path, next_path = self.model._find_next_prev_diff(cursor_path)
self.prev_path, self.next_path = prev_path, next_path
have_next_diffs = (prev_path is not None, next_path is not None)
self.emit("next-diff-changed", *have_next_diffs)
paths = self._get_selected_paths(pane)
if len(paths) > 0:
def rwx(mode):
......@@ -1090,20 +1102,16 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
def next_diff(self, direction):
if self.treeview_focussed:
pane = self.treeview.index( self.treeview_focussed )
pane = self.treeview.index(self.treeview_focussed)
else:
pane = 0
start_iter = self.model.get_iter( (self._get_selected_paths(pane) or [(0,)])[-1] )
search = {gtk.gdk.SCROLL_UP : self.model.inorder_search_up}.get(direction, self.model.inorder_search_down)
for it in search( start_iter ):
state = self.model.get_state(it, pane)
if state not in (tree.STATE_NORMAL, tree.STATE_EMPTY):
curpath = self.model.get_path(it)
self.treeview[pane].expand_to_path(curpath)
self.treeview[pane].set_cursor(curpath)
return
if direction == gtk.gdk.SCROLL_UP:
path = self.prev_path
else:
path = self.next_path
if path:
self.treeview[pane].expand_to_path(path)
self.treeview[pane].set_cursor(path)
def on_reload_activate(self, *extra):
self.on_fileentry_activate(None)
......@@ -169,3 +169,20 @@ class DiffTreeStore(gtk.TreeStore):
raise StopIteration()
yield it
def _find_next_prev_diff(self, start_path):
prev_path, next_path = None, None
start_iter = self.get_iter(start_path)
for it in self.inorder_search_up(start_iter):
state = self.get_state(it, 0)
if state not in (STATE_NORMAL, STATE_EMPTY):
prev_path = self.get_path(it)
break
for it in self.inorder_search_down(start_iter):
state = self.get_state(it, 0)
if state not in (STATE_NORMAL, STATE_EMPTY):
next_path = self.get_path(it)
break
return prev_path, next_path
### Copyright (C) 2002-2006 Stephen Kennedy <stevek@gnome.org>
### Copyright (C) 2010-2011 Kai Willadsen <kai.willadsen@gmail.com>
### This program is free software; you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
......@@ -153,6 +154,7 @@ class VcView(melddoc.MeldDoc, gnomeglade.Component):
self.treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.treeview.set_headers_visible(1)
self.treeview.set_search_equal_func(self.treeview_search_cb)
self.prev_path, self.next_path = None, None
column = gtk.TreeViewColumn( _("Name") )
renicon = ui.emblemcellrenderer.EmblemCellRenderer()
rentext = gtk.CellRendererText()
......@@ -211,8 +213,7 @@ class VcView(melddoc.MeldDoc, gnomeglade.Component):
def on_container_switch_in_event(self, ui):
melddoc.MeldDoc.on_container_switch_in_event(self, ui)
# FIXME: Add real sensitivity handling
self.emit("next-diff-changed", True, True)
self.scheduler.add_task(self.on_treeview_cursor_changed)
def update_actions_sensitivity(self):
"""Disable actions that use not implemented VC plugin methods
......@@ -293,6 +294,7 @@ class VcView(melddoc.MeldDoc, gnomeglade.Component):
# need to scan the rest of the repository
if os.path.isdir(self.vc.location):
self.scheduler.add_task(self._search_recursively_iter(self.model.get_iter_root()).next)
self.scheduler.add_task(self.on_treeview_cursor_changed)
def recompute_label(self):
self.label_text = os.path.basename(self.location)
......@@ -660,17 +662,25 @@ class VcView(melddoc.MeldDoc, gnomeglade.Component):
item.show()
menu.insert( item, 1 )
def on_treeview_cursor_changed(self, *args):
cursor_path, cursor_col = self.treeview.get_cursor()
if not cursor_path:
self.emit("next-diff-changed", False, False)
else:
# TODO: Only recalculate when needed; see DirDiff
prev_path, next_path = self.model._find_next_prev_diff(cursor_path)
self.prev_path, self.next_path = prev_path, next_path
have_next_diffs = (prev_path is not None, next_path is not None)
self.emit("next-diff-changed", *have_next_diffs)
def next_diff(self, direction):
start_iter = self.model.get_iter((self._get_selected_paths() or [(0,)])[-1])
search = {gtk.gdk.SCROLL_UP : self.model.inorder_search_up}.get(direction, self.model.inorder_search_down)
for it in search( start_iter ):
state = self.model.get_state(it, 0)
if state not in (tree.STATE_NORMAL, tree.STATE_EMPTY):
curpath = self.model.get_path(it)
self.treeview.expand_to_path(curpath)
self.treeview.set_cursor(curpath)
return
if direction == gtk.gdk.SCROLL_UP:
path = self.prev_path
else:
path = self.next_path
if path:
self.treeview.expand_to_path(path)
self.treeview.set_cursor(path)
def on_reload_activate(self, *extra):
self.on_fileentry_activate(self.fileentry)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment