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);