[meld] Added shallow directory comparison mode
- From: Kai Willadsen <kaiw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [meld] Added shallow directory comparison mode
- Date: Sat, 9 Feb 2013 22:18:41 +0000 (UTC)
commit 3bd021b412b185f281704ac7e234b5966ad1c5a9
Author: Cristian Dinu <goc9000 gmail com>
Date: Tue Feb 5 16:03:50 2013 +0100
Added shallow directory comparison mode
data/ui/preferences.ui | 125 +++++++++++++++++++++++++++++++++++++++++++++++-
meld/dirdiff.py | 30 ++++++++++--
meld/preferences.py | 31 ++++++++++++
3 files changed, 180 insertions(+), 6 deletions(-)
---
diff --git a/data/ui/preferences.ui b/data/ui/preferences.ui
index e2ee426..a06e2b7 100644
--- a/data/ui/preferences.ui
+++ b/data/ui/preferences.ui
@@ -558,6 +558,127 @@
<property name="border_width">12</property>
<property name="spacing">12</property>
<child>
+ <object class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Shallow comparison</property>
+ <property name="use_markup">True</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xpad">12</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox4">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="checkbutton_shallow_compare">
+ <property name="label" translatable="yes">Enable _shallow comparison (trust size+date)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0.51999998092651367</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_checkbutton_shallow_compare_toggled" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="timestamp_hbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Timestamp resolution:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">spinbutton_tabsize</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combo_timestamp">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <signal name="changed" handler="on_combo_timestamp_changed" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -623,7 +744,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">0</property>
+ <property name="position">1</property>
</packing>
</child>
<child>
@@ -689,7 +810,7 @@
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
</object>
diff --git a/meld/dirdiff.py b/meld/dirdiff.py
index 159fd42..412be6c 100644
--- a/meld/dirdiff.py
+++ b/meld/dirdiff.py
@@ -29,6 +29,8 @@ import time
import gtk
import gtk.keysyms
+from decimal import Decimal
+
from . import melddoc
from . import tree
from . import misc
@@ -58,6 +60,15 @@ class StatItem(namedtuple('StatItem', 'mode size time')):
return StatItem(stat.S_IFMT(stat_result.st_mode),
stat_result.st_size, stat_result.st_mtime)
+ def shallow_equal(self, other, prefs):
+ if self.size != other.size:
+ return False
+
+ mtime1 = Decimal(self.time).scaleb(9).quantize(1) // prefs.dirdiff_time_resolution_ns
+ mtime2 = Decimal(other.time).scaleb(9).quantize(1) // prefs.dirdiff_time_resolution_ns
+
+ return mtime1 == mtime2
+
CacheResult = namedtuple('CacheResult', 'stats result')
@@ -73,7 +84,7 @@ def all_same(lst):
return not lst or lst.count(lst[0]) == len(lst)
-def _files_same(files, regexes):
+def _files_same(files, regexes, prefs):
"""Determine whether a list of files are the same.
Possible results are:
@@ -104,6 +115,13 @@ def _files_same(files, regexes):
if not regexes and not all_same([s.size for s in stats]):
return Different
+ # Compare files superficially if the options tells us to
+ if prefs.dirdiff_shallow_comparison:
+ if all(s.shallow_equal(stats[0], prefs) for s in stats):
+ return DodgySame
+ else:
+ return Different
+
# Check the cache before doing the expensive comparison
cache = _cache.get((files, regexes))
if cache and cache.stats == stats:
@@ -378,6 +396,10 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
def on_preference_changed(self, key, value):
if key == "dirdiff_columns":
self.update_treeview_columns(value)
+ elif key == "dirdiff_shallow_comparison":
+ self.refresh()
+ elif key == "dirdiff_time_resolution_ns":
+ self.refresh()
def update_treeview_columns(self, columns):
"""Update the visibility and order of columns"""
@@ -1067,7 +1089,7 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
is_present = [ os.path.exists( f ) for f in curfiles ]
all_present = 0 not in is_present
if all_present:
- if _files_same(curfiles, regexes) in (Same, SameFiltered):
+ if _files_same(curfiles, regexes, self.prefs) in (Same, SameFiltered):
state = tree.STATE_NORMAL
else:
state = tree.STATE_MODIFIED
@@ -1099,7 +1121,7 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
newest_index = -1 # all same
all_present = 0 not in mod_times
if all_present:
- all_same = _files_same(files, regexes)
+ all_same = _files_same(files, regexes, self.prefs)
all_present_same = all_same
else:
lof = []
@@ -1107,7 +1129,7 @@ class DirDiff(melddoc.MeldDoc, gnomeglade.Component):
if mod_times[j]:
lof.append( files[j] )
all_same = Different
- all_present_same = _files_same(lof, regexes)
+ all_present_same = _files_same(lof, regexes, self.prefs)
different = 1
one_isdir = [None for i in range(self.model.ntree)]
for j in range(self.model.ntree):
diff --git a/meld/preferences.py b/meld/preferences.py
index e764552..28110cf 100644
--- a/meld/preferences.py
+++ b/meld/preferences.py
@@ -32,6 +32,12 @@ from .util import prefs
from .util.sourceviewer import srcviewer
+TIMESTAMP_RESOLUTION_PRESETS = [('1ns (ext4)', 1),
+ ('100ns (NTFS)', 100),
+ ('1s (ext2/ext3)', 1000000000),
+ ('2s (VFAT)', 2000000000)]
+
+
class FilterList(listwidget.ListWidget):
def __init__(self, prefs, key, filter_type):
@@ -192,6 +198,22 @@ class PreferencesDialog(gnomeglade.Component):
columnlist = ColumnList(self.prefs, "dirdiff_columns")
self.column_list_vbox.pack_start(columnlist.widget)
+ self.checkbutton_shallow_compare.set_active(self.prefs.dirdiff_shallow_comparison)
+
+ self.combo_timestamp.lock = True
+ model = gtk.ListStore(str, int)
+ active_idx = 0
+ for i, entry in enumerate(TIMESTAMP_RESOLUTION_PRESETS):
+ model.append(entry)
+ if entry[1] == self.prefs.dirdiff_time_resolution_ns:
+ active_idx = i
+ self.combo_timestamp.set_model(model)
+ cell = gtk.CellRendererText()
+ self.combo_timestamp.pack_start(cell, False)
+ self.combo_timestamp.add_attribute(cell, 'text', 0)
+ self.combo_timestamp.set_active(active_idx)
+ self.combo_timestamp.lock = False
+
self.widget.show()
def on_fontpicker_font_set(self, picker):
@@ -249,6 +271,13 @@ class PreferencesDialog(gnomeglade.Component):
# Called on "activate" and "focus-out-event"
self.prefs.text_codecs = entry.props.text
+ def on_checkbutton_shallow_compare_toggled(self, check):
+ self.prefs.dirdiff_shallow_comparison = check.get_active()
+
+ def on_combo_timestamp_changed(self, combo):
+ if not combo.lock:
+ self.prefs.dirdiff_time_resolution_ns = combo.get_model()[combo.get_active_iter()][1]
+
def on_response(self, dialog, response_id):
self.widget.destroy()
@@ -306,6 +335,8 @@ class MeldPreferences(prefs.Preferences):
"dirdiff_columns": prefs.Value(prefs.LIST,
["size 1", "modification time 1",
"permissions 0"]),
+ "dirdiff_shallow_comparison" : prefs.Value(prefs.BOOL, False),
+ "dirdiff_time_resolution_ns" : prefs.Value(prefs.INT, 100),
}
def __init__(self):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]