[meld] Alert with error bell when moving past first/last change (#439)



commit 73bd4e99ac82154bc1a7a04837779980cbb03dea
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Sun Mar 15 08:08:40 2020 +1000

    Alert with error bell when moving past first/last change (#439)
    
    Ideally this change would be half a dozen lines of `error_bell()`
    changes. However, because we currently do all of our change movement
    handling via GActions, our sensitivity handling prevents the actions
    from even being triggered.
    
    The workaround in this patch is to create a GObject signal with a
    trivial handler that just invokes the common change movement call. Since
    this signal is not subject to sensitivity, it will still be hit when the
    action is disabled.
    
    The way this currently works, we still have the action key bindings as
    well as the CSS-controlled signal bindings. I'm torn on what the best
    way to handle this is, since while the overlapping bindings may be
    slightly confusing, I definitely don't want to migrate everything to CSS
    bindings.

 meld/accelerators.py    |  2 ++
 meld/dirdiff.py         |  6 ++++++
 meld/filediff.py        | 12 ++++++++++--
 meld/melddoc.py         |  7 +++++++
 meld/resources/meld.css | 23 +++++++++++++++++++++++
 meld/vcview.py          |  6 ++++++
 6 files changed, 54 insertions(+), 2 deletions(-)
---
diff --git a/meld/accelerators.py b/meld/accelerators.py
index 2b87dc34..e1b26c3b 100644
--- a/meld/accelerators.py
+++ b/meld/accelerators.py
@@ -10,8 +10,10 @@ VIEW_ACCELERATORS: Dict[str, Union[str, Sequence[str]]] = {
     'view.find-previous': '<Primary><Shift>G',
     'view.find-replace': '<Primary>H',
     'view.go-to-line': '<Primary>I',
+    # Overridden in CSS
     'view.next-change': ('<Alt>Down', '<Alt>KP_Down', '<Primary>D'),
     'view.next-pane': '<Alt>Page_Down',
+    # Overridden in CSS
     'view.previous-change': ('<Alt>Up', '<Alt>KP_Up', '<Primary>E'),
     'view.previous-pane': '<Alt>Page_Up',
     'view.redo': '<Primary><Shift>Z',
diff --git a/meld/dirdiff.py b/meld/dirdiff.py
index 7565d7c8..deee301d 100644
--- a/meld/dirdiff.py
+++ b/meld/dirdiff.py
@@ -298,6 +298,7 @@ class DirDiff(Gtk.VBox, tree.TreeviewCommon, MeldDoc):
     create_diff_signal = MeldDoc.create_diff_signal
     file_changed_signal = MeldDoc.file_changed_signal
     label_changed = MeldDoc.label_changed
+    move_diff = MeldDoc.move_diff
     tab_state_changed = MeldDoc.tab_state_changed
 
     __gsettings_bindings__ = (
@@ -1649,6 +1650,8 @@ class DirDiff(Gtk.VBox, tree.TreeviewCommon, MeldDoc):
         if path:
             self.treeview[pane].expand_to_path(path)
             self.treeview[pane].set_cursor(path)
+        else:
+            self.error_bell()
 
     def action_previous_change(self, *args):
         self.next_diff(Gdk.ScrollDirection.UP)
@@ -1673,3 +1676,6 @@ class DirDiff(Gtk.VBox, tree.TreeviewCommon, MeldDoc):
         modified_states = (tree.STATE_MODIFIED, tree.STATE_CONFLICT)
         for it in self.model.state_rows(modified_states):
             self.run_diff_from_iter(it)
+
+
+DirDiff.set_css_name('meld-folder-diff')
diff --git a/meld/filediff.py b/meld/filediff.py
index 40aac6c6..8e5246f0 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -116,6 +116,7 @@ class FileDiff(Gtk.VBox, MeldDoc):
     create_diff_signal = MeldDoc.create_diff_signal
     file_changed_signal = MeldDoc.file_changed_signal
     label_changed = MeldDoc.label_changed
+    move_diff = MeldDoc.move_diff
     tab_state_changed = MeldDoc.tab_state_changed
 
     __gsettings_bindings_view__ = (
@@ -720,6 +721,7 @@ class FileDiff(Gtk.VBox, MeldDoc):
 
     def go_to_chunk(self, target, pane=None, centered=False):
         if target is None:
+            self.error_bell()
             return
 
         if pane is None:
@@ -729,6 +731,7 @@ class FileDiff(Gtk.VBox, MeldDoc):
 
         chunk = self.linediffer.get_chunk(target, pane)
         if not chunk:
+            self.error_bell()
             return
 
         # Warp the cursor to the first line of the chunk
@@ -1570,8 +1573,10 @@ class FileDiff(Gtk.VBox, MeldDoc):
 
             chunk, prev, next_ = self.linediffer.locate_chunk(1, 0)
             target_chunk = chunk if chunk is not None else next_
-            self.scheduler.add_task(
-                lambda: self.go_to_chunk(target_chunk, centered=True), True)
+            if target_chunk is not None:
+                self.scheduler.add_task(
+                    lambda: self.go_to_chunk(target_chunk, centered=True),
+                    True)
 
         self.queue_draw()
         self._connect_buffer_handlers()
@@ -2387,3 +2392,6 @@ class FileDiff(Gtk.VBox, MeldDoc):
             if mgr.get_msg_id() == FileDiff.MSG_SYNCPOINTS:
                 mgr.clear()
         self.refresh_comparison()
+
+
+FileDiff.set_css_name('meld-file-diff')
diff --git a/meld/melddoc.py b/meld/melddoc.py
index bbfa002d..be96bb7a 100644
--- a/meld/melddoc.py
+++ b/meld/melddoc.py
@@ -86,6 +86,13 @@ class MeldDoc(LabeledObjectMixin, GObject.GObject):
     def tab_state_changed(self, old_state: int, new_state: int) -> None:
         ...
 
+    @GObject.Signal(
+        name='move-diff',
+        flags=GObject.SignalFlags.RUN_FIRST | GObject.SignalFlags.ACTION,
+    )
+    def move_diff(self, direction: int) -> None:
+        self.next_diff(direction)
+
     def __init__(self) -> None:
         super().__init__()
         self.scheduler = FifoScheduler()
diff --git a/meld/resources/meld.css b/meld/resources/meld.css
index 79f8cd91..7ec8e70a 100644
--- a/meld/resources/meld.css
+++ b/meld/resources/meld.css
@@ -34,6 +34,29 @@ action-gutter {
     background-color: @theme_bg_color;
 }
 
+@binding-set ChunkMovementBindings {
+    /* Gdk.ScrollDirection.UP */
+    bind "<Alt>Up" { "move-diff" (0) };
+    bind "<Alt>KP_Up" { "move-diff" (0) };
+    bind "<Primary>E" { "move-diff" (0) };
+    /* Gdk.ScrollDirection.DOWN */
+    bind "<Alt>Down" { "move-diff" (1) };
+    bind "<Alt>KP_Down" { "move-diff" (1) };
+    bind "<Primary>D" { "move-diff" (1) };
+}
+
+meld-file-diff {
+    -gtk-key-bindings: ChunkMovementBindings;
+}
+
+meld-folder-diff {
+    -gtk-key-bindings: ChunkMovementBindings;
+}
+
+meld-vc-view {
+    -gtk-key-bindings: ChunkMovementBindings;
+}
+
 @binding-set MeldFindbarBindings {
     bind "<Shift>Return" { "activate-secondary" () };
 }
diff --git a/meld/vcview.py b/meld/vcview.py
index d30feaa1..cee2e725 100644
--- a/meld/vcview.py
+++ b/meld/vcview.py
@@ -128,6 +128,7 @@ class VcView(Gtk.VBox, tree.TreeviewCommon, MeldDoc):
     create_diff_signal = MeldDoc.create_diff_signal
     file_changed_signal = MeldDoc.file_changed_signal
     label_changed = MeldDoc.label_changed
+    move_diff = MeldDoc.move_diff
     tab_state_changed = MeldDoc.tab_state_changed
 
     status_filters = GObject.Property(
@@ -906,6 +907,8 @@ class VcView(Gtk.VBox, tree.TreeviewCommon, MeldDoc):
         if path:
             self.treeview.expand_to_path(path)
             self.treeview.set_cursor(path)
+        else:
+            self.error_bell()
 
     def action_previous_change(self, *args):
         self.next_diff(Gdk.ScrollDirection.UP)
@@ -925,3 +928,6 @@ class VcView(Gtk.VBox, tree.TreeviewCommon, MeldDoc):
             row_paths = self.model.value_paths(it)
             paths = [p for p in row_paths if os.path.exists(p)]
             self.run_diff(paths[0])
+
+
+VcView.set_css_name('meld-vc-view')


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]