Mercurial > geeqie
comparison src/view_dir_list.c @ 394:4a5e1377f3d7
Merge dirlist/dirview dnd code.
author | zas_ |
---|---|
date | Thu, 17 Apr 2008 14:51:32 +0000 |
parents | b78077f65eff |
children | c359fc2c5a1f |
comparison
equal
deleted
inserted
replaced
393:8d422d424d51 | 394:4a5e1377f3d7 |
---|---|
31 #define VDLIST_PAD 4 | 31 #define VDLIST_PAD 4 |
32 | 32 |
33 #define VDLIST_INFO(_vd_, _part_) (((ViewDirInfoList *)(_vd_->info))->_part_) | 33 #define VDLIST_INFO(_vd_, _part_) (((ViewDirInfoList *)(_vd_->info))->_part_) |
34 | 34 |
35 | 35 |
36 static gint vdlist_auto_scroll_notify_cb(GtkWidget *widget, gint x, gint y, gpointer data); | |
37 | |
38 /* | 36 /* |
39 *----------------------------------------------------------------------------- | 37 *----------------------------------------------------------------------------- |
40 * misc | 38 * misc |
41 *----------------------------------------------------------------------------- | 39 *----------------------------------------------------------------------------- |
42 */ | 40 */ |
96 *----------------------------------------------------------------------------- | 94 *----------------------------------------------------------------------------- |
97 * dnd | 95 * dnd |
98 *----------------------------------------------------------------------------- | 96 *----------------------------------------------------------------------------- |
99 */ | 97 */ |
100 | 98 |
101 static GtkTargetEntry vdlist_dnd_drop_types[] = { | 99 static void vdlist_scroll_to_row(ViewDir *vd, FileData *fd, gfloat y_align) |
102 { "text/uri-list", 0, TARGET_URI_LIST } | 100 { |
103 }; | |
104 static gint vdlist_dnd_drop_types_count = 1; | |
105 | |
106 static void vdlist_dest_set(ViewDir *vd, gint enable) | |
107 { | |
108 if (enable) | |
109 { | |
110 gtk_drag_dest_set(vd->view, | |
111 GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, | |
112 vdlist_dnd_drop_types, vdlist_dnd_drop_types_count, | |
113 GDK_ACTION_MOVE | GDK_ACTION_COPY); | |
114 } | |
115 else | |
116 { | |
117 gtk_drag_dest_unset(vd->view); | |
118 } | |
119 } | |
120 | |
121 static void vdlist_dnd_get(GtkWidget *widget, GdkDragContext *context, | |
122 GtkSelectionData *selection_data, guint info, | |
123 guint time, gpointer data) | |
124 { | |
125 ViewDir *vd = data; | |
126 GList *list; | |
127 gchar *text = NULL; | |
128 gint length = 0; | |
129 | |
130 if (!vd->click_fd) return; | |
131 | |
132 switch (info) | |
133 { | |
134 case TARGET_URI_LIST: | |
135 case TARGET_TEXT_PLAIN: | |
136 list = g_list_prepend(NULL, vd->click_fd); | |
137 text = uri_text_from_filelist(list, &length, (info == TARGET_TEXT_PLAIN)); | |
138 g_list_free(list); | |
139 break; | |
140 } | |
141 if (text) | |
142 { | |
143 gtk_selection_data_set (selection_data, selection_data->target, | |
144 8, (guchar *)text, length); | |
145 g_free(text); | |
146 } | |
147 } | |
148 | |
149 static void vdlist_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data) | |
150 { | |
151 ViewDir *vd = data; | |
152 | |
153 vd_color_set(vd, vd->click_fd, TRUE); | |
154 vdlist_dest_set(vd, FALSE); | |
155 } | |
156 | |
157 static void vdlist_dnd_end(GtkWidget *widget, GdkDragContext *context, gpointer data) | |
158 { | |
159 ViewDir *vd = data; | |
160 | |
161 vd_color_set(vd, vd->click_fd, FALSE); | |
162 | |
163 if (context->action == GDK_ACTION_MOVE) | |
164 { | |
165 vdlist_refresh(vd); | |
166 } | |
167 vdlist_dest_set(vd, TRUE); | |
168 } | |
169 | |
170 static void vdlist_dnd_drop_receive(GtkWidget *widget, | |
171 GdkDragContext *context, gint x, gint y, | |
172 GtkSelectionData *selection_data, guint info, | |
173 guint time, gpointer data) | |
174 { | |
175 ViewDir *vd = data; | |
176 GtkTreePath *tpath; | |
177 GtkTreeIter iter; | 101 GtkTreeIter iter; |
178 FileData *fd = NULL; | 102 |
179 | 103 if (GTK_WIDGET_REALIZED(vd->view) && vd_find_row(vd, fd, &iter) >= 0) |
180 vd->click_fd = NULL; | |
181 | |
182 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), x, y, | |
183 &tpath, NULL, NULL, NULL)) | |
184 { | |
185 GtkTreeModel *store; | |
186 | |
187 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
188 gtk_tree_model_get_iter(store, &iter, tpath); | |
189 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &fd, -1); | |
190 gtk_tree_path_free(tpath); | |
191 } | |
192 | |
193 if (!fd) return; | |
194 | |
195 if (info == TARGET_URI_LIST) | |
196 { | |
197 GList *list; | |
198 gint active; | |
199 | |
200 list = uri_filelist_from_text((gchar *)selection_data->data, TRUE); | |
201 if (!list) return; | |
202 | |
203 active = access_file(fd->path, W_OK | X_OK); | |
204 | |
205 vd_color_set(vd, fd, TRUE); | |
206 vd->popup = vd_drop_menu(vd, active); | |
207 gtk_menu_popup(GTK_MENU(vd->popup), NULL, NULL, NULL, NULL, 0, time); | |
208 | |
209 vd->drop_fd = fd; | |
210 vd->drop_list = list; | |
211 } | |
212 } | |
213 | |
214 #if 0 | |
215 static gint vdlist_get_row_visibility(ViewDir *vd, FileData *fd) | |
216 { | |
217 GtkTreeModel *store; | |
218 GtkTreeViewColumn *column; | |
219 GtkTreePath *tpath; | |
220 GtkTreeIter iter; | |
221 | |
222 GdkRectangle vrect; | |
223 GdkRectangle crect; | |
224 | |
225 if (!fd || vd_find_row(vd, fd, &iter) < 0) return 0; | |
226 | |
227 column = gtk_tree_view_get_column(GTK_TREE_VIEW(vd->view), 0); | |
228 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vd->view)); | |
229 tpath = gtk_tree_model_get_path(store, &iter); | |
230 | |
231 gtk_tree_view_get_visible_rect(GTK_TREE_VIEW(vd->view), &vrect); | |
232 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(vd->view), tpath, column, &crect); | |
233 printf("window: %d + %d; cell: %d + %d\n", vrect.y, vrect.height, crect.y, crect.height); | |
234 gtk_tree_path_free(tpath); | |
235 | |
236 if (crect.y + crect.height < vrect.y) return -1; | |
237 if (crect.y > vrect.y + vrect.height) return 1; | |
238 return 0; | |
239 } | |
240 #endif | |
241 | |
242 static void vdlist_scroll_to_row(ViewDir *vd, FileData *fd, gfloat y_align) | |
243 { | |
244 GtkTreeIter iter; | |
245 | |
246 if (GTK_WIDGET_REALIZED(vd->view) && | |
247 vd_find_row(vd, fd, &iter) >= 0) | |
248 { | 104 { |
249 GtkTreeModel *store; | 105 GtkTreeModel *store; |
250 GtkTreePath *tpath; | 106 GtkTreePath *tpath; |
251 | 107 |
252 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vd->view)); | 108 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vd->view)); |
255 gtk_tree_view_set_cursor(GTK_TREE_VIEW(vd->view), tpath, NULL, FALSE); | 111 gtk_tree_view_set_cursor(GTK_TREE_VIEW(vd->view), tpath, NULL, FALSE); |
256 gtk_tree_path_free(tpath); | 112 gtk_tree_path_free(tpath); |
257 | 113 |
258 if (!GTK_WIDGET_HAS_FOCUS(vd->view)) gtk_widget_grab_focus(vd->view); | 114 if (!GTK_WIDGET_HAS_FOCUS(vd->view)) gtk_widget_grab_focus(vd->view); |
259 } | 115 } |
260 } | |
261 | |
262 static void vdlist_drop_update(ViewDir *vd, gint x, gint y) | |
263 { | |
264 GtkTreePath *tpath; | |
265 GtkTreeIter iter; | |
266 FileData *fd = NULL; | |
267 | |
268 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vd->view), x, y, | |
269 &tpath, NULL, NULL, NULL)) | |
270 { | |
271 GtkTreeModel *store; | |
272 | |
273 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vd->view)); | |
274 gtk_tree_model_get_iter(store, &iter, tpath); | |
275 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &fd, -1); | |
276 gtk_tree_path_free(tpath); | |
277 } | |
278 | |
279 if (fd != vd->drop_fd) | |
280 { | |
281 vd_color_set(vd, vd->drop_fd, FALSE); | |
282 vd_color_set(vd, fd, TRUE); | |
283 } | |
284 | |
285 vd->drop_fd = fd; | |
286 } | |
287 | |
288 static void vdlist_dnd_drop_scroll_cancel(ViewDir *vd) | |
289 { | |
290 if (vd->drop_scroll_id != -1) g_source_remove(vd->drop_scroll_id); | |
291 vd->drop_scroll_id = -1; | |
292 } | |
293 | |
294 static gint vdlist_auto_scroll_idle_cb(gpointer data) | |
295 { | |
296 ViewDir *vd = data; | |
297 | |
298 if (vd->drop_fd) | |
299 { | |
300 GdkWindow *window; | |
301 gint x, y; | |
302 gint w, h; | |
303 | |
304 window = vd->view->window; | |
305 gdk_window_get_pointer(window, &x, &y, NULL); | |
306 gdk_drawable_get_size(window, &w, &h); | |
307 if (x >= 0 && x < w && y >= 0 && y < h) | |
308 { | |
309 vdlist_drop_update(vd, x, y); | |
310 } | |
311 } | |
312 | |
313 vd->drop_scroll_id = -1; | |
314 return FALSE; | |
315 } | |
316 | |
317 static gint vdlist_auto_scroll_notify_cb(GtkWidget *widget, gint x, gint y, gpointer data) | |
318 { | |
319 ViewDir *vd = data; | |
320 | |
321 if (!vd->drop_fd || vd->drop_list) return FALSE; | |
322 | |
323 if (vd->drop_scroll_id == -1) vd->drop_scroll_id = g_idle_add(vdlist_auto_scroll_idle_cb, vd); | |
324 | |
325 return TRUE; | |
326 } | |
327 | |
328 static gint vdlist_dnd_drop_motion(GtkWidget *widget, GdkDragContext *context, | |
329 gint x, gint y, guint time, gpointer data) | |
330 { | |
331 ViewDir *vd = data; | |
332 | |
333 vd->click_fd = NULL; | |
334 | |
335 if (gtk_drag_get_source_widget(context) == vd->view) | |
336 { | |
337 /* from same window */ | |
338 gdk_drag_status(context, 0, time); | |
339 return TRUE; | |
340 } | |
341 else | |
342 { | |
343 gdk_drag_status(context, context->suggested_action, time); | |
344 } | |
345 | |
346 vdlist_drop_update(vd, x, y); | |
347 | |
348 if (vd->drop_fd) | |
349 { | |
350 GtkAdjustment *adj = gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(vd->view)); | |
351 widget_auto_scroll_start(vd->view, adj, -1, -1, vdlist_auto_scroll_notify_cb, vd); | |
352 } | |
353 | |
354 return FALSE; | |
355 } | |
356 | |
357 static void vdlist_dnd_drop_leave(GtkWidget *widget, GdkDragContext *context, guint time, gpointer data) | |
358 { | |
359 ViewDir *vd = data; | |
360 | |
361 if (vd->drop_fd != vd->click_fd) vd_color_set(vd, vd->drop_fd, FALSE); | |
362 | |
363 vd->drop_fd = NULL; | |
364 } | |
365 | |
366 static void vdlist_dnd_init(ViewDir *vd) | |
367 { | |
368 gtk_drag_source_set(vd->view, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, | |
369 dnd_file_drag_types, dnd_file_drag_types_count, | |
370 GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK); | |
371 g_signal_connect(G_OBJECT(vd->view), "drag_data_get", | |
372 G_CALLBACK(vdlist_dnd_get), vd); | |
373 g_signal_connect(G_OBJECT(vd->view), "drag_begin", | |
374 G_CALLBACK(vdlist_dnd_begin), vd); | |
375 g_signal_connect(G_OBJECT(vd->view), "drag_end", | |
376 G_CALLBACK(vdlist_dnd_end), vd); | |
377 | |
378 vdlist_dest_set(vd, TRUE); | |
379 g_signal_connect(G_OBJECT(vd->view), "drag_data_received", | |
380 G_CALLBACK(vdlist_dnd_drop_receive), vd); | |
381 g_signal_connect(G_OBJECT(vd->view), "drag_motion", | |
382 G_CALLBACK(vdlist_dnd_drop_motion), vd); | |
383 g_signal_connect(G_OBJECT(vd->view), "drag_leave", | |
384 G_CALLBACK(vdlist_dnd_drop_leave), vd); | |
385 } | 116 } |
386 | 117 |
387 /* | 118 /* |
388 *----------------------------------------------------------------------------- | 119 *----------------------------------------------------------------------------- |
389 * main | 120 * main |
712 | 443 |
713 static void vdlist_destroy_cb(GtkWidget *widget, gpointer data) | 444 static void vdlist_destroy_cb(GtkWidget *widget, gpointer data) |
714 { | 445 { |
715 ViewDir *vd = data; | 446 ViewDir *vd = data; |
716 | 447 |
717 vdlist_dnd_drop_scroll_cancel(vd); | 448 vd_dnd_drop_scroll_cancel(vd); |
718 widget_auto_scroll_stop(vd->view); | 449 widget_auto_scroll_stop(vd->view); |
719 | 450 |
720 filelist_free(VDLIST_INFO(vd, list)); | 451 filelist_free(VDLIST_INFO(vd, list)); |
721 } | 452 } |
722 | 453 |
764 g_signal_connect(G_OBJECT(vd->view), "key_press_event", | 495 g_signal_connect(G_OBJECT(vd->view), "key_press_event", |
765 G_CALLBACK(vdlist_press_key_cb), vd); | 496 G_CALLBACK(vdlist_press_key_cb), vd); |
766 gtk_container_add(GTK_CONTAINER(vd->widget), vd->view); | 497 gtk_container_add(GTK_CONTAINER(vd->widget), vd->view); |
767 gtk_widget_show(vd->view); | 498 gtk_widget_show(vd->view); |
768 | 499 |
769 vdlist_dnd_init(vd); | 500 vd_dnd_init(vd); |
770 | 501 |
771 g_signal_connect(G_OBJECT(vd->view), "button_press_event", | 502 g_signal_connect(G_OBJECT(vd->view), "button_press_event", |
772 G_CALLBACK(vdlist_press_cb), vd); | 503 G_CALLBACK(vdlist_press_cb), vd); |
773 g_signal_connect(G_OBJECT(vd->view), "button_release_event", | 504 g_signal_connect(G_OBJECT(vd->view), "button_release_event", |
774 G_CALLBACK(vdlist_release_cb), vd); | 505 G_CALLBACK(vdlist_release_cb), vd); |