[meld/VersionControlRework: 91/123] vc: Move path state sensitivity checking to _vc and improve the API



commit 711690879daec820261bb312f358eaa75e560910
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Sat Apr 11 09:27:54 2015 +1000

    vc: Move path state sensitivity checking to _vc and improve the API
    
    This commit also makes subversion and mercurial use the new
    sensitivity logic. Hopefully the logic is generic enough that this
    won't be a problem.

 meld/vc/_vc.py |   33 +++++++++++++++++++++++++++++++++
 meld/vc/bzr.py |   27 ---------------------------
 meld/vc/git.py |   28 ----------------------------
 meld/vcview.py |   24 +++++++++++++-----------
 4 files changed, 46 insertions(+), 66 deletions(-)
---
diff --git a/meld/vc/_vc.py b/meld/vc/_vc.py
index 1d10573..7e78987 100644
--- a/meld/vc/_vc.py
+++ b/meld/vc/_vc.py
@@ -165,6 +165,39 @@ class Vc(object):
     def resolve(self, runner, files):
         raise NotImplementedError()
 
+    def get_valid_actions(self, path_states):
+        """Get the set of valid actions for paths with version states
+
+        path_states is a list of (path, state) tuples describing paths
+        in the version control system. This will return all valid
+        version control actions that could reasonably be taken on *all*
+        of the paths in path_states.
+        """
+        valid_actions = set()
+        states = path_states.values()
+
+        if bool(path_states):
+            valid_actions.add('compare')
+        valid_actions.add('update')
+        # TODO: We can't do this; this shells out for each selection change...
+        # if bool(self.get_commits_to_push()):
+        valid_actions.add('push')
+        # TODO: We can't disable this for NORMAL, because folders don't
+        # inherit any state from their children, but committing a folder with
+        # modified children is expected behaviour.
+        if all(s not in (STATE_NONE, STATE_IGNORED) for s in states):
+            valid_actions.add('commit')
+        if all(s not in (STATE_NORMAL, STATE_REMOVED) for s in states):
+            valid_actions.add('add')
+        if all(s == STATE_CONFLICT for s in states):
+            valid_actions.add('resolve')
+        if (all(s not in (STATE_NONE, STATE_IGNORED, STATE_REMOVED) for s in states)
+                and self.root not in path_states.keys()):
+            valid_actions.add('remove')
+        if all(s not in (STATE_NONE, STATE_NORMAL, STATE_IGNORED) for s in states):
+            valid_actions.add('revert')
+        return valid_actions
+
     def get_path_for_repo_file(self, path, commit=None):
         """Returns a file path for the repository path at commit
 
diff --git a/meld/vc/bzr.py b/meld/vc/bzr.py
index 9b092c0..ef71432 100644
--- a/meld/vc/bzr.py
+++ b/meld/vc/bzr.py
@@ -252,30 +252,3 @@ class Vc(_vc.Vc):
 
         # bzr paths are all temporary files
         return "%s%s" % (path, self.conflict_map[conflict]), False
-
-    # Sensitivity button mappings.
-    def update_actions_for_paths(self, path_states, actions):
-        states = path_states.values()
-
-        actions["VcCompare"] = bool(path_states)
-        # TODO: We can't disable this for NORMAL, because folders don't
-        # inherit any state from their children, but committing a folder with
-        # modified children is expected behaviour.
-        actions["VcCommit"] = all(s not in (
-            _vc.STATE_NONE, _vc.STATE_IGNORED) for s in states)
-
-        actions["VcUpdate"] = True
-        # TODO: We can't do this; this shells out for each selection change...
-        # actions["VcPush"] = bool(self.get_commits_to_push())
-        actions["VcPush"] = True
-
-        actions["VcAdd"] = all(s not in (
-            _vc.STATE_NORMAL, _vc.STATE_REMOVED) for s in states)
-        actions["VcResolved"] = all(s == _vc.STATE_CONFLICT for s in states)
-        actions["VcRemove"] = (all(s not in (
-            _vc.STATE_NONE, _vc.STATE_IGNORED,
-            _vc.STATE_REMOVED) for s in states) and
-            self.root not in path_states.keys())
-        actions["VcRevert"] = all(s not in (
-            _vc.STATE_NONE, _vc.STATE_NORMAL,
-            _vc.STATE_IGNORED) for s in states)
diff --git a/meld/vc/git.py b/meld/vc/git.py
index 7db8815..b8e6856 100644
--- a/meld/vc/git.py
+++ b/meld/vc/git.py
@@ -80,34 +80,6 @@ class Vc(_vc.Vc):
         # Check exists instead of isdir, since .git might be a git-file
         return os.path.exists(os.path.join(location, self.VC_DIR))
 
-    # Prototyping VC interface version 2
-
-    def update_actions_for_paths(self, path_states, actions):
-        states = path_states.values()
-
-        actions["VcCompare"] = bool(path_states)
-        # TODO: We can't disable this for NORMAL, because folders don't
-        # inherit any state from their children, but committing a folder with
-        # modified children is expected behaviour.
-        actions["VcCommit"] = all(s not in (
-            _vc.STATE_NONE, _vc.STATE_IGNORED) for s in states)
-
-        actions["VcUpdate"] = True
-        # TODO: We can't do this; this shells out for each selection change...
-        # actions["VcPush"] = bool(self.get_commits_to_push())
-        actions["VcPush"] = True
-
-        actions["VcAdd"] = all(s not in (
-            _vc.STATE_NORMAL, _vc.STATE_REMOVED) for s in states)
-        actions["VcResolved"] = all(s == _vc.STATE_CONFLICT for s in states)
-        actions["VcRemove"] = (all(s not in (
-            _vc.STATE_NONE, _vc.STATE_IGNORED,
-            _vc.STATE_REMOVED) for s in states) and
-            self.root not in path_states.keys())
-        actions["VcRevert"] = all(s not in (
-            _vc.STATE_NONE, _vc.STATE_NORMAL,
-            _vc.STATE_IGNORED) for s in states)
-
     def get_commits_to_push_summary(self):
         branch_refs = self.get_commits_to_push()
         unpushed_branches = len([v for v in branch_refs.values() if v])
diff --git a/meld/vcview.py b/meld/vcview.py
index cf9fa35..9be2db6 100644
--- a/meld/vcview.py
+++ b/meld/vcview.py
@@ -567,22 +567,23 @@ class VcView(melddoc.MeldDoc, gnomeglade.Component):
         if selection is None:
             selection = self.treeview.get_selection()
         model, rows = selection.get_selected_rows()
-        if hasattr(self.vc, 'update_actions_for_paths'):
+
+        if hasattr(self.vc, 'get_valid_actions'):
             paths = [self.model.value_path(model.get_iter(r), 0) for r in rows]
             states = [self.model.get_state(model.get_iter(r), 0) for r in rows]
+            path_states = dict(zip(paths, states))
+            valid_actions = self.vc.get_valid_actions(path_states)
             action_sensitivity = {
-                "VcCompare": False,
-                "VcCommit": False,
-                "VcUpdate": False,
-                "VcPush": False,
-                "VcAdd": False,
-                "VcResolved": False,
-                "VcRemove": False,
-                "VcRevert": False,
+                "VcCompare": 'compare' in valid_actions,
+                "VcCommit": 'commit' in valid_actions,
+                "VcUpdate": 'update' in valid_actions,
+                "VcPush": 'push' in valid_actions,
+                "VcAdd": 'add' in valid_actions,
+                "VcResolved": 'resolve' in valid_actions,
+                "VcRemove": 'remove' in valid_actions,
+                "VcRevert": 'revert' in valid_actions,
                 "VcDeleteLocally": bool(paths) and self.vc.root not in paths,
             }
-            path_states = dict(zip(paths, states))
-            self.vc.update_actions_for_paths(path_states, action_sensitivity)
             for action, sensitivity in action_sensitivity.items():
                 set_sensitive(action, sensitivity)
         else:
@@ -649,6 +650,7 @@ class VcView(melddoc.MeldDoc, gnomeglade.Component):
         # at this point. We're using whether a plugin has been updated to the
         # new API as a proxy for understanding these commands, since right now
         # that happens to work... this is bad.
+        # FIXME: This is now even more broken than it was already
         uses_new_api = hasattr(self.vc, 'update_actions_for_paths')
         return uses_new_api and command in self.command_map
 


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