Mercurial > geeqie.yaz
annotate src/view_file_list.c @ 111:3a69a7a3f461
Wed Nov 15 02:05:27 2006 John Ellis <johne@verizon.net>
* view_file_icon.c: Fix odd crash when removing files, it seems the
high priority idle sync is no longer called before the treeview tries
to redraw itself, so fix the cleanup of removed pointers so that they
are always valid or NULL (I wonder if the priorities used by
GtkTreeView have changed in newer versions of GTK?).
* view_file_list.c: Fix progress bar warning when files are removed
before thumbnail generation is finished.
author | gqview |
---|---|
date | Wed, 15 Nov 2006 07:19:16 +0000 |
parents | f1c8f8632e23 |
children | 55166d93498d |
rev | line source |
---|---|
9 | 1 /* |
2 * GQview | |
3 * (C) 2004 John Ellis | |
4 * | |
5 * Author: John Ellis | |
6 * | |
7 * This software is released under the GNU General Public License (GNU GPL). | |
8 * Please read the included file COPYING for more information. | |
9 * This software comes with no warranty of any kind, use at your own risk! | |
10 */ | |
11 | |
12 #include "gqview.h" | |
13 #include "view_file_list.h" | |
14 | |
15 #include "cache_maint.h" | |
16 #include "dnd.h" | |
17 #include "editors.h" | |
18 #include "img-view.h" | |
19 #include "info.h" | |
20 #include "layout.h" | |
21 #include "layout_image.h" | |
22 #include "menu.h" | |
23 #include "thumb.h" | |
24 #include "utilops.h" | |
25 #include "ui_bookmark.h" | |
26 #include "ui_fileops.h" | |
27 #include "ui_menu.h" | |
28 #include "ui_tree_edit.h" | |
29 | |
30 #include <gdk/gdkkeysyms.h> /* for keyboard values */ | |
31 | |
32 | |
33 enum { | |
34 FILE_COLUMN_POINTER = 0, | |
35 FILE_COLUMN_THUMB, | |
36 FILE_COLUMN_NAME, | |
37 FILE_COLUMN_SIZE, | |
38 FILE_COLUMN_DATE, | |
39 FILE_COLUMN_COLOR, | |
40 FILE_COLUMN_COUNT | |
41 }; | |
42 | |
43 | |
44 static gint vflist_row_is_selected(ViewFileList *vfl, FileData *fd); | |
45 static gint vflist_row_rename_cb(TreeEditData *td, const gchar *old, const gchar *new, gpointer data); | |
46 static void vflist_populate_view(ViewFileList *vfl); | |
47 | |
48 /* | |
49 *----------------------------------------------------------------------------- | |
50 * signals | |
51 *----------------------------------------------------------------------------- | |
52 */ | |
53 | |
54 static void vflist_send_update(ViewFileList *vfl) | |
55 { | |
56 if (vfl->func_status) vfl->func_status(vfl, vfl->data_status); | |
57 } | |
58 | |
59 /* | |
60 *----------------------------------------------------------------------------- | |
61 * misc | |
62 *----------------------------------------------------------------------------- | |
63 */ | |
64 | |
65 static gint vflist_find_row(ViewFileList *vfl, FileData *fd, GtkTreeIter *iter) | |
66 { | |
67 GtkTreeModel *store; | |
68 gint valid; | |
69 gint row = 0; | |
70 | |
71 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); | |
72 valid = gtk_tree_model_get_iter_first(store, iter); | |
73 while (valid) | |
74 { | |
75 FileData *fd_n; | |
76 gtk_tree_model_get(GTK_TREE_MODEL(store), iter, FILE_COLUMN_POINTER, &fd_n, -1); | |
77 if (fd_n == fd) return row; | |
78 | |
79 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), iter); | |
80 row++; | |
81 } | |
82 | |
83 return -1; | |
84 } | |
85 | |
86 static void vflist_color_set(ViewFileList *vfl, FileData *fd, gint color_set) | |
87 { | |
88 GtkTreeModel *store; | |
89 GtkTreeIter iter; | |
90 | |
91 if (vflist_find_row(vfl, fd, &iter) < 0) return; | |
92 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); | |
93 gtk_list_store_set(GTK_LIST_STORE(store), &iter, FILE_COLUMN_COLOR, color_set, -1); | |
94 } | |
95 | |
96 static void vflist_move_cursor(ViewFileList *vfl, GtkTreeIter *iter) | |
97 { | |
98 GtkTreeModel *store; | |
99 GtkTreePath *tpath; | |
100 | |
101 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); | |
102 | |
103 tpath = gtk_tree_model_get_path(store, iter); | |
104 gtk_tree_view_set_cursor(GTK_TREE_VIEW(vfl->listview), tpath, NULL, FALSE); | |
105 gtk_tree_path_free(tpath); | |
106 } | |
107 | |
108 /* | |
109 *----------------------------------------------------------------------------- | |
110 * dnd | |
111 *----------------------------------------------------------------------------- | |
112 */ | |
113 | |
114 static void vflist_dnd_get(GtkWidget *widget, GdkDragContext *context, | |
115 GtkSelectionData *selection_data, guint info, | |
116 guint time, gpointer data) | |
117 { | |
118 ViewFileList *vfl = data; | |
119 GList *list = NULL; | |
120 gchar *uri_text = NULL; | |
121 gint total; | |
122 | |
123 if (!vfl->click_fd) return; | |
124 | |
125 if (vflist_row_is_selected(vfl, vfl->click_fd)) | |
126 { | |
127 list = vflist_selection_get_list(vfl); | |
128 } | |
129 else | |
130 { | |
131 list = g_list_append(NULL, g_strdup(vfl->click_fd->path)); | |
132 } | |
133 | |
134 if (!list) return; | |
135 | |
136 uri_text = uri_text_from_list(list, &total, (info == TARGET_TEXT_PLAIN)); | |
137 path_list_free(list); | |
138 | |
139 if (debug) printf(uri_text); | |
140 | |
64
04ff0df3ad2f
Mon Aug 15 17:13:57 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
141 gtk_selection_data_set(selection_data, selection_data->target, |
04ff0df3ad2f
Mon Aug 15 17:13:57 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
142 8, (guchar *)uri_text, total); |
9 | 143 g_free(uri_text); |
144 } | |
145 | |
146 static void vflist_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data) | |
147 { | |
148 ViewFileList *vfl = data; | |
149 | |
150 vflist_color_set(vfl, vfl->click_fd, TRUE); | |
151 | |
152 if (vfl->thumbs_enabled && | |
153 vfl->click_fd && vfl->click_fd->pixbuf) | |
154 { | |
155 gint items; | |
156 | |
157 if (vflist_row_is_selected(vfl, vfl->click_fd)) | |
158 items = vflist_selection_count(vfl, NULL); | |
159 else | |
160 items = 1; | |
161 | |
162 dnd_set_drag_icon(widget, context, vfl->click_fd->pixbuf, items); | |
163 } | |
164 } | |
165 | |
166 static void vflist_dnd_end(GtkWidget *widget, GdkDragContext *context, gpointer data) | |
167 { | |
168 ViewFileList *vfl = data; | |
169 | |
170 vflist_color_set(vfl, vfl->click_fd, FALSE); | |
171 | |
172 if (context->action == GDK_ACTION_MOVE) | |
173 { | |
174 vflist_refresh(vfl); | |
175 } | |
176 } | |
177 | |
178 static void vflist_dnd_init(ViewFileList *vfl) | |
179 { | |
180 gtk_drag_source_set(vfl->listview, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, | |
181 dnd_file_drag_types, dnd_file_drag_types_count, | |
182 GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK); | |
183 g_signal_connect(G_OBJECT(vfl->listview), "drag_data_get", | |
184 G_CALLBACK(vflist_dnd_get), vfl); | |
185 g_signal_connect(G_OBJECT(vfl->listview), "drag_begin", | |
186 G_CALLBACK(vflist_dnd_begin), vfl); | |
187 g_signal_connect(G_OBJECT(vfl->listview), "drag_end", | |
188 G_CALLBACK(vflist_dnd_end), vfl); | |
189 } | |
190 | |
191 /* | |
192 *----------------------------------------------------------------------------- | |
193 * pop-up menu | |
194 *----------------------------------------------------------------------------- | |
195 */ | |
196 | |
197 static GList *vflist_pop_menu_file_list(ViewFileList *vfl) | |
198 { | |
199 if (!vfl->click_fd) return NULL; | |
200 | |
201 if (vflist_row_is_selected(vfl, vfl->click_fd)) | |
202 { | |
203 return vflist_selection_get_list(vfl); | |
204 } | |
205 | |
206 return g_list_append(NULL, g_strdup(vfl->click_fd->path)); | |
207 } | |
208 | |
209 static void vflist_pop_menu_edit_cb(GtkWidget *widget, gpointer data) | |
210 { | |
211 ViewFileList *vfl; | |
212 gint n; | |
213 GList *list; | |
214 | |
215 vfl = submenu_item_get_data(widget); | |
216 n = GPOINTER_TO_INT(data); | |
217 | |
218 if (!vfl) return; | |
219 | |
220 list = vflist_pop_menu_file_list(vfl); | |
221 start_editor_from_path_list(n, list); | |
222 path_list_free(list); | |
223 } | |
224 | |
225 static void vflist_pop_menu_info_cb(GtkWidget *widget, gpointer data) | |
226 { | |
227 ViewFileList *vfl = data; | |
228 | |
229 info_window_new(NULL, vflist_pop_menu_file_list(vfl)); | |
230 } | |
231 | |
232 static void vflist_pop_menu_view_cb(GtkWidget *widget, gpointer data) | |
233 { | |
234 ViewFileList *vfl = data; | |
235 | |
236 if (vflist_row_is_selected(vfl, vfl->click_fd)) | |
237 { | |
238 GList *list; | |
239 | |
240 list = vflist_selection_get_list(vfl); | |
241 view_window_new_from_list(list); | |
242 path_list_free(list); | |
243 } | |
244 else | |
245 { | |
246 const gchar *path; | |
247 | |
248 path = vfl->click_fd->path; | |
249 view_window_new(path); | |
250 } | |
251 } | |
252 | |
253 static void vflist_pop_menu_copy_cb(GtkWidget *widget, gpointer data) | |
254 { | |
255 ViewFileList *vfl = data; | |
256 | |
257 file_util_copy(NULL, vflist_pop_menu_file_list(vfl), NULL, vfl->listview); | |
258 } | |
259 | |
260 static void vflist_pop_menu_move_cb(GtkWidget *widget, gpointer data) | |
261 { | |
262 ViewFileList *vfl = data; | |
263 | |
264 file_util_move(NULL, vflist_pop_menu_file_list(vfl), NULL, vfl->listview); | |
265 } | |
266 | |
267 static void vflist_pop_menu_rename_cb(GtkWidget *widget, gpointer data) | |
268 { | |
269 ViewFileList *vfl = data; | |
270 GList *list; | |
271 | |
272 list = vflist_pop_menu_file_list(vfl); | |
273 if (enable_in_place_rename && | |
274 list && !list->next && vfl->click_fd) | |
275 { | |
276 GtkTreeModel *store; | |
277 GtkTreeIter iter; | |
278 | |
279 path_list_free(list); | |
280 | |
281 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); | |
282 if (vflist_find_row(vfl, vfl->click_fd, &iter) >= 0) | |
283 { | |
284 GtkTreePath *tpath; | |
285 | |
286 tpath = gtk_tree_model_get_path(store, &iter); | |
287 tree_edit_by_path(GTK_TREE_VIEW(vfl->listview), tpath, | |
288 FILE_COLUMN_NAME -1, vfl->click_fd->name, | |
289 vflist_row_rename_cb, vfl); | |
290 gtk_tree_path_free(tpath); | |
291 } | |
292 return; | |
293 } | |
294 | |
295 file_util_rename(NULL, list, vfl->listview); | |
296 } | |
297 | |
298 static void vflist_pop_menu_delete_cb(GtkWidget *widget, gpointer data) | |
299 { | |
300 ViewFileList *vfl = data; | |
301 | |
302 file_util_delete(NULL, vflist_pop_menu_file_list(vfl), vfl->listview); | |
303 } | |
304 | |
305 static void vflist_pop_menu_sort_cb(GtkWidget *widget, gpointer data) | |
306 { | |
307 ViewFileList *vfl; | |
308 SortType type; | |
309 | |
310 vfl = submenu_item_get_data(widget); | |
311 if (!vfl) return; | |
312 | |
313 type = (SortType)GPOINTER_TO_INT(data); | |
314 | |
315 if (vfl->layout) | |
316 { | |
317 layout_sort_set(vfl->layout, type, vfl->sort_ascend); | |
318 } | |
319 else | |
320 { | |
321 vflist_sort_set(vfl, type, vfl->sort_ascend); | |
322 } | |
323 } | |
324 | |
325 static void vflist_pop_menu_sort_ascend_cb(GtkWidget *widget, gpointer data) | |
326 { | |
327 ViewFileList *vfl = data; | |
328 | |
329 if (vfl->layout) | |
330 { | |
331 layout_sort_set(vfl->layout, vfl->sort_method, !vfl->sort_ascend); | |
332 } | |
333 else | |
334 { | |
335 vflist_sort_set(vfl, vfl->sort_method, !vfl->sort_ascend); | |
336 } | |
337 } | |
338 | |
339 static void vflist_pop_menu_icons_cb(GtkWidget *widget, gpointer data) | |
340 { | |
341 ViewFileList *vfl = data; | |
342 | |
343 if (vfl->layout) layout_views_set(vfl->layout, vfl->layout->tree_view, TRUE); | |
344 } | |
345 | |
346 static void vflist_pop_menu_thumbs_cb(GtkWidget *widget, gpointer data) | |
347 { | |
348 ViewFileList *vfl = data; | |
349 | |
350 vflist_color_set(vfl, vfl->click_fd, FALSE); | |
351 if (vfl->layout) | |
352 { | |
353 layout_thumb_set(vfl->layout, !vfl->thumbs_enabled); | |
354 } | |
355 else | |
356 { | |
357 vflist_thumb_set(vfl, !vfl->thumbs_enabled); | |
358 } | |
359 } | |
360 | |
361 static void vflist_pop_menu_refresh_cb(GtkWidget *widget, gpointer data) | |
362 { | |
363 ViewFileList *vfl = data; | |
364 | |
365 vflist_color_set(vfl, vfl->click_fd, FALSE); | |
366 vflist_refresh(vfl); | |
367 } | |
368 | |
369 static void vflist_popup_destroy_cb(GtkWidget *widget, gpointer data) | |
370 { | |
371 ViewFileList *vfl = data; | |
372 vflist_color_set(vfl, vfl->click_fd, FALSE); | |
373 vfl->click_fd = NULL; | |
374 vfl->popup = NULL; | |
375 } | |
376 | |
377 static GtkWidget *vflist_pop_menu(ViewFileList *vfl, FileData *fd) | |
378 { | |
379 GtkWidget *menu; | |
380 GtkWidget *item; | |
381 GtkWidget *submenu; | |
382 gint active; | |
383 | |
384 vflist_color_set(vfl, fd, TRUE); | |
385 active = (fd != NULL); | |
386 | |
387 menu = popup_menu_short_lived(); | |
388 g_signal_connect(G_OBJECT(menu), "destroy", | |
389 G_CALLBACK(vflist_popup_destroy_cb), vfl); | |
390 | |
391 submenu_add_edit(menu, &item, G_CALLBACK(vflist_pop_menu_edit_cb), vfl); | |
392 gtk_widget_set_sensitive(item, active); | |
393 | |
394 menu_item_add_stock_sensitive(menu, _("_Properties"), GTK_STOCK_PROPERTIES, active, | |
395 G_CALLBACK(vflist_pop_menu_info_cb), vfl); | |
396 menu_item_add_stock_sensitive(menu, _("View in _new window"), GTK_STOCK_NEW, active, | |
397 G_CALLBACK(vflist_pop_menu_view_cb), vfl); | |
398 | |
399 menu_item_add_divider(menu); | |
400 menu_item_add_stock_sensitive(menu, _("_Copy..."), GTK_STOCK_COPY, active, | |
401 G_CALLBACK(vflist_pop_menu_copy_cb), vfl); | |
402 menu_item_add_sensitive(menu, _("_Move..."), active, | |
403 G_CALLBACK(vflist_pop_menu_move_cb), vfl); | |
404 menu_item_add_sensitive(menu, _("_Rename..."), active, | |
405 G_CALLBACK(vflist_pop_menu_rename_cb), vfl); | |
406 menu_item_add_stock_sensitive(menu, _("_Delete..."), GTK_STOCK_DELETE, active, | |
407 G_CALLBACK(vflist_pop_menu_delete_cb), vfl); | |
408 | |
409 menu_item_add_divider(menu); | |
410 | |
411 submenu = submenu_add_sort(NULL, G_CALLBACK(vflist_pop_menu_sort_cb), vfl, | |
412 FALSE, FALSE, TRUE, vfl->sort_method); | |
413 menu_item_add_divider(submenu); | |
414 menu_item_add_check(submenu, _("Ascending"), vfl->sort_ascend, | |
415 G_CALLBACK(vflist_pop_menu_sort_ascend_cb), vfl); | |
416 | |
417 item = menu_item_add(menu, _("_Sort"), NULL, NULL); | |
418 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); | |
419 | |
420 menu_item_add_check(menu, _("View as _icons"), FALSE, | |
421 G_CALLBACK(vflist_pop_menu_icons_cb), vfl); | |
422 menu_item_add_check(menu, _("Show _thumbnails"), vfl->thumbs_enabled, | |
423 G_CALLBACK(vflist_pop_menu_thumbs_cb), vfl); | |
424 menu_item_add_stock(menu, _("Re_fresh"), GTK_STOCK_REFRESH, G_CALLBACK(vflist_pop_menu_refresh_cb), vfl); | |
425 | |
426 return menu; | |
427 } | |
428 | |
429 /* | |
430 *----------------------------------------------------------------------------- | |
431 * callbacks | |
432 *----------------------------------------------------------------------------- | |
433 */ | |
434 | |
435 static gint vflist_row_rename_cb(TreeEditData *td, const gchar *old, const gchar *new, gpointer data) | |
436 { | |
437 ViewFileList *vfl = data; | |
438 gchar *old_path; | |
439 gchar *new_path; | |
440 | |
441 if (strlen(new) == 0) return FALSE; | |
442 | |
443 old_path = concat_dir_and_file(vfl->path, old); | |
444 new_path = concat_dir_and_file(vfl->path, new); | |
445 | |
446 if (strchr(new, '/') != NULL) | |
447 { | |
448 gchar *text = g_strdup_printf(_("Invalid file name:\n%s"), new); | |
449 file_util_warning_dialog(_("Error renaming file"), text, GTK_STOCK_DIALOG_ERROR, vfl->listview); | |
450 g_free(text); | |
451 } | |
452 else if (isfile(new_path)) | |
453 { | |
454 gchar *text = g_strdup_printf(_("A file with name %s already exists."), new); | |
455 file_util_warning_dialog(_("Error renaming file"), text, GTK_STOCK_DIALOG_ERROR, vfl->listview); | |
456 g_free(text); | |
457 } | |
458 else if (!rename_file(old_path, new_path)) | |
459 { | |
460 gchar *text = g_strdup_printf(_("Unable to rename file:\n%s\nto:\n%s"), old, new); | |
461 file_util_warning_dialog(_("Error renaming file"), text, GTK_STOCK_DIALOG_ERROR, vfl->listview); | |
462 g_free(text); | |
463 } | |
464 else | |
465 { | |
466 file_maint_renamed(old_path, new_path); | |
467 } | |
468 | |
469 g_free(old_path); | |
470 g_free(new_path); | |
471 | |
472 return FALSE; | |
473 } | |
474 | |
475 static void vflist_menu_position_cb(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer data) | |
476 { | |
477 ViewFileList *vfl = data; | |
478 GtkTreeModel *store; | |
479 GtkTreeIter iter; | |
480 GtkTreePath *tpath; | |
481 gint cw, ch; | |
482 | |
483 if (vflist_find_row(vfl, vfl->click_fd, &iter) < 0) return; | |
484 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); | |
485 tpath = gtk_tree_model_get_path(store, &iter); | |
486 tree_view_get_cell_clamped(GTK_TREE_VIEW(vfl->listview), tpath, FILE_COLUMN_NAME - 1, TRUE, x, y, &cw, &ch); | |
487 gtk_tree_path_free(tpath); | |
488 *y += ch; | |
489 popup_menu_position_clamp(menu, x, y, 0); | |
490 } | |
491 | |
492 static gint vflist_press_key_cb(GtkWidget *widget, GdkEventKey *event, gpointer data) | |
493 { | |
494 ViewFileList *vfl = data; | |
495 GtkTreePath *tpath; | |
496 | |
497 if (event->keyval != GDK_Menu) return FALSE; | |
498 | |
499 gtk_tree_view_get_cursor(GTK_TREE_VIEW(vfl->listview), &tpath, NULL); | |
500 if (tpath) | |
501 { | |
502 GtkTreeModel *store; | |
503 GtkTreeIter iter; | |
504 | |
505 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
506 gtk_tree_model_get_iter(store, &iter, tpath); | |
507 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &vfl->click_fd, -1); | |
508 gtk_tree_path_free(tpath); | |
509 } | |
510 else | |
511 { | |
512 vfl->click_fd = NULL; | |
513 } | |
514 | |
515 vfl->popup = vflist_pop_menu(vfl, vfl->click_fd); | |
516 gtk_menu_popup(GTK_MENU(vfl->popup), NULL, NULL, vflist_menu_position_cb, vfl, 0, GDK_CURRENT_TIME); | |
517 | |
518 return TRUE; | |
519 } | |
520 | |
521 static gint vflist_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) | |
522 { | |
523 ViewFileList *vfl = data; | |
524 GtkTreePath *tpath; | |
525 GtkTreeIter iter; | |
526 FileData *fd = NULL; | |
527 | |
528 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), bevent->x, bevent->y, | |
529 &tpath, NULL, NULL, NULL)) | |
530 { | |
531 GtkTreeModel *store; | |
532 | |
533 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
534 gtk_tree_model_get_iter(store, &iter, tpath); | |
535 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); | |
536 #if 0 | |
537 gtk_tree_view_set_cursor(GTK_TREE_VIEW(widget), tpath, NULL, FALSE); | |
538 #endif | |
539 gtk_tree_path_free(tpath); | |
540 } | |
541 | |
542 vfl->click_fd = fd; | |
543 | |
544 if (bevent->button == 3) | |
545 { | |
546 vfl->popup = vflist_pop_menu(vfl, vfl->click_fd); | |
547 gtk_menu_popup(GTK_MENU(vfl->popup), NULL, NULL, NULL, NULL, | |
548 bevent->button, bevent->time); | |
549 return TRUE; | |
550 } | |
551 | |
552 if (!fd) return FALSE; | |
553 | |
554 if (bevent->button == 2) | |
555 { | |
556 if (!vflist_row_is_selected(vfl, fd)) | |
557 { | |
558 vflist_color_set(vfl, fd, TRUE); | |
559 } | |
560 return TRUE; | |
561 } | |
562 | |
563 | |
564 if (bevent->button == 1 && bevent->type == GDK_BUTTON_PRESS && | |
565 !(bevent->state & GDK_SHIFT_MASK ) && | |
566 !(bevent->state & GDK_CONTROL_MASK ) && | |
567 vflist_row_is_selected(vfl, fd)) | |
568 { | |
569 gtk_widget_grab_focus(widget); | |
570 return TRUE; | |
571 } | |
572 | |
573 #if 0 | |
574 if (bevent->button == 1 && bevent->type == GDK_2BUTTON_PRESS) | |
575 { | |
576 if (vfl->layout) layout_image_full_screen_start(vfl->layout); | |
577 } | |
578 #endif | |
579 | |
580 return FALSE; | |
581 } | |
582 | |
583 static gint vflist_release_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) | |
584 { | |
585 ViewFileList *vfl = data; | |
586 GtkTreePath *tpath; | |
587 GtkTreeIter iter; | |
588 FileData *fd = NULL; | |
589 | |
590 if (bevent->button == 2) | |
591 { | |
592 vflist_color_set(vfl, vfl->click_fd, FALSE); | |
593 } | |
594 | |
595 if (bevent->button != 1 && bevent->button != 2) | |
596 { | |
597 return TRUE; | |
598 } | |
599 | |
600 if ((bevent->x != 0 || bevent->y != 0) && | |
601 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), bevent->x, bevent->y, | |
602 &tpath, NULL, NULL, NULL)) | |
603 { | |
604 GtkTreeModel *store; | |
605 | |
606 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
607 gtk_tree_model_get_iter(store, &iter, tpath); | |
608 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); | |
609 gtk_tree_path_free(tpath); | |
610 } | |
611 | |
612 if (bevent->button == 2) | |
613 { | |
614 if (fd && vfl->click_fd == fd) | |
615 { | |
616 GtkTreeSelection *selection; | |
617 | |
618 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); | |
619 if (vflist_row_is_selected(vfl, fd)) | |
620 { | |
621 gtk_tree_selection_unselect_iter(selection, &iter); | |
622 } | |
623 else | |
624 { | |
625 gtk_tree_selection_select_iter(selection, &iter); | |
626 } | |
627 } | |
628 return TRUE; | |
629 } | |
630 | |
631 if (fd && vfl->click_fd == fd && | |
632 !(bevent->state & GDK_SHIFT_MASK ) && | |
633 !(bevent->state & GDK_CONTROL_MASK ) && | |
634 vflist_row_is_selected(vfl, fd)) | |
635 { | |
636 GtkTreeSelection *selection; | |
637 | |
638 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); | |
639 gtk_tree_selection_unselect_all(selection); | |
640 gtk_tree_selection_select_iter(selection, &iter); | |
641 vflist_move_cursor(vfl, &iter); | |
642 return TRUE; | |
643 } | |
644 | |
645 return FALSE; | |
646 } | |
647 | |
648 static void vflist_select_image(ViewFileList *vfl, gint row) | |
649 { | |
650 const gchar *path; | |
651 const gchar *read_ahead_path = NULL; | |
652 | |
653 path = vflist_index_get_path(vfl, row); | |
654 if (!path) return; | |
655 | |
656 if (path && enable_read_ahead) | |
657 { | |
658 FileData *fd; | |
659 if (row > vflist_index_by_path(vfl, layout_image_get_path(vfl->layout)) && | |
660 row + 1 < vflist_count(vfl, NULL)) | |
661 { | |
662 fd = vflist_index_get_data(vfl, row + 1); | |
663 } | |
664 else if (row > 0) | |
665 { | |
666 fd = vflist_index_get_data(vfl, row - 1); | |
667 } | |
668 else | |
669 { | |
670 fd = NULL; | |
671 } | |
672 if (fd) read_ahead_path = fd->path; | |
673 } | |
674 | |
675 layout_image_set_with_ahead(vfl->layout, path, read_ahead_path); | |
676 } | |
677 | |
678 static gint vflist_select_idle_cb(gpointer data) | |
679 { | |
680 ViewFileList *vfl = data; | |
681 | |
682 if (!vfl->layout) | |
683 { | |
684 vfl->select_idle_id = -1; | |
685 return FALSE; | |
686 } | |
687 | |
688 vflist_send_update(vfl); | |
689 | |
690 if (vfl->select_fd) | |
691 { | |
692 vflist_select_image(vfl, g_list_index(vfl->list, vfl->select_fd)); | |
693 vfl->select_fd = NULL; | |
694 } | |
695 | |
696 vfl->select_idle_id = -1; | |
697 return FALSE; | |
698 } | |
699 | |
700 static void vflist_select_idle_cancel(ViewFileList *vfl) | |
701 { | |
702 if (vfl->select_idle_id != -1) g_source_remove(vfl->select_idle_id); | |
703 vfl->select_idle_id = -1; | |
704 } | |
705 | |
706 static gboolean vflist_select_cb(GtkTreeSelection *selection, GtkTreeModel *store, GtkTreePath *tpath, | |
707 gboolean path_currently_selected, gpointer data) | |
708 { | |
709 ViewFileList *vfl = data; | |
710 GtkTreeIter iter; | |
711 | |
712 if (!path_currently_selected && | |
713 gtk_tree_model_get_iter(store, &iter, tpath)) | |
714 { | |
715 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &vfl->select_fd, -1); | |
716 } | |
717 else | |
718 { | |
719 vfl->select_fd = NULL; | |
720 } | |
721 | |
722 if (vfl->layout && | |
723 vfl->select_idle_id == -1) | |
724 { | |
725 vfl->select_idle_id = g_idle_add(vflist_select_idle_cb, vfl); | |
726 } | |
727 | |
728 return TRUE; | |
729 } | |
730 | |
731 /* | |
732 *----------------------------------------------------------------------------- | |
733 * misc | |
734 *----------------------------------------------------------------------------- | |
735 */ | |
736 | |
93
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
737 static gboolean vflist_dummy_select_cb(GtkTreeSelection *selection, GtkTreeModel *store, GtkTreePath *tpath, |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
738 gboolean path_currently_selected, gpointer data) |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
739 { |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
740 return TRUE; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
741 } |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
742 |
9 | 743 void vflist_sort_set(ViewFileList *vfl, SortType type, gint ascend) |
744 { | |
93
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
745 GtkTreeModel *model; |
9 | 746 GtkListStore *store; |
747 GList *work; | |
93
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
748 GtkTreeSelection *selection; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
749 GtkTreePath *tpath; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
750 GtkTreeIter iter; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
751 GList *select_list; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
752 FileData *cursor_fd = NULL; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
753 gint single_select; |
9 | 754 |
755 if (vfl->sort_method == type && vfl->sort_ascend == ascend) return; | |
756 | |
757 vfl->sort_method = type; | |
758 vfl->sort_ascend = ascend; | |
759 | |
760 if (!vfl->list) return; | |
761 | |
762 vfl->list = filelist_sort(vfl->list, vfl->sort_method, vfl->sort_ascend); | |
763 | |
93
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
764 /* now reorder the treeview, maintaining current selection */ |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
765 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
766 #if 0 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
767 /* this is simpler, but much slower */ |
9 | 768 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview))); |
769 | |
770 work = g_list_last(vfl->list); | |
771 while (work) | |
772 { | |
773 FileData *fd; | |
774 GtkTreeIter iter; | |
775 | |
776 fd = work->data; | |
777 if (vflist_find_row(vfl, fd, &iter) >= 0) | |
778 { | |
779 gtk_list_store_move_after(store, &iter, NULL); | |
780 } | |
781 | |
782 work = work->prev; | |
783 } | |
93
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
784 #endif |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
785 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
786 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
787 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
788 gtk_tree_selection_set_select_function(selection, vflist_dummy_select_cb, vfl, NULL); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
789 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
790 select_list = gtk_tree_selection_get_selected_rows(selection, &model); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
791 work = select_list; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
792 while (work) |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
793 { |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
794 FileData *fd; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
795 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
796 tpath = work->data; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
797 gtk_tree_model_get_iter(model, &iter, tpath); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
798 gtk_tree_model_get(model, &iter, FILE_COLUMN_POINTER, &fd, -1); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
799 gtk_tree_path_free(tpath); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
800 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
801 work->data = fd; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
802 work = work->next; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
803 } |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
804 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
805 select_list = filelist_sort(select_list, vfl->sort_method, vfl->sort_ascend); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
806 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
807 gtk_tree_view_get_cursor(GTK_TREE_VIEW(vfl->listview), &tpath, NULL); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
808 if (tpath) |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
809 { |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
810 if (gtk_tree_model_get_iter(model, &iter, tpath)) |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
811 { |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
812 gtk_tree_model_get(model, &iter, FILE_COLUMN_POINTER, &cursor_fd, -1); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
813 } |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
814 gtk_tree_path_free(tpath); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
815 } |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
816 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
817 single_select = (select_list && !select_list->next); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
818 if (single_select) cursor_fd = select_list->data; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
819 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
820 store = GTK_LIST_STORE(model); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
821 gtk_list_store_clear(store); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
822 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
823 work = vfl->list; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
824 while (work) |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
825 { |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
826 FileData *fd; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
827 gchar *size; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
828 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
829 fd = work->data; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
830 size = text_from_size(fd->size); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
831 gtk_list_store_append(store, &iter); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
832 gtk_list_store_set(store, &iter, FILE_COLUMN_POINTER, fd, |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
833 FILE_COLUMN_THUMB, (vfl->thumbs_enabled) ? fd->pixbuf : NULL, |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
834 FILE_COLUMN_NAME, fd->name, |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
835 FILE_COLUMN_SIZE, size, |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
836 FILE_COLUMN_DATE, text_from_time(fd->date), |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
837 FILE_COLUMN_COLOR, FALSE, -1); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
838 g_free(size); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
839 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
840 if (select_list && select_list->data == fd) |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
841 { |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
842 select_list = g_list_remove(select_list, fd); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
843 gtk_tree_selection_select_iter(selection, &iter); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
844 } |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
845 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
846 work = work->next; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
847 } |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
848 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
849 g_list_free(select_list); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
850 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
851 if (cursor_fd && |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
852 vflist_find_row(vfl, cursor_fd, &iter) >= 0) |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
853 { |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
854 if (single_select) |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
855 { |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
856 vflist_move_cursor(vfl, &iter); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
857 } |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
858 else |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
859 { |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
860 tree_view_row_make_visible(GTK_TREE_VIEW(vfl->listview), &iter, TRUE); |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
861 } |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
862 } |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
863 |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
864 gtk_tree_selection_set_select_function(selection, vflist_select_cb, vfl, NULL); |
9 | 865 } |
866 | |
867 /* | |
868 *----------------------------------------------------------------------------- | |
869 * thumb updates | |
870 *----------------------------------------------------------------------------- | |
871 */ | |
872 | |
873 static gint vflist_thumb_next(ViewFileList *vfl); | |
874 | |
875 static void vflist_thumb_status(ViewFileList *vfl, gdouble val, const gchar *text) | |
876 { | |
877 if (vfl->func_thumb_status) | |
878 { | |
879 vfl->func_thumb_status(vfl, val, text, vfl->data_thumb_status); | |
880 } | |
881 } | |
882 | |
883 static void vflist_thumb_cleanup(ViewFileList *vfl) | |
884 { | |
885 vflist_thumb_status(vfl, 0.0, NULL); | |
886 | |
887 vfl->thumbs_count = 0; | |
888 vfl->thumbs_running = FALSE; | |
889 | |
890 thumb_loader_free(vfl->thumbs_loader); | |
891 vfl->thumbs_loader = NULL; | |
892 | |
893 vfl->thumbs_filedata = NULL; | |
894 } | |
895 | |
896 static void vflist_thumb_stop(ViewFileList *vfl) | |
897 { | |
898 if (vfl->thumbs_running) vflist_thumb_cleanup(vfl); | |
899 } | |
900 | |
901 static void vflist_thumb_do(ViewFileList *vfl, ThumbLoader *tl, FileData *fd) | |
902 { | |
903 GtkListStore *store; | |
904 GtkTreeIter iter; | |
905 | |
906 if (!fd || vflist_find_row(vfl, fd, &iter) < 0) return; | |
907 | |
908 if (fd->pixbuf) g_object_unref(fd->pixbuf); | |
909 fd->pixbuf = thumb_loader_get_pixbuf(tl, TRUE); | |
910 | |
911 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview))); | |
912 gtk_list_store_set(store, &iter, FILE_COLUMN_THUMB, fd->pixbuf, -1); | |
913 | |
914 vflist_thumb_status(vfl, (gdouble)(vfl->thumbs_count) / g_list_length(vfl->list), _("Loading thumbs...")); | |
915 } | |
916 | |
917 static void vflist_thumb_error_cb(ThumbLoader *tl, gpointer data) | |
918 { | |
919 ViewFileList *vfl = data; | |
920 | |
921 if (vfl->thumbs_filedata && vfl->thumbs_loader == tl) | |
922 { | |
923 vflist_thumb_do(vfl, tl, vfl->thumbs_filedata); | |
924 } | |
925 | |
926 while (vflist_thumb_next(vfl)); | |
927 } | |
928 | |
929 static void vflist_thumb_done_cb(ThumbLoader *tl, gpointer data) | |
930 { | |
931 ViewFileList *vfl = data; | |
932 | |
933 if (vfl->thumbs_filedata && vfl->thumbs_loader == tl) | |
934 { | |
935 vflist_thumb_do(vfl, tl, vfl->thumbs_filedata); | |
936 } | |
937 | |
938 while (vflist_thumb_next(vfl)); | |
939 } | |
940 | |
941 static gint vflist_thumb_next(ViewFileList *vfl) | |
942 { | |
943 GtkTreePath *tpath; | |
944 FileData *fd = NULL; | |
945 | |
946 /* first check the visible files */ | |
947 | |
948 if (GTK_WIDGET_REALIZED(vfl->listview) && | |
949 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vfl->listview), 0, 0, &tpath, NULL, NULL, NULL)) | |
950 { | |
951 GtkTreeModel *store; | |
952 GtkTreeIter iter; | |
953 gint valid = TRUE; | |
954 | |
955 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); | |
956 gtk_tree_model_get_iter(store, &iter, tpath); | |
957 gtk_tree_path_free(tpath); | |
958 | |
959 while (!fd && valid && tree_view_row_get_visibility(GTK_TREE_VIEW(vfl->listview), &iter, FALSE) == 0) | |
960 { | |
961 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); | |
962 if (fd->pixbuf) fd = NULL; | |
963 | |
964 valid = gtk_tree_model_iter_next(store, &iter); | |
965 } | |
966 } | |
967 | |
968 /* then find first undone */ | |
969 | |
970 if (!fd) | |
971 { | |
972 GList *work = vfl->list; | |
973 while (work && !fd) | |
974 { | |
975 FileData *fd_p = work->data; | |
976 work = work->next; | |
977 | |
978 if (!fd_p->pixbuf) fd = fd_p; | |
979 } | |
980 } | |
981 | |
982 if (!fd) | |
983 { | |
984 /* done */ | |
985 vflist_thumb_cleanup(vfl); | |
986 return FALSE; | |
987 } | |
988 | |
989 vfl->thumbs_count++; | |
990 | |
991 vfl->thumbs_filedata = fd; | |
992 | |
993 thumb_loader_free(vfl->thumbs_loader); | |
994 | |
995 vfl->thumbs_loader = thumb_loader_new(thumb_max_width, thumb_max_height); | |
996 thumb_loader_set_callbacks(vfl->thumbs_loader, | |
997 vflist_thumb_done_cb, | |
998 vflist_thumb_error_cb, | |
999 NULL, | |
1000 vfl); | |
1001 | |
1002 if (!thumb_loader_start(vfl->thumbs_loader, fd->path)) | |
1003 { | |
1004 /* set icon to unknown, continue */ | |
1005 if (debug) printf("thumb loader start failed %s\n", vfl->thumbs_loader->path); | |
1006 vflist_thumb_do(vfl, vfl->thumbs_loader, fd); | |
1007 | |
1008 return TRUE; | |
1009 } | |
1010 | |
1011 return FALSE; | |
1012 } | |
1013 | |
1014 static void vflist_thumb_update(ViewFileList *vfl) | |
1015 { | |
1016 vflist_thumb_stop(vfl); | |
1017 if (!vfl->thumbs_enabled) return; | |
1018 | |
1019 vflist_thumb_status(vfl, 0.0, _("Loading thumbs...")); | |
1020 vfl->thumbs_running = TRUE; | |
1021 | |
1022 while (vflist_thumb_next(vfl)); | |
1023 } | |
1024 | |
1025 /* | |
1026 *----------------------------------------------------------------------------- | |
1027 * row stuff | |
1028 *----------------------------------------------------------------------------- | |
1029 */ | |
1030 | |
1031 FileData *vflist_index_get_data(ViewFileList *vfl, gint row) | |
1032 { | |
1033 return g_list_nth_data(vfl->list, row); | |
1034 } | |
1035 | |
1036 gchar *vflist_index_get_path(ViewFileList *vfl, gint row) | |
1037 { | |
1038 FileData *fd; | |
1039 | |
1040 fd = g_list_nth_data(vfl->list, row); | |
1041 | |
1042 return (fd ? fd->path : NULL); | |
1043 } | |
1044 | |
1045 static gint vflist_row_by_path(ViewFileList *vfl, const gchar *path, FileData **fd) | |
1046 { | |
1047 gint p = 0; | |
1048 GList *work; | |
1049 | |
1050 if (!path) return -1; | |
1051 | |
1052 work = vfl->list; | |
1053 while (work) | |
1054 { | |
1055 FileData *fd_n = work->data; | |
1056 if (strcmp(path, fd_n->path) == 0) | |
1057 { | |
1058 if (fd) *fd = fd_n; | |
1059 return p; | |
1060 } | |
1061 work = work->next; | |
1062 p++; | |
1063 } | |
1064 | |
1065 if (fd) *fd = NULL; | |
1066 return -1; | |
1067 } | |
1068 | |
1069 gint vflist_index_by_path(ViewFileList *vfl, const gchar *path) | |
1070 { | |
1071 return vflist_row_by_path(vfl, path, NULL); | |
1072 } | |
1073 | |
1074 gint vflist_count(ViewFileList *vfl, gint64 *bytes) | |
1075 { | |
1076 if (bytes) | |
1077 { | |
1078 gint64 b = 0; | |
1079 GList *work; | |
1080 | |
1081 work = vfl->list; | |
1082 while (work) | |
1083 { | |
1084 FileData *fd = work->data; | |
1085 work = work->next; | |
1086 b += fd->size; | |
1087 } | |
1088 | |
1089 *bytes = b; | |
1090 } | |
1091 | |
1092 return g_list_length(vfl->list); | |
1093 } | |
1094 | |
1095 GList *vflist_get_list(ViewFileList *vfl) | |
1096 { | |
1097 GList *list = NULL; | |
1098 GList *work; | |
1099 | |
1100 work = vfl->list; | |
1101 while (work) | |
1102 { | |
1103 FileData *fd = work->data; | |
1104 work = work->next; | |
1105 | |
1106 list = g_list_prepend(list, g_strdup(fd->path)); | |
1107 } | |
1108 | |
1109 return g_list_reverse(list); | |
1110 } | |
1111 | |
1112 /* | |
1113 *----------------------------------------------------------------------------- | |
1114 * selections | |
1115 *----------------------------------------------------------------------------- | |
1116 */ | |
1117 | |
1118 static gint vflist_row_is_selected(ViewFileList *vfl, FileData *fd) | |
1119 { | |
1120 GtkTreeModel *store; | |
1121 GtkTreeSelection *selection; | |
1122 GList *slist; | |
1123 GList *work; | |
1124 gint found = FALSE; | |
1125 | |
1126 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1127 slist = gtk_tree_selection_get_selected_rows(selection, &store); | |
1128 work = slist; | |
1129 while (!found && work) | |
1130 { | |
1131 GtkTreePath *tpath = work->data; | |
1132 FileData *fd_n; | |
1133 GtkTreeIter iter; | |
1134 | |
1135 gtk_tree_model_get_iter(store, &iter, tpath); | |
1136 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd_n, -1); | |
1137 if (fd_n == fd) found = TRUE; | |
1138 work = work->next; | |
1139 } | |
1140 g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL); | |
1141 g_list_free(slist); | |
1142 | |
1143 return found; | |
1144 } | |
1145 | |
1146 gint vflist_index_is_selected(ViewFileList *vfl, gint row) | |
1147 { | |
1148 FileData *fd; | |
1149 | |
1150 fd = vflist_index_get_data(vfl, row); | |
1151 return vflist_row_is_selected(vfl, fd); | |
1152 } | |
1153 | |
1154 gint vflist_selection_count(ViewFileList *vfl, gint64 *bytes) | |
1155 { | |
1156 GtkTreeModel *store; | |
1157 GtkTreeSelection *selection; | |
1158 GList *slist; | |
1159 gint count; | |
1160 | |
1161 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1162 slist = gtk_tree_selection_get_selected_rows(selection, &store); | |
1163 | |
1164 if (bytes) | |
1165 { | |
1166 gint64 b = 0; | |
1167 GList *work; | |
1168 | |
1169 work = slist; | |
1170 while (work) | |
1171 { | |
1172 GtkTreePath *tpath = work->data; | |
1173 GtkTreeIter iter; | |
1174 FileData *fd; | |
1175 | |
1176 gtk_tree_model_get_iter(store, &iter, tpath); | |
1177 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); | |
1178 b += fd->size; | |
1179 | |
1180 work = work->next; | |
1181 } | |
1182 | |
1183 *bytes = b; | |
1184 } | |
1185 | |
1186 count = g_list_length(slist); | |
1187 g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL); | |
1188 g_list_free(slist); | |
1189 | |
1190 return count; | |
1191 } | |
1192 | |
1193 GList *vflist_selection_get_list(ViewFileList *vfl) | |
1194 { | |
1195 GtkTreeModel *store; | |
1196 GtkTreeSelection *selection; | |
1197 GList *slist; | |
1198 GList *list = NULL; | |
1199 GList *work; | |
1200 | |
1201 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1202 slist = gtk_tree_selection_get_selected_rows(selection, &store); | |
1203 work = slist; | |
1204 while (work) | |
1205 { | |
1206 GtkTreePath *tpath = work->data; | |
1207 FileData *fd; | |
1208 GtkTreeIter iter; | |
1209 | |
1210 gtk_tree_model_get_iter(store, &iter, tpath); | |
1211 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); | |
1212 | |
1213 list = g_list_prepend(list, g_strdup(fd->path)); | |
1214 | |
1215 work = work->next; | |
1216 } | |
1217 g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL); | |
1218 g_list_free(slist); | |
1219 | |
1220 return g_list_reverse(list); | |
1221 } | |
1222 | |
1223 GList *vflist_selection_get_list_by_index(ViewFileList *vfl) | |
1224 { | |
1225 GtkTreeModel *store; | |
1226 GtkTreeSelection *selection; | |
1227 GList *slist; | |
1228 GList *list = NULL; | |
1229 GList *work; | |
1230 | |
1231 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1232 slist = gtk_tree_selection_get_selected_rows(selection, &store); | |
1233 work = slist; | |
1234 while (work) | |
1235 { | |
1236 GtkTreePath *tpath = work->data; | |
1237 FileData *fd; | |
1238 GtkTreeIter iter; | |
1239 | |
1240 gtk_tree_model_get_iter(store, &iter, tpath); | |
1241 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); | |
1242 | |
1243 list = g_list_prepend(list, GINT_TO_POINTER(g_list_index(vfl->list, fd))); | |
1244 | |
1245 work = work->next; | |
1246 } | |
1247 g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL); | |
1248 g_list_free(slist); | |
1249 | |
1250 return g_list_reverse(list); | |
1251 } | |
1252 | |
1253 void vflist_select_all(ViewFileList *vfl) | |
1254 { | |
1255 GtkTreeSelection *selection; | |
1256 | |
1257 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1258 gtk_tree_selection_select_all(selection); | |
1259 | |
1260 vfl->select_fd = NULL; | |
1261 } | |
1262 | |
1263 void vflist_select_none(ViewFileList *vfl) | |
1264 { | |
1265 GtkTreeSelection *selection; | |
1266 | |
1267 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1268 gtk_tree_selection_unselect_all(selection); | |
1269 } | |
1270 | |
1271 void vflist_select_by_path(ViewFileList *vfl, const gchar *path) | |
1272 { | |
1273 FileData *fd; | |
1274 GtkTreeIter iter; | |
1275 | |
1276 if (vflist_row_by_path(vfl, path, &fd) < 0) return; | |
1277 if (vflist_find_row(vfl, fd, &iter) < 0) return; | |
1278 | |
1279 tree_view_row_make_visible(GTK_TREE_VIEW(vfl->listview), &iter, TRUE); | |
1280 | |
1281 if (!vflist_row_is_selected(vfl, fd)) | |
1282 { | |
1283 GtkTreeSelection *selection; | |
1284 GtkTreeModel *store; | |
1285 GtkTreePath *tpath; | |
1286 | |
1287 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1288 gtk_tree_selection_unselect_all(selection); | |
1289 gtk_tree_selection_select_iter(selection, &iter); | |
1290 vflist_move_cursor(vfl, &iter); | |
1291 | |
1292 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); | |
1293 tpath = gtk_tree_model_get_path(store, &iter); | |
1294 gtk_tree_view_set_cursor(GTK_TREE_VIEW(vfl->listview), tpath, NULL, FALSE); | |
1295 gtk_tree_path_free(tpath); | |
1296 } | |
1297 } | |
1298 | |
1299 /* | |
1300 *----------------------------------------------------------------------------- | |
1301 * core (population) | |
1302 *----------------------------------------------------------------------------- | |
1303 */ | |
1304 | |
1305 static void vflist_listview_set_height(GtkWidget *listview, gint thumb) | |
1306 { | |
1307 GtkTreeViewColumn *column; | |
1308 GtkCellRenderer *cell; | |
1309 GList *list; | |
1310 | |
1311 column = gtk_tree_view_get_column(GTK_TREE_VIEW(listview), FILE_COLUMN_THUMB - 1); | |
1312 if (!column) return; | |
1313 | |
1314 gtk_tree_view_column_set_fixed_width(column, (thumb) ? thumb_max_width : 4); | |
1315 | |
1316 list = gtk_tree_view_column_get_cell_renderers(column); | |
1317 if (!list) return; | |
1318 cell = list->data; | |
1319 g_list_free(list); | |
1320 | |
1321 g_object_set(G_OBJECT(cell), "height", (thumb) ? thumb_max_height : -1, NULL); | |
1322 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(listview)); | |
1323 } | |
1324 | |
1325 static void vflist_populate_view(ViewFileList *vfl) | |
1326 { | |
1327 GtkListStore *store; | |
1328 GtkTreeIter iter; | |
1329 gint thumbs; | |
1330 GList *work; | |
1331 GtkTreeRowReference *visible_row = NULL; | |
1332 GtkTreePath *tpath; | |
1333 gint valid; | |
1334 | |
1335 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview))); | |
1336 thumbs = vfl->thumbs_enabled; | |
1337 | |
1338 vflist_thumb_stop(vfl); | |
1339 | |
1340 if (!vfl->list) | |
1341 { | |
1342 gtk_list_store_clear(store); | |
1343 vflist_send_update(vfl); | |
1344 return; | |
1345 } | |
1346 | |
1347 if (GTK_WIDGET_REALIZED(vfl->listview) && | |
1348 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vfl->listview), 0, 0, &tpath, NULL, NULL, NULL)) | |
1349 { | |
1350 visible_row = gtk_tree_row_reference_new(GTK_TREE_MODEL(store), tpath); | |
1351 gtk_tree_path_free(tpath); | |
1352 } | |
1353 | |
1354 vflist_listview_set_height(vfl->listview, thumbs); | |
1355 | |
1356 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter); | |
1357 | |
1358 work = vfl->list; | |
1359 while (work) | |
1360 { | |
1361 gint match; | |
1362 FileData *fd = work->data; | |
1363 gint done = FALSE; | |
1364 | |
1365 while (!done) | |
1366 { | |
1367 FileData *old_fd = NULL; | |
1368 | |
1369 if (valid) | |
1370 { | |
1371 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, FILE_COLUMN_POINTER, &old_fd, -1); | |
1372 match = CASE_SORT(fd->name, old_fd->name); | |
1373 } | |
1374 else | |
1375 { | |
1376 match = -1; | |
1377 } | |
1378 | |
1379 if (match < 0) | |
1380 { | |
1381 GtkTreeIter new; | |
1382 gchar *size; | |
1383 | |
1384 size = text_from_size(fd->size); | |
1385 if (valid) | |
1386 { | |
1387 gtk_list_store_insert_before(store, &new, &iter); | |
1388 } | |
1389 else | |
1390 { | |
1391 gtk_list_store_append(store, &new); | |
1392 } | |
1393 gtk_list_store_set(store, &new, FILE_COLUMN_POINTER, fd, | |
1394 FILE_COLUMN_THUMB, (thumbs) ? fd->pixbuf : NULL, | |
1395 FILE_COLUMN_NAME, fd->name, | |
1396 FILE_COLUMN_SIZE, size, | |
1397 FILE_COLUMN_DATE, text_from_time(fd->date), | |
1398 FILE_COLUMN_COLOR, FALSE, -1); | |
1399 g_free(size); | |
1400 | |
1401 done = TRUE; | |
1402 } | |
1403 else if (match > 0) | |
1404 { | |
1405 valid = gtk_list_store_remove(store, &iter); | |
1406 } | |
1407 else | |
1408 { | |
1409 gtk_list_store_set(store, &iter, FILE_COLUMN_POINTER, fd, -1); | |
1410 if (fd->date != old_fd->date) | |
1411 { | |
1412 gchar *size; | |
1413 | |
1414 /* update, file changed */ | |
1415 size = text_from_size(fd->size); | |
1416 gtk_list_store_set(store, &iter, FILE_COLUMN_SIZE, size, | |
1417 FILE_COLUMN_DATE, text_from_time(fd->date), -1); | |
1418 g_free(size); | |
1419 } | |
1420 else if (fd != old_fd) | |
1421 { | |
1422 /* preserve thumbnail */ | |
1423 if (fd->pixbuf) g_object_unref(fd->pixbuf); | |
1424 fd->pixbuf = old_fd->pixbuf; | |
1425 if (fd->pixbuf) g_object_ref(fd->pixbuf); | |
1426 } | |
1427 | |
1428 gtk_list_store_set(store, &iter, FILE_COLUMN_THUMB, (thumbs) ? fd->pixbuf : NULL, -1); | |
1429 | |
1430 if (vfl->select_fd == old_fd) vfl->select_fd = fd; | |
1431 | |
1432 if (valid) valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter); | |
1433 | |
1434 done = TRUE; | |
1435 } | |
1436 } | |
1437 work = work->next; | |
1438 } | |
1439 | |
1440 while (valid) | |
1441 { | |
1442 valid = gtk_list_store_remove(store, &iter); | |
1443 } | |
1444 | |
1445 if (visible_row) | |
1446 { | |
1447 if (gtk_tree_row_reference_valid(visible_row)) | |
1448 { | |
1449 tpath = gtk_tree_row_reference_get_path(visible_row); | |
1450 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(vfl->listview), tpath, NULL, TRUE, 0.0, 0.0); | |
1451 gtk_tree_path_free(tpath); | |
1452 } | |
1453 gtk_tree_row_reference_free(visible_row); | |
1454 } | |
1455 | |
1456 vflist_send_update(vfl); | |
1457 vflist_thumb_update(vfl); | |
1458 } | |
1459 | |
1460 gint vflist_refresh(ViewFileList *vfl) | |
1461 { | |
1462 GList *old_list; | |
1463 gint ret = TRUE; | |
1464 | |
1465 old_list = vfl->list; | |
1466 vfl->list = NULL; | |
1467 | |
1468 if (vfl->path) | |
1469 { | |
1470 ret = filelist_read(vfl->path, &vfl->list, NULL); | |
1471 } | |
1472 | |
1473 vfl->list = filelist_sort(vfl->list, vfl->sort_method, vfl->sort_ascend); | |
1474 vflist_populate_view(vfl); | |
1475 | |
1476 filelist_free(old_list); | |
1477 | |
1478 return ret; | |
1479 } | |
1480 | |
1481 /* this overrides the low default of a GtkCellRenderer from 100 to CELL_HEIGHT_OVERRIDE, something sane for our purposes */ | |
1482 | |
1483 #define CELL_HEIGHT_OVERRIDE 512 | |
1484 | |
1485 static void cell_renderer_height_override(GtkCellRenderer *renderer) | |
1486 { | |
1487 GParamSpec *spec; | |
1488 | |
1489 spec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(renderer)), "height"); | |
1490 if (spec && G_IS_PARAM_SPEC_INT(spec)) | |
1491 { | |
1492 GParamSpecInt *spec_int; | |
1493 | |
1494 spec_int = G_PARAM_SPEC_INT(spec); | |
1495 if (spec_int->maximum < CELL_HEIGHT_OVERRIDE) spec_int->maximum = CELL_HEIGHT_OVERRIDE; | |
1496 } | |
1497 } | |
1498 | |
1499 static GdkColor *vflist_listview_color_shifted(GtkWidget *widget) | |
1500 { | |
1501 static GdkColor color; | |
1502 static GtkWidget *done = NULL; | |
1503 | |
1504 if (done != widget) | |
1505 { | |
1506 GtkStyle *style; | |
1507 | |
1508 style = gtk_widget_get_style(widget); | |
1509 memcpy(&color, &style->base[GTK_STATE_NORMAL], sizeof(color)); | |
1510 shift_color(&color, -1, 0); | |
1511 done = widget; | |
1512 } | |
1513 | |
1514 return &color; | |
1515 } | |
1516 | |
1517 static void vflist_listview_color_cb(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, | |
1518 GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) | |
1519 { | |
1520 ViewFileList *vfl = data; | |
1521 gboolean set; | |
1522 | |
1523 gtk_tree_model_get(tree_model, iter, FILE_COLUMN_COLOR, &set, -1); | |
1524 g_object_set(G_OBJECT(cell), | |
1525 "cell-background-gdk", vflist_listview_color_shifted(vfl->listview), | |
1526 "cell-background-set", set, NULL); | |
1527 } | |
1528 | |
1529 static void vflist_listview_add_column(ViewFileList *vfl, gint n, const gchar *title, gint image, gint right_justify) | |
1530 { | |
1531 GtkTreeViewColumn *column; | |
1532 GtkCellRenderer *renderer; | |
1533 | |
1534 column = gtk_tree_view_column_new(); | |
1535 gtk_tree_view_column_set_title(column, title); | |
1536 gtk_tree_view_column_set_min_width(column, 4); | |
1537 | |
1538 if (!image) | |
1539 { | |
1540 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY); | |
1541 renderer = gtk_cell_renderer_text_new(); | |
1542 if (right_justify) | |
1543 { | |
1544 g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL); | |
1545 } | |
1546 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
1547 gtk_tree_view_column_add_attribute(column, renderer, "text", n); | |
1548 } | |
1549 else | |
1550 { | |
1551 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED); | |
1552 renderer = gtk_cell_renderer_pixbuf_new(); | |
1553 cell_renderer_height_override(renderer); | |
1554 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
1555 gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", n); | |
1556 } | |
1557 | |
1558 gtk_tree_view_column_set_cell_data_func(column, renderer, vflist_listview_color_cb, vfl, NULL); | |
1559 | |
1560 gtk_tree_view_append_column(GTK_TREE_VIEW(vfl->listview), column); | |
1561 } | |
1562 | |
1563 /* | |
1564 *----------------------------------------------------------------------------- | |
1565 * base | |
1566 *----------------------------------------------------------------------------- | |
1567 */ | |
1568 | |
1569 gint vflist_set_path(ViewFileList *vfl, const gchar *path) | |
1570 { | |
1571 GtkListStore *store; | |
1572 | |
1573 if (!path) return FALSE; | |
1574 if (vfl->path && strcmp(path, vfl->path) == 0) return TRUE; | |
1575 | |
1576 g_free(vfl->path); | |
1577 vfl->path = g_strdup(path); | |
1578 | |
1579 /* force complete reload */ | |
1580 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview))); | |
1581 gtk_list_store_clear(store); | |
1582 | |
1583 filelist_free(vfl->list); | |
1584 vfl->list = NULL; | |
1585 | |
1586 return vflist_refresh(vfl); | |
1587 } | |
1588 | |
1589 static void vflist_destroy_cb(GtkWidget *widget, gpointer data) | |
1590 { | |
1591 ViewFileList *vfl = data; | |
1592 | |
1593 if (vfl->popup) | |
1594 { | |
1595 g_signal_handlers_disconnect_matched(G_OBJECT(vfl->popup), G_SIGNAL_MATCH_DATA, | |
1596 0, 0, 0, NULL, vfl); | |
1597 gtk_widget_destroy(vfl->popup); | |
1598 } | |
1599 | |
1600 vflist_select_idle_cancel(vfl); | |
1601 vflist_thumb_stop(vfl); | |
1602 | |
1603 g_free(vfl->path); | |
1604 filelist_free(vfl->list); | |
1605 g_free(vfl); | |
1606 } | |
1607 | |
1608 ViewFileList *vflist_new(const gchar *path, gint thumbs) | |
1609 { | |
1610 ViewFileList *vfl; | |
1611 GtkListStore *store; | |
1612 GtkTreeSelection *selection; | |
1613 | |
1614 vfl = g_new0(ViewFileList, 1); | |
1615 | |
1616 vfl->path = NULL; | |
1617 vfl->list = NULL; | |
1618 vfl->click_fd = NULL; | |
1619 vfl->select_fd = NULL; | |
1620 vfl->sort_method = SORT_NAME; | |
1621 vfl->sort_ascend = TRUE; | |
1622 vfl->thumbs_enabled = thumbs; | |
1623 | |
1624 vfl->thumbs_running = FALSE; | |
1625 vfl->thumbs_count = 0; | |
1626 vfl->thumbs_loader = NULL; | |
1627 vfl->thumbs_filedata = NULL; | |
1628 | |
1629 vfl->select_idle_id = -1; | |
1630 | |
1631 vfl->popup = NULL; | |
1632 | |
1633 vfl->widget = gtk_scrolled_window_new(NULL, NULL); | |
1634 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(vfl->widget), GTK_SHADOW_IN); | |
1635 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(vfl->widget), | |
1636 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); | |
1637 g_signal_connect(G_OBJECT(vfl->widget), "destroy", | |
1638 G_CALLBACK(vflist_destroy_cb), vfl); | |
1639 | |
1640 store = gtk_list_store_new(6, G_TYPE_POINTER, GDK_TYPE_PIXBUF, G_TYPE_STRING, | |
1641 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN); | |
1642 vfl->listview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); | |
1643 g_object_unref(store); | |
1644 | |
1645 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1646 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_MULTIPLE); | |
1647 gtk_tree_selection_set_select_function(selection, vflist_select_cb, vfl, NULL); | |
1648 | |
1649 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(vfl->listview), FALSE); | |
1650 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(vfl->listview), FALSE); | |
1651 | |
1652 vflist_listview_add_column(vfl, FILE_COLUMN_THUMB, "", TRUE, FALSE); | |
1653 vflist_listview_add_column(vfl, FILE_COLUMN_NAME, _("Name"), FALSE, FALSE); | |
1654 vflist_listview_add_column(vfl, FILE_COLUMN_SIZE, _("Size"), FALSE, TRUE); | |
1655 vflist_listview_add_column(vfl, FILE_COLUMN_DATE, _("Date"), FALSE, TRUE); | |
1656 | |
1657 g_signal_connect(G_OBJECT(vfl->listview), "key_press_event", | |
1658 G_CALLBACK(vflist_press_key_cb), vfl); | |
1659 | |
1660 gtk_container_add (GTK_CONTAINER(vfl->widget), vfl->listview); | |
1661 gtk_widget_show(vfl->listview); | |
1662 | |
1663 vflist_dnd_init(vfl); | |
1664 | |
1665 g_signal_connect(G_OBJECT(vfl->listview), "button_press_event", | |
1666 G_CALLBACK(vflist_press_cb), vfl); | |
1667 g_signal_connect(G_OBJECT(vfl->listview), "button_release_event", | |
1668 G_CALLBACK(vflist_release_cb), vfl); | |
1669 | |
1670 if (path) vflist_set_path(vfl, path); | |
1671 | |
1672 return vfl; | |
1673 } | |
1674 | |
1675 void vflist_set_status_func(ViewFileList *vfl, | |
1676 void (*func)(ViewFileList *vfl, gpointer data), gpointer data) | |
1677 { | |
1678 vfl->func_status = func; | |
1679 vfl->data_status = data; | |
1680 } | |
1681 | |
1682 void vflist_set_thumb_status_func(ViewFileList *vfl, | |
1683 void (*func)(ViewFileList *vfl, gdouble val, const gchar *text, gpointer data), | |
1684 gpointer data) | |
1685 { | |
1686 vfl->func_thumb_status = func; | |
1687 vfl->data_thumb_status = data; | |
1688 } | |
1689 | |
1690 void vflist_thumb_set(ViewFileList *vfl, gint enable) | |
1691 { | |
1692 if (vfl->thumbs_enabled == enable) return; | |
1693 | |
1694 vfl->thumbs_enabled = enable; | |
1695 vflist_refresh(vfl); | |
1696 } | |
1697 | |
1698 void vflist_set_layout(ViewFileList *vfl, LayoutWindow *layout) | |
1699 { | |
1700 vfl->layout = layout; | |
1701 } | |
1702 | |
1703 /* | |
1704 *----------------------------------------------------------------------------- | |
1705 * maintenance (for rename, move, remove) | |
1706 *----------------------------------------------------------------------------- | |
1707 */ | |
1708 | |
1709 static gint vflist_maint_find_closest(ViewFileList *vfl, gint row, gint count, GList *ignore_list) | |
1710 { | |
1711 GList *list = NULL; | |
1712 GList *work; | |
1713 gint rev = row - 1; | |
1714 row ++; | |
1715 | |
1716 work = ignore_list; | |
1717 while (work) | |
1718 { | |
1719 gint f = vflist_index_by_path(vfl, work->data); | |
1720 if (f >= 0) list = g_list_prepend(list, GINT_TO_POINTER(f)); | |
1721 work = work->next; | |
1722 } | |
1723 | |
1724 while (list) | |
1725 { | |
1726 gint c = TRUE; | |
1727 work = list; | |
1728 while (work && c) | |
1729 { | |
1730 gpointer p = work->data; | |
1731 work = work->next; | |
1732 if (row == GPOINTER_TO_INT(p)) | |
1733 { | |
1734 row++; | |
1735 c = FALSE; | |
1736 } | |
1737 if (rev == GPOINTER_TO_INT(p)) | |
1738 { | |
1739 rev--; | |
1740 c = FALSE; | |
1741 } | |
1742 if (!c) list = g_list_remove(list, p); | |
1743 } | |
1744 if (c && list) | |
1745 { | |
1746 g_list_free(list); | |
1747 list = NULL; | |
1748 } | |
1749 } | |
1750 if (row > count - 1) | |
1751 { | |
1752 if (rev < 0) | |
1753 return -1; | |
1754 else | |
1755 return rev; | |
1756 } | |
1757 else | |
1758 { | |
1759 return row; | |
1760 } | |
1761 } | |
1762 | |
1763 gint vflist_maint_renamed(ViewFileList *vfl, const gchar *source, const gchar *dest) | |
1764 { | |
1765 gint ret = FALSE; | |
1766 gint row; | |
1767 gchar *source_base; | |
1768 gchar *dest_base; | |
1769 GList *work; | |
1770 FileData *fd; | |
1771 | |
1772 row = vflist_index_by_path(vfl, source); | |
1773 if (row < 0) return FALSE; | |
1774 | |
1775 source_base = remove_level_from_path(source); | |
1776 dest_base = remove_level_from_path(dest); | |
1777 | |
1778 work = g_list_nth(vfl->list, row); | |
1779 fd = work->data; | |
1780 | |
1781 if (strcmp(source_base, dest_base) == 0) | |
1782 { | |
1783 GtkListStore *store; | |
1784 GtkTreeIter iter; | |
1785 GtkTreeIter position; | |
1786 gint old_row; | |
1787 gint n; | |
1788 | |
1789 old_row = g_list_index(vfl->list, fd); | |
1790 | |
1791 vfl->list = g_list_remove(vfl->list, fd); | |
1792 g_free(fd->path); | |
1793 | |
1794 fd->path = g_strdup(dest); | |
1795 fd->name = filename_from_path(fd->path); | |
1796 | |
1797 vfl->list = filelist_insert_sort(vfl->list, fd, vfl->sort_method, vfl->sort_ascend); | |
1798 n = g_list_index(vfl->list, fd); | |
1799 | |
1800 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview))); | |
1801 row = vflist_find_row(vfl, fd, &iter); | |
1802 if (vflist_find_row(vfl, fd, &iter) >= 0 && | |
1803 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &position, NULL, n)) | |
1804 { | |
1805 if (old_row >= n) | |
1806 { | |
1807 gtk_list_store_move_before(store, &iter, &position); | |
1808 } | |
1809 else | |
1810 { | |
1811 gtk_list_store_move_after(store, &iter, &position); | |
1812 } | |
1813 } | |
1814 gtk_list_store_set(store, &iter, FILE_COLUMN_NAME, fd->name, -1); | |
1815 | |
1816 ret = TRUE; | |
1817 } | |
1818 else | |
1819 { | |
1820 ret = vflist_maint_removed(vfl, source, NULL); | |
1821 } | |
1822 | |
1823 g_free(source_base); | |
1824 g_free(dest_base); | |
1825 | |
1826 return ret; | |
1827 } | |
1828 | |
1829 gint vflist_maint_removed(ViewFileList *vfl, const gchar *path, GList *ignore_list) | |
1830 { | |
1831 GtkTreeIter iter; | |
1832 GList *list; | |
1833 FileData *fd; | |
1834 gint row; | |
1835 gint new_row = -1; | |
1836 | |
1837 row = vflist_index_by_path(vfl, path); | |
1838 if (row < 0) return FALSE; | |
1839 | |
1840 if (vflist_index_is_selected(vfl, row) && | |
1841 layout_image_get_collection(vfl->layout, NULL) == NULL) | |
1842 { | |
1843 gint n; | |
1844 | |
1845 n = vflist_count(vfl, NULL); | |
1846 if (ignore_list) | |
1847 { | |
1848 new_row = vflist_maint_find_closest(vfl, row, n, ignore_list); | |
1849 if (debug) printf("row = %d, closest is %d\n", row, new_row); | |
1850 } | |
1851 else | |
1852 { | |
1853 if (row + 1 < n) | |
1854 { | |
1855 new_row = row + 1; | |
1856 } | |
1857 else if (row > 0) | |
1858 { | |
1859 new_row = row - 1; | |
1860 } | |
1861 } | |
1862 vflist_select_none(vfl); | |
1863 if (new_row >= 0) | |
1864 { | |
1865 fd = vflist_index_get_data(vfl, new_row); | |
1866 if (vflist_find_row(vfl, fd, &iter) >= 0) | |
1867 { | |
1868 GtkTreeSelection *selection; | |
1869 | |
1870 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1871 gtk_tree_selection_select_iter(selection, &iter); | |
1872 vflist_move_cursor(vfl, &iter); | |
1873 } | |
1874 } | |
1875 } | |
1876 | |
1877 fd = vflist_index_get_data(vfl, row); | |
1878 if (vflist_find_row(vfl, fd, &iter) >= 0) | |
1879 { | |
1880 GtkListStore *store; | |
1881 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview))); | |
1882 gtk_list_store_remove(store, &iter); | |
1883 } | |
1884 list = g_list_nth(vfl->list, row); | |
1885 fd = list->data; | |
1886 | |
1887 /* thumbnail loader check */ | |
1888 if (fd == vfl->thumbs_filedata) vfl->thumbs_filedata = NULL; | |
111
3a69a7a3f461
Wed Nov 15 02:05:27 2006 John Ellis <johne@verizon.net>
gqview
parents:
93
diff
changeset
|
1889 if (vfl->thumbs_count > 0) vfl->thumbs_count--; |
9 | 1890 |
1891 vfl->list = g_list_remove(vfl->list, fd); | |
1892 file_data_free(fd); | |
1893 | |
1894 vflist_send_update(vfl); | |
1895 | |
1896 return TRUE; | |
1897 } | |
1898 | |
1899 gint vflist_maint_moved(ViewFileList *vfl, const gchar *source, const gchar *dest, GList *ignore_list) | |
1900 { | |
1901 gint ret = FALSE; | |
1902 gchar *buf; | |
1903 | |
1904 if (!source || !vfl->path) return FALSE; | |
1905 | |
1906 buf = remove_level_from_path(source); | |
1907 | |
1908 if (strcmp(buf, vfl->path) == 0) | |
1909 { | |
1910 ret = vflist_maint_removed(vfl, source, ignore_list); | |
1911 } | |
1912 | |
1913 g_free(buf); | |
1914 | |
1915 return ret; | |
1916 } | |
1917 |