[Xfce4-commits] <thunar:master> Add CopyTo, CopyInto, MoveInto, LinkInto, UnlinkFiles D-Bus methods.

Jannis Pohlmann noreply at xfce.org
Sun Aug 29 19:42:01 CEST 2010


Updating branch refs/heads/master
         to 6371d5d886dcb5b92eab532c0852a57a96da1fb1 (commit)
       from c1f67c1b39af1c03ac3d31e95a35744670ecf354 (commit)

commit 6371d5d886dcb5b92eab532c0852a57a96da1fb1
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Sun Aug 29 19:36:04 2010 +0200

    Add CopyTo, CopyInto, MoveInto, LinkInto, UnlinkFiles D-Bus methods.
    
    The groundwork for this was done by Daniel Morales. I refactored the
    code a little bit, fixed a few bugs and added a working directory
    parameter to all functions. The startup id parameter is unused at
    the moment but this may change in the future.
    
    The methods have been added to the org.xfce.FileManager D-Bus interface.

 thunar/thunar-application.c          |   14 +-
 thunar/thunar-application.h          |    3 +-
 thunar/thunar-dbus-service-infos.xml |  108 ++++++++++
 thunar/thunar-dbus-service.c         |  364 ++++++++++++++++++++++++++++++++++
 thunar/thunar-standard-view.c        |    2 +-
 thunar/thunar-tree-view.c            |    2 +-
 6 files changed, 486 insertions(+), 7 deletions(-)

diff --git a/thunar/thunar-application.c b/thunar/thunar-application.c
index 96186d6..cbc1f2d 100644
--- a/thunar/thunar-application.c
+++ b/thunar/thunar-application.c
@@ -1404,6 +1404,9 @@ unlink_stub (GList *source_path_list,
  * @application : a #ThunarApplication.
  * @parent      : a #GdkScreen, a #GtkWidget or %NULL.
  * @file_list   : the list of #ThunarFile<!---->s that should be deleted.
+ * @permanently : whether to unlink the files permanently. Even if this is set to
+ *                FALSE, the files may be erased permanently if the SHIFT key
+ *                is pressed at the time the function is called.
  *
  * Deletes all files in the @file_list and takes care of all user interaction.
  *
@@ -1414,13 +1417,13 @@ unlink_stub (GList *source_path_list,
 void
 thunar_application_unlink_files (ThunarApplication *application,
                                  gpointer           parent,
-                                 GList             *file_list)
+                                 GList             *file_list,
+                                 gboolean           permanently)
 {
   GdkModifierType state;
   GtkWidget      *dialog;
   GtkWindow      *window;
   GdkScreen      *screen;
-  gboolean        permanently;
   GList          *path_list = NULL;
   GList          *lp;
   gchar          *message;      
@@ -1430,8 +1433,11 @@ thunar_application_unlink_files (ThunarApplication *application,
   _thunar_return_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WIDGET (parent));
   _thunar_return_if_fail (THUNAR_IS_APPLICATION (application));
 
-  /* check if we should permanently delete the files (user holds shift) */
-  permanently = (gtk_get_current_event_state (&state) && (state & GDK_SHIFT_MASK) != 0);
+  if (!permanently)
+    {
+      /* check if we should permanently delete the files (user holds shift) */
+      permanently = (gtk_get_current_event_state (&state) && (state & GDK_SHIFT_MASK) != 0);
+    }
 
   /* determine the paths for the files */
   for (lp = g_list_last (file_list); lp != NULL; lp = lp->prev, ++n_path_list)
diff --git a/thunar/thunar-application.h b/thunar/thunar-application.h
index 8fdf401..53e3e3e 100644
--- a/thunar/thunar-application.h
+++ b/thunar/thunar-application.h
@@ -101,7 +101,8 @@ void               thunar_application_move_into           (ThunarApplication *ap
 
 void               thunar_application_unlink_files        (ThunarApplication *application,
                                                            gpointer           parent,
-                                                           GList             *file_list);
+                                                           GList             *file_list,
+                                                           gboolean           permanently);
 
 void               thunar_application_trash               (ThunarApplication *application,
                                                            gpointer           parent,
diff --git a/thunar/thunar-dbus-service-infos.xml b/thunar/thunar-dbus-service-infos.xml
index c2c01c7..ca7c0c4 100644
--- a/thunar/thunar-dbus-service-infos.xml
+++ b/thunar/thunar-dbus-service-infos.xml
@@ -124,6 +124,114 @@
     <method name="DisplayPreferencesDialog">
       <arg direction="in" name="display" type="s" />
     </method>
+
+
+    <!--
+      CopyTo (working-directory : STRING, source-filenames : ARRAY OF STRING, target-filenames : ARRAY OF STRING, display : STRING, startup-id : STRING) : VOID
+
+      working-directory : working directory used to resolve relative filenames.
+      source-filenames  : an array of file names to copy. The file names may
+                          be either file:-URIs, absolute paths or paths relative
+                          to the working-directory.
+      target-filenames  : the target filenames.
+      display           : the screen on which to launch the filenames or ""
+                          to use the default screen of the file manager.
+      startup-id        : the DESKTOP_STARTUP_ID environment variable for properly
+                          handling startup notification and focus stealing.
+    -->
+    <method name="CopyTo">
+      <arg direction="in" name="working-directory" type="s" />
+      <arg direction="in" name="source-filenames" type="as" />
+      <arg direction="in" name="target-filenames" type="as" />
+      <arg direction="in" name="display" type="s" />
+      <arg direction="in" name="startup-id" type="s" />
+    </method>
+
+
+    <!--
+      CopyInto (working-directory : STRING, source-filenames : ARRAY OF STRING, target-filename : STRING, display : STRING, startup-id : STRING) : VOID
+
+      working-directory : working directory used to resolve relative filenames.
+      source-filenames  : an array of file names to copy. The file names may
+                          be either file:-URIs, absolute paths or paths relative
+                          to the working-directory.
+      target-filename   : the target directory.
+      display           : the screen on which to launch the filenames or ""
+                          to use the default screen of the file manager.
+      startup-id        : the DESKTOP_STARTUP_ID environment variable for properly
+                          handling startup notification and focus stealing.
+    -->
+    <method name="CopyInto">
+      <arg direction="in" name="working-directory" type="s" />
+      <arg direction="in" name="source-filenames" type="as" />
+      <arg direction="in" name="target-filename" type="s" />
+      <arg direction="in" name="display" type="s" />
+      <arg direction="in" name="startup-id" type="s" />
+    </method>
+
+
+    <!--
+      MoveInto (working-directory : STRING, source-filenames : ARRAY OF STRING, target-filename : STRING, display : STRING, startup-id : STRING) : VOID
+
+      working-directory : working directory used to resolve relative filenames.
+      source-filenames  : an array of file names to move. The file names may
+                          be either file:-URIs, absolute paths or paths relative
+                          to the working-directory.
+      target-filename   : the target directory.
+      display           : the screen on which to launch the filenames or ""
+                          to use the default screen of the file manager.
+      startup-id        : the DESKTOP_STARTUP_ID environment variable for properly
+                           handling startup notification and focus stealing.
+    -->
+    <method name="MoveInto">
+      <arg direction="in" name="working-directory" type="s" />
+      <arg direction="in" name="source-filenames" type="as" />
+      <arg direction="in" name="target-filename" type="s" />
+      <arg direction="in" name="display" type="s" />
+      <arg direction="in" name="startup-id" type="s" />
+    </method>
+
+
+    <!--
+      LinkInto (working-directory : STRING, source-filenames : ARRAY OF STRING, target-filename : STRING, display : STRING, startup-id : STRING) : VOID
+
+      working-directory : working directory used to resolve relative filenames.
+      source-filenames  : an array of file names to link. The file names may
+                          be either file:-URIs, absolute paths or paths relative
+                          to the working-directory.
+      target-filename   : the target directory.
+      display           : the screen on which to launch the filenames or ""
+                          to use the default screen of the file manager.
+      startup-id        : the DESKTOP_STARTUP_ID environment variable for properly
+                           handling startup notification and focus stealing.
+    -->
+    <method name="LinkInto">
+      <arg direction="in" name="working-directory" type="s" />
+      <arg direction="in" name="source-filenames" type="as" />
+      <arg direction="in" name="target-filename" type="s" />
+      <arg direction="in" name="display" type="s" />
+      <arg direction="in" name="startup-id" type="s" />
+    </method>
+
+
+    <!--
+      UnlinkFiles (working-directory : STRING, filenames : ARRAY OF STRING, display : STRING, startup-id : STRING) : VOID
+
+      working-directory : working directory used to resolve relative filenames.
+      filenames         : an array of file names to delete. The file names may
+                          be either file:-URIs, absolute paths or paths relative
+                          to the working-directory.
+      display           : the screen on which to launch the filenames or ""
+                          to use the default screen of the file manager.
+      startup-id        : the DESKTOP_STARTUP_ID environment variable for properly
+                          handling startup notification and focus stealing.
+    -->
+    <method name="UnlinkFiles">
+      <arg direction="in" name="working-directory" type="s" />
+      <arg direction="in" name="filenames" type="as" />
+      <arg direction="in" name="display" type="s" />
+      <arg direction="in" name="startup-id" type="s" />
+    </method>
   </interface>
 
 
diff --git a/thunar/thunar-dbus-service.c b/thunar/thunar-dbus-service.c
index 987c8e6..1854379 100644
--- a/thunar/thunar-dbus-service.c
+++ b/thunar/thunar-dbus-service.c
@@ -35,6 +35,8 @@
 
 #include <glib/gstdio.h>
 
+#include <exo/exo.h>
+
 #include <thunar/thunar-application.h>
 #include <thunar/thunar-chooser-dialog.h>
 #include <thunar/thunar-dbus-service.h>
@@ -43,7 +45,16 @@
 #include <thunar/thunar-preferences-dialog.h>
 #include <thunar/thunar-private.h>
 #include <thunar/thunar-properties-dialog.h>
+#include <thunar/thunar-util.h>
+
 
+typedef enum
+{
+  THUNAR_DBUS_TRANSFER_MODE_COPY_TO,
+  THUNAR_DBUS_TRANSFER_MODE_COPY_INTO,
+  THUNAR_DBUS_TRANSFER_MODE_MOVE_INTO,
+  THUNAR_DBUS_TRANSFER_MODE_LINK_INTO,
+} ThunarDBusTransferMode;
 
 
 static void     thunar_dbus_service_finalize                    (GObject                *object);
@@ -55,6 +66,13 @@ static gboolean thunar_dbus_service_parse_uri_and_display       (ThunarDBusServi
                                                                  ThunarFile            **file_return,
                                                                  GdkScreen             **screen_return,
                                                                  GError                **error);
+static gboolean thunar_dbus_service_transfer_files              (ThunarDBusTransferMode  transfer_mode,
+                                                                 const gchar            *working_directory,
+                                                                 const gchar * const    *source_filenames,
+                                                                 const gchar * const    *target_filenames,
+                                                                 const gchar            *display,
+                                                                 const gchar            *startup_id,
+                                                                 GError                **error);
 static void     thunar_dbus_service_trash_bin_changed           (ThunarDBusService      *dbus_service,
                                                                  ThunarFile             *trash_bin);
 static gboolean thunar_dbus_service_display_chooser_dialog      (ThunarDBusService      *dbus_service,
@@ -108,6 +126,40 @@ static gboolean thunar_dbus_service_launch_files                (ThunarDBusServi
                                                                  const gchar            *display,
                                                                  const gchar            *startup_id,
                                                                  GError                **error);
+static gboolean thunar_dbus_service_copy_to                     (ThunarDBusService      *dbus_service,
+                                                                 const gchar            *working_directory,
+                                                                 gchar                 **source_filenames,
+                                                                 gchar                 **target_filenames,
+                                                                 const gchar            *display,
+                                                                 const gchar            *startup_id,
+                                                                 GError                **error);
+static gboolean thunar_dbus_service_copy_into                   (ThunarDBusService      *dbus_service,
+                                                                 const gchar            *working_directory,
+                                                                 gchar                 **source_filenames,
+                                                                 const gchar            *target_filename,
+                                                                 const gchar            *display,
+                                                                 const gchar            *startup_id,
+                                                                 GError                **error);
+static gboolean thunar_dbus_service_move_into                   (ThunarDBusService      *dbus_service,
+                                                                 const gchar            *working_directory,
+                                                                 gchar                 **source_filenames,
+                                                                 const gchar            *target_filenames,
+                                                                 const gchar            *display,
+                                                                 const gchar            *startup_id,
+                                                                 GError                **error);
+static gboolean thunar_dbus_service_link_into                   (ThunarDBusService      *dbus_service,
+                                                                 const gchar            *working_directory,
+                                                                 gchar                 **source_filenames,
+                                                                 const gchar            *target_filename,
+                                                                 const gchar            *display,
+                                                                 const gchar            *startup_id,
+                                                                 GError                **error);
+static gboolean thunar_dbus_service_unlink_files                (ThunarDBusService      *dbus_service,
+                                                                 const gchar            *working_directory,
+                                                                 gchar                 **filenames,
+                                                                 const gchar            *display,
+                                                                 const gchar            *startup_id,
+                                                                 GError                **error);
 static gboolean thunar_dbus_service_terminate                   (ThunarDBusService      *dbus_service,
                                                                  GError                **error);
 
@@ -724,6 +776,318 @@ thunar_dbus_service_launch_files (ThunarDBusService *dbus_service,
 
 
 static gboolean
+thunar_dbus_service_transfer_files (ThunarDBusTransferMode transfer_mode,
+                                    const gchar           *working_directory,
+                                    const gchar * const   *source_filenames,
+                                    const gchar * const   *target_filenames,
+                                    const gchar           *display,
+                                    const gchar           *startup_id,
+                                    GError               **error)
+{
+  ThunarApplication *application;
+  GdkScreen         *screen;
+  GError            *err = NULL;
+  GFile             *file;
+  GList             *source_file_list = NULL;
+  GList             *target_file_list = NULL;
+  gchar             *filename;
+  gchar             *new_working_dir = NULL;
+  gchar             *old_working_dir = NULL;
+  guint              n;
+
+  /* verify that at least one file to transfer is given */
+  if (source_filenames == NULL || *source_filenames == NULL)
+    {
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, 
+                   _("At least one source filename must be specified"));
+      return FALSE;
+    }
+
+  /* verify that the target filename is set / enough target filenames are given */
+  if (transfer_mode == THUNAR_DBUS_TRANSFER_MODE_COPY_TO) 
+    {
+      if (g_strv_length ((gchar **)source_filenames) != g_strv_length ((gchar **)target_filenames))
+        {
+          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL,
+                       _("The number of source and target filenames must be the same"));
+          return FALSE;
+        }
+    }
+  else
+    {
+      if (target_filenames == NULL || *target_filenames == NULL)
+        {
+          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL,
+                       _("A destination directory must be specified"));
+          return FALSE;
+        }
+    }
+
+  /* try to open the screen for the display name */
+  screen = thunar_gdk_screen_open (display, &err);
+  if (screen != NULL)
+    {
+      /* change the working directory if necessary */
+      if (!exo_str_is_empty (working_directory))
+        old_working_dir = thunar_util_change_working_directory (working_directory);
+
+      /* transform the source filenames into GFile objects */
+      for (n = 0; err == NULL && source_filenames[n] != NULL; ++n)
+        {
+          filename = g_filename_from_utf8 (source_filenames[n], -1, NULL, NULL, &err);
+          if (filename != NULL)
+            {
+              file = g_file_new_for_commandline_arg (filename);
+              source_file_list = thunar_g_file_list_append (source_file_list, file);
+              g_object_unref (file);
+              g_free (filename);
+            }
+        }
+
+      /* transform the target filename(s) into (a) GFile object(s) */
+      for (n = 0; err == NULL && target_filenames[n] != NULL; ++n)
+        {
+          filename = g_filename_from_utf8 (target_filenames[n], -1, NULL, NULL, &err);
+          if (filename != NULL)
+            {
+              file = g_file_new_for_commandline_arg (filename);
+              target_file_list = thunar_g_file_list_append (target_file_list, file);
+              g_object_unref (file);
+              g_free (filename);
+            }
+        }
+
+      /* switch back to the previous working directory */
+      if (!exo_str_is_empty (working_directory))
+        {
+          new_working_dir = thunar_util_change_working_directory (old_working_dir);
+          g_free (old_working_dir);
+          g_free (new_working_dir);
+        }
+
+      if (err == NULL)
+        {
+          /* let the application process the filenames */
+          application = thunar_application_get ();
+          switch (transfer_mode)
+            {
+            case THUNAR_DBUS_TRANSFER_MODE_COPY_TO:
+              thunar_application_copy_to (application, screen, 
+                                          source_file_list, target_file_list, 
+                                          NULL);
+              break;
+            case THUNAR_DBUS_TRANSFER_MODE_COPY_INTO:
+              thunar_application_copy_into (application, screen, 
+                                            source_file_list, target_file_list->data, 
+                                            NULL);
+              break;
+            case THUNAR_DBUS_TRANSFER_MODE_MOVE_INTO:
+              thunar_application_move_into (application, screen, 
+                                            source_file_list, target_file_list->data, 
+                                            NULL);
+              break;
+            case THUNAR_DBUS_TRANSFER_MODE_LINK_INTO:
+              thunar_application_link_into (application, screen, 
+                                            source_file_list, target_file_list->data, 
+                                            NULL);
+              break;
+            }
+          g_object_unref (application);
+        }
+
+      /* free the file lists */
+      thunar_g_file_list_free (source_file_list);
+      thunar_g_file_list_free (target_file_list);
+
+      /* release the screen */
+      g_object_unref (screen);
+    }
+
+  if (err != NULL)
+    {
+      g_propagate_error (error, err);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+
+
+static gboolean
+thunar_dbus_service_copy_to (ThunarDBusService *dbus_service,
+                             const gchar       *working_directory,
+                             gchar            **source_filenames,
+                             gchar            **target_filenames,
+                             const gchar       *display,
+                             const gchar       *startup_id,
+                             GError           **error)
+{
+  return thunar_dbus_service_transfer_files (THUNAR_DBUS_TRANSFER_MODE_COPY_TO,
+                                             working_directory,
+                                             (const gchar * const *)source_filenames,
+                                             (const gchar * const *)target_filenames,
+                                             display,
+                                             startup_id,
+                                             error);
+}
+
+
+
+static gboolean
+thunar_dbus_service_copy_into (ThunarDBusService *dbus_service,
+                               const gchar       *working_directory,
+                               gchar            **source_filenames,
+                               const gchar       *target_filename,
+                               const gchar       *display,
+                               const gchar       *startup_id,
+                               GError           **error)
+{
+  const gchar *target_filenames[2] = { target_filename, NULL };
+
+  return thunar_dbus_service_transfer_files (THUNAR_DBUS_TRANSFER_MODE_COPY_INTO,
+                                             working_directory,
+                                             (const gchar * const *)source_filenames,
+                                             target_filenames,
+                                             display,
+                                             startup_id,
+                                             error);
+}
+
+
+
+static gboolean
+thunar_dbus_service_move_into (ThunarDBusService *dbus_service,
+                               const gchar       *working_directory,
+                               gchar            **source_filenames,
+                               const gchar       *target_filename,
+                               const gchar       *display,
+                               const gchar       *startup_id,
+                               GError           **error)
+{
+  const gchar *target_filenames[2] = { target_filename, NULL };
+
+  return thunar_dbus_service_transfer_files (THUNAR_DBUS_TRANSFER_MODE_MOVE_INTO,
+                                             working_directory,
+                                             (const gchar * const *)source_filenames,
+                                             target_filenames,
+                                             display,
+                                             startup_id,
+                                             error);
+}
+
+
+
+static gboolean
+thunar_dbus_service_link_into (ThunarDBusService *dbus_service,
+                               const gchar       *working_directory,
+                               gchar            **source_filenames,
+                               const gchar       *target_filename,
+                               const gchar       *display,
+                               const gchar       *startup_id,
+                               GError           **error)
+{
+  const gchar *target_filenames[2] = { target_filename, NULL };
+
+  return thunar_dbus_service_transfer_files (THUNAR_DBUS_TRANSFER_MODE_LINK_INTO,
+                                             working_directory,
+                                             (const gchar * const *)source_filenames,
+                                             target_filenames,
+                                             display,
+                                             startup_id,
+                                             error);
+}
+
+
+static gboolean
+thunar_dbus_service_unlink_files (ThunarDBusService  *dbus_service,
+                                  const gchar        *working_directory,
+                                  gchar             **filenames,
+                                  const gchar        *display,
+                                  const gchar        *startup_id,
+                                  GError            **error)
+{
+  ThunarApplication *application;
+  ThunarFile        *thunar_file;
+  GFile             *file;
+  GdkScreen         *screen;
+  GError            *err = NULL;
+  GList             *file_list = NULL;
+  gchar             *filename;
+  gchar             *new_working_dir = NULL;
+  gchar             *old_working_dir = NULL;
+  guint              n;
+
+  /* verify that atleast one filename is given */
+  if (filenames == NULL || *filenames == NULL)
+    {
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("At least one filename must be specified"));
+      return FALSE;
+    }
+
+  /* try to open the screen for the display name */
+  screen = thunar_gdk_screen_open (display, &err);
+  if (screen != NULL)
+    {
+      /* change the working directory if necessary */
+      if (!exo_str_is_empty (working_directory))
+        old_working_dir = thunar_util_change_working_directory (working_directory);
+
+      /* try to parse the specified filenames */
+      for (n = 0; err == NULL && filenames[n] != NULL; ++n)
+        {
+          /* decode the filename (D-BUS uses UTF-8) */
+          filename = g_filename_from_utf8 (filenames[n], -1, NULL, NULL, &err);
+          if (filename != NULL)
+            {
+              /* determine the path for the filename */
+              file = g_file_new_for_commandline_arg (filename);
+              thunar_file = thunar_file_get (file, &err);
+
+              if (thunar_file != NULL)
+                file_list = g_list_append (file_list, thunar_file);
+
+              g_object_unref (file);
+            }
+
+          /* cleanup */
+          g_free (filename);
+        }
+
+      /* switch back to the previous working directory */
+      if (!exo_str_is_empty (working_directory))
+        {
+          new_working_dir = thunar_util_change_working_directory (old_working_dir);
+          g_free (old_working_dir);
+          g_free (new_working_dir);
+        }
+
+      /* check if we succeeded */
+      if (err == NULL)
+        {
+          /* tell the application to move the specified files to the trash */
+          application = thunar_application_get ();
+          thunar_application_unlink_files (application, screen, file_list, TRUE);
+          g_object_unref (application);
+        }
+
+      /* cleanup */
+      thunar_file_list_free (file_list);
+      g_object_unref (screen);
+    }
+
+  if (err != NULL)
+    {
+      g_propagate_error (error, err);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+
+
+static gboolean
 thunar_dbus_service_terminate (ThunarDBusService *dbus_service,
                                GError           **error)
 {
diff --git a/thunar/thunar-standard-view.c b/thunar/thunar-standard-view.c
index aed6542..04b3287 100644
--- a/thunar/thunar-standard-view.c
+++ b/thunar/thunar-standard-view.c
@@ -1973,7 +1973,7 @@ thunar_standard_view_action_delete (GtkAction          *action,
 
   /* delete the selected files */
   application = thunar_application_get ();
-  thunar_application_unlink_files (application, GTK_WIDGET (standard_view), standard_view->selected_files);
+  thunar_application_unlink_files (application, GTK_WIDGET (standard_view), standard_view->selected_files, FALSE);
   g_object_unref (G_OBJECT (application));
 }
 
diff --git a/thunar/thunar-tree-view.c b/thunar/thunar-tree-view.c
index 1bee4bb..2128e54 100644
--- a/thunar/thunar-tree-view.c
+++ b/thunar/thunar-tree-view.c
@@ -1643,7 +1643,7 @@ thunar_tree_view_action_delete (ThunarTreeView *view)
 
       /* delete the file */
       application = thunar_application_get ();
-      thunar_application_unlink_files (application, GTK_WIDGET (view), &file_list);
+      thunar_application_unlink_files (application, GTK_WIDGET (view), &file_list, FALSE);
       g_object_unref (G_OBJECT (application));
 
       /* release the file */



More information about the Xfce4-commits mailing list