[meld] Add "Copy change [left/right] [above/below]" actions (closes bgo#606613)



commit f22e4ced3d6c0c403996638f8577e1f6ac5dc6e3
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Sat Nov 27 06:28:47 2010 +1000

    Add "Copy change [left/right] [above/below]" actions (closes bgo#606613)
    
    These actions add the ability to copy chunks in FileDiff from the
    menus, based on the currenly focused change. These are the final
    actions in the set of things that could always be done via the central
    diff bar, but weren't available for keyboard navigation. Now, they're
    available in menus, which makes them significantly more discoverable.

 data/ui/filediff-ui.xml |    5 +++++
 meld/filediff.py        |   28 ++++++++++++++++++++++++++--
 2 files changed, 31 insertions(+), 2 deletions(-)
---
diff --git a/data/ui/filediff-ui.xml b/data/ui/filediff-ui.xml
index 1f37e15..c5c7700 100644
--- a/data/ui/filediff-ui.xml
+++ b/data/ui/filediff-ui.xml
@@ -24,6 +24,11 @@
         <menuitem action="PullRight"/>
         <menuitem action="Delete"/>
         <separator/>
+        <menuitem action="CopyLeftUp"/>
+        <menuitem action="CopyLeftDown"/>
+        <menuitem action="CopyRightUp"/>
+        <menuitem action="CopyRightDown"/>
+        <separator/>
         <menuitem action="MergeFromLeft"/>
         <menuitem action="MergeFromRight"/>
         <menuitem action="MergeAll"/>
diff --git a/meld/filediff.py b/meld/filediff.py
index d305a3d..218e269 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -252,6 +252,10 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
             # FIXME: using LAST and FIRST is terrible and unreliable icon abuse
             ("PullLeft",  gtk.STOCK_GOTO_LAST,  _("Pull from left"),  "<Alt><Shift>Right", _("Pull change from the left"), lambda x: self.pull_change(-1)),
             ("PullRight", gtk.STOCK_GOTO_FIRST, _("Pull from right"), "<Alt><Shift>Left", _("Pull change from the right"), lambda x: self.pull_change(1)),
+            ("CopyLeftUp", None, _("Copy above left"), "<Alt>bracketleft", _("Copy change above the left chunk"), lambda x: self.copy_change(-1, -1)),
+            ("CopyLeftDown", None, _("Copy below left"), "<Alt>semicolon", _("Copy change below the left chunk"), lambda x: self.copy_change(-1, 1)),
+            ("CopyRightUp", None, _("Copy above right"), "<Alt>bracketright", _("Copy change above the right chunk"), lambda x: self.copy_change(1, -1)),
+            ("CopyRightDown", None, _("Copy below right"), "<Alt>quoteright", _("Copy change below the right chunk"), lambda x: self.copy_change(1, 1)),
             ("Delete",    gtk.STOCK_DELETE,     _("Delete"),     "<Alt>Delete", _("Delete change"), self.delete_change),
             ("MergeFromLeft",  None, _("Merge all changes from left"),  None, _("Merge all non-conflicting changes from the left"), lambda x: self.pull_all_non_conflicting_changes(-1)),
             ("MergeFromRight", None, _("Merge all changes from right"), None, _("Merge all non-conflicting changes from the right"), lambda x: self.pull_all_non_conflicting_changes(1)),
@@ -362,9 +366,11 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
         pane = self.cursor.pane
         chunk_id = self.cursor.chunk
         # TODO: Handle editable states better; now it only works for auto-merge
-        push_left, push_right, pull_left, pull_right, delete = (True,) * 5
+        push_left, push_right, pull_left, pull_right, delete, \
+            copy_left, copy_right = (True,) * 7
         if pane == -1 or chunk_id is None:
-            push_left, push_right, pull_left, pull_right, delete = (False,) * 5
+            push_left, push_right, pull_left, pull_right, delete, \
+                copy_left, copy_right = (False,) * 7
         else:
             # Copy* and Delete are sensitive as long as there is something to
             # copy/delete (i.e., not an empty chunk), and the direction exists.
@@ -376,6 +382,8 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
                 pull_left = pane == 2 and not chunk[3] == chunk[4] and editable
                 pull_right = pane == 0 and not chunk[3] == chunk[4] and editable
                 delete = (push_left or push_right) and editable
+                copy_left = push_left and not chunk[3] == chunk[4]
+                copy_right = push_right and not chunk[3] == chunk[4]
             elif pane == 1:
                 chunk0 = self.linediffer.get_chunk(chunk_id, pane, 0)
                 chunk2 = None
@@ -389,11 +397,17 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
                 pull_right = chunk2 is not None and not chunk2[3] == chunk2[4]
                 delete = (chunk0 is not None and chunk0[1] != chunk0[2]) or \
                          (chunk2 is not None and chunk2[1] != chunk2[2])
+                copy_left = push_left and pull_left
+                copy_right = push_right and pull_right
         self.actiongroup.get_action("PushLeft").set_sensitive(push_left)
         self.actiongroup.get_action("PushRight").set_sensitive(push_right)
         self.actiongroup.get_action("PullLeft").set_sensitive(pull_left)
         self.actiongroup.get_action("PullRight").set_sensitive(pull_right)
         self.actiongroup.get_action("Delete").set_sensitive(delete)
+        self.actiongroup.get_action("CopyLeftUp").set_sensitive(copy_left)
+        self.actiongroup.get_action("CopyLeftDown").set_sensitive(copy_left)
+        self.actiongroup.get_action("CopyRightUp").set_sensitive(copy_right)
+        self.actiongroup.get_action("CopyRightDown").set_sensitive(copy_right)
         # FIXME: don't queue_draw() on everything... just on what changed
         self.queue_draw()
 
@@ -433,6 +447,16 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
         assert(chunk is not None)
         self.replace_chunk(src, dst, chunk)
 
+    def copy_change(self, direction, copy_direction):
+        src = self._get_focused_pane()
+        dst = src + direction
+        chunk = self.linediffer.get_chunk(self.cursor.chunk, src, dst)
+        assert(src != -1 and self.cursor.chunk is not None)
+        assert(dst in (0, 1, 2))
+        assert(chunk is not None)
+        copy_up = True if copy_direction < 0 else False
+        self.copy_chunk(src, dst, chunk, copy_up)
+
     def pull_all_non_conflicting_changes(self, direction):
         assert direction in (-1, 1)
         dst = self._get_focused_pane()



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