[Goodies-commits] r7852 - thunar-vcs-plugin/trunk/tvp-svn-helper

Peter de Ridder peter at xfce.org
Mon Jul 27 23:27:25 CEST 2009


Author: peter
Date: 2009-07-27 21:27:25 +0000 (Mon, 27 Jul 2009)
New Revision: 7852

Modified:
   thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-add.c
   thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-commit.c
   thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-delete.c
   thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-file-selection-dialog.c
   thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-file-selection-dialog.h
   thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-log-dialog.c
   thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-revert.c
Log:
* tvp-svn-helper/tsh-delete.c(delete_thread): Fixed segfault.
* tvp-svn-helper/tsh-file-selection-dialog.[ch]: Support for unversioned directory trees.
* tvp-svn-helper/tsh-revert.c(revert_thread): Execute revert in reverse directory order.
* tvp-svn-helper/tsh-add.c: Support for non-recursive add.
* tvp-svn-helper/tsh-log-dialog.c: Fixed 2 missing characters in last commit.
* tvp-svn-helper/tsh-commit.c: Support adding unversioned files before commiting. This fixes bug #3921.

Modified: thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-add.c
===================================================================
--- thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-add.c	2009-07-27 20:00:48 UTC (rev 7851)
+++ thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-add.c	2009-07-27 21:27:25 UTC (rev 7852)
@@ -41,7 +41,7 @@
 	svn_client_ctx_t *ctx;
 	apr_pool_t *pool;
 	TshNotifyDialog *dialog;
-	gchar **files;
+	GSList *files;
 };
 
 static gpointer add_thread (gpointer user_data)
@@ -52,36 +52,38 @@
 	svn_client_ctx_t *ctx = args->ctx;
 	apr_pool_t *subpool, *pool = args->pool;
 	TshNotifyDialog *dialog = args->dialog;
-	gchar **files = args->files;
-	gint size, i;
+	GSList *files = args->files;
   gchar *error_str;
 
 	g_free (args);
 
-	size = files?g_strv_length(files):0;
-
   subpool = svn_pool_create (pool);
 
-	if(size)
-	{
-		for (i = 0; i < size; i++)
-		{
-      if ((err = svn_client_add4(files[i], svn_depth_infinity, FALSE, FALSE, FALSE, ctx, subpool)))
+  if(files)
+  {
+    do
+    {
+      TshFileInfo *info = files->data;
+      if (!(info->flags & TSH_FILE_INFO_INDIRECT))
       {
-        error_str = tsh_strerror(err);
-        gdk_threads_enter();
-        tsh_notify_dialog_add(dialog, _("Failed"), error_str, NULL);
-        gdk_threads_leave();
-        g_free(error_str);
+        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;
-        break;//FIXME: needed ??
+          svn_error_clear(err);
+          result = FALSE;
+          break;//FIXME: needed ??
+        }
       }
-		}
-	}
-	else
-	{
+    }
+    while ((files = g_slist_next (files)));
+  }
+  else
+  {
     if ((err = svn_client_add4("", svn_depth_infinity, FALSE, FALSE, FALSE, ctx, subpool)))
     {
       error_str = tsh_strerror(err);
@@ -93,7 +95,7 @@
       svn_error_clear(err);
       result = FALSE;
     }
-	}
+  }
 
   svn_pool_destroy (subpool);
 
@@ -109,18 +111,19 @@
 {
 	GtkWidget *dialog;
 	struct thread_args *args;
+  GSList *file_list;
 
-  dialog = tsh_file_selection_dialog_new (_("Add"), NULL, 0, files, TSH_FILE_SELECTION_FLAG_RECURSIVE|TSH_FILE_SELECTION_FLAG_UNVERSIONED, ctx, pool);
+  dialog = tsh_file_selection_dialog_new (_("Add"), NULL, 0, files, TSH_FILE_SELECTION_FLAG_RECURSIVE|TSH_FILE_SELECTION_FLAG_UNVERSIONED|TSH_FILE_SELECTION_FLAG_AUTO_SELECT_UNVERSIONED, ctx, pool);
 	if(gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
   {
     gtk_widget_destroy (dialog);
     return NULL;
   }
   g_strfreev (files);
-  files = tsh_file_selection_dialog_get_files (TSH_FILE_SELECTION_DIALOG (dialog));
+  file_list = tsh_file_selection_dialog_get_file_info (TSH_FILE_SELECTION_DIALOG (dialog));
   gtk_widget_destroy (dialog);
 
-  if(!files)
+  if(!file_list)
     return NULL;
 
 	dialog = tsh_notify_dialog_new (_("Add"), NULL, 0);
@@ -134,7 +137,7 @@
 	args->ctx = ctx;
 	args->pool = pool;
 	args->dialog = TSH_NOTIFY_DIALOG (dialog);
-	args->files = files;
+	args->files = file_list;
 
 	return g_thread_create (add_thread, args, TRUE, NULL);
 }

Modified: thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-commit.c
===================================================================
--- thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-commit.c	2009-07-27 20:00:48 UTC (rev 7851)
+++ thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-commit.c	2009-07-27 21:27:25 UTC (rev 7852)
@@ -42,99 +42,135 @@
 	svn_client_ctx_t *ctx;
 	apr_pool_t *pool;
 	TshNotifyDialog *dialog;
-  gchar **files;
+  GSList *files;
 };
 
 static gpointer commit_thread (gpointer user_data)
 {
-	struct thread_args *args = user_data;
-	svn_error_t *err;
+  struct thread_args *args = user_data;
+  gboolean result = TRUE;
+  svn_error_t *err;
   svn_commit_info_t *commit_info;
   apr_array_header_t *paths;
-	svn_client_ctx_t *ctx = args->ctx;
-	apr_pool_t *subpool, *pool = args->pool;
-	TshNotifyDialog *dialog = args->dialog;
-  gchar **files = args->files;
-  gint size, i;
+  svn_client_ctx_t *ctx = args->ctx;
+  apr_pool_t *subpool, *pool = args->pool;
+  TshNotifyDialog *dialog = args->dialog;
+  GSList *files = args->files;
+  GSList *iter;
+  gint size;
   gchar *error_str;
   gchar *message;
   gchar buffer[256];
 
-	g_free (args);
+  g_free (args);
 
-  size = files?g_strv_length(files):0;
+  size = 0;
 
   subpool = svn_pool_create (pool);
 
-  if(size)
+  for (iter = files; iter; iter = g_slist_next (iter))
   {
-    paths = apr_array_make (subpool, size, sizeof (const char *));
+    TshFileInfo *info;
+    size++;
 
-    for (i = 0; i < size; i++)
+    info = iter->data;
+    if (info->status == TSH_FILE_STATUS_UNVERSIONED && !(info->flags&TSH_FILE_INFO_INDIRECT))
     {
-      APR_ARRAY_PUSH (paths, const char *) = files[i];
+      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;
+        break;//FIXME: needed ??
+      }
     }
   }
-  else
+
+  svn_pool_destroy (subpool);
+
+  /* check if an error occurred in add commands */
+  if (result)//FIXME: needed ??
   {
-    paths = apr_array_make (subpool, 1, sizeof (const char *));
+    subpool = svn_pool_create (pool);
 
-    APR_ARRAY_PUSH (paths, const char *) = ""; // current directory
-  }
+    if(size)
+    {
+      paths = apr_array_make (subpool, size, sizeof (const char *));
 
-	if ((err = svn_client_commit4(&commit_info, paths, svn_depth_empty, FALSE, FALSE, NULL, NULL, ctx, subpool)))
-	{
-    svn_pool_destroy (subpool);
+      for (iter = files; iter; iter = g_slist_next (iter))
+      {
+        TshFileInfo *info = iter->data;
+        APR_ARRAY_PUSH (paths, const char *) = info->path;
+      }
+    }
+    else
+    {
+      paths = apr_array_make (subpool, 1, sizeof (const char *));
 
-    error_str = tsh_strerror(err);
-		gdk_threads_enter();
-    tsh_notify_dialog_add(dialog, _("Failed"), error_str, NULL);
-		tsh_notify_dialog_done (dialog);
-		gdk_threads_leave();
-    g_free(error_str);
+      APR_ARRAY_PUSH (paths, const char *) = ""; // current directory
+    }
 
-		svn_error_clear(err);
-    tsh_reset_cancel();
-		return GINT_TO_POINTER (FALSE);
-	}
+    if ((err = svn_client_commit4(&commit_info, paths, svn_depth_empty, FALSE, FALSE, NULL, NULL, ctx, subpool)))
+    {
+      svn_pool_destroy (subpool);
 
-  if(SVN_IS_VALID_REVNUM(commit_info->revision))
-  {
-    g_snprintf(buffer, 256, _("At revision: %ld"), commit_info->revision);
-    message = buffer;
+      error_str = tsh_strerror(err);
+      gdk_threads_enter();
+      tsh_notify_dialog_add(dialog, _("Failed"), error_str, NULL);
+      tsh_notify_dialog_done (dialog);
+      gdk_threads_leave();
+      g_free(error_str);
+
+      svn_error_clear(err);
+      tsh_reset_cancel();
+      return GINT_TO_POINTER (FALSE);
+    }
+
+    if(SVN_IS_VALID_REVNUM(commit_info->revision))
+    {
+      g_snprintf(buffer, 256, _("At revision: %ld"), commit_info->revision);
+      message = buffer;
+    }
+    else
+    {
+      message = _("Nothing to do");
+    }
+
+    svn_pool_destroy (subpool);
   }
-  else
-  {
-    message = _("Nothing to do");
-  }
 
-  svn_pool_destroy (subpool);
+  gdk_threads_enter();
+  if (result)
+    tsh_notify_dialog_add(dialog, _("Completed"), message, NULL);
+  tsh_notify_dialog_done (dialog);
+  gdk_threads_leave();
 
-	gdk_threads_enter();
-  tsh_notify_dialog_add(dialog, _("Completed"), message, NULL);
-	tsh_notify_dialog_done (dialog);
-	gdk_threads_leave();
-	
   tsh_reset_cancel();
-	return GINT_TO_POINTER (TRUE);
+  return GINT_TO_POINTER (result);
 }
 
 GThread *tsh_commit (gchar **files, svn_client_ctx_t *ctx, apr_pool_t *pool)
 {
 	GtkWidget *dialog;
 	struct thread_args *args;
+  GSList *file_list;
 
-  dialog = tsh_file_selection_dialog_new (_("Commit"), NULL, 0, files, TSH_FILE_SELECTION_FLAG_RECURSIVE|TSH_FILE_SELECTION_FLAG_MODIFIED/*|TSH_FILE_SELECTION_FLAG_UNVERSIONED*/, ctx, pool);
+  dialog = tsh_file_selection_dialog_new (_("Commit"), NULL, 0, files, TSH_FILE_SELECTION_FLAG_RECURSIVE|TSH_FILE_SELECTION_FLAG_MODIFIED|TSH_FILE_SELECTION_FLAG_UNVERSIONED, ctx, pool);
 	if(gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
   {
     gtk_widget_destroy (dialog);
     return NULL;
   }
   g_strfreev (files);
-  files = tsh_file_selection_dialog_get_files (TSH_FILE_SELECTION_DIALOG (dialog));
+  file_list = tsh_file_selection_dialog_get_file_info (TSH_FILE_SELECTION_DIALOG (dialog));
   gtk_widget_destroy (dialog);
 
-  if(!files)
+  if(!file_list)
     return NULL;
 
 	dialog = tsh_notify_dialog_new (_("Commit"), NULL, 0);
@@ -151,7 +187,7 @@
 	args->ctx = ctx;
 	args->pool = pool;
 	args->dialog = TSH_NOTIFY_DIALOG (dialog);
-	args->files = files;
+	args->files = file_list;
 
 	return g_thread_create (commit_thread, args, TRUE, NULL);
 }

Modified: thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-delete.c
===================================================================
--- thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-delete.c	2009-07-27 20:00:48 UTC (rev 7851)
+++ thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-delete.c	2009-07-27 21:27:25 UTC (rev 7852)
@@ -98,7 +98,7 @@
 		return GINT_TO_POINTER (FALSE);
 	}
 
-  if(SVN_IS_VALID_REVNUM(commit_info->revision))
+  if(commit_info && SVN_IS_VALID_REVNUM(commit_info->revision))
   {
     g_snprintf(buffer, 256, _("At revision: %ld"), commit_info->revision);
     message = buffer;

Modified: thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-file-selection-dialog.c
===================================================================
--- thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-file-selection-dialog.c	2009-07-27 20:00:48 UTC (rev 7851)
+++ thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-file-selection-dialog.c	2009-07-27 21:27:25 UTC (rev 7852)
@@ -36,11 +36,16 @@
 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; };
 static gboolean count_selected (GtkTreeModel*, GtkTreePath*, GtkTreeIter*, gpointer);
-static gboolean copy_selected (GtkTreeModel*, GtkTreePath*, GtkTreeIter*, gpointer);
+static gboolean copy_selected_string (GtkTreeModel*, GtkTreePath*, GtkTreeIter*, gpointer);
+static gboolean copy_selected_linked (GtkTreeModel*, GtkTreePath*, GtkTreeIter*, gpointer);
 static gboolean set_selected (GtkTreeModel*, GtkTreePath*, GtkTreeIter*, gpointer);
 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);
+
 struct _TshFileSelectionDialog
 {
 	GtkDialog dialog;
@@ -69,7 +74,9 @@
   COLUMN_TEXT_STAT,
   COLUMN_PROP_STAT,
   COLUMN_SELECTION,
+  COLUMN_NON_RECURSIVE,
   COLUMN_ENABLED,
+  COLUMN_STATUS,
   COLUMN_COUNT
 };
 
@@ -93,6 +100,7 @@
 	gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
 	                                             -1, "", renderer,
                                                "active", COLUMN_SELECTION,
+                                               "inconsistent", COLUMN_NON_RECURSIVE,
                                                "activatable", COLUMN_ENABLED,
                                                NULL);
 
@@ -115,7 +123,7 @@
                                                "text", COLUMN_PROP_STAT,
                                                NULL);
 
-  model = GTK_TREE_MODEL (gtk_tree_store_new (COLUMN_COUNT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN));
+  model = GTK_TREE_MODEL (gtk_tree_store_new (COLUMN_COUNT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_INT));
 
 	gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), model);
 
@@ -221,28 +229,62 @@
 gchar**
 tsh_file_selection_dialog_get_files (TshFileSelectionDialog *dialog)
 {
+  return tsh_file_selection_dialog_get_files_by_status (dialog, TSH_FILE_STATUS_OTHER);
+}
+
+gchar**
+tsh_file_selection_dialog_get_files_by_status (TshFileSelectionDialog *dialog, TshFileStatus status)
+{
   GtkTreeModel *model;
-  gchar **files, **files_iter;
-  guint count = 0;
+  gchar **files;
+  struct copy_context ctx;
 
   g_return_val_if_fail (TSH_IS_FILE_SELECTION_DIALOG (dialog), NULL);
 
+  ctx.status = status;
+
   model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->tree_view));
 
-  gtk_tree_model_foreach (model, count_selected, &count);
+  ctx.list.count = 0;
+  gtk_tree_model_foreach (model, count_selected, &ctx);
 
-  if (!count)
+  if (!ctx.list.count)
     return NULL;
 
-  files_iter = files = g_new(gchar *, count+1);
+  ctx.list.string = files = g_new(gchar *, ctx.list.count+1);
 
-  gtk_tree_model_foreach (model, copy_selected, &files_iter);
+  gtk_tree_model_foreach (model, copy_selected_string, &ctx);
 
-  *files_iter = NULL;
+  *ctx.list.string = NULL;
 
   return files;
 }
 
+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);
+}
+
+GSList*
+tsh_file_selection_dialog_get_file_info_by_status (TshFileSelectionDialog *dialog, TshFileStatus status)
+{
+  GtkTreeModel *model;
+  struct copy_context ctx;
+
+  g_return_val_if_fail (TSH_IS_FILE_SELECTION_DIALOG (dialog), NULL);
+
+  ctx.status = status;
+
+  model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->tree_view));
+
+  ctx.list.linked = NULL;
+
+  gtk_tree_model_foreach (model, copy_selected_linked, &ctx);
+
+  return g_slist_reverse (ctx.list.linked);
+}
+
 static void
 tsh_file_selection_status_func2(void *baton, const char *path, svn_wc_status2_t *status)
 {
@@ -268,9 +310,17 @@
                         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, TRUE,
+                        COLUMN_SELECTION, (status->entry || dialog->flags & TSH_FILE_SELECTION_FLAG_AUTO_SELECT_UNVERSIONED),
+                        COLUMN_NON_RECURSIVE, FALSE,
                         COLUMN_ENABLED, TRUE,
+                        COLUMN_STATUS, status->entry?TSH_FILE_STATUS_OTHER:TSH_FILE_STATUS_UNVERSIONED,
                         -1);
+
+    if (!status->entry)
+    {
+      /* Unversioned: get all children */
+      add_unversioned (GTK_TREE_STORE (model), path, dialog->flags & TSH_FILE_SELECTION_FLAG_AUTO_SELECT_UNVERSIONED, FALSE);
+    }
   }
 }
 
@@ -287,7 +337,8 @@
 	TshFileSelectionDialog *dialog = TSH_FILE_SELECTION_DIALOG (user_data);
   GtkTreeModel *model;
   GtkTreeIter iter;
-  gboolean selection;
+  gboolean selection, non_recursive;
+  gint status;
 
   model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->tree_view));
 
@@ -295,10 +346,47 @@
 
   gtk_tree_model_get (model, &iter,
                       COLUMN_SELECTION, &selection,
+                      COLUMN_NON_RECURSIVE, &non_recursive,
+                      COLUMN_STATUS, &status,
                       -1);
+  switch (status)
+  {
+    case TSH_FILE_STATUS_UNVERSIONED:
+      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) */
+        if (non_recursive)
+        {
+          non_recursive = FALSE;
+          selection = !selection;
+        }
+        else
+          non_recursive = TRUE;
+#else   /* 3 states, not selected -> selected -> non recursive (children selected) */
+        if (non_recursive)
+        {
+          non_recursive = FALSE;
+          selection = FALSE;
+        }
+        else if (selection)
+          non_recursive = TRUE;
+        else
+          selection = TRUE;
+#endif
+        break;
+      }
+    default:
+      selection = !selection;
+      break;
+  }
   gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
-                      COLUMN_SELECTION, !selection,
+                      COLUMN_SELECTION, selection,
+                      COLUMN_NON_RECURSIVE, non_recursive,
                       -1);
+  if (status == TSH_FILE_STATUS_UNVERSIONED)
+  {
+    set_children_status (GTK_TREE_STORE (model), &iter, selection, non_recursive);
+  }
 
   gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (dialog->all), TRUE);
 }
@@ -320,44 +408,92 @@
 }
 
 static gboolean
-count_selected (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer count)
+count_selected (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer ctx)
 {
   gboolean selection;
+  gint status;
   gtk_tree_model_get (model, iter,
                       COLUMN_SELECTION, &selection,
+                      COLUMN_STATUS, &status,
                       -1);
-  if (selection)
-    (*(guint*)count)++;
+  if (selection && (((struct copy_context*)ctx)->status == TSH_FILE_STATUS_OTHER || ((struct copy_context*)ctx)->status == status))
+    ((struct copy_context*)ctx)->list.count++;
   return FALSE;
 }
 
 static gboolean
-copy_selected (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer files_iter)
+copy_selected_string (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer ctx)
 {
   gboolean selection;
+  gint status;
   gtk_tree_model_get (model, iter,
                       COLUMN_SELECTION, &selection,
+                      COLUMN_STATUS, &status,
                       -1);
-  if (selection)
+  if (selection && (((struct copy_context*)ctx)->status == TSH_FILE_STATUS_OTHER || ((struct copy_context*)ctx)->status == status))
   {
     gtk_tree_model_get (model, iter,
-                        COLUMN_PATH, *(gchar***)files_iter,
+                        COLUMN_PATH, ((struct copy_context*)ctx)->list.string,
                         -1);
-    (*(gchar***)files_iter)++;
+    ((struct copy_context*)ctx)->list.string++;
   }
   return FALSE;
 }
 
 static gboolean
+copy_selected_linked (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer ctx)
+{
+  gboolean selection;
+  gint status;
+  gtk_tree_model_get (model, iter,
+                      COLUMN_SELECTION, &selection,
+                      COLUMN_STATUS, &status,
+                      -1);
+  if (selection && (((struct copy_context*)ctx)->status == TSH_FILE_STATUS_OTHER || ((struct copy_context*)ctx)->status == status))
+  {
+    gboolean non_recursive, enabled;
+    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);
+  }
+  return FALSE;
+}
+
+static gboolean
 set_selected (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer selection)
 {
-  gboolean enabled;
+  GtkTreeIter parent;
+  gboolean enabled, unversioned_enabled = TRUE;
   gtk_tree_model_get (model, iter,
                       COLUMN_ENABLED, &enabled,
                       -1);
+
+  if (gtk_tree_model_iter_parent (model, &parent, iter))
+  {
+    gint status;
+    gtk_tree_model_get (model, &parent,
+                        COLUMN_STATUS, &status,
+                        -1);
+    if (status == TSH_FILE_STATUS_UNVERSIONED)
+    {
+      unversioned_enabled = FALSE;
+      enabled = TRUE;
+    }
+  }
+
   if (enabled)
     gtk_tree_store_set (GTK_TREE_STORE (model), iter,
                         COLUMN_SELECTION, GPOINTER_TO_INT (selection),
+                        COLUMN_NON_RECURSIVE, FALSE,
+                        COLUMN_ENABLED, unversioned_enabled,
                         -1);
   return FALSE;
 }
@@ -366,14 +502,17 @@
 move_info (GtkTreeStore *store, GtkTreeIter *dest, GtkTreeIter *src)
 {
   gchar *path, *text, *prop;
-  gboolean selected, enabled;
+  gboolean selected, non_recursive, enabled;
+  gint status;
 
   gtk_tree_model_get (GTK_TREE_MODEL (store), src,
                       COLUMN_PATH, &path,
                       COLUMN_TEXT_STAT, &text,
                       COLUMN_PROP_STAT, &prop,
                       COLUMN_SELECTION, &selected,
+                      COLUMN_NON_RECURSIVE, &non_recursive,
                       COLUMN_ENABLED, &enabled,
+                      COLUMN_STATUS, &status,
                       -1);
 
   gtk_tree_store_set (store, dest,
@@ -381,7 +520,9 @@
                       COLUMN_TEXT_STAT, text,
                       COLUMN_PROP_STAT, prop,
                       COLUMN_SELECTION, selected,
+                      COLUMN_NON_RECURSIVE, non_recursive,
                       COLUMN_ENABLED, enabled,
+                      COLUMN_STATUS, status,
                       -1);
 
   g_free (path);
@@ -389,3 +530,48 @@
   g_free (prop);
 }
 
+static void
+add_unversioned (GtkTreeStore *model, const gchar *path, gboolean select, gboolean enabled)
+{
+  GDir *dir = g_dir_open (path, 0, NULL);
+  if (dir)
+  {
+    const gchar *file;
+    while ((file = g_dir_read_name (dir)))
+    {
+      GtkTreeIter iter;
+      gchar *file_path = g_build_filename (path, file, NULL);
+      tsh_tree_get_iter_for_path (model, file_path, &iter, COLUMN_NAME, move_info);
+      gtk_tree_store_set (model, &iter,
+                          COLUMN_PATH, file_path,
+                          COLUMN_TEXT_STAT, "",
+                          COLUMN_PROP_STAT, "",
+                          COLUMN_SELECTION, select,
+                          COLUMN_NON_RECURSIVE, FALSE,
+                          COLUMN_ENABLED, enabled,
+                          COLUMN_STATUS, TSH_FILE_STATUS_UNVERSIONED,
+                          -1);
+      add_unversioned (model, file_path, select, FALSE);
+      g_free (file_path);
+    }
+    g_dir_close (dir);
+  }
+}
+
+static void
+set_children_status (GtkTreeStore *model, GtkTreeIter *parent, gboolean select, gboolean enabled)
+{
+  GtkTreeIter iter;
+  if (gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &iter, parent))
+    do
+    {
+      gtk_tree_store_set (model, &iter,
+                          COLUMN_SELECTION, select,
+                          COLUMN_NON_RECURSIVE, FALSE,
+                          COLUMN_ENABLED, enabled,
+                          -1);
+      set_children_status (model, &iter, select, FALSE);
+    }
+    while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter));
+}
+

Modified: thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-file-selection-dialog.h
===================================================================
--- thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-file-selection-dialog.h	2009-07-27 20:00:48 UTC (rev 7851)
+++ thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-file-selection-dialog.h	2009-07-27 21:27:25 UTC (rev 7852)
@@ -30,9 +30,27 @@
   TSH_FILE_SELECTION_FLAG_UNVERSIONED = 1<<2,
   TSH_FILE_SELECTION_FLAG_UNCHANGED   = 1<<3,
   TSH_FILE_SELECTION_FLAG_IGNORED     = 1<<4,
-  TSH_FILE_SELECTION_FLAG_CONFLICTED  = 1<<5
+  TSH_FILE_SELECTION_FLAG_CONFLICTED  = 1<<5,
+
+  TSH_FILE_SELECTION_FLAG_AUTO_SELECT_UNVERSIONED = 1<<6
 } TshFileSelectionFlags;
 
+typedef enum {
+  TSH_FILE_STATUS_OTHER = 0,
+  TSH_FILE_STATUS_UNVERSIONED
+} TshFileStatus;
+
+typedef enum {
+  TSH_FILE_INFO_RECURSIVE   = 1<<0,
+  TSH_FILE_INFO_INDIRECT    = 1<<1
+} TshFileInfoFlags;
+
+typedef struct {
+  gchar *path;
+  TshFileInfoFlags flags;
+  TshFileStatus status;
+} TshFileInfo;
+
 typedef struct _TshFileSelectionDialogClass TshFileSelectionDialogClass;
 typedef struct _TshFileSelectionDialog      TshFileSelectionDialog;
 
@@ -53,8 +71,12 @@
                                                  svn_client_ctx_t *ctx,
                                                  apr_pool_t *pool) G_GNUC_MALLOC G_GNUC_INTERNAL;
 
-gchar**    tsh_file_selection_dialog_get_files  (TshFileSelectionDialog *dialog);
+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;
 
+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;
+
 G_END_DECLS;
 
 #endif /* !__TSH_FILE_SELECTION_DIALOG_H__ */

Modified: thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-log-dialog.c
===================================================================
--- thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-log-dialog.c	2009-07-27 20:00:48 UTC (rev 7851)
+++ thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-log-dialog.c	2009-07-27 21:27:25 UTC (rev 7852)
@@ -401,7 +401,7 @@
   gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->text_view)), "", -1);
 
 	model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->file_view));
-  k_tree_store_clear (GTK_TREE_STORE (model));
+  gtk_tree_store_clear (GTK_TREE_STORE (model));
 }
 
 static void

Modified: thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-revert.c
===================================================================
--- thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-revert.c	2009-07-27 20:00:48 UTC (rev 7851)
+++ thunar-vcs-plugin/trunk/tvp-svn-helper/tsh-revert.c	2009-07-27 21:27:25 UTC (rev 7852)
@@ -53,7 +53,7 @@
 	apr_pool_t *subpool, *pool = args->pool;
 	TshNotifyDialog *dialog = args->dialog;
 	gchar **files = args->files;
-	gint size, i;
+	gint size;
   gchar *error_str;
 
 	g_free (args);
@@ -66,9 +66,9 @@
 	{
 		paths = apr_array_make (subpool, size, sizeof (const char *));
 		
-		for (i = 0; i < size; i++)
+		while (size--)
 		{
-			APR_ARRAY_PUSH (paths, const char *) = files[i];
+			APR_ARRAY_PUSH (paths, const char *) = files[size];
 		}
 	}
 	else




More information about the Goodies-commits mailing list