[Xfce4-commits] <thunar-vcs-plugin:master> * tvp-svn-helper/tsh-commit.c tvp-svn-helper/tsh-file-selection-dialog.[ch]: Better file Selector. Using recursion info in file selection and commit command to be able to commit directory deletion. * tvp-svn-helper/tsh-delete.c: Removed TSH_FILE_SELECTION_FLAG_MODIFIED flag. * tvp-svn-helper/tsh-revert.c: Added TSH_FILE_SELECTION_FLAG_REVERSE_DISABLE_CHILDREN flag.

Peter de Ridder peter at xfce.org
Sun Aug 30 13:52:02 CEST 2009


Updating branch refs/heads/master
         to 6962231135b468c9735e9decb32c9ff1be35340d (commit)
       from 861ecd7dbcf1aca9616e0a14d0f2bd66a7ca9c4c (commit)

commit 6962231135b468c9735e9decb32c9ff1be35340d
Author: Peter de Ridder <peter at xfce.org>
Date:   Thu Aug 27 22:37:36 2009 +0200

    * tvp-svn-helper/tsh-commit.c
      tvp-svn-helper/tsh-file-selection-dialog.[ch]: Better file Selector.
      Using recursion info in file selection and commit command to be able
      to commit directory deletion.
    * tvp-svn-helper/tsh-delete.c: Removed TSH_FILE_SELECTION_FLAG_MODIFIED
      flag.
    * tvp-svn-helper/tsh-revert.c: Added
      TSH_FILE_SELECTION_FLAG_REVERSE_DISABLE_CHILDREN flag.

 tvp-svn-helper/tsh-commit.c                |   98 +++++++--
 tvp-svn-helper/tsh-delete.c                |    2 +-
 tvp-svn-helper/tsh-file-selection-dialog.c |  348 +++++++++++++++++++++++-----
 tvp-svn-helper/tsh-file-selection-dialog.h |   18 +-
 tvp-svn-helper/tsh-revert.c                |    8 +-
 5 files changed, 390 insertions(+), 84 deletions(-)

diff --git a/tvp-svn-helper/tsh-commit.c b/tvp-svn-helper/tsh-commit.c
index 6a28913..1ae2032 100644
--- a/tvp-svn-helper/tsh-commit.c
+++ b/tvp-svn-helper/tsh-commit.c
@@ -57,40 +57,84 @@ static gpointer commit_thread (gpointer user_data)
   TshNotifyDialog *dialog = args->dialog;
   GSList *files = args->files;
   GSList *iter;
-  gint size;
+  GSList *delete = NULL;
+  //GSList *reverse_start = NULL, *reverse_end = NULL;
+  gint delete_size = 0;
+  gint size = 0;
+  gint size_indirect = 0;
+  gboolean recursive = TRUE;
   gchar *error_str;
   gchar *message;
   gchar buffer[256];
 
   g_free (args);
 
-  size = 0;
-
   subpool = svn_pool_create (pool);
 
-  for (iter = files; iter; iter = g_slist_next (iter))
+  for (iter = files; result && iter; iter = g_slist_next (iter))
   {
     TshFileInfo *info;
-    size++;
+    size_indirect++;
 
     info = iter->data;
-    if (info->status == TSH_FILE_STATUS_UNVERSIONED && !(info->flags&TSH_FILE_INFO_INDIRECT))
+
+    if (!(info->flags & TSH_FILE_INFO_INDIRECT))
     {
-      if ((err = svn_client_add4(info->path, (info->flags&TSH_FILE_INFO_RECURSIVE)?svn_depth_infinity:svn_depth_empty, FALSE, FALSE, FALSE, ctx, subpool)))
+      if (!(info->flags & TSH_FILE_INFO_RECURSIVE))
+        recursive = FALSE;
+      size++;
+      switch (info->status)
       {
-        error_str = tsh_strerror(err);
-        gdk_threads_enter();
-        tsh_notify_dialog_add(dialog, _("Failed"), error_str, NULL);
-        gdk_threads_leave();
-        g_free(error_str);
-
-        svn_error_clear(err);
-        result = FALSE;
-        break;//FIXME: needed ??
+        case TSH_FILE_STATUS_MISSING:
+          delete_size++;
+          delete = g_slist_prepend (delete, info);
+          break;
+        case TSH_FILE_STATUS_UNVERSIONED:
+          if ((err = svn_client_add4(info->path, (info->flags&TSH_FILE_INFO_RECURSIVE)?svn_depth_infinity:svn_depth_empty, FALSE, FALSE, FALSE, ctx, subpool)))
+          {
+            error_str = tsh_strerror(err);
+            gdk_threads_enter();
+            tsh_notify_dialog_add(dialog, _("Failed"), error_str, NULL);
+            gdk_threads_leave();
+            g_free(error_str);
+
+            svn_error_clear(err);
+            result = FALSE;//FIXME: needed ??
+          }
+          break;
+        default:
+          break;
       }
     }
   }
 
+  if (result && delete_size)
+  {
+    paths = apr_array_make (subpool, delete_size, sizeof (const char *));
+
+    for (iter = delete; iter; iter = g_slist_next (iter))
+    {
+      TshFileInfo *info = iter->data;
+      APR_ARRAY_PUSH (paths, const char *) = info->path;
+    }
+
+    if ((err = svn_client_delete3(NULL, paths, FALSE, FALSE, NULL, ctx, subpool)))
+    {
+      svn_pool_destroy (subpool);
+
+      error_str = tsh_strerror(err);
+      gdk_threads_enter();
+      tsh_notify_dialog_add(dialog, _("Failed"), error_str, NULL);
+      gdk_threads_leave();
+      g_free(error_str);
+
+      svn_error_clear(err);
+      result = FALSE;//FIXME: needed ??
+    }
+  }
+
+  g_slist_free (delete);
+
   svn_pool_destroy (subpool);
 
   /* check if an error occurred in add commands */
@@ -98,13 +142,29 @@ static gpointer commit_thread (gpointer user_data)
   {
     subpool = svn_pool_create (pool);
 
-    if(size)
+    if(recursive && size)
     {
       paths = apr_array_make (subpool, size, sizeof (const char *));
 
       for (iter = files; iter; iter = g_slist_next (iter))
       {
         TshFileInfo *info = iter->data;
+        if (!(info->flags & TSH_FILE_INFO_INDIRECT))
+        {
+          APR_ARRAY_PUSH (paths, const char *) = info->path;
+        }
+      }
+    }
+    else if(size_indirect)
+    {
+      /* Set recursive to false if it wasn't already, FIXME: needed?? */
+      recursive = FALSE;
+
+      paths = apr_array_make (subpool, size_indirect, sizeof (const char *));
+
+      for (iter = files; iter; iter = g_slist_next (iter))
+      {
+        TshFileInfo *info = iter->data;
         APR_ARRAY_PUSH (paths, const char *) = info->path;
       }
     }
@@ -115,7 +175,7 @@ static gpointer commit_thread (gpointer user_data)
       APR_ARRAY_PUSH (paths, const char *) = ""; // current directory
     }
 
-    if ((err = svn_client_commit4(&commit_info, paths, svn_depth_empty, FALSE, FALSE, NULL, NULL, ctx, subpool)))
+    if ((err = svn_client_commit4(&commit_info, paths, recursive?svn_depth_infinity:svn_depth_empty, FALSE, FALSE, NULL, NULL, ctx, subpool)))
     {
       svn_pool_destroy (subpool);
 
@@ -167,7 +227,7 @@ GThread *tsh_commit (gchar **files, svn_client_ctx_t *ctx, apr_pool_t *pool)
     return NULL;
   }
   g_strfreev (files);
-  file_list = tsh_file_selection_dialog_get_file_info (TSH_FILE_SELECTION_DIALOG (dialog));
+  file_list = tsh_file_selection_dialog_get_file_info_by_status (TSH_FILE_SELECTION_DIALOG (dialog), TSH_FILE_STATUS_INVALID, TRUE);
   gtk_widget_destroy (dialog);
 
   if(!file_list)
diff --git a/tvp-svn-helper/tsh-delete.c b/tvp-svn-helper/tsh-delete.c
index 9c4e73c..00ac41b 100644
--- a/tvp-svn-helper/tsh-delete.c
+++ b/tvp-svn-helper/tsh-delete.c
@@ -124,7 +124,7 @@ GThread *tsh_delete (gchar **files, svn_client_ctx_t *ctx, apr_pool_t *pool)
 	GtkWidget *dialog;
 	struct thread_args *args;
 
-  dialog = tsh_file_selection_dialog_new (_("Delete"), NULL, 0, files, TSH_FILE_SELECTION_FLAG_RECURSIVE|TSH_FILE_SELECTION_FLAG_MODIFIED|TSH_FILE_SELECTION_FLAG_UNCHANGED, ctx, pool);
+  dialog = tsh_file_selection_dialog_new (_("Delete"), NULL, 0, files, TSH_FILE_SELECTION_FLAG_RECURSIVE|TSH_FILE_SELECTION_FLAG_UNCHANGED, ctx, pool);
 	if(gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
   {
     gtk_widget_destroy (dialog);
diff --git a/tvp-svn-helper/tsh-file-selection-dialog.c b/tvp-svn-helper/tsh-file-selection-dialog.c
index f2c9e1b..454b6c7 100644
--- a/tvp-svn-helper/tsh-file-selection-dialog.c
+++ b/tvp-svn-helper/tsh-file-selection-dialog.c
@@ -36,7 +36,8 @@ static svn_error_t *tsh_file_selection_status_func3 (void *, const char *, svn_w
 static void selection_cell_toggled (GtkCellRendererToggle *, gchar *, gpointer);
 static void selection_all_toggled (GtkToggleButton *, gpointer);
 
-struct copy_context { union { gchar **string; GSList *linked; guint count; } list; TshFileStatus status; };
+struct select_context { TshFileSelectionDialog *dialog; gboolean select; };
+struct copy_context { union { gchar **string; GSList *linked; guint count; } list; TshFileStatus status; gboolean indirect; };
 static gboolean count_selected (GtkTreeModel*, GtkTreePath*, GtkTreeIter*, gpointer);
 static gboolean copy_selected_string (GtkTreeModel*, GtkTreePath*, GtkTreeIter*, gpointer);
 static gboolean copy_selected_linked (GtkTreeModel*, GtkTreePath*, GtkTreeIter*, gpointer);
@@ -44,7 +45,8 @@ static gboolean set_selected (GtkTreeModel*, GtkTreePath*, GtkTreeIter*, gpointe
 static void move_info (GtkTreeStore*, GtkTreeIter*, GtkTreeIter*);
 
 static void add_unversioned (GtkTreeStore*, const gchar*, gboolean, gboolean);
-static void set_children_status (GtkTreeStore*, GtkTreeIter*, gboolean, gboolean);
+static void set_children_status_unversioned (GtkTreeStore*, GtkTreeIter*, gboolean, gboolean);
+static void set_children_status (TshFileSelectionDialog *, GtkTreeStore*, GtkTreeIter*, gboolean, gboolean);
 
 struct _TshFileSelectionDialog
 {
@@ -229,11 +231,11 @@ tsh_file_selection_dialog_new (const gchar *title, GtkWindow *parent, GtkDialogF
 gchar**
 tsh_file_selection_dialog_get_files (TshFileSelectionDialog *dialog)
 {
-  return tsh_file_selection_dialog_get_files_by_status (dialog, TSH_FILE_STATUS_OTHER);
+  return tsh_file_selection_dialog_get_files_by_status (dialog, TSH_FILE_STATUS_INVALID, FALSE);
 }
 
 gchar**
-tsh_file_selection_dialog_get_files_by_status (TshFileSelectionDialog *dialog, TshFileStatus status)
+tsh_file_selection_dialog_get_files_by_status (TshFileSelectionDialog *dialog, TshFileStatus status, gboolean indirect)
 {
   GtkTreeModel *model;
   gchar **files;
@@ -242,6 +244,7 @@ tsh_file_selection_dialog_get_files_by_status (TshFileSelectionDialog *dialog, T
   g_return_val_if_fail (TSH_IS_FILE_SELECTION_DIALOG (dialog), NULL);
 
   ctx.status = status;
+  ctx.indirect = indirect;
 
   model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->tree_view));
 
@@ -263,11 +266,11 @@ tsh_file_selection_dialog_get_files_by_status (TshFileSelectionDialog *dialog, T
 GSList*
 tsh_file_selection_dialog_get_file_info (TshFileSelectionDialog *dialog)
 {
-  return tsh_file_selection_dialog_get_file_info_by_status (dialog, TSH_FILE_STATUS_OTHER);
+  return tsh_file_selection_dialog_get_file_info_by_status (dialog, TSH_FILE_STATUS_INVALID, FALSE);
 }
 
 GSList*
-tsh_file_selection_dialog_get_file_info_by_status (TshFileSelectionDialog *dialog, TshFileStatus status)
+tsh_file_selection_dialog_get_file_info_by_status (TshFileSelectionDialog *dialog, TshFileStatus status, gboolean indirect)
 {
   GtkTreeModel *model;
   struct copy_context ctx;
@@ -275,6 +278,7 @@ tsh_file_selection_dialog_get_file_info_by_status (TshFileSelectionDialog *dialo
   g_return_val_if_fail (TSH_IS_FILE_SELECTION_DIALOG (dialog), NULL);
 
   ctx.status = status;
+  ctx.indirect = indirect;
 
   model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->tree_view));
 
@@ -285,41 +289,139 @@ tsh_file_selection_dialog_get_file_info_by_status (TshFileSelectionDialog *dialo
   return g_slist_reverse (ctx.list.linked);
 }
 
+static TshFileStatus
+get_parent_status(GtkTreeModel *model, GtkTreeIter *iter)
+{
+  GtkTreeIter parent, child;
+  TshFileStatus status = TSH_FILE_STATUS_INVALID;
+
+  child = *iter;
+
+  while (gtk_tree_model_iter_parent (model, &parent, &child))
+  {
+    gint parent_status;
+    gtk_tree_model_get (model, &parent, COLUMN_STATUS, &parent_status, -1);
+
+    if (parent_status != TSH_FILE_STATUS_INVALID)
+    {
+      status = parent_status;
+      break;
+    }
+  }
+
+  return status;
+}
+
 static void
 tsh_file_selection_status_func2(void *baton, const char *path, svn_wc_status2_t *status)
 {
-	TshFileSelectionDialog *dialog = TSH_FILE_SELECTION_DIALOG (baton);
+  TshFileSelectionDialog *dialog = TSH_FILE_SELECTION_DIALOG (baton);
   gboolean add = FALSE;
 
-  if (dialog->flags & (status->entry?(TSH_FILE_SELECTION_FLAG_MODIFIED|TSH_FILE_SELECTION_FLAG_UNCHANGED|TSH_FILE_SELECTION_FLAG_IGNORED):TSH_FILE_SELECTION_FLAG_UNVERSIONED))
-    add = TRUE;
+  if (status->entry)
+  {
+    if (dialog->flags & TSH_FILE_SELECTION_FLAG_CONFLICTED)
+      if (status->text_status == svn_wc_status_conflicted || status->prop_status == svn_wc_status_conflicted)
+        add = TRUE;
+
+    if (dialog->flags & TSH_FILE_SELECTION_FLAG_UNCHANGED)
+      if (status->text_status == svn_wc_status_normal && (status->prop_status == svn_wc_status_normal || status->prop_status == svn_wc_status_none))
+        add = TRUE;
 
-  if (dialog->flags & TSH_FILE_SELECTION_FLAG_CONFLICTED)
-    if(status->text_status == svn_wc_status_conflicted || status->prop_status == svn_wc_status_conflicted)
+    if (dialog->flags & (TSH_FILE_SELECTION_FLAG_MODIFIED|TSH_FILE_SELECTION_FLAG_IGNORED))
       add = TRUE;
 
+  }
+  else if (dialog->flags & TSH_FILE_SELECTION_FLAG_UNVERSIONED)
+    add = TRUE;
+
   if (add)
   {
     GtkTreeModel *model;
     GtkTreeIter iter;
+    gboolean select = TRUE;
+    gboolean enable = TRUE;
+    gint file_status = TSH_FILE_STATUS_OTHER;
+    TshFileStatus parent_status;
+
+    if (G_LIKELY (status->entry))
+    {
+      if (status->text_status == svn_wc_status_added)
+      {
+        file_status = TSH_FILE_STATUS_ADDED;
+      }
+      else if (status->text_status == svn_wc_status_deleted)
+      {
+        file_status = TSH_FILE_STATUS_DELETED;
+      }
+      else if (status->text_status == svn_wc_status_missing)
+      {
+        file_status = TSH_FILE_STATUS_MISSING;
+        if (dialog->flags & TSH_FILE_SELECTION_FLAG_REVERSE_DISABLE_CHILDREN)
+          enable = FALSE;
+        else if (!(dialog->flags & TSH_FILE_SELECTION_FLAG_AUTO_SELECT_MISSING))
+          select = FALSE;
+      }
+    }
+    else
+    {
+      file_status = TSH_FILE_STATUS_UNVERSIONED;
+      if (!(dialog->flags & TSH_FILE_SELECTION_FLAG_AUTO_SELECT_UNVERSIONED))
+        select = FALSE;
+    }
 
     model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->tree_view));
 
     tsh_tree_get_iter_for_path (GTK_TREE_STORE (model), path, &iter, COLUMN_NAME, move_info);
+
+    parent_status = get_parent_status (model, &iter);
+
+    if (status->text_status == svn_wc_status_normal && (status->prop_status == svn_wc_status_normal || status->prop_status == svn_wc_status_none))
+    {
+      file_status = TSH_FILE_STATUS_UNCHANGED;
+      if (parent_status == TSH_FILE_STATUS_UNCHANGED)
+        enable = FALSE;
+    }
+    else if (status->entry && status->text_status != svn_wc_status_missing)
+    {
+      if (parent_status != TSH_FILE_STATUS_INVALID)
+        enable = FALSE;
+    }
+
     gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
                         COLUMN_PATH, path,
                         COLUMN_TEXT_STAT, tsh_status_to_string(status->text_status),
                         COLUMN_PROP_STAT, tsh_status_to_string(status->prop_status),
-                        COLUMN_SELECTION, (status->entry || dialog->flags & TSH_FILE_SELECTION_FLAG_AUTO_SELECT_UNVERSIONED),
+                        COLUMN_SELECTION, select,
                         COLUMN_NON_RECURSIVE, FALSE,
-                        COLUMN_ENABLED, TRUE,
-                        COLUMN_STATUS, status->entry?TSH_FILE_STATUS_OTHER:TSH_FILE_STATUS_UNVERSIONED,
+                        COLUMN_ENABLED, enable,
+                        COLUMN_STATUS, file_status,
                         -1);
 
-    if (!status->entry)
+    switch (file_status)
     {
-      /* Unversioned: get all children */
-      add_unversioned (GTK_TREE_STORE (model), path, dialog->flags & TSH_FILE_SELECTION_FLAG_AUTO_SELECT_UNVERSIONED, FALSE);
+      case TSH_FILE_STATUS_UNCHANGED:
+        set_children_status (dialog, GTK_TREE_STORE (model), &iter, select, !select);
+        break;
+      case TSH_FILE_STATUS_ADDED:
+        if (dialog->flags & TSH_FILE_SELECTION_FLAG_REVERSE_DISABLE_CHILDREN)
+          set_children_status (dialog, GTK_TREE_STORE (model), &iter, select, !select);
+        else
+          set_children_status (dialog, GTK_TREE_STORE (model), &iter, select, FALSE);
+        break;
+      case TSH_FILE_STATUS_DELETED:
+        if (dialog->flags & TSH_FILE_SELECTION_FLAG_REVERSE_DISABLE_CHILDREN)
+          set_children_status (dialog, GTK_TREE_STORE (model), &iter, select, FALSE);
+        else
+          set_children_status (dialog, GTK_TREE_STORE (model), &iter, select, !select);
+        break;
+      case TSH_FILE_STATUS_UNVERSIONED:
+        /* Unversioned: get all children */
+        add_unversioned (GTK_TREE_STORE (model), path, select, FALSE);
+        break;
+      default:
+        set_children_status (dialog, GTK_TREE_STORE (model), &iter, select, !select);
+        break;
     }
   }
 }
@@ -334,7 +436,7 @@ tsh_file_selection_status_func3(void *baton, const char *path, svn_wc_status2_t
 static void
 selection_cell_toggled (GtkCellRendererToggle *renderer, gchar *path, gpointer user_data)
 {
-	TshFileSelectionDialog *dialog = TSH_FILE_SELECTION_DIALOG (user_data);
+  TshFileSelectionDialog *dialog = TSH_FILE_SELECTION_DIALOG (user_data);
   GtkTreeModel *model;
   GtkTreeIter iter;
   gboolean selection, non_recursive;
@@ -351,7 +453,13 @@ selection_cell_toggled (GtkCellRendererToggle *renderer, gchar *path, gpointer u
                       -1);
   switch (status)
   {
-    case TSH_FILE_STATUS_UNVERSIONED:
+    case TSH_FILE_STATUS_DELETED:
+      if (!(dialog->flags & TSH_FILE_SELECTION_FLAG_REVERSE_DISABLE_CHILDREN))
+      {
+        selection = !selection;
+        break;
+      }
+    default:
       if (gtk_tree_model_iter_has_child (model, &iter))
       {
 #if 0   /* 4 states, not selected -> non recursive (no children selected) -> selected -> non recursive (children selected) */
@@ -375,17 +483,42 @@ selection_cell_toggled (GtkCellRendererToggle *renderer, gchar *path, gpointer u
 #endif
         break;
       }
-    default:
+    case TSH_FILE_STATUS_UNCHANGED:
       selection = !selection;
       break;
   }
+
   gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
                       COLUMN_SELECTION, selection,
                       COLUMN_NON_RECURSIVE, non_recursive,
                       -1);
-  if (status == TSH_FILE_STATUS_UNVERSIONED)
+  switch (status)
   {
-    set_children_status (GTK_TREE_STORE (model), &iter, selection, non_recursive);
+    case TSH_FILE_STATUS_UNCHANGED:
+      set_children_status (dialog, GTK_TREE_STORE (model), &iter, selection, !selection);
+      break;
+    case TSH_FILE_STATUS_ADDED:
+      if (dialog->flags & TSH_FILE_SELECTION_FLAG_REVERSE_DISABLE_CHILDREN)
+        set_children_status (dialog, GTK_TREE_STORE (model), &iter, selection, !selection);
+      else
+        set_children_status (dialog, GTK_TREE_STORE (model), &iter, selection, non_recursive);
+      break;
+    case TSH_FILE_STATUS_DELETED:
+      if (dialog->flags & TSH_FILE_SELECTION_FLAG_REVERSE_DISABLE_CHILDREN)
+      {
+        if(selection)
+          set_children_status (dialog, GTK_TREE_STORE (model), &iter, selection, non_recursive);
+      }
+      else
+        set_children_status (dialog, GTK_TREE_STORE (model), &iter, selection, !selection);
+      break;
+    case TSH_FILE_STATUS_UNVERSIONED:
+      set_children_status_unversioned (GTK_TREE_STORE (model), &iter, selection, non_recursive);
+      break;
+    default:
+      if(selection)
+        set_children_status (dialog, GTK_TREE_STORE (model), &iter, selection, non_recursive);
+      break;
   }
 
   gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (dialog->all), TRUE);
@@ -394,29 +527,32 @@ selection_cell_toggled (GtkCellRendererToggle *renderer, gchar *path, gpointer u
 static void
 selection_all_toggled (GtkToggleButton *button, gpointer user_data)
 {
-	TshFileSelectionDialog *dialog = TSH_FILE_SELECTION_DIALOG (user_data);
+  TshFileSelectionDialog *dialog = TSH_FILE_SELECTION_DIALOG (user_data);
   GtkTreeModel *model;
-  gboolean selection;
+  struct select_context ctx;
+  
+  ctx.dialog = dialog;
 
   gtk_toggle_button_set_inconsistent (button, FALSE);
-  
-  selection = gtk_toggle_button_get_active (button);
+
+  ctx.select = gtk_toggle_button_get_active (button);
 
   model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->tree_view));
 
-  gtk_tree_model_foreach (model, set_selected, GINT_TO_POINTER (selection));
+  gtk_tree_model_foreach (model, set_selected, &ctx);
 }
 
 static gboolean
 count_selected (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer ctx)
 {
-  gboolean selection;
+  gboolean selection, enabled;
   gint status;
   gtk_tree_model_get (model, iter,
                       COLUMN_SELECTION, &selection,
                       COLUMN_STATUS, &status,
+                      COLUMN_ENABLED, &enabled,
                       -1);
-  if (selection && (((struct copy_context*)ctx)->status == TSH_FILE_STATUS_OTHER || ((struct copy_context*)ctx)->status == status))
+  if (selection && (((struct copy_context*)ctx)->status == TSH_FILE_STATUS_INVALID || ((struct copy_context*)ctx)->status == status) && (enabled || ((struct copy_context*)ctx)->indirect))
     ((struct copy_context*)ctx)->list.count++;
   return FALSE;
 }
@@ -424,13 +560,14 @@ count_selected (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpoin
 static gboolean
 copy_selected_string (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer ctx)
 {
-  gboolean selection;
+  gboolean selection, enabled;
   gint status;
   gtk_tree_model_get (model, iter,
                       COLUMN_SELECTION, &selection,
                       COLUMN_STATUS, &status,
+                      COLUMN_ENABLED, &enabled,
                       -1);
-  if (selection && (((struct copy_context*)ctx)->status == TSH_FILE_STATUS_OTHER || ((struct copy_context*)ctx)->status == status))
+  if (selection && (((struct copy_context*)ctx)->status == TSH_FILE_STATUS_INVALID || ((struct copy_context*)ctx)->status == status) && (enabled || ((struct copy_context*)ctx)->indirect))
   {
     gtk_tree_model_get (model, iter,
                         COLUMN_PATH, ((struct copy_context*)ctx)->list.string,
@@ -443,23 +580,21 @@ copy_selected_string (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
 static gboolean
 copy_selected_linked (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer ctx)
 {
-  gboolean selection;
+  gboolean selection, enabled;
   gint status;
   gtk_tree_model_get (model, iter,
                       COLUMN_SELECTION, &selection,
                       COLUMN_STATUS, &status,
+                      COLUMN_ENABLED, &enabled,
                       -1);
-  if (selection && (((struct copy_context*)ctx)->status == TSH_FILE_STATUS_OTHER || ((struct copy_context*)ctx)->status == status))
+  if (selection && (((struct copy_context*)ctx)->status == TSH_FILE_STATUS_INVALID || ((struct copy_context*)ctx)->status == status) && (enabled || ((struct copy_context*)ctx)->indirect))
   {
-    gboolean non_recursive, enabled;
+    gboolean non_recursive;
     TshFileInfo *info = g_new (TshFileInfo, 1);
     gtk_tree_model_get (model, iter,
                         COLUMN_PATH, &info->path,
                         COLUMN_NON_RECURSIVE, &non_recursive,
-                        COLUMN_ENABLED, &enabled,
                         -1);
-    if (status != TSH_FILE_STATUS_UNVERSIONED)
-      non_recursive = !non_recursive;
     info->flags = (non_recursive?0:TSH_FILE_INFO_RECURSIVE) | (enabled?0:TSH_FILE_INFO_INDIRECT);
     info->status = status;
     ((struct copy_context*)ctx)->list.linked = g_slist_prepend (((struct copy_context*)ctx)->list.linked, info);
@@ -468,33 +603,51 @@ copy_selected_linked (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
 }
 
 static gboolean
-set_selected (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer selection)
+set_selected (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer ctx)
 {
-  GtkTreeIter parent;
-  gboolean enabled, unversioned_enabled = TRUE;
+  TshFileStatus parent_status;
+  gint status;
+  gboolean enabled = TRUE;
   gtk_tree_model_get (model, iter,
-                      COLUMN_ENABLED, &enabled,
+                      COLUMN_STATUS, &status,
                       -1);
 
-  if (gtk_tree_model_iter_parent (model, &parent, iter))
+  if (status != TSH_FILE_STATUS_INVALID)
   {
-    gint status;
-    gtk_tree_model_get (model, &parent,
-                        COLUMN_STATUS, &status,
-                        -1);
-    if (status == TSH_FILE_STATUS_UNVERSIONED)
+    parent_status = get_parent_status (model, iter);
+
+    switch (parent_status)
     {
-      unversioned_enabled = FALSE;
-      enabled = TRUE;
+      case TSH_FILE_STATUS_UNCHANGED:
+        enabled = !((struct select_context*)ctx)->select;
+        break;
+      case TSH_FILE_STATUS_ADDED:
+        if (((struct select_context*)ctx)->dialog->flags & TSH_FILE_SELECTION_FLAG_REVERSE_DISABLE_CHILDREN)
+          enabled = !((struct select_context*)ctx)->select;
+        else
+          enabled = status == TSH_FILE_STATUS_UNVERSIONED && ((struct select_context*)ctx)->select;
+        break;
+      case TSH_FILE_STATUS_DELETED:
+        enabled = !((struct select_context*)ctx)->select;
+        break;
+      case TSH_FILE_STATUS_UNVERSIONED:
+        enabled = FALSE;
+        break;
+      case TSH_FILE_STATUS_OTHER:
+        enabled = status == TSH_FILE_STATUS_UNVERSIONED || (status == TSH_FILE_STATUS_MISSING && !(((struct select_context*)ctx)->dialog->flags & TSH_FILE_SELECTION_FLAG_REVERSE_DISABLE_CHILDREN)) || !((struct select_context*)ctx)->select;
+        break;
+      case TSH_FILE_STATUS_MISSING:
+      case TSH_FILE_STATUS_INVALID:
+        break;
     }
-  }
 
-  if (enabled)
     gtk_tree_store_set (GTK_TREE_STORE (model), iter,
-                        COLUMN_SELECTION, GPOINTER_TO_INT (selection),
+                        COLUMN_SELECTION, ((struct select_context*)ctx)->select,
                         COLUMN_NON_RECURSIVE, FALSE,
-                        COLUMN_ENABLED, unversioned_enabled,
+                        COLUMN_ENABLED, enabled,
                         -1);
+  }
+
   return FALSE;
 }
 
@@ -559,7 +712,92 @@ add_unversioned (GtkTreeStore *model, const gchar *path, gboolean select, gboole
 }
 
 static void
-set_children_status (GtkTreeStore *model, GtkTreeIter *parent, gboolean select, gboolean enabled)
+set_children_status (TshFileSelectionDialog *dialog, GtkTreeStore *model, GtkTreeIter *parent, gboolean select, gboolean enabled)
+{
+  gint parent_status;
+  GtkTreeIter iter;
+
+  gtk_tree_model_get (GTK_TREE_MODEL (model), parent,
+                      COLUMN_STATUS, &parent_status,
+                      -1);
+
+  if (gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &iter, parent))
+    do
+    {
+      gboolean selection;
+      gboolean non_recursive;
+      gboolean enable;
+      gint status;
+      gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
+                          COLUMN_SELECTION, &selection,
+                          COLUMN_NON_RECURSIVE, &non_recursive,
+                          COLUMN_STATUS, &status,
+                          -1);
+      switch (parent_status)
+      {
+        case TSH_FILE_STATUS_ADDED:
+          switch (status)
+          {
+            case TSH_FILE_STATUS_UNVERSIONED:
+              enable = select;
+              if (!select)
+                selection = FALSE;
+              break;
+            default:
+              enable = enabled;
+              selection = select;
+              break;
+          }
+          break;
+        default:
+          enable = enabled;
+          switch (status)
+          {
+            case TSH_FILE_STATUS_UNVERSIONED:
+              if (select)
+                continue;
+              break;
+            case TSH_FILE_STATUS_MISSING:
+              if (select && !(dialog->flags & TSH_FILE_SELECTION_FLAG_REVERSE_DISABLE_CHILDREN))
+                continue;
+              break;
+            default:
+              selection = select;
+          }
+          break;
+      }
+      if (!enable)
+        non_recursive = FALSE;
+      gtk_tree_store_set (model, &iter,
+                          COLUMN_SELECTION, selection,
+                          COLUMN_NON_RECURSIVE, non_recursive,
+                          COLUMN_ENABLED, enable,
+                          -1);
+      switch (status)
+      {
+        case TSH_FILE_STATUS_UNVERSIONED:
+          if (!non_recursive)
+            set_children_status_unversioned (model, &iter, selection, FALSE);
+          break;
+        case TSH_FILE_STATUS_DELETED:
+          if (dialog->flags & TSH_FILE_SELECTION_FLAG_REVERSE_DISABLE_CHILDREN)
+          {
+            set_children_status (dialog, model, &iter, selection, non_recursive && selection);
+            break;
+          }
+        case TSH_FILE_STATUS_UNCHANGED:
+          set_children_status (dialog, model, &iter, selection, non_recursive || !selection);
+          break;
+        default:
+          set_children_status (dialog, model, &iter, selection, non_recursive);
+          break;
+      }
+    }
+    while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter));
+}
+
+static void
+set_children_status_unversioned (GtkTreeStore *model, GtkTreeIter *parent, gboolean select, gboolean enabled)
 {
   GtkTreeIter iter;
   if (gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &iter, parent))
@@ -570,7 +808,7 @@ set_children_status (GtkTreeStore *model, GtkTreeIter *parent, gboolean select,
                           COLUMN_NON_RECURSIVE, FALSE,
                           COLUMN_ENABLED, enabled,
                           -1);
-      set_children_status (model, &iter, select, FALSE);
+      set_children_status_unversioned (model, &iter, select, FALSE);
     }
     while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter));
 }
diff --git a/tvp-svn-helper/tsh-file-selection-dialog.h b/tvp-svn-helper/tsh-file-selection-dialog.h
index 0eaf7cc..41534a1 100644
--- a/tvp-svn-helper/tsh-file-selection-dialog.h
+++ b/tvp-svn-helper/tsh-file-selection-dialog.h
@@ -32,12 +32,20 @@ typedef enum {
   TSH_FILE_SELECTION_FLAG_IGNORED     = 1<<4,
   TSH_FILE_SELECTION_FLAG_CONFLICTED  = 1<<5,
 
-  TSH_FILE_SELECTION_FLAG_AUTO_SELECT_UNVERSIONED = 1<<6
+  TSH_FILE_SELECTION_FLAG_AUTO_SELECT_UNVERSIONED = 1<<6,
+  TSH_FILE_SELECTION_FLAG_AUTO_SELECT_MISSING     = 1<<7,
+
+  TSH_FILE_SELECTION_FLAG_REVERSE_DISABLE_CHILDREN = 1<<8
 } TshFileSelectionFlags;
 
 typedef enum {
-  TSH_FILE_STATUS_OTHER = 0,
-  TSH_FILE_STATUS_UNVERSIONED
+  TSH_FILE_STATUS_INVALID = 0,
+  TSH_FILE_STATUS_UNCHANGED,
+  TSH_FILE_STATUS_ADDED,
+  TSH_FILE_STATUS_DELETED,
+  TSH_FILE_STATUS_MISSING,
+  TSH_FILE_STATUS_UNVERSIONED,
+  TSH_FILE_STATUS_OTHER
 } TshFileStatus;
 
 typedef enum {
@@ -72,10 +80,10 @@ GtkWidget* tsh_file_selection_dialog_new        (const gchar *title,
                                                  apr_pool_t *pool) G_GNUC_MALLOC G_GNUC_INTERNAL;
 
 gchar**    tsh_file_selection_dialog_get_files              (TshFileSelectionDialog *dialog) G_GNUC_WARN_UNUSED_RESULT;
-gchar**    tsh_file_selection_dialog_get_files_by_status    (TshFileSelectionDialog *dialog, TshFileStatus status) G_GNUC_WARN_UNUSED_RESULT;
+gchar**    tsh_file_selection_dialog_get_files_by_status    (TshFileSelectionDialog *dialog, TshFileStatus status, gboolean indirect) G_GNUC_WARN_UNUSED_RESULT;
 
 GSList*    tsh_file_selection_dialog_get_file_info              (TshFileSelectionDialog *dialog) G_GNUC_WARN_UNUSED_RESULT;
-GSList*    tsh_file_selection_dialog_get_file_info_by_status    (TshFileSelectionDialog *dialog, TshFileStatus status) G_GNUC_WARN_UNUSED_RESULT;
+GSList*    tsh_file_selection_dialog_get_file_info_by_status    (TshFileSelectionDialog *dialog, TshFileStatus status, gboolean indirect) G_GNUC_WARN_UNUSED_RESULT;
 
 G_END_DECLS;
 
diff --git a/tvp-svn-helper/tsh-revert.c b/tvp-svn-helper/tsh-revert.c
index ff7d883..aeeab53 100644
--- a/tvp-svn-helper/tsh-revert.c
+++ b/tvp-svn-helper/tsh-revert.c
@@ -53,7 +53,7 @@ static gpointer revert_thread (gpointer user_data)
 	apr_pool_t *subpool, *pool = args->pool;
 	TshNotifyDialog *dialog = args->dialog;
 	gchar **files = args->files;
-	gint size;
+	gint size, i;
   gchar *error_str;
 
 	g_free (args);
@@ -66,9 +66,9 @@ static gpointer revert_thread (gpointer user_data)
 	{
 		paths = apr_array_make (subpool, size, sizeof (const char *));
 		
-		while (size--)
+		for (i=0; i < size; i++)
 		{
-			APR_ARRAY_PUSH (paths, const char *) = files[size];
+			APR_ARRAY_PUSH (paths, const char *) = files[i];
 		}
 	}
 	else
@@ -109,7 +109,7 @@ GThread *tsh_revert (gchar **files, svn_client_ctx_t *ctx, apr_pool_t *pool)
 	GtkWidget *dialog;
 	struct thread_args *args;
 
-  dialog = tsh_file_selection_dialog_new (_("Revert"), NULL, 0, files, TSH_FILE_SELECTION_FLAG_RECURSIVE|TSH_FILE_SELECTION_FLAG_MODIFIED, ctx, pool);
+  dialog = tsh_file_selection_dialog_new (_("Revert"), NULL, 0, files, TSH_FILE_SELECTION_FLAG_RECURSIVE|TSH_FILE_SELECTION_FLAG_MODIFIED|TSH_FILE_SELECTION_FLAG_REVERSE_DISABLE_CHILDREN, ctx, pool);
 	if(gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
   {
     gtk_widget_destroy (dialog);



More information about the Xfce4-commits mailing list