Documentation: Use G_SOURCE_CONTINUE and G_SOURCE_REMOVE
[geeqie.git] / src / utilops.cc
index 1619142..27c2eec 100644 (file)
 #include "utilops.h"
 
 #include "cache.h"
-#include "cache-maint.h"
-#include "collect.h"
-#include "dupe.h"
 #include "filedata.h"
 #include "filefilter.h"
 #include "image.h"
-#include "img-view.h"
-#include "layout.h"
-#include "search.h"
 #include "thumb-standard.h"
 #include "trash.h"
 #include "ui-bookmark.h"
 #include "ui-fileops.h"
 #include "ui-misc.h"
-#include "ui-tabcomp.h"
 #include "editors.h"
 #include "metadata.h"
 #include "exif.h"
 
 static GdkPixbuf *file_util_get_error_icon(FileData *fd, GList *list, GtkWidget *widget);
 
+static GtkTargetEntry target_types[] =
+{
+       {(gchar *)const_cast<gchar *>("text/plain"), 0, CLIPBOARD_TEXT_PLAIN},
+       {(gchar *)const_cast<gchar *>("text/uri-list"), 0, CLIPBOARD_TEXT_URI_LIST},
+       {(gchar *)"x-special/gnome-copied-files", 0, CLIPBOARD_X_SPECIAL_GNOME_COPIED_FILES},
+       {(gchar *)"UTF8_STRING", 0, CLIPBOARD_UTF8_STRING}
+};
+static gint target_types_n = 4;
+
+typedef struct _ClipboardData ClipboardData;
+struct _ClipboardData
+{
+       GList *path_list; /**< g_strdup(fd->path) */
+       gboolean quoted;
+};
+
 /*
  *--------------------------------------------------------------------------
  * Adds 1 or 2 images (if 2, side by side) to a GenericDialog
@@ -269,11 +278,11 @@ enum {
 
 typedef struct _UtilityDataMessages UtilityDataMessages;
 struct _UtilityDataMessages {
-       gchar *title;
-       gchar *question;
-       gchar *desc_flist;
-       gchar *desc_source_fd;
-       gchar *fail;
+       const gchar *title;
+       const gchar *question;
+       const gchar *desc_flist;
+       const gchar *desc_source_fd;
+       const gchar *fail;
 };
 
 typedef struct _UtilityData UtilityData;
@@ -360,8 +369,8 @@ static void generic_dialog_image_set(UtilityData *ud, FileData *fd)
        FileData *fd2 = NULL;
        gchar *buf;
 
-       imd = g_object_get_data(G_OBJECT(ud->gd->dialog), "img_image");
-       label = g_object_get_data(G_OBJECT(ud->gd->dialog), "img_label");
+       imd = static_cast<ImageWindow *>(g_object_get_data(G_OBJECT(ud->gd->dialog), "img_image"));
+       label = static_cast<GtkWidget *>(g_object_get_data(G_OBJECT(ud->gd->dialog), "img_label"));
 
        if (!imd) return;
 
@@ -372,8 +381,8 @@ static void generic_dialog_image_set(UtilityData *ud, FileData *fd)
 
        if (ud->type == UTILITY_TYPE_RENAME || ud->type == UTILITY_TYPE_COPY || ud->type == UTILITY_TYPE_MOVE)
                {
-               imd = g_object_get_data(G_OBJECT(ud->gd->dialog), "img_image2");
-               label = g_object_get_data(G_OBJECT(ud->gd->dialog), "img_label2");
+               imd = static_cast<ImageWindow *>(g_object_get_data(G_OBJECT(ud->gd->dialog), "img_image2"));
+               label = static_cast<GtkWidget *>(g_object_get_data(G_OBJECT(ud->gd->dialog), "img_label2"));
 
                if (imd)
                        {
@@ -513,7 +522,7 @@ static GtkWidget *file_util_dialog_add_list(GtkWidget *box, GList *list, gboolea
 
        while (list)
                {
-               FileData *fd = list->data;
+               FileData *fd = static_cast<FileData *>(list->data);
                GtkTreeIter iter;
                gchar *sidecars;
 
@@ -547,7 +556,7 @@ static gint file_util_perform_ci_cb(gpointer resume_data, EditorFlags flags, GLi
 
 static void file_util_resume_cb(GenericDialog *UNUSED(gd), gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
        if (ud->external)
                editor_resume(ud->resume_data);
        else
@@ -556,7 +565,7 @@ static void file_util_resume_cb(GenericDialog *UNUSED(gd), gpointer data)
 
 static void file_util_abort_cb(GenericDialog *UNUSED(gd), gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
        if (ud->external)
                editor_skip(ud->resume_data);
        else
@@ -567,7 +576,7 @@ static void file_util_abort_cb(GenericDialog *UNUSED(gd), gpointer data)
 
 static gint file_util_perform_ci_cb(gpointer resume_data, EditorFlags flags, GList *list, gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
        gint ret = EDITOR_CB_CONTINUE;
 
        ud->resume_data = resume_data;
@@ -581,7 +590,7 @@ static gint file_util_perform_ci_cb(gpointer resume_data, EditorFlags flags, GLi
                g_string_append(msg, "\n");
                while (list)
                        {
-                       FileData *fd = list->data;
+                       FileData *fd = static_cast<FileData *>(list->data);
 
                        g_string_append(msg, fd->path);
                        g_string_append(msg, "\n");
@@ -611,7 +620,7 @@ static gint file_util_perform_ci_cb(gpointer resume_data, EditorFlags flags, GLi
 
        while (list)  /* be careful, file_util_perform_ci_internal can pass ud->flist as list */
                {
-               FileData *fd = list->data;
+               FileData *fd = static_cast<FileData *>(list->data);
                list = list->next;
 
                if (!EDITOR_ERRORS(flags)) /* files were successfully deleted, call the maint functions */
@@ -654,7 +663,7 @@ static gint file_util_perform_ci_cb(gpointer resume_data, EditorFlags flags, GLi
 
 static gboolean file_util_perform_ci_internal(gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
 
        if (!ud->perform_idle_id)
                {
@@ -664,7 +673,7 @@ static gboolean file_util_perform_ci_internal(gpointer data)
 
                /* this is removed when ud is destroyed */
                ud->perform_idle_id = g_idle_add(file_util_perform_ci_internal, ud);
-               return TRUE;
+               return G_SOURCE_CONTINUE;
                }
 
        g_assert(ud->flist);
@@ -678,23 +687,23 @@ static gboolean file_util_perform_ci_internal(gpointer data)
                gboolean last = !ud->flist->next;
                EditorFlags status = EDITOR_ERROR_STATUS;
 
-               if (ud->with_sidecars ? file_data_sc_perform_ci(single_entry->data)
-                                     : file_data_perform_ci(single_entry->data))
-                       status = 0; /* OK */
+               if (ud->with_sidecars ? file_data_sc_perform_ci(static_cast<FileData *>(single_entry->data))
+                                     : file_data_perform_ci(static_cast<FileData *>(single_entry->data)))
+                       status = static_cast<EditorFlags>(0); /* OK */
 
                ret = file_util_perform_ci_cb(GINT_TO_POINTER(!last), status, single_entry, ud);
                g_list_free(single_entry);
 
-               if (ret == EDITOR_CB_SUSPEND || last) return FALSE;
+               if (ret == EDITOR_CB_SUSPEND || last) return G_SOURCE_REMOVE;
 
                if (ret == EDITOR_CB_SKIP)
                        {
                        file_util_perform_ci_cb(NULL, EDITOR_ERROR_SKIPPED, ud->flist, ud);
-                       return FALSE;
+                       return G_SOURCE_REMOVE;
                        }
                }
 
-       return TRUE;
+       return G_SOURCE_CONTINUE;
 }
 
 static void file_util_perform_ci_dir(UtilityData *ud, gboolean internal, gboolean ext_result)
@@ -729,7 +738,7 @@ static void file_util_perform_ci_dir(UtilityData *ud, gboolean internal, gboolea
                                {
                                FileData *fd;
 
-                               fd = work->data;
+                               fd = static_cast<FileData *>(work->data);
                                work = work->next;
 
                                if (!fail)
@@ -805,7 +814,7 @@ static void file_util_perform_ci_dir(UtilityData *ud, gboolean internal, gboolea
                                {
                                FileData *fd;
 
-                               fd = work->data;
+                               fd = static_cast<FileData *>(work->data);
                                work = work->next;
 
                                if (!fail)
@@ -854,7 +863,7 @@ static void file_util_perform_ci_dir(UtilityData *ud, gboolean internal, gboolea
 
 static gint file_util_perform_ci_dir_cb(gpointer UNUSED(resume_data), EditorFlags flags, GList *UNUSED(list), gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
        file_util_perform_ci_dir(ud, FALSE, !EDITOR_ERRORS_BUT_SKIPPED(flags));
        return EDITOR_CB_CONTINUE; /* does not matter, there was just single directory */
 }
@@ -978,14 +987,14 @@ static GdkPixbuf *file_util_get_error_icon(FileData *fd, GList *list, GtkWidget
 
 static void file_util_check_resume_cb(GenericDialog *UNUSED(gd), gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
        ud->phase = UTILITY_PHASE_CHECKED;
        file_util_dialog_run(ud);
 }
 
 static void file_util_check_abort_cb(GenericDialog *UNUSED(gd), gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
        ud->phase = UTILITY_PHASE_START;
        file_util_dialog_run(ud);
 }
@@ -1069,7 +1078,7 @@ void file_util_check_ci(UtilityData *ud)
 
 static void file_util_cancel_cb(GenericDialog *gd, gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
 
        generic_dialog_close(gd);
 
@@ -1081,7 +1090,7 @@ static void file_util_cancel_cb(GenericDialog *gd, gpointer data)
 
 static void file_util_discard_cb(GenericDialog *gd, gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
 
        generic_dialog_close(gd);
 
@@ -1093,7 +1102,7 @@ static void file_util_discard_cb(GenericDialog *gd, gpointer data)
 
 static void file_util_ok_cb(GenericDialog *gd, gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
 
        generic_dialog_close(gd);
 
@@ -1104,7 +1113,7 @@ static void file_util_ok_cb(GenericDialog *gd, gpointer data)
 
 static void file_util_fdlg_cancel_cb(FileDialog *fdlg, gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
 
        file_dialog_close(fdlg);
 
@@ -1147,7 +1156,7 @@ static void file_util_dest_folder_update_path(UtilityData *ud)
 
 static void file_util_fdlg_rename_cb(FileDialog *fdlg, gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
        gchar *desc = NULL;
        GenericDialog *d = NULL;
 
@@ -1183,7 +1192,7 @@ static void file_util_fdlg_rename_cb(FileDialog *fdlg, gpointer data)
 
 static void file_util_fdlg_ok_cb(FileDialog *fdlg, gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
 
        file_util_dest_folder_update_path(ud);
        if (isdir(ud->dest_path)) file_dialog_sync_history(fdlg, TRUE);
@@ -1199,7 +1208,7 @@ static void file_util_fdlg_ok_cb(FileDialog *fdlg, gpointer data)
 
 static void file_util_dest_folder_entry_cb(GtkWidget *UNUSED(entry), gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
        file_util_dest_folder_update_path(ud);
 }
 
@@ -1420,30 +1429,30 @@ static void file_util_rename_preview_update(UtilityData *ud)
 
 static void file_util_rename_preview_entry_cb(GtkWidget *UNUSED(entry), gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
        file_util_rename_preview_update(ud);
 }
 
 static void file_util_rename_preview_adj_cb(GtkWidget *UNUSED(spin), gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
        file_util_rename_preview_update(ud);
 }
 
 static gboolean file_util_rename_idle_cb(gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
 
        file_util_rename_preview_update(ud);
 
        ud->update_idle_id = 0;
-       return FALSE;
+       return G_SOURCE_REMOVE;
 }
 
 static void file_util_rename_preview_order_cb(GtkTreeModel *UNUSED(treemodel), GtkTreePath *UNUSED(tpath),
                                              GtkTreeIter *UNUSED(iter), gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
 
        if (ud->update_idle_id) return;
 
@@ -1455,7 +1464,7 @@ static gboolean file_util_preview_cb(GtkTreeSelection *UNUSED(selection), GtkTre
                                     GtkTreePath *tpath, gboolean path_currently_selected,
                                     gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
        GtkTreeIter iter;
        FileData *fd = NULL;
 
@@ -1500,7 +1509,7 @@ static void box_append_safe_delete_status(GenericDialog *gd)
 
 static void file_util_details_cb(GenericDialog *UNUSED(gd), gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
        if (ud->details_func && ud->sel_fd)
                {
                ud->details_func(ud, ud->sel_fd);
@@ -1722,7 +1731,7 @@ static void file_util_dialog_init_source_dest(UtilityData *ud, gboolean second_i
        pref_table_label(table, 0, 1, _("New name:"), 1.0);
 
        ud->rename_entry = gtk_entry_new();
-       gtk_table_attach(GTK_TABLE(table), ud->rename_entry, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 0, 0);
+       gtk_table_attach(GTK_TABLE(table), ud->rename_entry, 1, 2, 1, 2, static_cast<GtkAttachOptions>(GTK_EXPAND | GTK_FILL), static_cast<GtkAttachOptions>(0), 0, 0);
        generic_dialog_attach_default(GENERIC_DIALOG(ud->gd), ud->rename_entry);
        gtk_widget_grab_focus(ud->rename_entry);
 
@@ -1799,7 +1808,7 @@ static void file_util_finalize_all(UtilityData *ud)
 
        while (work)
                {
-               FileData *fd = work->data;
+               FileData *fd = static_cast<FileData *>(work->data);
                work = work->next;
                if (ud->phase == UTILITY_PHASE_DONE) ud->finalize_func(fd);
                else if (ud->phase == UTILITY_PHASE_DISCARD) ud->discard_func(fd);
@@ -1927,13 +1936,13 @@ static void file_util_warn_op_in_progress(const gchar *title)
 
 static void file_util_details_dialog_close_cb(GtkWidget *UNUSED(widget), gpointer data)
 {
-       gtk_widget_destroy(data);
+       gtk_widget_destroy(GTK_WIDGET(data));
 
 }
 
 static void file_util_details_dialog_destroy_cb(GtkWidget *widget, gpointer data)
 {
-       UtilityData *ud = data;
+       UtilityData *ud = static_cast<UtilityData *>(data);
        g_signal_handlers_disconnect_by_func(ud->gd->dialog, (gpointer)(file_util_details_dialog_close_cb), widget);
 }
 
@@ -1945,8 +1954,8 @@ static void file_util_details_dialog_ok_cb(GenericDialog *UNUSED(gd), gpointer U
 
 static void file_util_details_dialog_exclude(GenericDialog *gd, gpointer data, gboolean discard)
 {
-       UtilityData *ud = data;
-       FileData *fd = g_object_get_data(G_OBJECT(gd->dialog), "file_data");
+       UtilityData *ud = static_cast<UtilityData *>(data);
+       FileData *fd = static_cast<FileData *>(g_object_get_data(G_OBJECT(gd->dialog), "file_data"));
 
        if (!fd) return;
        file_util_exclude_fd(ud, fd);
@@ -1987,7 +1996,7 @@ static gchar *file_util_details_get_message(UtilityData *ud, FileData *fd, const
 
                while (work)
                        {
-                       FileData *sfd = work->data;
+                       FileData *sfd = static_cast<FileData *>(work->data);
                        work =work->next;
                        g_string_append_printf(message, _(" '%s'\n"), sfd->path);
                        }
@@ -2102,7 +2111,7 @@ static void file_util_write_metadata_details_dialog(UtilityData *ud, FileData *f
        i = 0;
        while (work)
                {
-               const gchar *key = work->data;
+               const gchar *key = static_cast<const gchar *>(work->data);
                gchar *title = exif_get_description_by_key(key);
                gchar *title_f = g_strdup_printf("%s:", title);
                gchar *value = metadata_read_string(fd, key, METADATA_FORMATTED);
@@ -2153,7 +2162,7 @@ static void file_util_mark_ungrouped_files(GList *work)
 {
        while (work)
                {
-               FileData *fd = work->data;
+               FileData *fd = static_cast<FileData *>(work->data);
                file_data_set_regroup_when_finished(fd, TRUE);
                work = work->next;
                }
@@ -2498,7 +2507,7 @@ static GList *file_util_delete_dir_remaining_folders(GList *dlist)
                {
                FileData *fd;
 
-               fd = dlist->data;
+               fd = static_cast<FileData *>(dlist->data);
                dlist = dlist->next;
 
                if (!fd->name ||
@@ -2552,7 +2561,7 @@ static gboolean file_util_delete_dir_empty_path(UtilityData *ud, FileData *fd, g
                {
                FileData *lfd;
 
-               lfd = work->data;
+               lfd = static_cast<FileData *>(work->data);
                work = work->next;
 
                ok = file_util_delete_dir_empty_path(ud, lfd, level);
@@ -2563,7 +2572,7 @@ static gboolean file_util_delete_dir_empty_path(UtilityData *ud, FileData *fd, g
                {
                FileData *lfd;
 
-               lfd = work->data;
+               lfd = static_cast<FileData *>(work->data);
                work = work->next;
 
                DEBUG_1("deltree child: %s", lfd->path);
@@ -2596,7 +2605,7 @@ static gboolean file_util_delete_dir_prepare(UtilityData *ud, GList *flist, GLis
                {
                FileData *fd;
 
-               fd = work->data;
+               fd = static_cast<FileData *>(work->data);
                work = work->next;
 
                ok = file_util_delete_dir_empty_path(ud, fd, 0);
@@ -2624,7 +2633,7 @@ static gboolean file_util_delete_dir_prepare(UtilityData *ud, GList *flist, GLis
                        {
                        FileData *fd;
 
-                       fd = work->data;
+                       fd = static_cast<FileData *>(work->data);
                        work = work->next;
                        file_data_sc_free_ci(fd);
                        }
@@ -2778,7 +2787,7 @@ static gboolean file_util_rename_dir_scan(UtilityData *ud, FileData *fd)
                {
                FileData *lfd;
 
-               lfd = work->data;
+               lfd = static_cast<FileData *>(work->data);
                work = work->next;
 
                ud->content_list = g_list_prepend(ud->content_list, file_data_ref(lfd));
@@ -2805,7 +2814,7 @@ static gboolean file_util_rename_dir_prepare(UtilityData *ud, const gchar *new_p
                gchar *np;
                FileData *fd;
 
-               fd = work->data;
+               fd = static_cast<FileData *>(work->data);
                work = work->next;
 
                g_assert(strncmp(fd->path, ud->dir_fd->path, orig_len) == 0);
@@ -2830,7 +2839,7 @@ static gboolean file_util_rename_dir_prepare(UtilityData *ud, const gchar *new_p
                        {
                        FileData *fd;
 
-                       fd = work->data;
+                       fd = static_cast<FileData *>(work->data);
                        work = work->next;
                        file_data_sc_free_ci(fd);
                        }
@@ -2926,7 +2935,7 @@ static void file_util_create_dir_full(FileData *fd, const gchar *dest_path, GtkW
 
 static gboolean file_util_write_metadata_first_after_done(gpointer data)
 {
-       UtilityDelayData *dd = data;
+       UtilityDelayData *dd = static_cast<UtilityDelayData *>(data);
 
        /* start the delayed operation with original arguments */
        switch (dd->type)
@@ -2944,12 +2953,12 @@ static gboolean file_util_write_metadata_first_after_done(gpointer data)
        g_free(dd->dest_path);
        g_free(dd->editor_key);
        g_free(dd);
-       return FALSE;
+       return G_SOURCE_REMOVE;
 }
 
 static void file_util_write_metadata_first_done(gboolean success, const gchar *UNUSED(done_path), gpointer data)
 {
-       UtilityDelayData *dd = data;
+       UtilityDelayData *dd = static_cast<UtilityDelayData *>(data);
 
        if (success)
                {
@@ -2974,7 +2983,7 @@ static gboolean file_util_write_metadata_first(UtilityType type, UtilityPhase ph
        work = flist;
        while (work)
                {
-               FileData *fd = work->data;
+               FileData *fd = static_cast<FileData *>(work->data);
                work = work->next;
 
                if (fd->change)
@@ -3071,10 +3080,10 @@ void file_util_start_editor_from_filelist(const gchar *key, GList *list, const g
        file_util_start_editor_full(key, NULL, list, NULL, working_directory, parent, UTILITY_PHASE_ENTERING);
 }
 
-void file_util_start_filter_from_file(const gchar *key, FileData *fd, const gchar *dest_path, GtkWidget *parent)
-{
-       file_util_start_editor_full(key, fd, NULL, dest_path, NULL, parent, UTILITY_PHASE_ENTERING);
-}
+//void file_util_start_filter_from_file(const gchar *key, FileData *fd, const gchar *dest_path, GtkWidget *parent)
+//{
+       //file_util_start_editor_full(key, fd, NULL, dest_path, NULL, parent, UTILITY_PHASE_ENTERING);
+//}
 
 void file_util_start_filter_from_filelist(const gchar *key, GList *list, const gchar *dest_path, GtkWidget *parent)
 {
@@ -3096,71 +3105,174 @@ void file_util_rename_dir(FileData *source_fd, const gchar *new_path, GtkWidget
        file_util_rename_dir_full(source_fd, new_path, parent, UTILITY_PHASE_ENTERING, done_func, done_data);
 }
 
-
-void file_util_copy_path_to_clipboard(FileData *fd, gboolean quoted)
+/**
+ * @brief
+ * @param clipboard
+ * @param selection_data
+ * @param info
+ * @param data #_ClipboardData
+ *
+ *
+ */
+static void clipboard_get_func(GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info, gpointer data)
 {
-       if (!fd || !*fd->path) return;
+       ClipboardData *cbd = static_cast<ClipboardData *>(data);
+       gchar *file_path;
+       gchar *file_path_quoted = NULL;
+       gchar *file_path_uri;
+       GString *path_list_str;
+       GList *work;
 
-       if (options->clipboard_selection == CLIPBOARD_PRIMARY)
-               {
-               gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), quoted ? g_shell_quote(fd->path) :  fd->path , -1);
-               }
-       else if (options->clipboard_selection == CLIPBOARD_CLIPBOARD)
+       path_list_str = g_string_new("");
+       work = cbd->path_list;
+
+       if (clipboard == gtk_clipboard_get(GDK_SELECTION_CLIPBOARD) && info == CLIPBOARD_X_SPECIAL_GNOME_COPIED_FILES)
                {
-               gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), quoted ? g_shell_quote(fd->path) :  fd->path , -1);
+               g_string_append(path_list_str, "copy");
+
+               while (work)
+                       {
+                       file_path = static_cast<gchar *>(work->data);
+                       work = work->next;
+
+                       file_path_uri = g_filename_to_uri(file_path, NULL, NULL);
+                       g_string_append(path_list_str, "\n");
+                       g_string_append(path_list_str, file_path_uri);
+                       g_free(file_path_uri);
+                       }
                }
        else
                {
-               gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), quoted ? g_shell_quote(fd->path) :  fd->path , -1);
-               gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), quoted ? g_shell_quote(fd->path) :  fd->path , -1);
+               while (work)
+                       {
+                       file_path = static_cast<gchar *>(work->data);
+                       work = work->next;
+
+                       if (cbd->quoted)
+                               {
+                               file_path_quoted = g_shell_quote(file_path);
+                               g_string_append(path_list_str, file_path_quoted);
+                               g_free(file_path_quoted);
+                               }
+                       else
+                               {
+                               g_string_append(path_list_str, file_path);
+                               }
+
+                       if (work)
+                               {
+                               g_string_append_c(path_list_str, ' ');
+                               }
+                       }
                }
+
+       gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data), 8, reinterpret_cast<guchar *>(path_list_str->str), strlen(path_list_str->str));
+
+       g_string_free(path_list_str, TRUE);
 }
 
-void file_util_copy_path_list_to_clipboard(GList *list, gboolean quoted)
+/**
+ * @brief
+ * @param UNUSED
+ * @param data _ClipboardData
+ *
+ *
+ */
+static void clipboard_clear_func(GtkClipboard *UNUSED(clipboard), gpointer data)
 {
-       GList *work;
-       GString *path_list_str;
+       ClipboardData *cbd = static_cast<ClipboardData *>(data);
 
-       path_list_str = g_string_new("");
-       work = list;
-       while (work) {
-               FileData *fd = work->data;
-               work = work->next;
+       string_list_free(cbd->path_list);
+       g_free(cbd);
+}
 
-               if (!fd || !*fd->path) continue;
+void file_util_copy_path_to_clipboard(FileData *fd, gboolean quoted)
+{
+       ClipboardData *cbd;
 
-               if (quoted)
-                       {
-                       g_string_append(path_list_str, g_shell_quote(fd->path));
-                       }
-               else
-                       {
-                       g_string_append(path_list_str, fd->path);
-                       }
-               if (work) g_string_append_c(path_list_str, ' ');
+       if (!fd || !*fd->path) return;
+
+
+       if (options->clipboard_selection == CLIPBOARD_PRIMARY || options->clipboard_selection == CLIPBOARD_BOTH)
+               {
+               cbd = g_new0(ClipboardData, 1);
+               cbd->path_list = NULL;
+               cbd->quoted = quoted;
+               cbd->path_list = g_list_append(cbd->path_list, g_strdup(fd->path));
+
+               gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_PRIMARY), target_types, target_types_n, clipboard_get_func, clipboard_clear_func, cbd);
                }
 
-       if (options->clipboard_selection == CLIPBOARD_PRIMARY)
+       if (options->clipboard_selection == CLIPBOARD_CLIPBOARD || options->clipboard_selection == CLIPBOARD_BOTH)
                {
-               gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), path_list_str->str, path_list_str->len);
+               cbd = g_new0(ClipboardData, 1);
+               cbd->path_list = NULL;
+               cbd->quoted = quoted;
+               cbd->path_list = g_list_append(cbd->path_list, g_strdup(fd->path));
+
+               gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), target_types, target_types_n, clipboard_get_func, clipboard_clear_func, cbd);
                }
-       else if  (options->clipboard_selection == CLIPBOARD_CLIPBOARD)
+}
+
+/**
+ * @brief
+ * @param fd_list List of fd
+ * @param quoted
+ *
+ *
+ */
+void file_util_copy_path_list_to_clipboard(GList *fd_list, gboolean quoted)
+{
+       ClipboardData *cbd;
+       FileData *fd;
+       GList *work;
+
+       if (options->clipboard_selection == CLIPBOARD_PRIMARY || options->clipboard_selection == CLIPBOARD_BOTH)
                {
-               gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), path_list_str->str, path_list_str->len);
+               cbd = g_new0(ClipboardData, 1);
+               cbd->path_list = NULL;
+               cbd->quoted = quoted;
+               work = fd_list;
+
+               while (work)
+                       {
+                       fd = static_cast<FileData *>(work->data);
+                       work = work->next;
+
+                       if (!fd || !*fd->path) continue;
+
+                       cbd->path_list = g_list_append(cbd->path_list, g_strdup(fd->path));
+                       }
+
+                       gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_PRIMARY), target_types, target_types_n, clipboard_get_func, clipboard_clear_func, cbd);
                }
-       else
+
+       if (options->clipboard_selection == CLIPBOARD_CLIPBOARD || options->clipboard_selection == CLIPBOARD_BOTH)
                {
-               gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), path_list_str->str, path_list_str->len);
-               gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), path_list_str->str, path_list_str->len);
+               cbd = g_new0(ClipboardData, 1);
+               cbd->path_list = NULL;
+               cbd->quoted = quoted;
+               work = fd_list;
+
+               while (work)
+                       {
+                       fd = static_cast<FileData *>(work->data);
+                       work = work->next;
+
+                       if (!fd || !*fd->path) continue;
+
+                       cbd->path_list = g_list_append(cbd->path_list, g_strdup(fd->path));
+                       }
+
+                       gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), target_types, target_types_n, clipboard_get_func, clipboard_clear_func, cbd);
                }
 
-       g_string_free(path_list_str, TRUE);
-       filelist_free(list);
+       filelist_free(fd_list);
 }
 
 static void new_folder_entry_activate_cb(GtkWidget *UNUSED(widget), gpointer data)
 {
-       GtkDialog *dialog = data;
+       GtkDialog *dialog = static_cast<GtkDialog *>(data);
 
        gtk_dialog_response(dialog, GTK_RESPONSE_ACCEPT);
 }