File: | libbaul-private/baul-tree-view-drag-dest.c |
Warning: | line 682, column 9 Value stored to 'action' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ |
2 | |
3 | /* |
4 | * Baul |
5 | * |
6 | * Copyright (C) 2002 Sun Microsystems, Inc. |
7 | * |
8 | * Baul is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU General Public License as |
10 | * published by the Free Software Foundation; either version 2 of the |
11 | * License, or (at your option) any later version. |
12 | * |
13 | * Baul is distributed in the hope that it will be useful, but |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | * General Public License for more details. |
17 | * |
18 | * You should have received a copy of the GNU General Public |
19 | * License along with this program; if not, write to the |
20 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |
21 | * Boston, MA 02110-1301, USA. |
22 | * |
23 | * Author: Dave Camp <dave@ximian.com> |
24 | * XDS support: Benedikt Meurer <benny@xfce.org> (adapted by Amos Brocco <amos.brocco@unifr.ch>) |
25 | */ |
26 | |
27 | /* baul-tree-view-drag-dest.c: Handles drag and drop for treeviews which |
28 | * contain a hierarchy of files |
29 | */ |
30 | |
31 | #include <config.h> |
32 | #include <stdio.h> |
33 | #include <string.h> |
34 | |
35 | #include <ctk/ctk.h> |
36 | |
37 | #include <eel/eel-ctk-macros.h> |
38 | |
39 | #include "baul-tree-view-drag-dest.h" |
40 | #include "baul-file-dnd.h" |
41 | #include "baul-file-changes-queue.h" |
42 | #include "baul-icon-dnd.h" |
43 | #include "baul-link.h" |
44 | #include "baul-marshal.h" |
45 | #include "baul-debug-log.h" |
46 | |
47 | #define AUTO_SCROLL_MARGIN20 20 |
48 | |
49 | #define HOVER_EXPAND_TIMEOUT1 1 |
50 | |
51 | struct _BaulTreeViewDragDestDetails |
52 | { |
53 | CtkTreeView *tree_view; |
54 | |
55 | gboolean drop_occurred; |
56 | |
57 | gboolean have_drag_data; |
58 | guint drag_type; |
59 | CtkSelectionData *drag_data; |
60 | GList *drag_list; |
61 | |
62 | guint highlight_id; |
63 | guint scroll_id; |
64 | guint expand_id; |
65 | |
66 | char *direct_save_uri; |
67 | }; |
68 | |
69 | enum |
70 | { |
71 | GET_ROOT_URI, |
72 | GET_FILE_FOR_PATH, |
73 | MOVE_COPY_ITEMS, |
74 | HANDLE_NETSCAPE_URL, |
75 | HANDLE_URI_LIST, |
76 | HANDLE_TEXT, |
77 | HANDLE_RAW, |
78 | LAST_SIGNAL |
79 | }; |
80 | |
81 | static guint signals[LAST_SIGNAL] = { 0 }; |
82 | |
83 | G_DEFINE_TYPE (BaulTreeViewDragDest, baul_tree_view_drag_dest,static void baul_tree_view_drag_dest_init (BaulTreeViewDragDest *self); static void baul_tree_view_drag_dest_class_init (BaulTreeViewDragDestClass *klass); static GType baul_tree_view_drag_dest_get_type_once (void); static gpointer baul_tree_view_drag_dest_parent_class = ((void*)0); static gint BaulTreeViewDragDest_private_offset ; static void baul_tree_view_drag_dest_class_intern_init (gpointer klass) { baul_tree_view_drag_dest_parent_class = g_type_class_peek_parent (klass); if (BaulTreeViewDragDest_private_offset != 0) g_type_class_adjust_private_offset (klass, &BaulTreeViewDragDest_private_offset); baul_tree_view_drag_dest_class_init ((BaulTreeViewDragDestClass*) klass); } __attribute__ ((__unused__ )) static inline gpointer baul_tree_view_drag_dest_get_instance_private (BaulTreeViewDragDest *self) { return (((gpointer) ((guint8* ) (self) + (glong) (BaulTreeViewDragDest_private_offset)))); } GType baul_tree_view_drag_dest_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); (void) (0 ? (gpointer) * ( &static_g_define_type_id) : ((void*)0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = baul_tree_view_drag_dest_get_type_once (); (__extension__ ( { _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); 0 ? (void) (*( &static_g_define_type_id) = (g_define_type_id)) : (void) 0 ; g_once_init_leave_pointer ((&static_g_define_type_id), ( gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id ; } __attribute__ ((__noinline__)) static GType baul_tree_view_drag_dest_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("BaulTreeViewDragDest" ), sizeof (BaulTreeViewDragDestClass), (GClassInitFunc)(void ( *)(void)) baul_tree_view_drag_dest_class_intern_init, sizeof ( BaulTreeViewDragDest), (GInstanceInitFunc)(void (*)(void)) baul_tree_view_drag_dest_init , (GTypeFlags) 0); { {{};} } return g_define_type_id; } |
84 | G_TYPE_OBJECT)static void baul_tree_view_drag_dest_init (BaulTreeViewDragDest *self); static void baul_tree_view_drag_dest_class_init (BaulTreeViewDragDestClass *klass); static GType baul_tree_view_drag_dest_get_type_once (void); static gpointer baul_tree_view_drag_dest_parent_class = ((void*)0); static gint BaulTreeViewDragDest_private_offset ; static void baul_tree_view_drag_dest_class_intern_init (gpointer klass) { baul_tree_view_drag_dest_parent_class = g_type_class_peek_parent (klass); if (BaulTreeViewDragDest_private_offset != 0) g_type_class_adjust_private_offset (klass, &BaulTreeViewDragDest_private_offset); baul_tree_view_drag_dest_class_init ((BaulTreeViewDragDestClass*) klass); } __attribute__ ((__unused__ )) static inline gpointer baul_tree_view_drag_dest_get_instance_private (BaulTreeViewDragDest *self) { return (((gpointer) ((guint8* ) (self) + (glong) (BaulTreeViewDragDest_private_offset)))); } GType baul_tree_view_drag_dest_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); (void) (0 ? (gpointer) * ( &static_g_define_type_id) : ((void*)0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = baul_tree_view_drag_dest_get_type_once (); (__extension__ ( { _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); 0 ? (void) (*( &static_g_define_type_id) = (g_define_type_id)) : (void) 0 ; g_once_init_leave_pointer ((&static_g_define_type_id), ( gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id ; } __attribute__ ((__noinline__)) static GType baul_tree_view_drag_dest_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("BaulTreeViewDragDest" ), sizeof (BaulTreeViewDragDestClass), (GClassInitFunc)(void ( *)(void)) baul_tree_view_drag_dest_class_intern_init, sizeof ( BaulTreeViewDragDest), (GInstanceInitFunc)(void (*)(void)) baul_tree_view_drag_dest_init , (GTypeFlags) 0); { {{};} } return g_define_type_id; }; |
85 | |
86 | #define parent_classbaul_tree_view_drag_dest_parent_class baul_tree_view_drag_dest_parent_class |
87 | |
88 | static const CtkTargetEntry drag_types [] = |
89 | { |
90 | { BAUL_ICON_DND_CAFE_ICON_LIST_TYPE"x-special/cafe-icon-list", 0, BAUL_ICON_DND_CAFE_ICON_LIST }, |
91 | /* prefer "_NETSCAPE_URL" over "text/uri-list" to satisfy web browsers. */ |
92 | { BAUL_ICON_DND_NETSCAPE_URL_TYPE"_NETSCAPE_URL", 0, BAUL_ICON_DND_NETSCAPE_URL }, |
93 | { BAUL_ICON_DND_URI_LIST_TYPE"text/uri-list", 0, BAUL_ICON_DND_URI_LIST }, |
94 | { BAUL_ICON_DND_KEYWORD_TYPE"property/keyword", 0, BAUL_ICON_DND_KEYWORD }, |
95 | { BAUL_ICON_DND_XDNDDIRECTSAVE_TYPE"XdndDirectSave0", 0, BAUL_ICON_DND_XDNDDIRECTSAVE }, /* XDS Protocol Type */ |
96 | { BAUL_ICON_DND_RAW_TYPE"application/octet-stream", 0, BAUL_ICON_DND_RAW } |
97 | }; |
98 | |
99 | |
100 | static void |
101 | ctk_tree_view_vertical_autoscroll (CtkTreeView *tree_view) |
102 | { |
103 | CdkRectangle visible_rect; |
104 | CtkAdjustment *vadjustment; |
105 | CdkDisplay *display; |
106 | CdkSeat *seat; |
107 | CdkDevice *pointer; |
108 | CdkWindow *window; |
109 | int y; |
110 | int offset; |
111 | float value; |
112 | |
113 | window = ctk_tree_view_get_bin_window (tree_view); |
114 | |
115 | vadjustment = ctk_scrollable_get_vadjustment (CTK_SCROLLABLE(tree_view)((((CtkScrollable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_scrollable_get_type ()))))))); |
116 | |
117 | display = ctk_widget_get_display (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
118 | seat = cdk_display_get_default_seat (display); |
119 | pointer = cdk_seat_get_pointer (seat); |
120 | cdk_window_get_device_position (window, pointer, |
121 | NULL((void*)0), &y, NULL((void*)0)); |
122 | |
123 | y += ctk_adjustment_get_value (vadjustment); |
124 | |
125 | ctk_tree_view_get_visible_rect (tree_view, &visible_rect); |
126 | |
127 | offset = y - (visible_rect.y + 2 * AUTO_SCROLL_MARGIN20); |
128 | if (offset > 0) |
129 | { |
130 | offset = y - (visible_rect.y + visible_rect.height - 2 * AUTO_SCROLL_MARGIN20); |
131 | if (offset < 0) |
132 | { |
133 | return; |
134 | } |
135 | } |
136 | |
137 | value = CLAMP (ctk_adjustment_get_value (vadjustment) + offset, 0.0,(((ctk_adjustment_get_value (vadjustment) + offset) > (ctk_adjustment_get_upper (vadjustment) - ctk_adjustment_get_page_size (vadjustment))) ? (ctk_adjustment_get_upper (vadjustment) - ctk_adjustment_get_page_size (vadjustment)) : (((ctk_adjustment_get_value (vadjustment) + offset) < (0.0)) ? (0.0) : (ctk_adjustment_get_value (vadjustment ) + offset))) |
138 | ctk_adjustment_get_upper (vadjustment) - ctk_adjustment_get_page_size (vadjustment))(((ctk_adjustment_get_value (vadjustment) + offset) > (ctk_adjustment_get_upper (vadjustment) - ctk_adjustment_get_page_size (vadjustment))) ? (ctk_adjustment_get_upper (vadjustment) - ctk_adjustment_get_page_size (vadjustment)) : (((ctk_adjustment_get_value (vadjustment) + offset) < (0.0)) ? (0.0) : (ctk_adjustment_get_value (vadjustment ) + offset))); |
139 | ctk_adjustment_set_value (vadjustment, value); |
140 | } |
141 | |
142 | static int |
143 | scroll_timeout (gpointer data) |
144 | { |
145 | CtkTreeView *tree_view = CTK_TREE_VIEW (data)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_view_get_type ())))))); |
146 | |
147 | ctk_tree_view_vertical_autoscroll (tree_view); |
148 | |
149 | return TRUE(!(0)); |
150 | } |
151 | |
152 | static void |
153 | remove_scroll_timeout (BaulTreeViewDragDest *dest) |
154 | { |
155 | if (dest->details->scroll_id) |
156 | { |
157 | g_source_remove (dest->details->scroll_id); |
158 | dest->details->scroll_id = 0; |
159 | } |
160 | } |
161 | |
162 | static int |
163 | expand_timeout (gpointer data) |
164 | { |
165 | CtkTreeView *tree_view; |
166 | CtkTreePath *drop_path; |
167 | |
168 | tree_view = CTK_TREE_VIEW (data)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_view_get_type ())))))); |
169 | |
170 | ctk_tree_view_get_drag_dest_row (tree_view, &drop_path, NULL((void*)0)); |
171 | |
172 | if (drop_path) |
173 | { |
174 | ctk_tree_view_expand_row (tree_view, drop_path, FALSE(0)); |
175 | ctk_tree_path_free (drop_path); |
176 | } |
177 | |
178 | return FALSE(0); |
179 | } |
180 | |
181 | static void |
182 | remove_expand_timeout (BaulTreeViewDragDest *dest) |
183 | { |
184 | if (dest->details->expand_id) |
185 | { |
186 | g_source_remove (dest->details->expand_id); |
187 | dest->details->expand_id = 0; |
188 | } |
189 | } |
190 | |
191 | static gboolean |
192 | highlight_draw (CtkWidget *widget, |
193 | cairo_t *cr, |
194 | gpointer data G_GNUC_UNUSED__attribute__ ((__unused__))) |
195 | { |
196 | CdkWindow *bin_window; |
197 | int width; |
198 | int height; |
199 | CtkStyleContext *style; |
200 | |
201 | /* FIXMEchpe: is bin window right here??? */ |
202 | bin_window = ctk_tree_view_get_bin_window (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ()))))))); |
203 | |
204 | width = cdk_window_get_width(bin_window); |
205 | height = cdk_window_get_height(bin_window); |
206 | |
207 | style = ctk_widget_get_style_context (widget); |
208 | |
209 | ctk_style_context_save (style); |
210 | ctk_style_context_add_class (style, "treeview-drop-indicator"); |
211 | |
212 | ctk_render_focus (style, |
213 | cr, |
214 | 0, 0, width, height); |
215 | |
216 | ctk_style_context_restore (style); |
217 | |
218 | return FALSE(0); |
219 | } |
220 | |
221 | static void |
222 | set_widget_highlight (BaulTreeViewDragDest *dest, gboolean highlight) |
223 | { |
224 | if (!highlight && dest->details->highlight_id) |
225 | { |
226 | g_signal_handler_disconnect (dest->details->tree_view, |
227 | dest->details->highlight_id); |
228 | dest->details->highlight_id = 0; |
229 | ctk_widget_queue_draw (CTK_WIDGET (dest->details->tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((dest->details->tree_view)), ((ctk_widget_get_type ( )))))))); |
230 | } |
231 | |
232 | if (highlight && !dest->details->highlight_id) |
233 | { |
234 | dest->details->highlight_id = |
235 | g_signal_connect_object (dest->details->tree_view, |
236 | "draw", |
237 | G_CALLBACK (highlight_draw)((GCallback) (highlight_draw)), |
238 | dest, 0); |
239 | ctk_widget_queue_draw (CTK_WIDGET (dest->details->tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((dest->details->tree_view)), ((ctk_widget_get_type ( )))))))); |
240 | } |
241 | } |
242 | |
243 | static void |
244 | set_drag_dest_row (BaulTreeViewDragDest *dest, |
245 | CtkTreePath *path) |
246 | { |
247 | if (path) |
248 | { |
249 | set_widget_highlight (dest, FALSE(0)); |
250 | ctk_tree_view_set_drag_dest_row |
251 | (dest->details->tree_view, |
252 | path, |
253 | CTK_TREE_VIEW_DROP_INTO_OR_BEFORE); |
254 | } |
255 | else |
256 | { |
257 | set_widget_highlight (dest, TRUE(!(0))); |
258 | ctk_tree_view_set_drag_dest_row (dest->details->tree_view, |
259 | NULL((void*)0), |
260 | 0); |
261 | } |
262 | } |
263 | |
264 | static void |
265 | clear_drag_dest_row (BaulTreeViewDragDest *dest) |
266 | { |
267 | ctk_tree_view_set_drag_dest_row (dest->details->tree_view, NULL((void*)0), 0); |
268 | set_widget_highlight (dest, FALSE(0)); |
269 | } |
270 | |
271 | static gboolean |
272 | get_drag_data (BaulTreeViewDragDest *dest, |
273 | CdkDragContext *context, |
274 | guint32 time) |
275 | { |
276 | CdkAtom target; |
277 | |
278 | target = ctk_drag_dest_find_target (CTK_WIDGET (dest->details->tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((dest->details->tree_view)), ((ctk_widget_get_type ( ))))))), |
279 | context, |
280 | NULL((void*)0)); |
281 | |
282 | if (target == CDK_NONE((CdkAtom)((gpointer) (gulong) (0)))) |
283 | { |
284 | return FALSE(0); |
285 | } |
286 | |
287 | if (target == cdk_atom_intern (BAUL_ICON_DND_XDNDDIRECTSAVE_TYPE"XdndDirectSave0", FALSE(0)) && |
288 | !dest->details->drop_occurred) |
289 | { |
290 | dest->details->drag_type = BAUL_ICON_DND_XDNDDIRECTSAVE; |
291 | dest->details->have_drag_data = TRUE(!(0)); |
292 | return TRUE(!(0)); |
293 | } |
294 | |
295 | ctk_drag_get_data (CTK_WIDGET (dest->details->tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((dest->details->tree_view)), ((ctk_widget_get_type ( ))))))), |
296 | context, target, time); |
297 | |
298 | return TRUE(!(0)); |
299 | } |
300 | |
301 | static void |
302 | free_drag_data (BaulTreeViewDragDest *dest) |
303 | { |
304 | dest->details->have_drag_data = FALSE(0); |
305 | |
306 | if (dest->details->drag_data) |
307 | { |
308 | ctk_selection_data_free (dest->details->drag_data); |
309 | dest->details->drag_data = NULL((void*)0); |
310 | } |
311 | |
312 | if (dest->details->drag_list) |
313 | { |
314 | baul_drag_destroy_selection_list (dest->details->drag_list); |
315 | dest->details->drag_list = NULL((void*)0); |
316 | } |
317 | |
318 | g_free (dest->details->direct_save_uri); |
319 | dest->details->direct_save_uri = NULL((void*)0); |
320 | } |
321 | |
322 | static char * |
323 | get_root_uri (BaulTreeViewDragDest *dest) |
324 | { |
325 | char *uri; |
326 | |
327 | g_signal_emit (dest, signals[GET_ROOT_URI], 0, &uri); |
328 | |
329 | return uri; |
330 | } |
331 | |
332 | static BaulFile * |
333 | file_for_path (BaulTreeViewDragDest *dest, CtkTreePath *path) |
334 | { |
335 | BaulFile *file; |
336 | |
337 | if (path) |
338 | { |
339 | g_signal_emit (dest, signals[GET_FILE_FOR_PATH], 0, path, &file); |
340 | } |
341 | else |
342 | { |
343 | char *uri; |
344 | |
345 | uri = get_root_uri (dest); |
346 | |
347 | file = NULL((void*)0); |
348 | if (uri != NULL((void*)0)) |
349 | { |
350 | file = baul_file_get_by_uri (uri); |
351 | } |
352 | |
353 | g_free (uri); |
354 | } |
355 | |
356 | return file; |
357 | } |
358 | |
359 | static CtkTreePath * |
360 | get_drop_path (BaulTreeViewDragDest *dest, |
361 | CtkTreePath *path) |
362 | { |
363 | BaulFile *file; |
364 | CtkTreePath *ret; |
365 | |
366 | if (!path || !dest->details->have_drag_data) |
367 | { |
368 | return NULL((void*)0); |
369 | } |
370 | |
371 | ret = ctk_tree_path_copy (path); |
372 | file = file_for_path (dest, ret); |
373 | |
374 | /* Go up the tree until we find a file that can accept a drop */ |
375 | while (file == NULL((void*)0) /* dummy row */ || |
376 | !baul_drag_can_accept_info (file, |
377 | dest->details->drag_type, |
378 | dest->details->drag_list)) |
379 | { |
380 | if (ctk_tree_path_get_depth (ret) == 1) |
381 | { |
382 | ctk_tree_path_free (ret); |
383 | ret = NULL((void*)0); |
384 | break; |
385 | } |
386 | else |
387 | { |
388 | ctk_tree_path_up (ret); |
389 | |
390 | baul_file_unref (file); |
391 | file = file_for_path (dest, ret); |
392 | } |
393 | } |
394 | baul_file_unref (file); |
395 | |
396 | return ret; |
397 | } |
398 | |
399 | static char * |
400 | get_drop_target_uri_for_path (BaulTreeViewDragDest *dest, |
401 | CtkTreePath *path) |
402 | { |
403 | BaulFile *file; |
404 | char *target; |
405 | |
406 | file = file_for_path (dest, path); |
407 | if (file == NULL((void*)0)) |
408 | { |
409 | return NULL((void*)0); |
410 | } |
411 | |
412 | target = baul_file_get_drop_target_uri (file); |
413 | baul_file_unref (file); |
414 | |
415 | return target; |
416 | } |
417 | |
418 | static guint |
419 | get_drop_action (BaulTreeViewDragDest *dest, |
420 | CdkDragContext *context, |
421 | CtkTreePath *path) |
422 | { |
423 | char *drop_target; |
424 | int action; |
425 | |
426 | if (!dest->details->have_drag_data || |
427 | (dest->details->drag_type == BAUL_ICON_DND_CAFE_ICON_LIST && |
428 | dest->details->drag_list == NULL((void*)0))) |
429 | { |
430 | return 0; |
431 | } |
432 | |
433 | switch (dest->details->drag_type) |
434 | { |
435 | case BAUL_ICON_DND_CAFE_ICON_LIST : |
436 | drop_target = get_drop_target_uri_for_path (dest, path); |
437 | |
438 | if (!drop_target) |
439 | { |
440 | return 0; |
441 | } |
442 | |
443 | baul_drag_default_drop_action_for_icons |
444 | (context, |
445 | drop_target, |
446 | dest->details->drag_list, |
447 | &action); |
448 | |
449 | g_free (drop_target); |
450 | |
451 | return action; |
452 | |
453 | case BAUL_ICON_DND_NETSCAPE_URL: |
454 | drop_target = get_drop_target_uri_for_path (dest, path); |
455 | |
456 | if (drop_target == NULL((void*)0)) |
457 | { |
458 | return 0; |
459 | } |
460 | |
461 | action = baul_drag_default_drop_action_for_netscape_url (context); |
462 | |
463 | g_free (drop_target); |
464 | |
465 | return action; |
466 | |
467 | case BAUL_ICON_DND_URI_LIST : |
468 | drop_target = get_drop_target_uri_for_path (dest, path); |
469 | |
470 | if (drop_target == NULL((void*)0)) |
471 | { |
472 | return 0; |
473 | } |
474 | |
475 | g_free (drop_target); |
476 | |
477 | return cdk_drag_context_get_suggested_action (context); |
478 | |
479 | case BAUL_ICON_DND_TEXT: |
480 | case BAUL_ICON_DND_RAW: |
481 | case BAUL_ICON_DND_XDNDDIRECTSAVE: |
482 | return CDK_ACTION_COPY; |
483 | |
484 | case BAUL_ICON_DND_KEYWORD: |
485 | |
486 | if (!path) |
487 | { |
488 | return 0; |
489 | } |
490 | |
491 | return CDK_ACTION_COPY; |
492 | } |
493 | |
494 | return 0; |
495 | } |
496 | |
497 | static gboolean |
498 | drag_motion_callback (CtkWidget *widget, |
499 | CdkDragContext *context, |
500 | int x, |
501 | int y, |
502 | guint32 time, |
503 | gpointer data) |
504 | { |
505 | BaulTreeViewDragDest *dest; |
506 | CtkTreePath *path; |
507 | CtkTreePath *drop_path, *old_drop_path; |
508 | CtkTreeIter drop_iter; |
509 | CtkTreeViewDropPosition pos; |
510 | CdkWindow *bin_window; |
511 | guint action; |
512 | gboolean res = TRUE(!(0)); |
513 | |
514 | dest = BAUL_TREE_VIEW_DRAG_DEST (data)((((BaulTreeViewDragDest*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((data)), ((baul_tree_view_drag_dest_get_type ())))))); |
515 | |
516 | ctk_tree_view_get_dest_row_at_pos (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))), |
517 | x, y, &path, &pos); |
518 | |
519 | |
520 | if (!dest->details->have_drag_data) |
521 | { |
522 | res = get_drag_data (dest, context, time); |
523 | } |
524 | |
525 | if (!res) |
526 | { |
527 | return FALSE(0); |
528 | } |
529 | |
530 | drop_path = get_drop_path (dest, path); |
531 | |
532 | action = 0; |
533 | bin_window = ctk_tree_view_get_bin_window (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ()))))))); |
534 | if (bin_window != NULL((void*)0)) |
535 | { |
536 | int bin_x, bin_y; |
537 | cdk_window_get_position (bin_window, &bin_x, &bin_y); |
538 | if (bin_y <= y) |
539 | { |
540 | /* ignore drags on the header */ |
541 | action = get_drop_action (dest, context, drop_path); |
542 | } |
543 | } |
544 | |
545 | ctk_tree_view_get_drag_dest_row (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))), &old_drop_path, |
546 | NULL((void*)0)); |
547 | |
548 | if (action) |
549 | { |
550 | CtkTreeModel *model; |
551 | |
552 | set_drag_dest_row (dest, drop_path); |
553 | model = ctk_tree_view_get_model (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ()))))))); |
554 | if (drop_path == NULL((void*)0) || (old_drop_path != NULL((void*)0) && |
555 | ctk_tree_path_compare (old_drop_path, drop_path) != 0)) |
556 | { |
557 | remove_expand_timeout (dest); |
558 | } |
559 | if (dest->details->expand_id == 0 && drop_path != NULL((void*)0)) |
560 | { |
561 | ctk_tree_model_get_iter (model, &drop_iter, drop_path); |
562 | if (ctk_tree_model_iter_has_child (model, &drop_iter)) |
563 | { |
564 | dest->details->expand_id = g_timeout_add_seconds (HOVER_EXPAND_TIMEOUT1, |
565 | expand_timeout, |
566 | dest->details->tree_view); |
567 | } |
568 | } |
569 | } |
570 | else |
571 | { |
572 | clear_drag_dest_row (dest); |
573 | remove_expand_timeout (dest); |
574 | } |
575 | |
576 | if (path) |
577 | { |
578 | ctk_tree_path_free (path); |
579 | } |
580 | |
581 | if (drop_path) |
582 | { |
583 | ctk_tree_path_free (drop_path); |
584 | } |
585 | |
586 | if (old_drop_path) |
587 | { |
588 | ctk_tree_path_free (old_drop_path); |
589 | } |
590 | |
591 | if (dest->details->scroll_id == 0) |
592 | { |
593 | dest->details->scroll_id = |
594 | g_timeout_add (150, |
595 | scroll_timeout, |
596 | dest->details->tree_view); |
597 | } |
598 | |
599 | cdk_drag_status (context, action, time); |
600 | |
601 | return TRUE(!(0)); |
602 | } |
603 | |
604 | static void |
605 | drag_leave_callback (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)), |
606 | CdkDragContext *context G_GNUC_UNUSED__attribute__ ((__unused__)), |
607 | guint32 time G_GNUC_UNUSED__attribute__ ((__unused__)), |
608 | gpointer data) |
609 | { |
610 | BaulTreeViewDragDest *dest; |
611 | |
612 | dest = BAUL_TREE_VIEW_DRAG_DEST (data)((((BaulTreeViewDragDest*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((data)), ((baul_tree_view_drag_dest_get_type ())))))); |
613 | |
614 | clear_drag_dest_row (dest); |
615 | |
616 | free_drag_data (dest); |
617 | |
618 | remove_scroll_timeout (dest); |
619 | remove_expand_timeout (dest); |
620 | } |
621 | |
622 | static char * |
623 | get_drop_target_uri_at_pos (BaulTreeViewDragDest *dest, int x, int y) |
624 | { |
625 | char *drop_target; |
626 | CtkTreePath *path; |
627 | CtkTreePath *drop_path; |
628 | CtkTreeViewDropPosition pos; |
629 | |
630 | ctk_tree_view_get_dest_row_at_pos (dest->details->tree_view, x, y, |
631 | &path, &pos); |
632 | |
633 | drop_path = get_drop_path (dest, path); |
634 | |
635 | drop_target = get_drop_target_uri_for_path (dest, drop_path); |
636 | |
637 | if (path != NULL((void*)0)) |
638 | { |
639 | ctk_tree_path_free (path); |
640 | } |
641 | |
642 | if (drop_path != NULL((void*)0)) |
643 | { |
644 | ctk_tree_path_free (drop_path); |
645 | } |
646 | |
647 | return drop_target; |
648 | } |
649 | |
650 | static void |
651 | receive_uris (BaulTreeViewDragDest *dest, |
652 | CdkDragContext *context, |
653 | GList *source_uris, |
654 | int x, int y) |
655 | { |
656 | char *drop_target; |
657 | CdkDragAction action, real_action; |
658 | |
659 | drop_target = get_drop_target_uri_at_pos (dest, x, y); |
660 | g_assert (drop_target != NULL)do { if (drop_target != ((void*)0)) ; else g_assertion_message_expr (((gchar*) 0), "baul-tree-view-drag-dest.c", 660, ((const char *) (__func__)), "drop_target != NULL"); } while (0); |
661 | |
662 | real_action = cdk_drag_context_get_selected_action (context); |
663 | |
664 | if (real_action == CDK_ACTION_ASK) |
665 | { |
666 | if (baul_drag_selection_includes_special_link (dest->details->drag_list)) |
667 | { |
668 | /* We only want to move the trash */ |
669 | action = CDK_ACTION_MOVE; |
670 | } |
671 | else |
672 | { |
673 | action = CDK_ACTION_MOVE | CDK_ACTION_COPY | CDK_ACTION_LINK; |
674 | } |
675 | real_action = baul_drag_drop_action_ask |
676 | (CTK_WIDGET (dest->details->tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((dest->details->tree_view)), ((ctk_widget_get_type ( ))))))), action); |
677 | } |
678 | |
679 | /* We only want to copy external uris */ |
680 | if (dest->details->drag_type == BAUL_ICON_DND_URI_LIST) |
681 | { |
682 | action = CDK_ACTION_COPY; |
Value stored to 'action' is never read | |
683 | } |
684 | |
685 | if (real_action > 0) |
686 | { |
687 | if (!baul_drag_uris_local (drop_target, source_uris) |
688 | || real_action != CDK_ACTION_MOVE) |
689 | { |
690 | g_signal_emit (dest, signals[MOVE_COPY_ITEMS], 0, |
691 | source_uris, |
692 | drop_target, |
693 | real_action, |
694 | x, y); |
695 | } |
696 | } |
697 | |
698 | g_free (drop_target); |
699 | } |
700 | |
701 | static void |
702 | receive_dropped_icons (BaulTreeViewDragDest *dest, |
703 | CdkDragContext *context, |
704 | int x, int y) |
705 | { |
706 | GList *source_uris; |
707 | GList *l; |
708 | |
709 | /* FIXME: ignore local only moves */ |
710 | |
711 | if (!dest->details->drag_list) |
712 | { |
713 | return; |
714 | } |
715 | |
716 | source_uris = NULL((void*)0); |
717 | for (l = dest->details->drag_list; l != NULL((void*)0); l = l->next) |
718 | { |
719 | source_uris = g_list_prepend (source_uris, |
720 | ((BaulDragSelectionItem *)l->data)->uri); |
721 | } |
722 | |
723 | source_uris = g_list_reverse (source_uris); |
724 | |
725 | receive_uris (dest, context, source_uris, x, y); |
726 | |
727 | g_list_free (source_uris); |
728 | } |
729 | |
730 | static void |
731 | receive_dropped_uri_list (BaulTreeViewDragDest *dest, |
732 | CdkDragContext *context, |
733 | int x, int y) |
734 | { |
735 | char *drop_target; |
736 | |
737 | if (!dest->details->drag_data) |
738 | { |
739 | return; |
740 | } |
741 | |
742 | drop_target = get_drop_target_uri_at_pos (dest, x, y); |
743 | g_assert (drop_target != NULL)do { if (drop_target != ((void*)0)) ; else g_assertion_message_expr (((gchar*) 0), "baul-tree-view-drag-dest.c", 743, ((const char *) (__func__)), "drop_target != NULL"); } while (0); |
744 | |
745 | g_signal_emit (dest, signals[HANDLE_URI_LIST], 0, |
746 | (char*) ctk_selection_data_get_data (dest->details->drag_data), |
747 | drop_target, |
748 | cdk_drag_context_get_selected_action (context), |
749 | x, y); |
750 | |
751 | g_free (drop_target); |
752 | } |
753 | |
754 | static void |
755 | receive_dropped_text (BaulTreeViewDragDest *dest, |
756 | CdkDragContext *context, |
757 | int x, int y) |
758 | { |
759 | char *drop_target; |
760 | char *text; |
761 | |
762 | if (!dest->details->drag_data) |
763 | { |
764 | return; |
765 | } |
766 | |
767 | drop_target = get_drop_target_uri_at_pos (dest, x, y); |
768 | g_assert (drop_target != NULL)do { if (drop_target != ((void*)0)) ; else g_assertion_message_expr (((gchar*) 0), "baul-tree-view-drag-dest.c", 768, ((const char *) (__func__)), "drop_target != NULL"); } while (0); |
769 | |
770 | text = ctk_selection_data_get_text (dest->details->drag_data); |
771 | g_signal_emit (dest, signals[HANDLE_TEXT], 0, |
772 | (char *) text, drop_target, |
773 | cdk_drag_context_get_selected_action (context), |
774 | x, y); |
775 | |
776 | g_free (text); |
777 | g_free (drop_target); |
778 | } |
779 | |
780 | static void |
781 | receive_dropped_raw (BaulTreeViewDragDest *dest, |
782 | const char *raw_data, int length, |
783 | CdkDragContext *context, |
784 | int x, int y) |
785 | { |
786 | char *drop_target; |
787 | |
788 | if (!dest->details->drag_data) |
789 | { |
790 | return; |
791 | } |
792 | |
793 | drop_target = get_drop_target_uri_at_pos (dest, x, y); |
794 | g_assert (drop_target != NULL)do { if (drop_target != ((void*)0)) ; else g_assertion_message_expr (((gchar*) 0), "baul-tree-view-drag-dest.c", 794, ((const char *) (__func__)), "drop_target != NULL"); } while (0); |
795 | |
796 | g_signal_emit (dest, signals[HANDLE_RAW], 0, |
797 | raw_data, length, drop_target, |
798 | dest->details->direct_save_uri, |
799 | cdk_drag_context_get_selected_action (context), |
800 | x, y); |
801 | |
802 | g_free (drop_target); |
803 | } |
804 | |
805 | static void |
806 | receive_dropped_netscape_url (BaulTreeViewDragDest *dest, |
807 | CdkDragContext *context, |
808 | int x, int y) |
809 | { |
810 | char *drop_target; |
811 | |
812 | if (!dest->details->drag_data) |
813 | { |
814 | return; |
815 | } |
816 | |
817 | drop_target = get_drop_target_uri_at_pos (dest, x, y); |
818 | g_assert (drop_target != NULL)do { if (drop_target != ((void*)0)) ; else g_assertion_message_expr (((gchar*) 0), "baul-tree-view-drag-dest.c", 818, ((const char *) (__func__)), "drop_target != NULL"); } while (0); |
819 | |
820 | g_signal_emit (dest, signals[HANDLE_NETSCAPE_URL], 0, |
821 | (char*) ctk_selection_data_get_data (dest->details->drag_data), |
822 | drop_target, |
823 | cdk_drag_context_get_selected_action (context), |
824 | x, y); |
825 | |
826 | g_free (drop_target); |
827 | } |
828 | |
829 | static void |
830 | receive_dropped_keyword (BaulTreeViewDragDest *dest, |
831 | CdkDragContext *context G_GNUC_UNUSED__attribute__ ((__unused__)), |
832 | int x, |
833 | int y) |
834 | { |
835 | char *drop_target_uri; |
836 | BaulFile *drop_target_file; |
837 | |
838 | if (!dest->details->drag_data) |
839 | { |
840 | return; |
841 | } |
842 | |
843 | drop_target_uri = get_drop_target_uri_at_pos (dest, x, y); |
844 | g_assert (drop_target_uri != NULL)do { if (drop_target_uri != ((void*)0)) ; else g_assertion_message_expr (((gchar*) 0), "baul-tree-view-drag-dest.c", 844, ((const char *) (__func__)), "drop_target_uri != NULL"); } while (0); |
845 | |
846 | drop_target_file = baul_file_get_by_uri (drop_target_uri); |
847 | |
848 | if (drop_target_file != NULL((void*)0)) |
849 | { |
850 | baul_drag_file_receive_dropped_keyword (drop_target_file, |
851 | (char *) ctk_selection_data_get_data (dest->details->drag_data)); |
852 | baul_file_unref (drop_target_file); |
853 | } |
854 | |
855 | g_free (drop_target_uri); |
856 | } |
857 | |
858 | static gboolean |
859 | receive_xds (BaulTreeViewDragDest *dest, |
860 | CtkWidget *widget, |
861 | guint32 time, |
862 | CdkDragContext *context, |
863 | int x G_GNUC_UNUSED__attribute__ ((__unused__)), |
864 | int y G_GNUC_UNUSED__attribute__ ((__unused__))) |
865 | { |
866 | GFile *location; |
867 | const guchar *selection_data; |
868 | gint selection_format; |
869 | gint selection_length; |
870 | |
871 | selection_data = ctk_selection_data_get_data (dest->details->drag_data); |
872 | selection_format = ctk_selection_data_get_format (dest->details->drag_data); |
873 | selection_length = ctk_selection_data_get_length (dest->details->drag_data); |
874 | |
875 | if (selection_format == 8 |
876 | && selection_length == 1 |
877 | && selection_data[0] == 'F') |
878 | { |
879 | ctk_drag_get_data (widget, context, |
880 | cdk_atom_intern (BAUL_ICON_DND_RAW_TYPE"application/octet-stream", |
881 | FALSE(0)), |
882 | time); |
883 | return FALSE(0); |
884 | } |
885 | else if (selection_format == 8 |
886 | && selection_length == 1 |
887 | && selection_data[0] == 'S') |
888 | { |
889 | g_assert (dest->details->direct_save_uri != NULL)do { if (dest->details->direct_save_uri != ((void*)0)) ; else g_assertion_message_expr (((gchar*) 0), "baul-tree-view-drag-dest.c" , 889, ((const char*) (__func__)), "dest->details->direct_save_uri != NULL" ); } while (0); |
890 | location = g_file_new_for_uri (dest->details->direct_save_uri); |
891 | |
892 | baul_file_changes_queue_file_added (location); |
893 | baul_file_changes_consume_changes (TRUE(!(0))); |
894 | |
895 | g_object_unref (location); |
896 | } |
897 | return TRUE(!(0)); |
898 | } |
899 | |
900 | |
901 | static gboolean |
902 | drag_data_received_callback (CtkWidget *widget, |
903 | CdkDragContext *context, |
904 | int x, |
905 | int y, |
906 | CtkSelectionData *selection_data, |
907 | guint info, |
908 | guint32 time, |
909 | gpointer data) |
910 | { |
911 | BaulTreeViewDragDest *dest; |
912 | gboolean success, finished; |
913 | |
914 | dest = BAUL_TREE_VIEW_DRAG_DEST (data)((((BaulTreeViewDragDest*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((data)), ((baul_tree_view_drag_dest_get_type ())))))); |
915 | |
916 | if (!dest->details->have_drag_data) |
917 | { |
918 | dest->details->have_drag_data = TRUE(!(0)); |
919 | dest->details->drag_type = info; |
920 | dest->details->drag_data = |
921 | ctk_selection_data_copy (selection_data); |
922 | if (info == BAUL_ICON_DND_CAFE_ICON_LIST) |
923 | { |
924 | dest->details->drag_list = |
925 | baul_drag_build_selection_list (selection_data); |
926 | } |
927 | } |
928 | |
929 | if (dest->details->drop_occurred) |
930 | { |
931 | success = FALSE(0); |
932 | finished = TRUE(!(0)); |
933 | switch (info) |
934 | { |
935 | case BAUL_ICON_DND_CAFE_ICON_LIST : |
936 | receive_dropped_icons (dest, context, x, y); |
937 | success = TRUE(!(0)); |
938 | break; |
939 | case BAUL_ICON_DND_NETSCAPE_URL : |
940 | receive_dropped_netscape_url (dest, context, x, y); |
941 | success = TRUE(!(0)); |
942 | break; |
943 | case BAUL_ICON_DND_URI_LIST : |
944 | receive_dropped_uri_list (dest, context, x, y); |
945 | success = TRUE(!(0)); |
946 | break; |
947 | case BAUL_ICON_DND_TEXT: |
948 | receive_dropped_text (dest, context, x, y); |
949 | success = TRUE(!(0)); |
950 | break; |
951 | case BAUL_ICON_DND_RAW: |
952 | { |
953 | const char *tmp; |
954 | int length; |
955 | |
956 | length = ctk_selection_data_get_length (selection_data); |
957 | tmp = ctk_selection_data_get_data (selection_data); |
958 | receive_dropped_raw (dest, tmp, length, context, x, y); |
959 | success = TRUE(!(0)); |
960 | break; |
961 | } |
962 | case BAUL_ICON_DND_KEYWORD: |
963 | receive_dropped_keyword (dest, context, x, y); |
964 | success = TRUE(!(0)); |
965 | break; |
966 | case BAUL_ICON_DND_XDNDDIRECTSAVE: |
967 | finished = receive_xds (dest, widget, time, context, x, y); |
968 | success = TRUE(!(0)); |
969 | break; |
970 | } |
971 | |
972 | if (finished) |
973 | { |
974 | dest->details->drop_occurred = FALSE(0); |
975 | free_drag_data (dest); |
976 | ctk_drag_finish (context, success, FALSE(0), time); |
977 | } |
978 | } |
979 | |
980 | /* appease CtkTreeView by preventing its drag_data_receive |
981 | * from being called */ |
982 | g_signal_stop_emission_by_name (dest->details->tree_view, |
983 | "drag_data_received"); |
984 | |
985 | return TRUE(!(0)); |
986 | } |
987 | |
988 | static char * |
989 | get_direct_save_filename (CdkDragContext *context) |
990 | { |
991 | guchar *prop_text; |
992 | gint prop_len; |
993 | |
994 | if (!cdk_property_get (cdk_drag_context_get_source_window (context), cdk_atom_intern (BAUL_ICON_DND_XDNDDIRECTSAVE_TYPE"XdndDirectSave0", FALSE(0)), |
995 | cdk_atom_intern ("text/plain", FALSE(0)), 0, 1024, FALSE(0), NULL((void*)0), NULL((void*)0), |
996 | &prop_len, &prop_text)) |
997 | { |
998 | return NULL((void*)0); |
999 | } |
1000 | |
1001 | /* Zero-terminate the string */ |
1002 | prop_text = g_realloc (prop_text, prop_len + 1); |
1003 | prop_text[prop_len] = '\0'; |
1004 | |
1005 | /* Verify that the file name provided by the source is valid */ |
1006 | if (*prop_text == '\0' || |
1007 | strchr ((const gchar *) prop_text, G_DIR_SEPARATOR'/') != NULL((void*)0)) |
1008 | { |
1009 | baul_debug_log (FALSE(0), BAUL_DEBUG_LOG_DOMAIN_USER"USER", |
1010 | "Invalid filename provided by XDS drag site"); |
1011 | g_free (prop_text); |
1012 | return NULL((void*)0); |
1013 | } |
1014 | |
1015 | return prop_text; |
1016 | } |
1017 | |
1018 | static gboolean |
1019 | set_direct_save_uri (BaulTreeViewDragDest *dest, |
1020 | CdkDragContext *context, |
1021 | int x, int y) |
1022 | { |
1023 | char *drop_uri; |
1024 | char *uri; |
1025 | |
1026 | g_assert (dest->details->direct_save_uri == NULL)do { if (dest->details->direct_save_uri == ((void*)0)) ; else g_assertion_message_expr (((gchar*) 0), "baul-tree-view-drag-dest.c" , 1026, ((const char*) (__func__)), "dest->details->direct_save_uri == NULL" ); } while (0); |
1027 | |
1028 | uri = NULL((void*)0); |
1029 | |
1030 | drop_uri = get_drop_target_uri_at_pos (dest, x, y); |
1031 | if (drop_uri != NULL((void*)0)) |
1032 | { |
1033 | char *filename; |
1034 | |
1035 | filename = get_direct_save_filename (context); |
1036 | if (filename != NULL((void*)0)) |
1037 | { |
1038 | GFile *base, *child; |
1039 | |
1040 | /* Resolve relative path */ |
1041 | base = g_file_new_for_uri (drop_uri); |
1042 | child = g_file_get_child (base, filename); |
1043 | uri = g_file_get_uri (child); |
1044 | |
1045 | g_object_unref (base); |
1046 | g_object_unref (child); |
1047 | g_free (filename); |
1048 | |
1049 | /* Change the property */ |
1050 | cdk_property_change (cdk_drag_context_get_source_window (context), |
1051 | cdk_atom_intern (BAUL_ICON_DND_XDNDDIRECTSAVE_TYPE"XdndDirectSave0", FALSE(0)), |
1052 | cdk_atom_intern ("text/plain", FALSE(0)), 8, |
1053 | CDK_PROP_MODE_REPLACE, (const guchar *) uri, |
1054 | strlen (uri)); |
1055 | |
1056 | dest->details->direct_save_uri = uri; |
1057 | } |
1058 | else |
1059 | { |
1060 | baul_debug_log (FALSE(0), BAUL_DEBUG_LOG_DOMAIN_USER"USER", |
1061 | "Invalid filename provided by XDS drag site"); |
1062 | } |
1063 | } |
1064 | else |
1065 | { |
1066 | baul_debug_log (FALSE(0), BAUL_DEBUG_LOG_DOMAIN_USER"USER", |
1067 | "Could not retrieve XDS drop destination"); |
1068 | } |
1069 | |
1070 | return uri != NULL((void*)0); |
1071 | } |
1072 | |
1073 | static gboolean |
1074 | drag_drop_callback (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)), |
1075 | CdkDragContext *context, |
1076 | int x, |
1077 | int y, |
1078 | guint32 time, |
1079 | gpointer data) |
1080 | { |
1081 | BaulTreeViewDragDest *dest; |
1082 | guint info; |
1083 | CdkAtom target; |
1084 | |
1085 | dest = BAUL_TREE_VIEW_DRAG_DEST (data)((((BaulTreeViewDragDest*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((data)), ((baul_tree_view_drag_dest_get_type ())))))); |
1086 | |
1087 | target = ctk_drag_dest_find_target (CTK_WIDGET (dest->details->tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((dest->details->tree_view)), ((ctk_widget_get_type ( ))))))), |
1088 | context, |
1089 | NULL((void*)0)); |
1090 | if (target == CDK_NONE((CdkAtom)((gpointer) (gulong) (0)))) |
1091 | { |
1092 | return FALSE(0); |
1093 | } |
1094 | |
1095 | info = dest->details->drag_type; |
1096 | |
1097 | if (info == BAUL_ICON_DND_XDNDDIRECTSAVE) |
1098 | { |
1099 | /* We need to set this or get_drop_path will fail, and it |
1100 | was unset by drag_leave_callback */ |
1101 | dest->details->have_drag_data = TRUE(!(0)); |
1102 | if (!set_direct_save_uri (dest, context, x, y)) |
1103 | { |
1104 | return FALSE(0); |
1105 | } |
1106 | dest->details->have_drag_data = FALSE(0); |
1107 | } |
1108 | |
1109 | dest->details->drop_occurred = TRUE(!(0)); |
1110 | |
1111 | get_drag_data (dest, context, time); |
1112 | remove_scroll_timeout (dest); |
1113 | remove_expand_timeout (dest); |
1114 | clear_drag_dest_row (dest); |
1115 | |
1116 | return TRUE(!(0)); |
1117 | } |
1118 | |
1119 | static void |
1120 | tree_view_weak_notify (gpointer user_data, |
1121 | GObject *object G_GNUC_UNUSED__attribute__ ((__unused__))) |
1122 | { |
1123 | BaulTreeViewDragDest *dest; |
1124 | |
1125 | dest = BAUL_TREE_VIEW_DRAG_DEST (user_data)((((BaulTreeViewDragDest*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((user_data)), ((baul_tree_view_drag_dest_get_type ())))))); |
1126 | |
1127 | remove_scroll_timeout (dest); |
1128 | remove_expand_timeout (dest); |
1129 | |
1130 | dest->details->tree_view = NULL((void*)0); |
1131 | } |
1132 | |
1133 | static void |
1134 | baul_tree_view_drag_dest_dispose (GObject *object) |
1135 | { |
1136 | BaulTreeViewDragDest *dest; |
1137 | |
1138 | dest = BAUL_TREE_VIEW_DRAG_DEST (object)((((BaulTreeViewDragDest*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((object)), ((baul_tree_view_drag_dest_get_type ())))))); |
1139 | |
1140 | if (dest->details->tree_view) |
1141 | { |
1142 | g_object_weak_unref (G_OBJECT (dest->details->tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((dest->details->tree_view)), (((GType) ((20) << (2)))))))), |
1143 | tree_view_weak_notify, |
1144 | dest); |
1145 | } |
1146 | |
1147 | remove_scroll_timeout (dest); |
1148 | remove_expand_timeout (dest); |
1149 | |
1150 | EEL_CALL_PARENT (G_OBJECT_CLASS, dispose, (object))do { if (((((GObjectClass*) (void *) g_type_check_class_cast ( (GTypeClass*) ((baul_tree_view_drag_dest_parent_class)), (((GType ) ((20) << (2))))))))->dispose != ((void*)0)) { (* ( (((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((baul_tree_view_drag_dest_parent_class)), (((GType) ((20) << (2))))))))->dispose) (object); } } while (0); |
1151 | } |
1152 | |
1153 | static void |
1154 | baul_tree_view_drag_dest_finalize (GObject *object) |
1155 | { |
1156 | BaulTreeViewDragDest *dest; |
1157 | |
1158 | dest = BAUL_TREE_VIEW_DRAG_DEST (object)((((BaulTreeViewDragDest*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((object)), ((baul_tree_view_drag_dest_get_type ())))))); |
1159 | |
1160 | free_drag_data (dest); |
1161 | |
1162 | g_free (dest->details); |
1163 | |
1164 | EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object))do { if (((((GObjectClass*) (void *) g_type_check_class_cast ( (GTypeClass*) ((baul_tree_view_drag_dest_parent_class)), (((GType ) ((20) << (2))))))))->finalize != ((void*)0)) { (* ( (((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((baul_tree_view_drag_dest_parent_class)), (((GType) ((20) << (2))))))))->finalize) (object); } } while (0); |
1165 | } |
1166 | |
1167 | static void |
1168 | baul_tree_view_drag_dest_init (BaulTreeViewDragDest *dest) |
1169 | { |
1170 | dest->details = g_new0 (BaulTreeViewDragDestDetails, 1)((BaulTreeViewDragDestDetails *) g_malloc0_n ((1), sizeof (BaulTreeViewDragDestDetails ))); |
1171 | } |
1172 | |
1173 | static void |
1174 | baul_tree_view_drag_dest_class_init (BaulTreeViewDragDestClass *class) |
1175 | { |
1176 | GObjectClass *gobject_class; |
1177 | |
1178 | gobject_class = G_OBJECT_CLASS (class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((class)), (((GType) ((20) << (2)))))))); |
1179 | |
1180 | gobject_class->dispose = baul_tree_view_drag_dest_dispose; |
1181 | gobject_class->finalize = baul_tree_view_drag_dest_finalize; |
1182 | |
1183 | signals[GET_ROOT_URI] = |
1184 | g_signal_new ("get_root_uri", |
1185 | G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type), |
1186 | G_SIGNAL_RUN_LAST, |
1187 | G_STRUCT_OFFSET (BaulTreeViewDragDestClass,((glong) __builtin_offsetof(BaulTreeViewDragDestClass, get_root_uri )) |
1188 | get_root_uri)((glong) __builtin_offsetof(BaulTreeViewDragDestClass, get_root_uri )), |
1189 | NULL((void*)0), NULL((void*)0), |
1190 | baul_marshal_STRING__VOID, |
1191 | G_TYPE_STRING((GType) ((16) << (2))), 0); |
1192 | signals[GET_FILE_FOR_PATH] = |
1193 | g_signal_new ("get_file_for_path", |
1194 | G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type), |
1195 | G_SIGNAL_RUN_LAST, |
1196 | G_STRUCT_OFFSET (BaulTreeViewDragDestClass,((glong) __builtin_offsetof(BaulTreeViewDragDestClass, get_file_for_path )) |
1197 | get_file_for_path)((glong) __builtin_offsetof(BaulTreeViewDragDestClass, get_file_for_path )), |
1198 | NULL((void*)0), NULL((void*)0), |
1199 | baul_marshal_OBJECT__BOXED, |
1200 | BAUL_TYPE_FILEbaul_file_get_type(), 1, |
1201 | CTK_TYPE_TREE_PATH(ctk_tree_path_get_type ())); |
1202 | signals[MOVE_COPY_ITEMS] = |
1203 | g_signal_new ("move_copy_items", |
1204 | G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type), |
1205 | G_SIGNAL_RUN_LAST, |
1206 | G_STRUCT_OFFSET (BaulTreeViewDragDestClass,((glong) __builtin_offsetof(BaulTreeViewDragDestClass, move_copy_items )) |
1207 | move_copy_items)((glong) __builtin_offsetof(BaulTreeViewDragDestClass, move_copy_items )), |
1208 | NULL((void*)0), NULL((void*)0), |
1209 | |
1210 | baul_marshal_VOID__POINTER_STRING_ENUM_INT_INT, |
1211 | G_TYPE_NONE((GType) ((1) << (2))), 5, |
1212 | G_TYPE_POINTER((GType) ((17) << (2))), |
1213 | G_TYPE_STRING((GType) ((16) << (2))), |
1214 | CDK_TYPE_DRAG_ACTION(cdk_drag_action_get_type ()), |
1215 | G_TYPE_INT((GType) ((6) << (2))), |
1216 | G_TYPE_INT((GType) ((6) << (2)))); |
1217 | signals[HANDLE_NETSCAPE_URL] = |
1218 | g_signal_new ("handle_netscape_url", |
1219 | G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type), |
1220 | G_SIGNAL_RUN_LAST, |
1221 | G_STRUCT_OFFSET (BaulTreeViewDragDestClass,((glong) __builtin_offsetof(BaulTreeViewDragDestClass, handle_netscape_url )) |
1222 | handle_netscape_url)((glong) __builtin_offsetof(BaulTreeViewDragDestClass, handle_netscape_url )), |
1223 | NULL((void*)0), NULL((void*)0), |
1224 | baul_marshal_VOID__STRING_STRING_ENUM_INT_INT, |
1225 | G_TYPE_NONE((GType) ((1) << (2))), 5, |
1226 | G_TYPE_STRING((GType) ((16) << (2))), |
1227 | G_TYPE_STRING((GType) ((16) << (2))), |
1228 | CDK_TYPE_DRAG_ACTION(cdk_drag_action_get_type ()), |
1229 | G_TYPE_INT((GType) ((6) << (2))), |
1230 | G_TYPE_INT((GType) ((6) << (2)))); |
1231 | signals[HANDLE_URI_LIST] = |
1232 | g_signal_new ("handle_uri_list", |
1233 | G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type), |
1234 | G_SIGNAL_RUN_LAST, |
1235 | G_STRUCT_OFFSET (BaulTreeViewDragDestClass,((glong) __builtin_offsetof(BaulTreeViewDragDestClass, handle_uri_list )) |
1236 | handle_uri_list)((glong) __builtin_offsetof(BaulTreeViewDragDestClass, handle_uri_list )), |
1237 | NULL((void*)0), NULL((void*)0), |
1238 | baul_marshal_VOID__STRING_STRING_ENUM_INT_INT, |
1239 | G_TYPE_NONE((GType) ((1) << (2))), 5, |
1240 | G_TYPE_STRING((GType) ((16) << (2))), |
1241 | G_TYPE_STRING((GType) ((16) << (2))), |
1242 | CDK_TYPE_DRAG_ACTION(cdk_drag_action_get_type ()), |
1243 | G_TYPE_INT((GType) ((6) << (2))), |
1244 | G_TYPE_INT((GType) ((6) << (2)))); |
1245 | signals[HANDLE_TEXT] = |
1246 | g_signal_new ("handle_text", |
1247 | G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type), |
1248 | G_SIGNAL_RUN_LAST, |
1249 | G_STRUCT_OFFSET (BaulTreeViewDragDestClass,((glong) __builtin_offsetof(BaulTreeViewDragDestClass, handle_text )) |
1250 | handle_text)((glong) __builtin_offsetof(BaulTreeViewDragDestClass, handle_text )), |
1251 | NULL((void*)0), NULL((void*)0), |
1252 | baul_marshal_VOID__STRING_STRING_ENUM_INT_INT, |
1253 | G_TYPE_NONE((GType) ((1) << (2))), 5, |
1254 | G_TYPE_STRING((GType) ((16) << (2))), |
1255 | G_TYPE_STRING((GType) ((16) << (2))), |
1256 | CDK_TYPE_DRAG_ACTION(cdk_drag_action_get_type ()), |
1257 | G_TYPE_INT((GType) ((6) << (2))), |
1258 | G_TYPE_INT((GType) ((6) << (2)))); |
1259 | signals[HANDLE_RAW] = |
1260 | g_signal_new ("handle_raw", |
1261 | G_TYPE_FROM_CLASS (class)(((GTypeClass*) (class))->g_type), |
1262 | G_SIGNAL_RUN_LAST, |
1263 | G_STRUCT_OFFSET (BaulTreeViewDragDestClass,((glong) __builtin_offsetof(BaulTreeViewDragDestClass, handle_raw )) |
1264 | handle_raw)((glong) __builtin_offsetof(BaulTreeViewDragDestClass, handle_raw )), |
1265 | NULL((void*)0), NULL((void*)0), |
1266 | baul_marshal_VOID__POINTER_INT_STRING_STRING_ENUM_INT_INT, |
1267 | G_TYPE_NONE((GType) ((1) << (2))), 7, |
1268 | G_TYPE_POINTER((GType) ((17) << (2))), |
1269 | G_TYPE_INT((GType) ((6) << (2))), |
1270 | G_TYPE_STRING((GType) ((16) << (2))), |
1271 | G_TYPE_STRING((GType) ((16) << (2))), |
1272 | CDK_TYPE_DRAG_ACTION(cdk_drag_action_get_type ()), |
1273 | G_TYPE_INT((GType) ((6) << (2))), |
1274 | G_TYPE_INT((GType) ((6) << (2)))); |
1275 | } |
1276 | |
1277 | |
1278 | |
1279 | BaulTreeViewDragDest * |
1280 | baul_tree_view_drag_dest_new (CtkTreeView *tree_view) |
1281 | { |
1282 | BaulTreeViewDragDest *dest; |
1283 | CtkTargetList *targets; |
1284 | |
1285 | dest = g_object_new (BAUL_TYPE_TREE_VIEW_DRAG_DEST(baul_tree_view_drag_dest_get_type ()), NULL((void*)0)); |
1286 | |
1287 | dest->details->tree_view = tree_view; |
1288 | g_object_weak_ref (G_OBJECT (dest->details->tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((dest->details->tree_view)), (((GType) ((20) << (2)))))))), |
1289 | tree_view_weak_notify, dest); |
1290 | |
1291 | ctk_drag_dest_set (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), |
1292 | 0, drag_types, G_N_ELEMENTS (drag_types)(sizeof (drag_types) / sizeof ((drag_types)[0])), |
1293 | CDK_ACTION_MOVE | CDK_ACTION_COPY | CDK_ACTION_LINK | CDK_ACTION_ASK); |
1294 | |
1295 | targets = ctk_drag_dest_get_target_list (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
1296 | ctk_target_list_add_text_targets (targets, BAUL_ICON_DND_TEXT); |
1297 | |
1298 | g_signal_connect_object (tree_view, |
1299 | "drag_motion", |
1300 | G_CALLBACK (drag_motion_callback)((GCallback) (drag_motion_callback)), |
1301 | dest, 0); |
1302 | g_signal_connect_object (tree_view, |
1303 | "drag_leave", |
1304 | G_CALLBACK (drag_leave_callback)((GCallback) (drag_leave_callback)), |
1305 | dest, 0); |
1306 | g_signal_connect_object (tree_view, |
1307 | "drag_drop", |
1308 | G_CALLBACK (drag_drop_callback)((GCallback) (drag_drop_callback)), |
1309 | dest, 0); |
1310 | g_signal_connect_object (tree_view, |
1311 | "drag_data_received", |
1312 | G_CALLBACK (drag_data_received_callback)((GCallback) (drag_data_received_callback)), |
1313 | dest, 0); |
1314 | |
1315 | return dest; |
1316 | } |