[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