]> uap-core.de Git - note.git/commitdiff
implement gtk3 textview dnd handler
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sat, 5 Apr 2025 20:12:55 +0000 (22:12 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sat, 5 Apr 2025 20:12:55 +0000 (22:12 +0200)
application/gtk-text.c

index 43f755c81b85b907aa322c866ed68b188a142a26..ab238bfa919d7f3d8932f36bfff6073285e8c1fd 100644 (file)
@@ -88,6 +88,16 @@ static gboolean editor_drop_cb(
 
 static gboolean editor_textview_event_after(GtkWidget *textview, GdkEvent *ev, NoteEditor *editor);
 
+static void editor_drop_cb(
+        GtkWidget *textview,
+        GdkDragContext *context,
+        gint x,
+        gint y,
+        GtkSelectionData *data,
+        guint info,
+        guint time,
+        NoteEditor *editor);
+
 #endif
 
 void editor_global_init() {
@@ -136,6 +146,20 @@ void editor_init_textview(UiObject *obj, UIWIDGET textview) {
     gtk_widget_add_controller(textview, GTK_EVENT_CONTROLLER(dndtarget));
 #else
     g_signal_connect(textview, "event-after", G_CALLBACK(editor_textview_event_after), editor);
+    
+    // dnd
+    GtkTargetEntry targets[] = {
+        { "text/uri-list", 0, 0 },
+        { "text/plain", 0, 0 }
+    };
+
+    gtk_drag_dest_set(textview,
+                      0,
+                      targets,
+                      G_N_ELEMENTS(targets),
+                      GDK_ACTION_COPY);
+    
+    g_signal_connect(textview, "drag-data-received", G_CALLBACK(editor_drop_cb), editor);
 #endif
     
     g_signal_connect(textview, "notify::buffer", G_CALLBACK(editor_set_buffer_cb), editor);
@@ -314,6 +338,44 @@ static void editor_attach_image(NoteEditor *editor, GdkPixbuf *pixbuf, char *att
     ui_list_update(model->attachments);
 }
 
+static gboolean editor_dnd_add_file(NoteEditor *editor, GFile *file) {
+    char *scheme = g_file_get_uri_scheme(file);
+    if(scheme && strcmp(scheme, "file")) {
+        g_free(scheme);
+        return FALSE;
+    }
+    g_free(scheme);
+    
+    gboolean success = 1;
+
+    GdkPixbuf *pixbuf = NULL;
+    
+    char *path = g_file_get_path(file);
+    char *attachment_path = strdup(path);
+    printf("dnd file: %s\n", path);
+
+    if(path_is_image_file(cx_str(path))) {
+        GError *error = NULL;
+        pixbuf = gdk_pixbuf_new_from_file(path, &error);
+        if(!pixbuf) {
+            // cannot load image, attach as generic file
+            success = editor_attach_file(editor, path);
+        }
+    } else {
+        // attach generic file
+        success = editor_attach_file(editor, path);
+    }
+    g_free(path);
+    
+    if(pixbuf && success) {
+        editor_attach_image(editor, pixbuf, attachment_path);
+    } else {
+        free(attachment_path);
+    }
+    
+    return success;
+}
+
 #if GTK_CHECK_VERSION(4, 0, 0)
 
 /*
@@ -366,50 +428,45 @@ static gboolean editor_drop_cb(
     if(G_VALUE_HOLDS(value, G_TYPE_FILE)) {
         // dnd type: uri
         GFile *file = g_value_get_object(value);
-        if(!file) {
-            return FALSE;
-        }
-        char *scheme = g_file_get_uri_scheme(file);
-        if(scheme && strcmp(scheme, "file")) {
-            g_free(scheme);
-            return FALSE;
-        }
-        g_free(scheme);
-        
-        char *path = g_file_get_path(file);
-        attachment_path = strdup(path);
-        printf("dnd file: %s\n", path);
-        
-        if(path_is_image_file(cx_str(path))) {
-            GError *error = NULL;
-            pixbuf = gdk_pixbuf_new_from_file(path, &error);
-            if(!pixbuf) {
-                // cannot load image, attach as generic file
-                success = editor_attach_file(editor, path);
-            }
-        } else {
-            // attach generic file
-            success = editor_attach_file(editor, path);
-        }
-        g_free(path);
+        success = editor_dnd_add_file(editor, file);
     } else if(G_VALUE_HOLDS (value, GDK_TYPE_PIXBUF)) {
         // dnd type image
         pixbuf = g_value_get_object(value);
+        editor_attach_image(editor, pixbuf, NULL);
     } else {
         return FALSE;
     }
     
-    if(pixbuf && success) {
-        editor_attach_image(editor, pixbuf, attachment_path);
-    } else {
-        free(attachment_path);
-    }
-    
     return success;
 }
 
 #else
 
+static void editor_drop_cb(
+        GtkWidget *textview,
+        GdkDragContext *context,
+        gint x,
+        gint y,
+        GtkSelectionData *data,
+        guint info,
+        guint time,
+        NoteEditor *editor)
+{
+    char **uris = gtk_selection_data_get_uris(data);
+    if(uris) {
+        char **uri = uris;
+        while(*uri) {
+            GFile *file = g_file_new_for_uri(*uri);
+            editor_dnd_add_file(editor, file); // TODO: handle error?
+            g_object_unref(file);
+            uri++;
+        }
+        g_strfreev(uris);
+    }
+    
+    gtk_drag_finish(context, TRUE, FALSE, time);
+}
+
 static gboolean editor_textview_event_after(GtkWidget *textview, GdkEvent *ev, NoteEditor *editor) {
     int x, y;
     if(ev->type == GDK_BUTTON_RELEASE) {