Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drag and drop #592

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ indent_size = 4
insert_final_newline = false
max_line_length = 120
tab_width = 8
trim_trailing_whitespace = true
trim_trailing_whitespace = true

[COMMIT_EDITMSG]
max_line_length = 72
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Makefile.in
/.version
/config.h*
fsearch*-dirty
.ccls-cache/

# Project files
tags
Expand Down Expand Up @@ -152,4 +153,4 @@ po/stamp-it
/src/ui_resources.h
/tools/print_version.sh
/data/io.github.cboxdoerfer.FSearch.desktop
/data/io.github.cboxdoerfer.FSearch.desktop.in
/data/io.github.cboxdoerfer.FSearch.desktop.in
68 changes: 67 additions & 1 deletion src/fsearch_list_view.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ struct _FsearchListView {
FsearchListViewSelectToggleFunc select_toggle_func;
FsearchListViewUnselectAllFunc unselect_func;
FsearchListViewNumSelectedFunc num_selected_func;
FsearchListViewDragDataGetFunc drag_data_get_func;
gpointer selection_user_data;
};

Expand Down Expand Up @@ -869,6 +870,14 @@ on_fsearch_list_view_bin_drag_gesture_end(GtkGestureDrag *gesture,
FsearchListView *view) {
// GdkEventSequence *sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture));
if (view->bin_drag_mode) {
double drag_distance = hypot(view->x_bin_drag_offset, view->y_bin_drag_offset);
double coordinate_x = view->x_bin_drag_started + offset_x, coordinate_y = view->y_bin_drag_started + offset_y;
printf("Drag details: %d, %d, %d, %d, %f\n",
view->x_bin_drag_started,
view->x_bin_drag_offset,
view->y_bin_drag_started,
view->y_bin_drag_offset,
drag_distance);
view->bin_drag_mode = FALSE;
view->rubberband_state = RUBBERBAND_SELECT_INACTIVE;
view->x_bin_drag_started = -1;
Expand All @@ -879,7 +888,15 @@ on_fsearch_list_view_bin_drag_gesture_end(GtkGestureDrag *gesture,
view->rubberband_end_idx = UNSET_ROW;
view->rubberband_extend = FALSE;
view->rubberband_modify = FALSE;
GtkTargetEntry targets[] = {{"text/plain", 0, 0}, {"text/uri-list", 0, 1}};
gtk_widget_queue_draw(GTK_WIDGET(view));
gtk_drag_begin_with_coordinates(GTK_WIDGET(view),
gtk_target_list_new(targets, G_N_ELEMENTS(targets)),
GDK_ACTION_COPY,
GDK_BUTTON_PRIMARY,
gtk_get_current_event(),
coordinate_x,
coordinate_y);
}
}

Expand Down Expand Up @@ -1107,6 +1124,49 @@ on_fsearch_list_view_bin_drag_gesture_begin(GtkGestureDrag *gesture,
}
}

static void
on_drag_data_get(GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint32 time,
gpointer user_data) {
FsearchListView *view = FSEARCH_LIST_VIEW(widget);
if (!view->drag_data_get_func) {
g_warning("drag_data_get_func is not set for FsearchListView.");
return;
}

GList *indices = NULL;
for (int i = 0; i < view->num_rows; i++) {
if (view->is_selected_func(i, view->selection_user_data)) {
indices = g_list_append(indices, GINT_TO_POINTER(i));
}
}

GList *uris = view->drag_data_get_func(indices, view->selection_user_data);

g_list_free(indices);

if (uris) {
gchar **uri_array = g_new(gchar *, g_list_length(uris) + 1);
int index = 0;
for (GList *l = uris; l != NULL; l = l->next) {
uri_array[index++] = g_strdup((gchar *)l->data);
}
uri_array[index] = NULL;
gtk_selection_data_set_uris(selection_data, uri_array);
g_list_free_full(uris, g_free);
for (int i = 0; uri_array[i] != NULL; i++) {
g_free(uri_array[i]);
}
g_free(uri_array);
}
else {
g_warning("No URIs available for drag operation.");
}
}

static void
on_fsearch_list_view_header_drag_gesture_end(GtkGestureDrag *gesture,
gdouble offset_x,
Expand Down Expand Up @@ -1956,6 +2016,7 @@ fsearch_list_view_init(FsearchListView *view) {
g_signal_connect(view->bin_drag_gesture, "drag-begin", G_CALLBACK(on_fsearch_list_view_bin_drag_gesture_begin), view);
g_signal_connect(view->bin_drag_gesture, "drag-update", G_CALLBACK(on_fsearch_list_view_bin_drag_gesture_update), view);
g_signal_connect(view->bin_drag_gesture, "drag-end", G_CALLBACK(on_fsearch_list_view_bin_drag_gesture_end), view);
g_signal_connect(view, "drag-data-get", G_CALLBACK(on_drag_data_get), view);

view->header_drag_gesture = gtk_gesture_drag_new(GTK_WIDGET(view));
g_signal_connect(view->header_drag_gesture,
Expand Down Expand Up @@ -2262,6 +2323,11 @@ fsearch_list_view_set_selection_handlers(FsearchListView *view,
}
}

void
fsearch_list_view_set_drag_data_get_handler(FsearchListView *view, FsearchListViewDragDataGetFunc drag_data_get_func) {
view->drag_data_get_func = drag_data_get_func;
}

gint
fsearch_list_view_get_cursor(FsearchListView *view) {
if (!view) {
Expand Down Expand Up @@ -2357,4 +2423,4 @@ fsearch_list_view_column_new(int type,
col->ref_count = 1;

return col;
}
}
7 changes: 6 additions & 1 deletion src/fsearch_list_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ typedef void (*FsearchListViewSelectRangeFunc)(int start_idx, int end_idx, gpoin
typedef void (*FsearchListViewUnselectAllFunc)(gpointer user_data);
typedef guint (*FsearchListViewNumSelectedFunc)(gpointer user_data);

typedef GList* (*FsearchListViewDragDataGetFunc) (GList *indices, gpointer user_data);

FsearchListViewColumn *
fsearch_list_view_column_ref(FsearchListViewColumn *col);

Expand Down Expand Up @@ -91,6 +93,9 @@ fsearch_list_view_set_selection_handlers(FsearchListView *view,
FsearchListViewNumSelectedFunc num_selected_func,
gpointer user_data);

void
fsearch_list_view_set_drag_data_get_handler(FsearchListView *view, FsearchListViewDragDataGetFunc drag_data_get_func);

void
fsearch_list_view_column_set_visible(FsearchListView *view, FsearchListViewColumn *col, gboolean visible);

Expand Down Expand Up @@ -136,4 +141,4 @@ fsearch_list_view_set_query_tooltip_func(FsearchListView *view,
gpointer func_data);

void
fsearch_list_view_set_draw_row_func(FsearchListView *view, FsearchListViewDrawRowFunc func, gpointer func_data);
fsearch_list_view_set_draw_row_func(FsearchListView *view, FsearchListViewDrawRowFunc func, gpointer func_data);
33 changes: 32 additions & 1 deletion src/fsearch_window.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,36 @@ on_listview_row_is_selected(int row, gpointer user_data) {
return FALSE;
}

static GList*
listview_on_drag_data_get(GList *indices, gpointer user_data) {
FsearchApplicationWindow *win = FSEARCH_APPLICATION_WINDOW(user_data);
FsearchDatabaseView *db_view = win->result_view->database_view;

if (!db_view) {
g_warning("Database view is NULL.");
return NULL;
}

GList *uris = NULL;
for (GList *l = indices; l != NULL; l = l->next) {
int idx = GPOINTER_TO_INT(l->data);
GString *path = db_view_entry_get_path_full_for_idx(db_view, idx);
if (path) {
gchar *uri = g_filename_to_uri(path->str, NULL, NULL);
if (uri) {
uris = g_list_append(uris, uri);
} else {
g_warning("Failed to convert path to URI: %s", path->str);
}
g_free(path);
} else {
g_warning("Failed to retrieve path for index: %d", idx);
}
}

return uris;
}

static void
fsearch_application_window_init_overlays(FsearchApplicationWindow *win) {
g_assert(FSEARCH_IS_APPLICATION_WINDOW(win));
Expand Down Expand Up @@ -786,6 +816,7 @@ fsearch_application_window_init_listview(FsearchApplicationWindow *win) {
on_listview_row_unselect_all,
on_listview_row_num_selected,
win);
fsearch_list_view_set_drag_data_get_handler(list_view, listview_on_drag_data_get);
fsearch_list_view_set_single_click_activate(list_view, config->single_click_open);
gtk_widget_set_has_tooltip(GTK_WIDGET(list_view), config->enable_list_tooltips);

Expand Down Expand Up @@ -1386,4 +1417,4 @@ FsearchApplicationWindow *
fsearch_application_window_new(FsearchApplication *app) {
g_assert(FSEARCH_IS_APPLICATION(app));
return g_object_new(FSEARCH_APPLICATION_WINDOW_TYPE, "application", app, NULL);
}
}