Re: [PATCH] auto merge actions
- From: Piotr Piastucki <leech miranda gmail com>
- To: meld-list <meld-list gnome org>
- Subject: Re: [PATCH] auto merge actions
- Date: Fri, 14 May 2010 10:52:32 +0200
Hi,
Here is a new and improved version of the patch based on Kai's comments:
- popup_in_pane() changes moved to a separate patch
- new Changes menu
- proper sensitivity setting
- fixes for formatting issues
Comments welcome.
Cheers,
Piotr
From 3e43f50e715e7f7cc66eb28a61935af599632fd5 Mon Sep 17 00:00:00 2001
From: Piotr Piastucki <leech miranda gmail com>
Date: Tue, 11 May 2010 13:13:29 +0200
Subject: [PATCH 1/2] Fix Copy All sensitivity
Sensitivity of Copy All actions should depend on editable flag
of the respective text view.
---
meld/filediff.py | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/meld/filediff.py b/meld/filediff.py
index 246e054..c5415a6 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -587,8 +587,8 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
self.findbar.hide()
def popup_in_pane(self, pane):
- self.actiongroup.get_action("CopyAllLeft").set_sensitive(pane > 0)
- self.actiongroup.get_action("CopyAllRight").set_sensitive(pane+1 < self.num_panes)
+ self.actiongroup.get_action("CopyAllLeft").set_sensitive(pane > 0 and self.textview[pane - 1].get_editable())
+ self.actiongroup.get_action("CopyAllRight").set_sensitive(pane + 1 < self.num_panes and self.textview[pane + 1].get_editable())
self.popup_menu.popup(None, None, None, 3, gtk.get_current_event_time())
def on_scrolledwindow__size_allocate(self, scrolledwindow, allocation):
--
1.7.0.4
From 8453395f05179da4d923ce0c8db1603e97eff458 Mon Sep 17 00:00:00 2001
From: Piotr Piastucki <leech miranda gmail com>
Date: Wed, 12 May 2010 11:34:38 +0200
Subject: [PATCH 2/2] Add Changes menu and new change-related actions
This commit adds a new menu called Changes and moves all existing
actions related to manipulating or navigating chunks there.
Moreover, a set of new bulk change actions is added including:
Pull all non-conflicing and Merge all non-conflicting.
---
data/ui/filediff-ui.xml | 15 ++++++++++---
data/ui/meldapp-ui.xml | 6 +----
meld/filediff.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++
meld/meldapp.py | 2 +
meld/merge.py | 45 ++++++++++++++++++++++++++++++++----------
5 files changed, 97 insertions(+), 20 deletions(-)
diff --git a/data/ui/filediff-ui.xml b/data/ui/filediff-ui.xml
index 2df3e7f..26e35a4 100644
--- a/data/ui/filediff-ui.xml
+++ b/data/ui/filediff-ui.xml
@@ -15,15 +15,22 @@
</toolbar>
<menubar name="Menubar">
- <menu action="EditMenu">
- <placeholder name="EditActionsPlaceholder">
+ <placeholder name="ChangesMenuPlaceholder">
+ <menu action="ChangesMenu">
+ <menuitem action="Down"/>
+ <menuitem action="Up"/>
+ <separator/>
<menuitem action="PushLeft"/>
<menuitem action="PushRight"/>
<menuitem action="PullLeft"/>
<menuitem action="PullRight"/>
<menuitem action="Delete"/>
- </placeholder>
- </menu>
+ <separator/>
+ <menuitem action="MergeNonConflicting"/>
+ <menuitem action="PullNonConflictingLeft"/>
+ <menuitem action="PullNonConflictingRight"/>
+ </menu>
+ </placeholder>
</menubar>
<popup name="Popup">
diff --git a/data/ui/meldapp-ui.xml b/data/ui/meldapp-ui.xml
index 28c96b6..4b1244c 100644
--- a/data/ui/meldapp-ui.xml
+++ b/data/ui/meldapp-ui.xml
@@ -16,17 +16,13 @@
<menuitem action="Copy"/>
<menuitem action="Paste"/>
<separator/>
- <placeholder name="EditActionsPlaceholder" />
- <separator/>
<menuitem action="Find"/>
<menuitem action="FindNext"/>
<menuitem action="Replace"/>
<separator/>
- <menuitem action="Down"/>
- <menuitem action="Up"/>
- <separator/>
<menuitem name="Preferences" action="Preferences"/>
</menu>
+ <placeholder name="ChangesMenuPlaceholder" />
<menu action="ViewMenu">
<menuitem action="ToolbarVisible" />
<menuitem action="StatusbarVisible" />
diff --git a/meld/filediff.py b/meld/filediff.py
index c5415a6..d058364 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -33,6 +33,7 @@ from ui import gnomeglade
import misc
import melddoc
import paths
+import merge
from util.sourceviewer import srcviewer
@@ -185,6 +186,9 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
("Delete", gtk.STOCK_DELETE, _("Delete"), "<Alt>Delete", _("Delete change"), self.delete_change),
("CopyAllLeft", gtk.STOCK_GOTO_FIRST, _("Copy To Left"), None, _("Copy all changes from right pane to left pane"), lambda x: self.copy_selected(-1)),
("CopyAllRight", gtk.STOCK_GOTO_LAST, _("Copy To Right"), None, _("Copy all changes from left pane to right pane"), lambda x: self.copy_selected(1)),
+ ("MergeNonConflicting", None, _("Merge all non-conflicting"), None, _("Merge all non-conflicting changes from left and right pane"), lambda x: self.merge_all_non_conflicting_changes()),
+ ("PullNonConflictingLeft", None, _("Pull all non-conflicting from left"), None, _("Pull all non-conflicting changes from right pane to left pane"), lambda x: self.pull_all_non_conflicting_changes(-1)),
+ ("PullNonConflictingRight", None, _("Pull all non-conflicting from right"), None, _("Pull all non-conflicting changes from left pane to right pane"), lambda x: self.pull_all_non_conflicting_changes(1)),
)
self.ui_file = paths.ui_dir("filediff-ui.xml")
@@ -305,6 +309,21 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
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)
+ editable = self.textview[pane].get_editable();
+ sensitiveleft = sensitiveright = False
+ if editable:
+ for change in self.linediffer.pair_changes(pane - 1, pane):
+ if change[0] != 'conflict':
+ sensitiveleft = True
+ break
+ for change in self.linediffer.pair_changes(pane + 1, pane):
+ if change[0] != 'conflict':
+ sensitiveright = True
+ break
+ self.actiongroup.get_action("PullNonConflictingLeft").set_sensitive(pane > 0 and sensitiveleft and editable)
+ self.actiongroup.get_action("PullNonConflictingRight").set_sensitive(pane + 1 < self.num_panes and sensitiveright and editable)
+ self.actiongroup.get_action("MergeNonConflicting").set_sensitive(self.num_panes == 3 and self.textview[1].get_editable() and (sensitiveleft or sensitiveright))
+
def push_change(self, direction):
src = self._get_focused_pane()
@@ -324,6 +343,34 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
assert(chunk is not None)
self.replace_chunk(src, dst, chunk)
+ def pull_all_non_conflicting_changes(self, direction):
+ assert direction in (-1, 1)
+ dst = self._get_focused_pane()
+ src = dst + direction
+ assert src in range(self.num_panes)
+ merger = merge.Merger()
+ merger.differ = self.linediffer
+ merger.texts = [t for t in self._get_texts(raw=1)]
+ for mergedfile in merger.merge_2_files(src, dst):
+ pass
+ self.on_textbuffer__begin_user_action()
+ self.textbuffer[dst].set_text(mergedfile)
+ self.on_textbuffer__end_user_action()
+ self.emit("current-diff-changed")
+ self.scheduler.add_task(lambda: self._sync_vscroll(self.scrolledwindow[src].get_vadjustment(), src) and None)
+
+ def merge_all_non_conflicting_changes(self):
+ merger = merge.Merger()
+ merger.differ = self.linediffer
+ merger.texts = [t for t in self._get_texts(raw=1)]
+ for mergedfile in merger.merge_3_files(False):
+ pass
+ self.on_textbuffer__begin_user_action()
+ self.textbuffer[1].set_text(mergedfile)
+ self.on_textbuffer__end_user_action()
+ self.emit("current-diff-changed")
+ self.scheduler.add_task(lambda: self._sync_vscroll(self.scrolledwindow[0].get_vadjustment(), 0) and None)
+
def delete_change(self, widget):
pane = self._get_focused_pane()
chunk = self.linediffer.get_chunk(self.cursor.chunk, pane)
@@ -365,6 +412,8 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
if not line_end.ends_line():
line_end.forward_to_line_end()
return self.buf.get_text(line_start, line_end, False)
+ def __len__(self):
+ return self.buf.get_line_count()
class FakeTextArray(object):
def __init__(self, bufs, textfilter):
diff --git a/meld/meldapp.py b/meld/meldapp.py
index 7de8ab3..968d8f2 100644
--- a/meld/meldapp.py
+++ b/meld/meldapp.py
@@ -445,6 +445,8 @@ class MeldApp(gnomeglade.Component):
("Up", gtk.STOCK_GO_UP, None, "<control>E", _("Go to the previous difference"), self.on_menu_edit_up_activate),
("Preferences", gtk.STOCK_PREFERENCES, _("Prefere_nces"), None, _("Configure the application"), self.on_menu_preferences_activate),
+ ("ChangesMenu", None, _("_Changes")),
+
("ViewMenu", None, _("_View")),
("FileStatus", None, _("File status")),
("VcStatus", None, _("Version status")),
diff --git a/meld/merge.py b/meld/merge.py
index 3333f86..6583ae1 100644
--- a/meld/merge.py
+++ b/meld/merge.py
@@ -188,7 +188,7 @@ class Merger(diffutil.Differ):
else:
return change[HI] - change[LO]
- def merge_3_files(self):
+ def merge_3_files(self, mark_conflicts = True):
LO, HI = 1, 2
self.unresolved = []
lastline = 0
@@ -208,18 +208,19 @@ class Merger(diffutil.Differ):
lastline = low_mark
if change[0] != None and change[1] != None and change[0][0] == 'conflict':
high_mark = max(change[0][HI], change[1][HI])
- if low_mark < high_mark:
- for i in range(low_mark, high_mark):
- mergedtext.append("(??)" + self.texts[1][i])
+ if mark_conflicts:
+ if low_mark < high_mark:
+ for i in range(low_mark, high_mark):
+ mergedtext.append("(??)" + self.texts[1][i])
+ self.unresolved.append(mergedline)
+ mergedline += 1
+ else:
+ #conflictsize = min(1, max(change[0][HI + 2] - change[0][LO + 2], change[1][HI + 2] - change[1][LO + 2]))
+ #for i in range(conflictsize):
+ mergedtext.append("(??)")
self.unresolved.append(mergedline)
mergedline += 1
- else:
- #conflictsize = min(1, max(change[0][HI + 2] - change[0][LO + 2], change[1][HI + 2] - change[1][LO + 2]))
- #for i in range(conflictsize):
- mergedtext.append("(??)")
- self.unresolved.append(mergedline)
- mergedline += 1
- lastline = high_mark
+ lastline = high_mark
elif change[0] != None:
lastline += self._apply_change(self.texts[0], change[0], mergedtext)
mergedline += change[0][HI + 2] - change[0][LO + 2]
@@ -231,3 +232,25 @@ class Merger(diffutil.Differ):
mergedtext.append(self.texts[1][i])
yield "\n".join(mergedtext)
+
+ def merge_2_files(self, fromindex, toindex):
+ LO, HI = 1, 2
+ self.unresolved = []
+ lastline = 0
+ mergedtext = []
+ for change in self.differ.pair_changes(toindex, fromindex):
+ yield None
+ if change[0] == 'conflict':
+ low_mark = change[HI]
+ else:
+ low_mark = change[LO]
+ for i in range(lastline, low_mark, 1):
+ mergedtext.append(self.texts[toindex][i])
+ lastline = low_mark
+ if change[0] != 'conflict':
+ lastline += self._apply_change(self.texts[fromindex], change, mergedtext)
+ baselen = len(self.texts[toindex])
+ for i in range(lastline, baselen, 1):
+ mergedtext.append(self.texts[toindex][i])
+
+ yield "\n".join(mergedtext)
--
1.7.0.4
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]