Mercurial > geeqie.yaz
annotate src/view_file_list.c @ 276:4f526d436873
Implement secure rc file saving.
First data is written to a temporary file, then if nothing
was wrong, this file is renamed to the final name.
This way the risk of corrupted rc file is greatly reduced.
The code is borrowed from ELinks (http://elinks.cz).
author | zas_ |
---|---|
date | Tue, 08 Apr 2008 21:55:58 +0000 |
parents | fa7d69e7d02d |
children | 9995c5fb202a |
rev | line source |
---|---|
9 | 1 /* |
196 | 2 * Geeqie |
9 | 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" | |
132 | 29 #include "typedefs.h" |
9 | 30 |
31 #include <gdk/gdkkeysyms.h> /* for keyboard values */ | |
32 | |
33 | |
34 enum { | |
35 FILE_COLUMN_POINTER = 0, | |
36 FILE_COLUMN_THUMB, | |
37 FILE_COLUMN_NAME, | |
139 | 38 FILE_COLUMN_SIDECARS, |
9 | 39 FILE_COLUMN_SIZE, |
40 FILE_COLUMN_DATE, | |
41 FILE_COLUMN_COLOR, | |
139 | 42 FILE_COLUMN_MARKS, |
43 FILE_COLUMN_MARKS_LAST = FILE_COLUMN_MARKS + FILEDATA_MARKS_SIZE - 1, | |
9 | 44 FILE_COLUMN_COUNT |
45 }; | |
46 | |
47 | |
48 static gint vflist_row_is_selected(ViewFileList *vfl, FileData *fd); | |
49 static gint vflist_row_rename_cb(TreeEditData *td, const gchar *old, const gchar *new, gpointer data); | |
50 static void vflist_populate_view(ViewFileList *vfl); | |
51 | |
52 /* | |
53 *----------------------------------------------------------------------------- | |
54 * signals | |
55 *----------------------------------------------------------------------------- | |
56 */ | |
57 | |
58 static void vflist_send_update(ViewFileList *vfl) | |
59 { | |
60 if (vfl->func_status) vfl->func_status(vfl, vfl->data_status); | |
61 } | |
62 | |
63 /* | |
64 *----------------------------------------------------------------------------- | |
65 * misc | |
66 *----------------------------------------------------------------------------- | |
67 */ | |
168
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
68 typedef struct { |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
69 FileData *fd; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
70 GtkTreeIter *iter; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
71 gint found; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
72 gint row; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
73 } ViewFileListFindRowData; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
74 |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
75 static gboolean vflist_find_row_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
76 { |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
77 ViewFileListFindRowData *find = data; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
78 FileData *fd; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
79 gtk_tree_model_get(model, iter, FILE_COLUMN_POINTER, &fd, -1); |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
80 if (fd == find->fd) |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
81 { |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
82 *find->iter = *iter; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
83 find->found = 1; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
84 return TRUE; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
85 } |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
86 find->row++; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
87 return FALSE; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
88 } |
9 | 89 |
90 static gint vflist_find_row(ViewFileList *vfl, FileData *fd, GtkTreeIter *iter) | |
91 { | |
92 GtkTreeModel *store; | |
168
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
93 ViewFileListFindRowData data = {fd, iter, 0, 0}; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
94 |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
95 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
96 gtk_tree_model_foreach(store, vflist_find_row_cb, &data); |
9 | 97 |
168
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
98 if (data.found) |
9 | 99 { |
168
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
100 return data.row; |
9 | 101 } |
102 | |
103 return -1; | |
104 } | |
105 | |
169 | 106 |
259 | 107 /* |
169 | 108 static gint vflist_find_sidecar_list_idx(GList *work, FileData *fd) |
109 { | |
110 gint i = 0; | |
111 while (work) | |
112 { | |
113 FileData *fd_p = work->data; | |
114 if (fd == fd_p) return i; | |
115 | |
116 i++; | |
117 | |
118 GList *work2 = fd_p->sidecar_files; | |
119 while (work2) | |
120 { | |
121 fd_p = work2->data; | |
122 if (fd == fd_p) return i; | |
123 | |
124 i++; | |
125 work2 = work2->next; | |
126 } | |
127 work = work->next; | |
128 } | |
129 return -1; | |
130 } | |
259 | 131 */ |
169 | 132 |
133 static gint vflist_sidecar_list_count(GList *work) | |
134 { | |
135 gint i = 0; | |
136 while (work) | |
137 { | |
138 FileData *fd = work->data; | |
139 i++; | |
140 | |
141 GList *work2 = fd->sidecar_files; | |
142 while (work2) | |
143 { | |
144 i++; | |
145 work2 = work2->next; | |
146 } | |
147 work = work->next; | |
148 } | |
149 return i; | |
150 } | |
151 | |
152 | |
9 | 153 static void vflist_color_set(ViewFileList *vfl, FileData *fd, gint color_set) |
154 { | |
155 GtkTreeModel *store; | |
156 GtkTreeIter iter; | |
157 | |
158 if (vflist_find_row(vfl, fd, &iter) < 0) return; | |
159 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
160 gtk_tree_store_set(GTK_TREE_STORE(store), &iter, FILE_COLUMN_COLOR, color_set, -1); |
9 | 161 } |
162 | |
163 static void vflist_move_cursor(ViewFileList *vfl, GtkTreeIter *iter) | |
164 { | |
165 GtkTreeModel *store; | |
166 GtkTreePath *tpath; | |
167 | |
168 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); | |
169 | |
170 tpath = gtk_tree_model_get_path(store, iter); | |
171 gtk_tree_view_set_cursor(GTK_TREE_VIEW(vfl->listview), tpath, NULL, FALSE); | |
172 gtk_tree_path_free(tpath); | |
173 } | |
174 | |
157 | 175 |
176 static gint vflist_column_idx(ViewFileList *vfl, gint store_idx) | |
177 { | |
178 GList *columns, *work; | |
179 gint i = 0; | |
180 | |
181 columns = gtk_tree_view_get_columns(GTK_TREE_VIEW(vfl->listview)); | |
182 work = columns; | |
183 while (work) | |
184 { | |
185 GtkTreeViewColumn *column = work->data; | |
186 if (store_idx == GPOINTER_TO_INT(g_object_get_data (G_OBJECT(column), "column_store_idx"))) | |
187 break; | |
188 work = work->next; | |
189 i++; | |
190 } | |
191 | |
192 g_list_free(columns); | |
193 return i; | |
194 } | |
195 | |
196 | |
9 | 197 /* |
198 *----------------------------------------------------------------------------- | |
199 * dnd | |
200 *----------------------------------------------------------------------------- | |
201 */ | |
202 | |
203 static void vflist_dnd_get(GtkWidget *widget, GdkDragContext *context, | |
204 GtkSelectionData *selection_data, guint info, | |
205 guint time, gpointer data) | |
206 { | |
207 ViewFileList *vfl = data; | |
208 GList *list = NULL; | |
209 gchar *uri_text = NULL; | |
210 gint total; | |
211 | |
212 if (!vfl->click_fd) return; | |
213 | |
214 if (vflist_row_is_selected(vfl, vfl->click_fd)) | |
215 { | |
216 list = vflist_selection_get_list(vfl); | |
217 } | |
218 else | |
219 { | |
138 | 220 list = g_list_append(NULL, file_data_ref(vfl->click_fd)); |
9 | 221 } |
222 | |
223 if (!list) return; | |
224 | |
138 | 225 uri_text = uri_text_from_filelist(list, &total, (info == TARGET_TEXT_PLAIN)); |
226 filelist_free(list); | |
9 | 227 |
228 if (debug) printf(uri_text); | |
229 | |
64
04ff0df3ad2f
Mon Aug 15 17:13:57 2005 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
230 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
|
231 8, (guchar *)uri_text, total); |
9 | 232 g_free(uri_text); |
233 } | |
234 | |
235 static void vflist_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data) | |
236 { | |
237 ViewFileList *vfl = data; | |
238 | |
239 vflist_color_set(vfl, vfl->click_fd, TRUE); | |
240 | |
241 if (vfl->thumbs_enabled && | |
242 vfl->click_fd && vfl->click_fd->pixbuf) | |
243 { | |
244 gint items; | |
245 | |
246 if (vflist_row_is_selected(vfl, vfl->click_fd)) | |
247 items = vflist_selection_count(vfl, NULL); | |
248 else | |
249 items = 1; | |
250 | |
251 dnd_set_drag_icon(widget, context, vfl->click_fd->pixbuf, items); | |
252 } | |
253 } | |
254 | |
255 static void vflist_dnd_end(GtkWidget *widget, GdkDragContext *context, gpointer data) | |
256 { | |
257 ViewFileList *vfl = data; | |
258 | |
259 vflist_color_set(vfl, vfl->click_fd, FALSE); | |
260 | |
261 if (context->action == GDK_ACTION_MOVE) | |
262 { | |
263 vflist_refresh(vfl); | |
264 } | |
265 } | |
266 | |
267 static void vflist_dnd_init(ViewFileList *vfl) | |
268 { | |
269 gtk_drag_source_set(vfl->listview, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, | |
270 dnd_file_drag_types, dnd_file_drag_types_count, | |
271 GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK); | |
272 g_signal_connect(G_OBJECT(vfl->listview), "drag_data_get", | |
273 G_CALLBACK(vflist_dnd_get), vfl); | |
274 g_signal_connect(G_OBJECT(vfl->listview), "drag_begin", | |
275 G_CALLBACK(vflist_dnd_begin), vfl); | |
276 g_signal_connect(G_OBJECT(vfl->listview), "drag_end", | |
277 G_CALLBACK(vflist_dnd_end), vfl); | |
278 } | |
279 | |
280 /* | |
281 *----------------------------------------------------------------------------- | |
282 * pop-up menu | |
283 *----------------------------------------------------------------------------- | |
284 */ | |
285 | |
286 static GList *vflist_pop_menu_file_list(ViewFileList *vfl) | |
287 { | |
288 if (!vfl->click_fd) return NULL; | |
289 | |
290 if (vflist_row_is_selected(vfl, vfl->click_fd)) | |
291 { | |
292 return vflist_selection_get_list(vfl); | |
293 } | |
294 | |
138 | 295 return g_list_append(NULL, file_data_ref(vfl->click_fd)); |
9 | 296 } |
297 | |
298 static void vflist_pop_menu_edit_cb(GtkWidget *widget, gpointer data) | |
299 { | |
300 ViewFileList *vfl; | |
301 gint n; | |
302 GList *list; | |
303 | |
304 vfl = submenu_item_get_data(widget); | |
305 n = GPOINTER_TO_INT(data); | |
306 | |
307 if (!vfl) return; | |
308 | |
309 list = vflist_pop_menu_file_list(vfl); | |
138 | 310 start_editor_from_filelist(n, list); |
311 filelist_free(list); | |
9 | 312 } |
313 | |
314 static void vflist_pop_menu_info_cb(GtkWidget *widget, gpointer data) | |
315 { | |
316 ViewFileList *vfl = data; | |
317 | |
318 info_window_new(NULL, vflist_pop_menu_file_list(vfl)); | |
319 } | |
320 | |
321 static void vflist_pop_menu_view_cb(GtkWidget *widget, gpointer data) | |
322 { | |
323 ViewFileList *vfl = data; | |
324 | |
325 if (vflist_row_is_selected(vfl, vfl->click_fd)) | |
326 { | |
327 GList *list; | |
328 | |
329 list = vflist_selection_get_list(vfl); | |
330 view_window_new_from_list(list); | |
138 | 331 filelist_free(list); |
9 | 332 } |
333 else | |
334 { | |
138 | 335 view_window_new(vfl->click_fd); |
9 | 336 } |
337 } | |
338 | |
339 static void vflist_pop_menu_copy_cb(GtkWidget *widget, gpointer data) | |
340 { | |
341 ViewFileList *vfl = data; | |
342 | |
343 file_util_copy(NULL, vflist_pop_menu_file_list(vfl), NULL, vfl->listview); | |
344 } | |
345 | |
346 static void vflist_pop_menu_move_cb(GtkWidget *widget, gpointer data) | |
347 { | |
348 ViewFileList *vfl = data; | |
349 | |
350 file_util_move(NULL, vflist_pop_menu_file_list(vfl), NULL, vfl->listview); | |
351 } | |
352 | |
353 static void vflist_pop_menu_rename_cb(GtkWidget *widget, gpointer data) | |
354 { | |
355 ViewFileList *vfl = data; | |
356 GList *list; | |
357 | |
358 list = vflist_pop_menu_file_list(vfl); | |
359 if (enable_in_place_rename && | |
360 list && !list->next && vfl->click_fd) | |
361 { | |
362 GtkTreeModel *store; | |
363 GtkTreeIter iter; | |
364 | |
138 | 365 filelist_free(list); |
9 | 366 |
367 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); | |
368 if (vflist_find_row(vfl, vfl->click_fd, &iter) >= 0) | |
369 { | |
370 GtkTreePath *tpath; | |
371 | |
372 tpath = gtk_tree_model_get_path(store, &iter); | |
373 tree_edit_by_path(GTK_TREE_VIEW(vfl->listview), tpath, | |
157 | 374 vflist_column_idx(vfl, FILE_COLUMN_NAME), vfl->click_fd->name, |
9 | 375 vflist_row_rename_cb, vfl); |
376 gtk_tree_path_free(tpath); | |
377 } | |
378 return; | |
379 } | |
380 | |
381 file_util_rename(NULL, list, vfl->listview); | |
382 } | |
383 | |
384 static void vflist_pop_menu_delete_cb(GtkWidget *widget, gpointer data) | |
385 { | |
386 ViewFileList *vfl = data; | |
387 | |
388 file_util_delete(NULL, vflist_pop_menu_file_list(vfl), vfl->listview); | |
389 } | |
390 | |
391 static void vflist_pop_menu_sort_cb(GtkWidget *widget, gpointer data) | |
392 { | |
393 ViewFileList *vfl; | |
394 SortType type; | |
113
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
111
diff
changeset
|
395 |
55166d93498d
Fri Nov 24 21:37:01 2006 John Ellis <johne@verizon.net>
gqview
parents:
111
diff
changeset
|
396 if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) return; |
9 | 397 |
398 vfl = submenu_item_get_data(widget); | |
399 if (!vfl) return; | |
400 | |
401 type = (SortType)GPOINTER_TO_INT(data); | |
402 | |
403 if (vfl->layout) | |
404 { | |
405 layout_sort_set(vfl->layout, type, vfl->sort_ascend); | |
406 } | |
407 else | |
408 { | |
409 vflist_sort_set(vfl, type, vfl->sort_ascend); | |
410 } | |
411 } | |
412 | |
413 static void vflist_pop_menu_sort_ascend_cb(GtkWidget *widget, gpointer data) | |
414 { | |
415 ViewFileList *vfl = data; | |
416 | |
417 if (vfl->layout) | |
418 { | |
419 layout_sort_set(vfl->layout, vfl->sort_method, !vfl->sort_ascend); | |
420 } | |
421 else | |
422 { | |
423 vflist_sort_set(vfl, vfl->sort_method, !vfl->sort_ascend); | |
424 } | |
425 } | |
426 | |
427 static void vflist_pop_menu_icons_cb(GtkWidget *widget, gpointer data) | |
428 { | |
429 ViewFileList *vfl = data; | |
430 | |
431 if (vfl->layout) layout_views_set(vfl->layout, vfl->layout->tree_view, TRUE); | |
432 } | |
433 | |
434 static void vflist_pop_menu_thumbs_cb(GtkWidget *widget, gpointer data) | |
435 { | |
436 ViewFileList *vfl = data; | |
437 | |
438 vflist_color_set(vfl, vfl->click_fd, FALSE); | |
439 if (vfl->layout) | |
440 { | |
441 layout_thumb_set(vfl->layout, !vfl->thumbs_enabled); | |
442 } | |
443 else | |
444 { | |
445 vflist_thumb_set(vfl, !vfl->thumbs_enabled); | |
446 } | |
447 } | |
448 | |
449 static void vflist_pop_menu_refresh_cb(GtkWidget *widget, gpointer data) | |
450 { | |
451 ViewFileList *vfl = data; | |
452 | |
453 vflist_color_set(vfl, vfl->click_fd, FALSE); | |
454 vflist_refresh(vfl); | |
455 } | |
456 | |
150 | 457 static void vflist_pop_menu_sel_mark_cb(GtkWidget *widget, gpointer data) |
458 { | |
459 ViewFileList *vfl = data; | |
161 | 460 vflist_mark_to_selection(vfl, vfl->active_mark, MTS_MODE_SET); |
461 } | |
462 | |
463 static void vflist_pop_menu_sel_mark_and_cb(GtkWidget *widget, gpointer data) | |
464 { | |
465 ViewFileList *vfl = data; | |
466 vflist_mark_to_selection(vfl, vfl->active_mark, MTS_MODE_AND); | |
467 } | |
468 | |
469 static void vflist_pop_menu_sel_mark_or_cb(GtkWidget *widget, gpointer data) | |
470 { | |
471 ViewFileList *vfl = data; | |
472 vflist_mark_to_selection(vfl, vfl->active_mark, MTS_MODE_OR); | |
473 } | |
474 | |
475 static void vflist_pop_menu_sel_mark_minus_cb(GtkWidget *widget, gpointer data) | |
476 { | |
477 ViewFileList *vfl = data; | |
478 vflist_mark_to_selection(vfl, vfl->active_mark, MTS_MODE_MINUS); | |
150 | 479 } |
480 | |
481 static void vflist_pop_menu_set_mark_sel_cb(GtkWidget *widget, gpointer data) | |
482 { | |
483 ViewFileList *vfl = data; | |
161 | 484 vflist_selection_to_mark(vfl, vfl->active_mark, STM_MODE_SET); |
150 | 485 } |
486 | |
487 static void vflist_pop_menu_res_mark_sel_cb(GtkWidget *widget, gpointer data) | |
488 { | |
489 ViewFileList *vfl = data; | |
161 | 490 vflist_selection_to_mark(vfl, vfl->active_mark, STM_MODE_RESET); |
150 | 491 } |
492 | |
493 static void vflist_pop_menu_toggle_mark_sel_cb(GtkWidget *widget, gpointer data) | |
494 { | |
495 ViewFileList *vfl = data; | |
161 | 496 vflist_selection_to_mark(vfl, vfl->active_mark, STM_MODE_TOGGLE); |
150 | 497 } |
498 | |
499 | |
9 | 500 static void vflist_popup_destroy_cb(GtkWidget *widget, gpointer data) |
501 { | |
502 ViewFileList *vfl = data; | |
503 vflist_color_set(vfl, vfl->click_fd, FALSE); | |
504 vfl->click_fd = NULL; | |
505 vfl->popup = NULL; | |
506 } | |
507 | |
150 | 508 |
509 static GtkWidget *vflist_pop_menu(ViewFileList *vfl, FileData *fd, gint col_idx) | |
9 | 510 { |
511 GtkWidget *menu; | |
512 GtkWidget *item; | |
513 GtkWidget *submenu; | |
514 gint active; | |
515 | |
516 vflist_color_set(vfl, fd, TRUE); | |
517 active = (fd != NULL); | |
518 | |
519 menu = popup_menu_short_lived(); | |
520 g_signal_connect(G_OBJECT(menu), "destroy", | |
521 G_CALLBACK(vflist_popup_destroy_cb), vfl); | |
522 | |
150 | 523 if (col_idx >= FILE_COLUMN_MARKS && col_idx <= FILE_COLUMN_MARKS_LAST) |
524 { | |
525 gint mark = col_idx - FILE_COLUMN_MARKS; | |
526 gchar *str_set_mark = g_strdup_printf(_("_Set mark %d"), mark + 1); | |
527 gchar *str_res_mark = g_strdup_printf(_("_Reset mark %d"), mark + 1); | |
528 gchar *str_toggle_mark = g_strdup_printf(_("_Toggle mark %d"), mark + 1); | |
529 gchar *str_sel_mark = g_strdup_printf(_("_Select mark %d"), mark + 1); | |
161 | 530 gchar *str_sel_mark_or = g_strdup_printf(_("_Add mark %d"), mark + 1); |
531 gchar *str_sel_mark_and = g_strdup_printf(_("_Intersection with mark %d"), mark + 1); | |
532 gchar *str_sel_mark_minus = g_strdup_printf(_("_Unselect mark %d"), mark + 1); | |
150 | 533 |
534 | |
535 vfl->active_mark = mark; | |
536 menu_item_add_sensitive(menu, str_set_mark, active, | |
537 G_CALLBACK(vflist_pop_menu_set_mark_sel_cb), vfl); | |
538 | |
539 menu_item_add_sensitive(menu, str_res_mark, active, | |
540 G_CALLBACK(vflist_pop_menu_res_mark_sel_cb), vfl); | |
541 | |
542 menu_item_add_sensitive(menu, str_toggle_mark, active, | |
543 G_CALLBACK(vflist_pop_menu_toggle_mark_sel_cb), vfl); | |
161 | 544 |
545 menu_item_add_divider(menu); | |
150 | 546 |
547 menu_item_add_sensitive(menu, str_sel_mark, active, | |
548 G_CALLBACK(vflist_pop_menu_sel_mark_cb), vfl); | |
161 | 549 menu_item_add_sensitive(menu, str_sel_mark_or, active, |
550 G_CALLBACK(vflist_pop_menu_sel_mark_or_cb), vfl); | |
551 menu_item_add_sensitive(menu, str_sel_mark_and, active, | |
552 G_CALLBACK(vflist_pop_menu_sel_mark_and_cb), vfl); | |
553 menu_item_add_sensitive(menu, str_sel_mark_minus, active, | |
554 G_CALLBACK(vflist_pop_menu_sel_mark_minus_cb), vfl); | |
150 | 555 |
556 menu_item_add_divider(menu); | |
557 | |
558 g_free(str_set_mark); | |
559 g_free(str_res_mark); | |
560 g_free(str_toggle_mark); | |
561 g_free(str_sel_mark); | |
161 | 562 g_free(str_sel_mark_and); |
563 g_free(str_sel_mark_or); | |
564 g_free(str_sel_mark_minus); | |
150 | 565 } |
566 | |
9 | 567 submenu_add_edit(menu, &item, G_CALLBACK(vflist_pop_menu_edit_cb), vfl); |
568 gtk_widget_set_sensitive(item, active); | |
569 | |
570 menu_item_add_stock_sensitive(menu, _("_Properties"), GTK_STOCK_PROPERTIES, active, | |
571 G_CALLBACK(vflist_pop_menu_info_cb), vfl); | |
572 menu_item_add_stock_sensitive(menu, _("View in _new window"), GTK_STOCK_NEW, active, | |
573 G_CALLBACK(vflist_pop_menu_view_cb), vfl); | |
574 | |
575 menu_item_add_divider(menu); | |
576 menu_item_add_stock_sensitive(menu, _("_Copy..."), GTK_STOCK_COPY, active, | |
577 G_CALLBACK(vflist_pop_menu_copy_cb), vfl); | |
578 menu_item_add_sensitive(menu, _("_Move..."), active, | |
579 G_CALLBACK(vflist_pop_menu_move_cb), vfl); | |
580 menu_item_add_sensitive(menu, _("_Rename..."), active, | |
581 G_CALLBACK(vflist_pop_menu_rename_cb), vfl); | |
582 menu_item_add_stock_sensitive(menu, _("_Delete..."), GTK_STOCK_DELETE, active, | |
583 G_CALLBACK(vflist_pop_menu_delete_cb), vfl); | |
584 | |
585 menu_item_add_divider(menu); | |
586 | |
587 submenu = submenu_add_sort(NULL, G_CALLBACK(vflist_pop_menu_sort_cb), vfl, | |
588 FALSE, FALSE, TRUE, vfl->sort_method); | |
589 menu_item_add_divider(submenu); | |
590 menu_item_add_check(submenu, _("Ascending"), vfl->sort_ascend, | |
591 G_CALLBACK(vflist_pop_menu_sort_ascend_cb), vfl); | |
592 | |
593 item = menu_item_add(menu, _("_Sort"), NULL, NULL); | |
594 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); | |
595 | |
596 menu_item_add_check(menu, _("View as _icons"), FALSE, | |
597 G_CALLBACK(vflist_pop_menu_icons_cb), vfl); | |
598 menu_item_add_check(menu, _("Show _thumbnails"), vfl->thumbs_enabled, | |
599 G_CALLBACK(vflist_pop_menu_thumbs_cb), vfl); | |
600 menu_item_add_stock(menu, _("Re_fresh"), GTK_STOCK_REFRESH, G_CALLBACK(vflist_pop_menu_refresh_cb), vfl); | |
601 | |
602 return menu; | |
603 } | |
604 | |
605 /* | |
606 *----------------------------------------------------------------------------- | |
607 * callbacks | |
608 *----------------------------------------------------------------------------- | |
609 */ | |
610 | |
611 static gint vflist_row_rename_cb(TreeEditData *td, const gchar *old, const gchar *new, gpointer data) | |
612 { | |
613 ViewFileList *vfl = data; | |
614 gchar *old_path; | |
615 gchar *new_path; | |
616 | |
617 if (strlen(new) == 0) return FALSE; | |
618 | |
619 old_path = concat_dir_and_file(vfl->path, old); | |
620 new_path = concat_dir_and_file(vfl->path, new); | |
621 | |
622 if (strchr(new, '/') != NULL) | |
623 { | |
624 gchar *text = g_strdup_printf(_("Invalid file name:\n%s"), new); | |
625 file_util_warning_dialog(_("Error renaming file"), text, GTK_STOCK_DIALOG_ERROR, vfl->listview); | |
626 g_free(text); | |
627 } | |
628 else if (isfile(new_path)) | |
629 { | |
630 gchar *text = g_strdup_printf(_("A file with name %s already exists."), new); | |
631 file_util_warning_dialog(_("Error renaming file"), text, GTK_STOCK_DIALOG_ERROR, vfl->listview); | |
632 g_free(text); | |
633 } | |
138 | 634 else |
9 | 635 { |
138 | 636 gint row = vflist_index_by_path(vfl, old_path); |
637 if (row >= 0) | |
638 { | |
639 GList *work = g_list_nth(vfl->list, row); | |
640 FileData *fd = work->data; | |
143
0d1bf3ac6cd8
improved FileDataChangeInfo structure, check for another file operation in progress
nadvornik
parents:
142
diff
changeset
|
641 |
0d1bf3ac6cd8
improved FileDataChangeInfo structure, check for another file operation in progress
nadvornik
parents:
142
diff
changeset
|
642 if (!file_data_add_change_info(fd, FILEDATA_CHANGE_RENAME, old_path, new_path) || !rename_file_ext(fd)) |
138 | 643 { |
644 gchar *text = g_strdup_printf(_("Unable to rename file:\n%s\nto:\n%s"), old, new); | |
645 file_util_warning_dialog(_("Error renaming file"), text, GTK_STOCK_DIALOG_ERROR, vfl->listview); | |
646 g_free(text); | |
647 } | |
648 } | |
649 | |
9 | 650 } |
651 g_free(old_path); | |
652 g_free(new_path); | |
653 | |
654 return FALSE; | |
655 } | |
656 | |
657 static void vflist_menu_position_cb(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer data) | |
658 { | |
659 ViewFileList *vfl = data; | |
660 GtkTreeModel *store; | |
661 GtkTreeIter iter; | |
662 GtkTreePath *tpath; | |
663 gint cw, ch; | |
664 | |
665 if (vflist_find_row(vfl, vfl->click_fd, &iter) < 0) return; | |
666 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); | |
667 tpath = gtk_tree_model_get_path(store, &iter); | |
668 tree_view_get_cell_clamped(GTK_TREE_VIEW(vfl->listview), tpath, FILE_COLUMN_NAME - 1, TRUE, x, y, &cw, &ch); | |
669 gtk_tree_path_free(tpath); | |
670 *y += ch; | |
671 popup_menu_position_clamp(menu, x, y, 0); | |
672 } | |
673 | |
674 static gint vflist_press_key_cb(GtkWidget *widget, GdkEventKey *event, gpointer data) | |
675 { | |
676 ViewFileList *vfl = data; | |
677 GtkTreePath *tpath; | |
678 | |
679 if (event->keyval != GDK_Menu) return FALSE; | |
680 | |
681 gtk_tree_view_get_cursor(GTK_TREE_VIEW(vfl->listview), &tpath, NULL); | |
682 if (tpath) | |
683 { | |
684 GtkTreeModel *store; | |
685 GtkTreeIter iter; | |
686 | |
687 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
688 gtk_tree_model_get_iter(store, &iter, tpath); | |
689 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &vfl->click_fd, -1); | |
690 gtk_tree_path_free(tpath); | |
691 } | |
692 else | |
693 { | |
694 vfl->click_fd = NULL; | |
695 } | |
696 | |
150 | 697 vfl->popup = vflist_pop_menu(vfl, vfl->click_fd, 0); |
9 | 698 gtk_menu_popup(GTK_MENU(vfl->popup), NULL, NULL, vflist_menu_position_cb, vfl, 0, GDK_CURRENT_TIME); |
699 | |
700 return TRUE; | |
701 } | |
702 | |
703 static gint vflist_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) | |
704 { | |
705 ViewFileList *vfl = data; | |
706 GtkTreePath *tpath; | |
707 GtkTreeIter iter; | |
708 FileData *fd = NULL; | |
149 | 709 GtkTreeViewColumn *column; |
150 | 710 gint col_idx = 0; |
132 | 711 |
9 | 712 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), bevent->x, bevent->y, |
132 | 713 &tpath, &column, NULL, NULL)) |
9 | 714 { |
715 GtkTreeModel *store; | |
149 | 716 col_idx = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(column), "column_store_idx")); |
132 | 717 |
149 | 718 if (bevent->button == 1 && |
719 col_idx >= FILE_COLUMN_MARKS && col_idx <= FILE_COLUMN_MARKS_LAST) | |
720 return FALSE; | |
132 | 721 |
149 | 722 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); |
9 | 723 |
724 gtk_tree_model_get_iter(store, &iter, tpath); | |
725 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); | |
726 #if 0 | |
727 gtk_tree_view_set_cursor(GTK_TREE_VIEW(widget), tpath, NULL, FALSE); | |
728 #endif | |
729 gtk_tree_path_free(tpath); | |
730 } | |
731 | |
732 vfl->click_fd = fd; | |
733 | |
734 if (bevent->button == 3) | |
735 { | |
150 | 736 vfl->popup = vflist_pop_menu(vfl, vfl->click_fd, col_idx); |
9 | 737 gtk_menu_popup(GTK_MENU(vfl->popup), NULL, NULL, NULL, NULL, |
738 bevent->button, bevent->time); | |
739 return TRUE; | |
740 } | |
741 | |
742 if (!fd) return FALSE; | |
743 | |
744 if (bevent->button == 2) | |
745 { | |
746 if (!vflist_row_is_selected(vfl, fd)) | |
747 { | |
748 vflist_color_set(vfl, fd, TRUE); | |
749 } | |
750 return TRUE; | |
751 } | |
752 | |
753 | |
754 if (bevent->button == 1 && bevent->type == GDK_BUTTON_PRESS && | |
755 !(bevent->state & GDK_SHIFT_MASK ) && | |
756 !(bevent->state & GDK_CONTROL_MASK ) && | |
757 vflist_row_is_selected(vfl, fd)) | |
758 { | |
759 gtk_widget_grab_focus(widget); | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
760 // return TRUE; // FIXME - expand |
9 | 761 } |
762 | |
763 #if 0 | |
764 if (bevent->button == 1 && bevent->type == GDK_2BUTTON_PRESS) | |
765 { | |
766 if (vfl->layout) layout_image_full_screen_start(vfl->layout); | |
767 } | |
768 #endif | |
769 | |
770 return FALSE; | |
771 } | |
772 | |
773 static gint vflist_release_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) | |
774 { | |
775 ViewFileList *vfl = data; | |
776 GtkTreePath *tpath; | |
777 GtkTreeIter iter; | |
778 FileData *fd = NULL; | |
779 | |
780 if (bevent->button == 2) | |
781 { | |
782 vflist_color_set(vfl, vfl->click_fd, FALSE); | |
783 } | |
784 | |
785 if (bevent->button != 1 && bevent->button != 2) | |
786 { | |
787 return TRUE; | |
788 } | |
789 | |
790 if ((bevent->x != 0 || bevent->y != 0) && | |
791 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), bevent->x, bevent->y, | |
792 &tpath, NULL, NULL, NULL)) | |
793 { | |
794 GtkTreeModel *store; | |
795 | |
796 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); | |
797 gtk_tree_model_get_iter(store, &iter, tpath); | |
798 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); | |
799 gtk_tree_path_free(tpath); | |
800 } | |
801 | |
802 if (bevent->button == 2) | |
803 { | |
804 if (fd && vfl->click_fd == fd) | |
805 { | |
806 GtkTreeSelection *selection; | |
807 | |
808 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); | |
809 if (vflist_row_is_selected(vfl, fd)) | |
810 { | |
811 gtk_tree_selection_unselect_iter(selection, &iter); | |
812 } | |
813 else | |
814 { | |
815 gtk_tree_selection_select_iter(selection, &iter); | |
816 } | |
817 } | |
818 return TRUE; | |
819 } | |
820 | |
821 if (fd && vfl->click_fd == fd && | |
822 !(bevent->state & GDK_SHIFT_MASK ) && | |
823 !(bevent->state & GDK_CONTROL_MASK ) && | |
824 vflist_row_is_selected(vfl, fd)) | |
825 { | |
826 GtkTreeSelection *selection; | |
827 | |
828 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); | |
829 gtk_tree_selection_unselect_all(selection); | |
830 gtk_tree_selection_select_iter(selection, &iter); | |
831 vflist_move_cursor(vfl, &iter); | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
832 // return TRUE;// FIXME - expand |
9 | 833 } |
834 | |
835 return FALSE; | |
836 } | |
837 | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
838 static void vflist_select_image(ViewFileList *vfl, FileData *sel_fd) |
9 | 839 { |
138 | 840 FileData *read_ahead_fd = NULL; |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
841 gint row; |
144 | 842 FileData *cur_fd; |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
843 if (!sel_fd) return; |
144 | 844 |
845 cur_fd = layout_image_get_fd(vfl->layout); | |
846 if (sel_fd == cur_fd) return; /* no change */ | |
847 | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
848 row = g_list_index(vfl->list, sel_fd); |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
849 // FIXME sidecar data |
9 | 850 |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
851 if (sel_fd && enable_read_ahead && row >= 0) |
9 | 852 { |
144 | 853 if (row > g_list_index(vfl->list, cur_fd) && |
9 | 854 row + 1 < vflist_count(vfl, NULL)) |
855 { | |
144 | 856 read_ahead_fd = vflist_index_get_data(vfl, row + 1); |
9 | 857 } |
858 else if (row > 0) | |
859 { | |
144 | 860 read_ahead_fd = vflist_index_get_data(vfl, row - 1); |
9 | 861 } |
862 } | |
863 | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
864 layout_image_set_with_ahead(vfl->layout, sel_fd, read_ahead_fd); |
9 | 865 } |
866 | |
867 static gint vflist_select_idle_cb(gpointer data) | |
868 { | |
869 ViewFileList *vfl = data; | |
870 | |
871 if (!vfl->layout) | |
872 { | |
873 vfl->select_idle_id = -1; | |
874 return FALSE; | |
875 } | |
876 | |
877 vflist_send_update(vfl); | |
878 | |
879 if (vfl->select_fd) | |
880 { | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
881 vflist_select_image(vfl, vfl->select_fd); |
9 | 882 vfl->select_fd = NULL; |
883 } | |
884 | |
885 vfl->select_idle_id = -1; | |
886 return FALSE; | |
887 } | |
888 | |
889 static void vflist_select_idle_cancel(ViewFileList *vfl) | |
890 { | |
891 if (vfl->select_idle_id != -1) g_source_remove(vfl->select_idle_id); | |
892 vfl->select_idle_id = -1; | |
893 } | |
894 | |
895 static gboolean vflist_select_cb(GtkTreeSelection *selection, GtkTreeModel *store, GtkTreePath *tpath, | |
896 gboolean path_currently_selected, gpointer data) | |
897 { | |
898 ViewFileList *vfl = data; | |
899 GtkTreeIter iter; | |
900 | |
901 if (!path_currently_selected && | |
902 gtk_tree_model_get_iter(store, &iter, tpath)) | |
903 { | |
904 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &vfl->select_fd, -1); | |
905 } | |
906 else | |
907 { | |
908 vfl->select_fd = NULL; | |
909 } | |
910 | |
911 if (vfl->layout && | |
912 vfl->select_idle_id == -1) | |
913 { | |
914 vfl->select_idle_id = g_idle_add(vflist_select_idle_cb, vfl); | |
915 } | |
916 | |
917 return TRUE; | |
918 } | |
919 | |
920 /* | |
921 *----------------------------------------------------------------------------- | |
922 * misc | |
923 *----------------------------------------------------------------------------- | |
924 */ | |
925 | |
259 | 926 /* |
93
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
927 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
|
928 gboolean path_currently_selected, gpointer data) |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
929 { |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
930 return TRUE; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
931 } |
259 | 932 */ |
93
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
933 |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
934 |
168
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
935 static void vflist_setup_iter(ViewFileList *vfl, GtkTreeStore *store, GtkTreeIter *iter, FileData *fd) |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
936 { |
167 | 937 int i; |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
938 gchar *size; |
167 | 939 gchar *sidecars = NULL; |
940 | |
941 if (fd->sidecar_files) | |
942 sidecars = sidecar_file_data_list_to_string(fd); | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
943 size = text_from_size(fd->size); |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
944 |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
945 gtk_tree_store_set(store, iter, FILE_COLUMN_POINTER, fd, |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
946 FILE_COLUMN_THUMB, (vfl->thumbs_enabled) ? fd->pixbuf : NULL, |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
947 FILE_COLUMN_NAME, fd->name, |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
948 FILE_COLUMN_SIDECARS, sidecars, |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
949 FILE_COLUMN_SIZE, size, |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
950 FILE_COLUMN_DATE, text_from_time(fd->date), |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
951 FILE_COLUMN_COLOR, FALSE, -1); |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
952 for (i = 0; i < FILEDATA_MARKS_SIZE; i++) |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
953 gtk_tree_store_set(store, iter, FILE_COLUMN_MARKS + i, fd->marks[i], -1); |
168
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
954 |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
955 g_free(size); |
167 | 956 if (sidecars) |
957 g_free(sidecars); | |
958 } | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
959 |
168
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
960 static void vflist_setup_iter_with_sidecars(ViewFileList *vfl, GtkTreeStore *store, GtkTreeIter *iter, FileData *fd) |
167 | 961 { |
962 GList *work; | |
963 GtkTreeIter s_iter; | |
964 gint valid; | |
965 | |
168
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
966 vflist_setup_iter(vfl, store, iter, fd); |
167 | 967 |
968 | |
969 /* this is almost the same code as in vflist_populate_view | |
970 maybe it should be made more generic and used in both places */ | |
971 | |
972 | |
973 valid = gtk_tree_model_iter_children(GTK_TREE_MODEL(store), &s_iter, iter); | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
974 |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
975 work = fd->sidecar_files; |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
976 while (work) |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
977 { |
167 | 978 gint match; |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
979 FileData *sfd = work->data; |
167 | 980 gint done = FALSE; |
981 | |
982 while (!done) | |
983 { | |
984 FileData *old_sfd = NULL; | |
985 | |
986 if (valid) | |
987 { | |
988 gtk_tree_model_get(GTK_TREE_MODEL(store), &s_iter, FILE_COLUMN_POINTER, &old_sfd, -1); | |
989 | |
990 if (sfd == old_sfd) | |
991 { | |
992 match = 0; | |
993 } | |
994 else | |
995 { | |
996 match = filelist_sort_compare_filedata_full(sfd, old_sfd, SORT_NAME, TRUE); | |
997 } | |
998 } | |
999 | |
1000 else | |
1001 { | |
1002 match = -1; | |
1003 } | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1004 |
167 | 1005 if (match < 0) |
1006 { | |
1007 GtkTreeIter new; | |
1008 | |
1009 if (valid) | |
1010 { | |
1011 gtk_tree_store_insert_before(store, &new, iter, &s_iter); | |
1012 } | |
1013 else | |
1014 { | |
1015 gtk_tree_store_append(store, &new, iter); | |
1016 } | |
1017 | |
1018 vflist_setup_iter(vfl, store, &new, sfd); | |
1019 | |
1020 done = TRUE; | |
1021 } | |
1022 else if (match > 0) | |
1023 { | |
1024 valid = gtk_tree_store_remove(store, &s_iter); | |
1025 } | |
1026 else | |
1027 { | |
1028 vflist_setup_iter(vfl, store, &s_iter, sfd); | |
1029 | |
1030 if (valid) valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &s_iter); | |
1031 | |
1032 done = TRUE; | |
1033 } | |
1034 } | |
1035 work = work->next; | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1036 } |
167 | 1037 |
1038 while (valid) | |
1039 { | |
1040 valid = gtk_tree_store_remove(store, &s_iter); | |
1041 } | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1042 } |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1043 |
9 | 1044 void vflist_sort_set(ViewFileList *vfl, SortType type, gint ascend) |
1045 { | |
168
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1046 gint i; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1047 GHashTable *fd_idx_hash = g_hash_table_new(NULL, NULL); |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1048 gint *new_order; |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1049 GtkTreeStore *store; |
9 | 1050 GList *work; |
1051 | |
1052 if (vfl->sort_method == type && vfl->sort_ascend == ascend) return; | |
168
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1053 if (!vfl->list) return; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1054 |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1055 work = vfl->list; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1056 i = 0; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1057 while (work) |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1058 { |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1059 FileData *fd = work->data; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1060 g_hash_table_insert(fd_idx_hash, fd, GINT_TO_POINTER(i)); |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1061 i++; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1062 work = work->next; |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1063 } |
9 | 1064 |
1065 vfl->sort_method = type; | |
1066 vfl->sort_ascend = ascend; | |
1067 | |
1068 vfl->list = filelist_sort(vfl->list, vfl->sort_method, vfl->sort_ascend); | |
168
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1069 |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1070 new_order = g_malloc(i * sizeof(gint)); |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1071 |
93
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1072 work = vfl->list; |
168
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1073 i = 0; |
93
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1074 while (work) |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1075 { |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1076 FileData *fd = work->data; |
168
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1077 new_order[i] = GPOINTER_TO_INT(g_hash_table_lookup(fd_idx_hash, fd)); |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1078 i++; |
93
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1079 work = work->next; |
f1c8f8632e23
Thu Nov 2 14:38:54 2006 John Ellis <johne@verizon.net>
gqview
parents:
64
diff
changeset
|
1080 } |
168
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1081 |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1082 store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview))); |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1083 gtk_tree_store_reorder(store, NULL, new_order); |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1084 |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1085 g_free(new_order); |
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
1086 g_hash_table_destroy(fd_idx_hash); |
9 | 1087 } |
1088 | |
1089 /* | |
1090 *----------------------------------------------------------------------------- | |
1091 * thumb updates | |
1092 *----------------------------------------------------------------------------- | |
1093 */ | |
1094 | |
1095 static gint vflist_thumb_next(ViewFileList *vfl); | |
1096 | |
1097 static void vflist_thumb_status(ViewFileList *vfl, gdouble val, const gchar *text) | |
1098 { | |
1099 if (vfl->func_thumb_status) | |
1100 { | |
1101 vfl->func_thumb_status(vfl, val, text, vfl->data_thumb_status); | |
1102 } | |
1103 } | |
1104 | |
1105 static void vflist_thumb_cleanup(ViewFileList *vfl) | |
1106 { | |
1107 vflist_thumb_status(vfl, 0.0, NULL); | |
1108 | |
1109 vfl->thumbs_count = 0; | |
1110 vfl->thumbs_running = FALSE; | |
1111 | |
1112 thumb_loader_free(vfl->thumbs_loader); | |
1113 vfl->thumbs_loader = NULL; | |
1114 | |
1115 vfl->thumbs_filedata = NULL; | |
1116 } | |
1117 | |
1118 static void vflist_thumb_stop(ViewFileList *vfl) | |
1119 { | |
1120 if (vfl->thumbs_running) vflist_thumb_cleanup(vfl); | |
1121 } | |
1122 | |
1123 static void vflist_thumb_do(ViewFileList *vfl, ThumbLoader *tl, FileData *fd) | |
1124 { | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1125 GtkTreeStore *store; |
9 | 1126 GtkTreeIter iter; |
1127 | |
1128 if (!fd || vflist_find_row(vfl, fd, &iter) < 0) return; | |
1129 | |
1130 if (fd->pixbuf) g_object_unref(fd->pixbuf); | |
1131 fd->pixbuf = thumb_loader_get_pixbuf(tl, TRUE); | |
1132 | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1133 store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview))); |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1134 gtk_tree_store_set(store, &iter, FILE_COLUMN_THUMB, fd->pixbuf, -1); |
9 | 1135 |
169 | 1136 vflist_thumb_status(vfl, (gdouble)(vfl->thumbs_count) / vflist_sidecar_list_count(vfl->list), _("Loading thumbs...")); |
9 | 1137 } |
1138 | |
1139 static void vflist_thumb_error_cb(ThumbLoader *tl, gpointer data) | |
1140 { | |
1141 ViewFileList *vfl = data; | |
1142 | |
1143 if (vfl->thumbs_filedata && vfl->thumbs_loader == tl) | |
1144 { | |
1145 vflist_thumb_do(vfl, tl, vfl->thumbs_filedata); | |
1146 } | |
1147 | |
1148 while (vflist_thumb_next(vfl)); | |
1149 } | |
1150 | |
1151 static void vflist_thumb_done_cb(ThumbLoader *tl, gpointer data) | |
1152 { | |
1153 ViewFileList *vfl = data; | |
1154 | |
1155 if (vfl->thumbs_filedata && vfl->thumbs_loader == tl) | |
1156 { | |
1157 vflist_thumb_do(vfl, tl, vfl->thumbs_filedata); | |
1158 } | |
1159 | |
1160 while (vflist_thumb_next(vfl)); | |
1161 } | |
1162 | |
1163 static gint vflist_thumb_next(ViewFileList *vfl) | |
1164 { | |
1165 GtkTreePath *tpath; | |
1166 FileData *fd = NULL; | |
1167 | |
1168 /* first check the visible files */ | |
1169 | |
1170 if (GTK_WIDGET_REALIZED(vfl->listview) && | |
1171 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vfl->listview), 0, 0, &tpath, NULL, NULL, NULL)) | |
1172 { | |
1173 GtkTreeModel *store; | |
1174 GtkTreeIter iter; | |
1175 gint valid = TRUE; | |
1176 | |
1177 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); | |
1178 gtk_tree_model_get_iter(store, &iter, tpath); | |
1179 gtk_tree_path_free(tpath); | |
1180 | |
1181 while (!fd && valid && tree_view_row_get_visibility(GTK_TREE_VIEW(vfl->listview), &iter, FALSE) == 0) | |
1182 { | |
1183 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); | |
1184 if (fd->pixbuf) fd = NULL; | |
1185 | |
1186 valid = gtk_tree_model_iter_next(store, &iter); | |
1187 } | |
1188 } | |
1189 | |
1190 /* then find first undone */ | |
1191 | |
1192 if (!fd) | |
1193 { | |
1194 GList *work = vfl->list; | |
1195 while (work && !fd) | |
1196 { | |
1197 FileData *fd_p = work->data; | |
169 | 1198 if (!fd_p->pixbuf) |
1199 fd = fd_p; | |
1200 else | |
1201 { | |
1202 GList *work2 = fd_p->sidecar_files; | |
1203 | |
1204 while (work2 && !fd) | |
1205 { | |
1206 fd_p = work2->data; | |
1207 if (!fd_p->pixbuf) fd = fd_p; | |
1208 work2 = work2->next; | |
1209 } | |
1210 } | |
9 | 1211 work = work->next; |
1212 } | |
1213 } | |
1214 | |
1215 if (!fd) | |
1216 { | |
1217 /* done */ | |
1218 vflist_thumb_cleanup(vfl); | |
1219 return FALSE; | |
1220 } | |
1221 | |
1222 vfl->thumbs_count++; | |
1223 | |
1224 vfl->thumbs_filedata = fd; | |
1225 | |
1226 thumb_loader_free(vfl->thumbs_loader); | |
1227 | |
1228 vfl->thumbs_loader = thumb_loader_new(thumb_max_width, thumb_max_height); | |
1229 thumb_loader_set_callbacks(vfl->thumbs_loader, | |
1230 vflist_thumb_done_cb, | |
1231 vflist_thumb_error_cb, | |
1232 NULL, | |
1233 vfl); | |
1234 | |
1235 if (!thumb_loader_start(vfl->thumbs_loader, fd->path)) | |
1236 { | |
1237 /* set icon to unknown, continue */ | |
1238 if (debug) printf("thumb loader start failed %s\n", vfl->thumbs_loader->path); | |
1239 vflist_thumb_do(vfl, vfl->thumbs_loader, fd); | |
1240 | |
1241 return TRUE; | |
1242 } | |
1243 | |
1244 return FALSE; | |
1245 } | |
1246 | |
1247 static void vflist_thumb_update(ViewFileList *vfl) | |
1248 { | |
1249 vflist_thumb_stop(vfl); | |
1250 if (!vfl->thumbs_enabled) return; | |
1251 | |
1252 vflist_thumb_status(vfl, 0.0, _("Loading thumbs...")); | |
1253 vfl->thumbs_running = TRUE; | |
1254 | |
1255 while (vflist_thumb_next(vfl)); | |
1256 } | |
1257 | |
1258 /* | |
1259 *----------------------------------------------------------------------------- | |
1260 * row stuff | |
1261 *----------------------------------------------------------------------------- | |
1262 */ | |
1263 | |
1264 FileData *vflist_index_get_data(ViewFileList *vfl, gint row) | |
1265 { | |
1266 return g_list_nth_data(vfl->list, row); | |
1267 } | |
1268 | |
1269 gchar *vflist_index_get_path(ViewFileList *vfl, gint row) | |
1270 { | |
1271 FileData *fd; | |
1272 | |
1273 fd = g_list_nth_data(vfl->list, row); | |
1274 | |
1275 return (fd ? fd->path : NULL); | |
1276 } | |
1277 | |
1278 static gint vflist_row_by_path(ViewFileList *vfl, const gchar *path, FileData **fd) | |
1279 { | |
1280 gint p = 0; | |
1281 GList *work; | |
1282 | |
1283 if (!path) return -1; | |
1284 | |
1285 work = vfl->list; | |
1286 while (work) | |
1287 { | |
1288 FileData *fd_n = work->data; | |
1289 if (strcmp(path, fd_n->path) == 0) | |
1290 { | |
1291 if (fd) *fd = fd_n; | |
1292 return p; | |
1293 } | |
1294 work = work->next; | |
1295 p++; | |
1296 } | |
1297 | |
1298 if (fd) *fd = NULL; | |
1299 return -1; | |
1300 } | |
1301 | |
1302 gint vflist_index_by_path(ViewFileList *vfl, const gchar *path) | |
1303 { | |
1304 return vflist_row_by_path(vfl, path, NULL); | |
1305 } | |
1306 | |
1307 gint vflist_count(ViewFileList *vfl, gint64 *bytes) | |
1308 { | |
1309 if (bytes) | |
1310 { | |
1311 gint64 b = 0; | |
1312 GList *work; | |
1313 | |
1314 work = vfl->list; | |
1315 while (work) | |
1316 { | |
1317 FileData *fd = work->data; | |
1318 work = work->next; | |
1319 b += fd->size; | |
1320 } | |
1321 | |
1322 *bytes = b; | |
1323 } | |
1324 | |
1325 return g_list_length(vfl->list); | |
1326 } | |
1327 | |
1328 GList *vflist_get_list(ViewFileList *vfl) | |
1329 { | |
1330 GList *list = NULL; | |
1331 GList *work; | |
1332 | |
1333 work = vfl->list; | |
1334 while (work) | |
1335 { | |
1336 FileData *fd = work->data; | |
1337 work = work->next; | |
1338 | |
138 | 1339 list = g_list_prepend(list, file_data_ref(fd)); |
9 | 1340 } |
1341 | |
1342 return g_list_reverse(list); | |
1343 } | |
1344 | |
1345 /* | |
1346 *----------------------------------------------------------------------------- | |
1347 * selections | |
1348 *----------------------------------------------------------------------------- | |
1349 */ | |
1350 | |
1351 static gint vflist_row_is_selected(ViewFileList *vfl, FileData *fd) | |
1352 { | |
1353 GtkTreeModel *store; | |
1354 GtkTreeSelection *selection; | |
1355 GList *slist; | |
1356 GList *work; | |
1357 gint found = FALSE; | |
1358 | |
1359 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1360 slist = gtk_tree_selection_get_selected_rows(selection, &store); | |
1361 work = slist; | |
1362 while (!found && work) | |
1363 { | |
1364 GtkTreePath *tpath = work->data; | |
1365 FileData *fd_n; | |
1366 GtkTreeIter iter; | |
1367 | |
1368 gtk_tree_model_get_iter(store, &iter, tpath); | |
1369 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd_n, -1); | |
1370 if (fd_n == fd) found = TRUE; | |
1371 work = work->next; | |
1372 } | |
1373 g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL); | |
1374 g_list_free(slist); | |
1375 | |
1376 return found; | |
1377 } | |
1378 | |
1379 gint vflist_index_is_selected(ViewFileList *vfl, gint row) | |
1380 { | |
1381 FileData *fd; | |
1382 | |
1383 fd = vflist_index_get_data(vfl, row); | |
1384 return vflist_row_is_selected(vfl, fd); | |
1385 } | |
1386 | |
1387 gint vflist_selection_count(ViewFileList *vfl, gint64 *bytes) | |
1388 { | |
1389 GtkTreeModel *store; | |
1390 GtkTreeSelection *selection; | |
1391 GList *slist; | |
1392 gint count; | |
1393 | |
1394 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1395 slist = gtk_tree_selection_get_selected_rows(selection, &store); | |
1396 | |
1397 if (bytes) | |
1398 { | |
1399 gint64 b = 0; | |
1400 GList *work; | |
1401 | |
1402 work = slist; | |
1403 while (work) | |
1404 { | |
1405 GtkTreePath *tpath = work->data; | |
1406 GtkTreeIter iter; | |
1407 FileData *fd; | |
1408 | |
1409 gtk_tree_model_get_iter(store, &iter, tpath); | |
1410 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); | |
1411 b += fd->size; | |
1412 | |
1413 work = work->next; | |
1414 } | |
1415 | |
1416 *bytes = b; | |
1417 } | |
1418 | |
1419 count = g_list_length(slist); | |
1420 g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL); | |
1421 g_list_free(slist); | |
1422 | |
1423 return count; | |
1424 } | |
1425 | |
1426 GList *vflist_selection_get_list(ViewFileList *vfl) | |
1427 { | |
1428 GtkTreeModel *store; | |
1429 GtkTreeSelection *selection; | |
1430 GList *slist; | |
1431 GList *list = NULL; | |
1432 GList *work; | |
1433 | |
1434 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1435 slist = gtk_tree_selection_get_selected_rows(selection, &store); | |
1436 work = slist; | |
1437 while (work) | |
1438 { | |
1439 GtkTreePath *tpath = work->data; | |
1440 FileData *fd; | |
1441 GtkTreeIter iter; | |
1442 | |
1443 gtk_tree_model_get_iter(store, &iter, tpath); | |
1444 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); | |
1445 | |
138 | 1446 list = g_list_prepend(list, file_data_ref(fd)); |
9 | 1447 |
1448 work = work->next; | |
1449 } | |
1450 g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL); | |
1451 g_list_free(slist); | |
1452 | |
1453 return g_list_reverse(list); | |
1454 } | |
1455 | |
1456 GList *vflist_selection_get_list_by_index(ViewFileList *vfl) | |
1457 { | |
1458 GtkTreeModel *store; | |
1459 GtkTreeSelection *selection; | |
1460 GList *slist; | |
1461 GList *list = NULL; | |
1462 GList *work; | |
1463 | |
1464 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1465 slist = gtk_tree_selection_get_selected_rows(selection, &store); | |
1466 work = slist; | |
1467 while (work) | |
1468 { | |
1469 GtkTreePath *tpath = work->data; | |
1470 FileData *fd; | |
1471 GtkTreeIter iter; | |
1472 | |
1473 gtk_tree_model_get_iter(store, &iter, tpath); | |
1474 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); | |
1475 | |
1476 list = g_list_prepend(list, GINT_TO_POINTER(g_list_index(vfl->list, fd))); | |
1477 | |
1478 work = work->next; | |
1479 } | |
1480 g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL); | |
1481 g_list_free(slist); | |
1482 | |
1483 return g_list_reverse(list); | |
1484 } | |
1485 | |
1486 void vflist_select_all(ViewFileList *vfl) | |
1487 { | |
1488 GtkTreeSelection *selection; | |
1489 | |
1490 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1491 gtk_tree_selection_select_all(selection); | |
1492 | |
1493 vfl->select_fd = NULL; | |
1494 } | |
1495 | |
1496 void vflist_select_none(ViewFileList *vfl) | |
1497 { | |
1498 GtkTreeSelection *selection; | |
1499 | |
1500 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1501 gtk_tree_selection_unselect_all(selection); | |
1502 } | |
1503 | |
1504 void vflist_select_by_path(ViewFileList *vfl, const gchar *path) | |
1505 { | |
1506 FileData *fd; | |
138 | 1507 |
1508 if (vflist_row_by_path(vfl, path, &fd) < 0) return; | |
1509 | |
1510 vflist_select_by_fd(vfl, fd); | |
1511 } | |
1512 | |
1513 void vflist_select_by_fd(ViewFileList *vfl, FileData *fd) | |
1514 { | |
9 | 1515 GtkTreeIter iter; |
1516 | |
1517 if (vflist_find_row(vfl, fd, &iter) < 0) return; | |
1518 | |
1519 tree_view_row_make_visible(GTK_TREE_VIEW(vfl->listview), &iter, TRUE); | |
1520 | |
1521 if (!vflist_row_is_selected(vfl, fd)) | |
1522 { | |
1523 GtkTreeSelection *selection; | |
1524 GtkTreeModel *store; | |
1525 GtkTreePath *tpath; | |
1526 | |
1527 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1528 gtk_tree_selection_unselect_all(selection); | |
1529 gtk_tree_selection_select_iter(selection, &iter); | |
1530 vflist_move_cursor(vfl, &iter); | |
1531 | |
1532 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); | |
1533 tpath = gtk_tree_model_get_path(store, &iter); | |
1534 gtk_tree_view_set_cursor(GTK_TREE_VIEW(vfl->listview), tpath, NULL, FALSE); | |
1535 gtk_tree_path_free(tpath); | |
1536 } | |
1537 } | |
1538 | |
161 | 1539 void vflist_mark_to_selection(ViewFileList *vfl, gint mark, MarkToSelectionMode mode) |
150 | 1540 { |
1541 GtkTreeModel *store; | |
1542 GtkTreeIter iter; | |
1543 GtkTreeSelection *selection; | |
1544 gint valid; | |
1545 | |
1546 g_assert(mark >= 0 && mark < FILEDATA_MARKS_SIZE); | |
1547 | |
1548 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); | |
1549 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1550 | |
1551 valid = gtk_tree_model_get_iter_first(store, &iter); | |
1552 while (valid) | |
1553 { | |
1554 FileData *fd; | |
161 | 1555 gboolean mark_val, selected; |
150 | 1556 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, FILE_COLUMN_POINTER, &fd, -1); |
1557 | |
161 | 1558 mark_val = fd->marks[mark]; |
1559 selected = gtk_tree_selection_iter_is_selected(selection, &iter); | |
1560 | |
1561 switch (mode) | |
1562 { | |
1563 case MTS_MODE_SET: selected = mark_val; | |
1564 break; | |
1565 case MTS_MODE_OR: selected = mark_val | selected; | |
1566 break; | |
1567 case MTS_MODE_AND: selected = mark_val & selected; | |
1568 break; | |
1569 case MTS_MODE_MINUS: selected = !mark_val & selected; | |
1570 break; | |
1571 } | |
1572 | |
1573 if (selected) | |
150 | 1574 gtk_tree_selection_select_iter(selection, &iter); |
161 | 1575 else |
1576 gtk_tree_selection_unselect_iter(selection, &iter); | |
150 | 1577 |
1578 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter); | |
1579 } | |
1580 } | |
1581 | |
161 | 1582 void vflist_selection_to_mark(ViewFileList *vfl, gint mark, SelectionToMarkMode mode) |
150 | 1583 { |
1584 GtkTreeModel *store; | |
1585 GtkTreeSelection *selection; | |
1586 GList *slist; | |
1587 GList *work; | |
1588 | |
1589 g_assert(mark >= 0 && mark < FILEDATA_MARKS_SIZE); | |
1590 | |
1591 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
1592 slist = gtk_tree_selection_get_selected_rows(selection, &store); | |
1593 work = slist; | |
1594 while (work) | |
1595 { | |
1596 GtkTreePath *tpath = work->data; | |
1597 FileData *fd; | |
1598 GtkTreeIter iter; | |
1599 | |
1600 gtk_tree_model_get_iter(store, &iter, tpath); | |
1601 gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); | |
1602 | |
161 | 1603 switch (mode) |
1604 { | |
1605 case STM_MODE_SET: fd->marks[mark] = 1; | |
1606 break; | |
1607 case STM_MODE_RESET: fd->marks[mark] = 0; | |
1608 break; | |
1609 case STM_MODE_TOGGLE: fd->marks[mark] = !fd->marks[mark]; | |
1610 break; | |
1611 } | |
150 | 1612 |
1613 gtk_tree_store_set(GTK_TREE_STORE(store), &iter, FILE_COLUMN_MARKS + mark, fd->marks[mark], -1); | |
1614 | |
1615 work = work->next; | |
1616 } | |
1617 g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL); | |
1618 g_list_free(slist); | |
1619 } | |
1620 | |
9 | 1621 /* |
1622 *----------------------------------------------------------------------------- | |
1623 * core (population) | |
1624 *----------------------------------------------------------------------------- | |
1625 */ | |
1626 | |
1627 static void vflist_listview_set_height(GtkWidget *listview, gint thumb) | |
1628 { | |
1629 GtkTreeViewColumn *column; | |
1630 GtkCellRenderer *cell; | |
1631 GList *list; | |
1632 | |
1633 column = gtk_tree_view_get_column(GTK_TREE_VIEW(listview), FILE_COLUMN_THUMB - 1); | |
1634 if (!column) return; | |
1635 | |
149 | 1636 gtk_tree_view_column_set_fixed_width(column, ((thumb) ? thumb_max_width : 4) + 10); |
9 | 1637 |
1638 list = gtk_tree_view_column_get_cell_renderers(column); | |
1639 if (!list) return; | |
1640 cell = list->data; | |
1641 g_list_free(list); | |
1642 | |
1643 g_object_set(G_OBJECT(cell), "height", (thumb) ? thumb_max_height : -1, NULL); | |
1644 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(listview)); | |
1645 } | |
1646 | |
1647 static void vflist_populate_view(ViewFileList *vfl) | |
1648 { | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1649 GtkTreeStore *store; |
9 | 1650 GtkTreeIter iter; |
1651 gint thumbs; | |
1652 GList *work; | |
1653 GtkTreeRowReference *visible_row = NULL; | |
1654 GtkTreePath *tpath; | |
1655 gint valid; | |
1656 | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1657 store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview))); |
9 | 1658 thumbs = vfl->thumbs_enabled; |
1659 | |
1660 vflist_thumb_stop(vfl); | |
1661 | |
1662 if (!vfl->list) | |
1663 { | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1664 gtk_tree_store_clear(store); |
9 | 1665 vflist_send_update(vfl); |
1666 return; | |
1667 } | |
1668 | |
1669 if (GTK_WIDGET_REALIZED(vfl->listview) && | |
1670 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vfl->listview), 0, 0, &tpath, NULL, NULL, NULL)) | |
1671 { | |
1672 visible_row = gtk_tree_row_reference_new(GTK_TREE_MODEL(store), tpath); | |
1673 gtk_tree_path_free(tpath); | |
1674 } | |
1675 | |
1676 vflist_listview_set_height(vfl->listview, thumbs); | |
1677 | |
1678 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter); | |
1679 | |
1680 work = vfl->list; | |
1681 while (work) | |
1682 { | |
1683 gint match; | |
1684 FileData *fd = work->data; | |
1685 gint done = FALSE; | |
1686 | |
1687 while (!done) | |
1688 { | |
1689 FileData *old_fd = NULL; | |
132 | 1690 |
9 | 1691 if (valid) |
1692 { | |
1693 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, FILE_COLUMN_POINTER, &old_fd, -1); | |
167 | 1694 |
1695 if (fd == old_fd) | |
1696 { | |
1697 match = 0; | |
1698 } | |
1699 else | |
1700 { | |
1701 match = filelist_sort_compare_filedata_full(fd, old_fd, vfl->sort_method, vfl->sort_ascend); | |
1702 if (match == 0) | |
1703 match = -1; /* probably should not happen*/ | |
1704 } | |
9 | 1705 } |
167 | 1706 |
9 | 1707 else |
1708 { | |
1709 match = -1; | |
1710 } | |
1711 | |
1712 if (match < 0) | |
1713 { | |
1714 GtkTreeIter new; | |
139 | 1715 |
9 | 1716 if (valid) |
1717 { | |
167 | 1718 gtk_tree_store_insert_before(store, &new, NULL, &iter); |
9 | 1719 } |
1720 else | |
1721 { | |
167 | 1722 gtk_tree_store_append(store, &new, NULL); |
9 | 1723 } |
167 | 1724 vflist_setup_iter_with_sidecars(vfl, store, &new, fd); |
9 | 1725 |
1726 done = TRUE; | |
1727 } | |
1728 else if (match > 0) | |
1729 { | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1730 valid = gtk_tree_store_remove(store, &iter); |
9 | 1731 } |
1732 else | |
1733 { | |
167 | 1734 vflist_setup_iter_with_sidecars(vfl, store, &iter, fd); |
9 | 1735 |
1736 if (valid) valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter); | |
1737 | |
1738 done = TRUE; | |
1739 } | |
1740 } | |
1741 work = work->next; | |
1742 } | |
1743 | |
1744 while (valid) | |
1745 { | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1746 valid = gtk_tree_store_remove(store, &iter); |
9 | 1747 } |
1748 | |
1749 if (visible_row) | |
1750 { | |
1751 if (gtk_tree_row_reference_valid(visible_row)) | |
1752 { | |
1753 tpath = gtk_tree_row_reference_get_path(visible_row); | |
1754 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(vfl->listview), tpath, NULL, TRUE, 0.0, 0.0); | |
1755 gtk_tree_path_free(tpath); | |
1756 } | |
1757 gtk_tree_row_reference_free(visible_row); | |
1758 } | |
1759 | |
1760 vflist_send_update(vfl); | |
1761 vflist_thumb_update(vfl); | |
1762 } | |
1763 | |
1764 gint vflist_refresh(ViewFileList *vfl) | |
1765 { | |
1766 GList *old_list; | |
1767 gint ret = TRUE; | |
1768 | |
1769 old_list = vfl->list; | |
1770 vfl->list = NULL; | |
1771 | |
1772 if (vfl->path) | |
1773 { | |
1774 ret = filelist_read(vfl->path, &vfl->list, NULL); | |
1775 } | |
1776 | |
1777 vfl->list = filelist_sort(vfl->list, vfl->sort_method, vfl->sort_ascend); | |
1778 vflist_populate_view(vfl); | |
1779 | |
1780 filelist_free(old_list); | |
1781 | |
1782 return ret; | |
1783 } | |
1784 | |
1785 /* this overrides the low default of a GtkCellRenderer from 100 to CELL_HEIGHT_OVERRIDE, something sane for our purposes */ | |
1786 | |
1787 #define CELL_HEIGHT_OVERRIDE 512 | |
1788 | |
1789 static void cell_renderer_height_override(GtkCellRenderer *renderer) | |
1790 { | |
1791 GParamSpec *spec; | |
1792 | |
1793 spec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(renderer)), "height"); | |
1794 if (spec && G_IS_PARAM_SPEC_INT(spec)) | |
1795 { | |
1796 GParamSpecInt *spec_int; | |
1797 | |
1798 spec_int = G_PARAM_SPEC_INT(spec); | |
1799 if (spec_int->maximum < CELL_HEIGHT_OVERRIDE) spec_int->maximum = CELL_HEIGHT_OVERRIDE; | |
1800 } | |
1801 } | |
1802 | |
1803 static GdkColor *vflist_listview_color_shifted(GtkWidget *widget) | |
1804 { | |
1805 static GdkColor color; | |
1806 static GtkWidget *done = NULL; | |
1807 | |
1808 if (done != widget) | |
1809 { | |
1810 GtkStyle *style; | |
1811 | |
1812 style = gtk_widget_get_style(widget); | |
1813 memcpy(&color, &style->base[GTK_STATE_NORMAL], sizeof(color)); | |
1814 shift_color(&color, -1, 0); | |
1815 done = widget; | |
1816 } | |
1817 | |
1818 return &color; | |
1819 } | |
1820 | |
1821 static void vflist_listview_color_cb(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, | |
1822 GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) | |
1823 { | |
1824 ViewFileList *vfl = data; | |
1825 gboolean set; | |
1826 | |
1827 gtk_tree_model_get(tree_model, iter, FILE_COLUMN_COLOR, &set, -1); | |
1828 g_object_set(G_OBJECT(cell), | |
1829 "cell-background-gdk", vflist_listview_color_shifted(vfl->listview), | |
1830 "cell-background-set", set, NULL); | |
1831 } | |
1832 | |
132 | 1833 static void vflist_listview_add_column(ViewFileList *vfl, gint n, const gchar *title, gint image, gint right_justify, gint expand) |
9 | 1834 { |
1835 GtkTreeViewColumn *column; | |
1836 GtkCellRenderer *renderer; | |
1837 | |
1838 column = gtk_tree_view_column_new(); | |
1839 gtk_tree_view_column_set_title(column, title); | |
1840 gtk_tree_view_column_set_min_width(column, 4); | |
1841 | |
1842 if (!image) | |
1843 { | |
149 | 1844 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY); |
9 | 1845 renderer = gtk_cell_renderer_text_new(); |
1846 if (right_justify) | |
1847 { | |
1848 g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL); | |
1849 } | |
1850 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
1851 gtk_tree_view_column_add_attribute(column, renderer, "text", n); | |
149 | 1852 if (expand) |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1853 gtk_tree_view_column_set_expand(column, TRUE); |
149 | 1854 } |
9 | 1855 else |
1856 { | |
1857 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED); | |
1858 renderer = gtk_cell_renderer_pixbuf_new(); | |
1859 cell_renderer_height_override(renderer); | |
1860 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
1861 gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", n); | |
1862 } | |
1863 | |
1864 gtk_tree_view_column_set_cell_data_func(column, renderer, vflist_listview_color_cb, vfl, NULL); | |
149 | 1865 g_object_set_data (G_OBJECT (column), "column_store_idx", GUINT_TO_POINTER(n)); |
1866 g_object_set_data (G_OBJECT (renderer), "column_store_idx", GUINT_TO_POINTER(n)); | |
9 | 1867 |
1868 gtk_tree_view_append_column(GTK_TREE_VIEW(vfl->listview), column); | |
1869 } | |
1870 | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1871 static void vflist_listview_mark_toggled(GtkCellRendererToggle *cell, gchar *path_str, GtkTreeStore *store) |
132 | 1872 { |
149 | 1873 GtkTreePath *path = gtk_tree_path_new_from_string(path_str); |
1874 GtkTreeIter iter; | |
1875 FileData *fd; | |
1876 gboolean mark; | |
1877 guint col_idx; | |
132 | 1878 |
149 | 1879 if (!path || !gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path)) |
1880 return; | |
132 | 1881 |
149 | 1882 col_idx = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(cell), "column_store_idx")); |
1883 | |
1884 g_assert(col_idx >= FILE_COLUMN_MARKS && col_idx <= FILE_COLUMN_MARKS_LAST); | |
132 | 1885 |
149 | 1886 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, FILE_COLUMN_POINTER, &fd, col_idx, &mark, -1); |
150 | 1887 mark = !mark; |
149 | 1888 fd->marks[col_idx - FILE_COLUMN_MARKS] = mark; |
132 | 1889 |
149 | 1890 gtk_tree_store_set(store, &iter, col_idx, mark, -1); |
1891 gtk_tree_path_free(path); | |
132 | 1892 } |
1893 | |
1894 static void vflist_listview_add_column_toggle(ViewFileList *vfl, gint n, const gchar *title) | |
1895 { | |
149 | 1896 GtkTreeViewColumn *column; |
1897 GtkCellRenderer *renderer; | |
1898 GtkTreeStore *store; | |
1899 gint index; | |
132 | 1900 |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1901 store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview))); |
132 | 1902 |
149 | 1903 renderer = gtk_cell_renderer_toggle_new(); |
1904 column = gtk_tree_view_column_new_with_attributes(title, renderer, "active", n, NULL); | |
132 | 1905 |
149 | 1906 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED); |
1907 g_object_set_data (G_OBJECT (column), "column_store_idx", GUINT_TO_POINTER(n)); | |
1908 g_object_set_data (G_OBJECT (renderer), "column_store_idx", GUINT_TO_POINTER(n)); | |
132 | 1909 |
149 | 1910 index = gtk_tree_view_append_column(GTK_TREE_VIEW(vfl->listview), column); |
1911 gtk_tree_view_column_set_fixed_width(column, 16); | |
1912 gtk_tree_view_column_set_visible(column, vfl->marks_enabled); | |
132 | 1913 |
1914 | |
149 | 1915 g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(vflist_listview_mark_toggled), store); |
132 | 1916 } |
1917 | |
9 | 1918 /* |
1919 *----------------------------------------------------------------------------- | |
1920 * base | |
1921 *----------------------------------------------------------------------------- | |
1922 */ | |
1923 | |
1924 gint vflist_set_path(ViewFileList *vfl, const gchar *path) | |
1925 { | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1926 GtkTreeStore *store; |
9 | 1927 |
1928 if (!path) return FALSE; | |
1929 if (vfl->path && strcmp(path, vfl->path) == 0) return TRUE; | |
1930 | |
1931 g_free(vfl->path); | |
1932 vfl->path = g_strdup(path); | |
1933 | |
1934 /* force complete reload */ | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1935 store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview))); |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1936 gtk_tree_store_clear(store); |
9 | 1937 |
1938 filelist_free(vfl->list); | |
1939 vfl->list = NULL; | |
1940 | |
1941 return vflist_refresh(vfl); | |
1942 } | |
1943 | |
1944 static void vflist_destroy_cb(GtkWidget *widget, gpointer data) | |
1945 { | |
1946 ViewFileList *vfl = data; | |
1947 | |
1948 if (vfl->popup) | |
1949 { | |
1950 g_signal_handlers_disconnect_matched(G_OBJECT(vfl->popup), G_SIGNAL_MATCH_DATA, | |
1951 0, 0, 0, NULL, vfl); | |
1952 gtk_widget_destroy(vfl->popup); | |
1953 } | |
1954 | |
1955 vflist_select_idle_cancel(vfl); | |
1956 vflist_thumb_stop(vfl); | |
1957 | |
1958 g_free(vfl->path); | |
1959 filelist_free(vfl->list); | |
1960 g_free(vfl); | |
1961 } | |
1962 | |
1963 ViewFileList *vflist_new(const gchar *path, gint thumbs) | |
1964 { | |
1965 ViewFileList *vfl; | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
1966 GtkTreeStore *store; |
9 | 1967 GtkTreeSelection *selection; |
1968 | |
149 | 1969 GType flist_types[FILE_COLUMN_COUNT]; |
1970 int i; | |
132 | 1971 |
9 | 1972 vfl = g_new0(ViewFileList, 1); |
1973 | |
1974 vfl->path = NULL; | |
1975 vfl->list = NULL; | |
1976 vfl->click_fd = NULL; | |
1977 vfl->select_fd = NULL; | |
1978 vfl->sort_method = SORT_NAME; | |
1979 vfl->sort_ascend = TRUE; | |
1980 vfl->thumbs_enabled = thumbs; | |
1981 | |
1982 vfl->thumbs_running = FALSE; | |
1983 vfl->thumbs_count = 0; | |
1984 vfl->thumbs_loader = NULL; | |
1985 vfl->thumbs_filedata = NULL; | |
1986 | |
1987 vfl->select_idle_id = -1; | |
1988 | |
1989 vfl->popup = NULL; | |
1990 | |
1991 vfl->widget = gtk_scrolled_window_new(NULL, NULL); | |
1992 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(vfl->widget), GTK_SHADOW_IN); | |
1993 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(vfl->widget), | |
1994 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); | |
1995 g_signal_connect(G_OBJECT(vfl->widget), "destroy", | |
1996 G_CALLBACK(vflist_destroy_cb), vfl); | |
1997 | |
139 | 1998 flist_types[FILE_COLUMN_POINTER] = G_TYPE_POINTER; |
1999 flist_types[FILE_COLUMN_THUMB] = GDK_TYPE_PIXBUF; | |
2000 flist_types[FILE_COLUMN_NAME] = G_TYPE_STRING; | |
2001 flist_types[FILE_COLUMN_SIDECARS] = G_TYPE_STRING; | |
2002 flist_types[FILE_COLUMN_SIZE] = G_TYPE_STRING; | |
2003 flist_types[FILE_COLUMN_DATE] = G_TYPE_STRING; | |
2004 flist_types[FILE_COLUMN_COLOR] = G_TYPE_BOOLEAN; | |
2005 for (i = FILE_COLUMN_MARKS; i < FILE_COLUMN_MARKS + FILEDATA_MARKS_SIZE; i++) | |
2006 flist_types[i] = G_TYPE_BOOLEAN; | |
132 | 2007 |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
2008 store = gtk_tree_store_newv(FILE_COLUMN_COUNT, flist_types); |
132 | 2009 |
139 | 2010 vfl->listview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); |
9 | 2011 g_object_unref(store); |
2012 | |
2013 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
2014 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_MULTIPLE); | |
2015 gtk_tree_selection_set_select_function(selection, vflist_select_cb, vfl, NULL); | |
2016 | |
149 | 2017 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(vfl->listview), FALSE); |
9 | 2018 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(vfl->listview), FALSE); |
2019 | |
132 | 2020 vflist_listview_add_column(vfl, FILE_COLUMN_THUMB, "", TRUE, FALSE, FALSE); |
9 | 2021 |
139 | 2022 for(i = 0; i < FILEDATA_MARKS_SIZE;i++) |
2023 vflist_listview_add_column_toggle(vfl, i + FILE_COLUMN_MARKS, ""); | |
2024 | |
149 | 2025 vflist_listview_add_column(vfl, FILE_COLUMN_NAME, _("Name"), FALSE, FALSE, FALSE); |
2026 vflist_listview_add_column(vfl, FILE_COLUMN_SIDECARS, _("SC"), FALSE, FALSE, FALSE); | |
2027 | |
2028 vflist_listview_add_column(vfl, FILE_COLUMN_SIZE, _("Size"), FALSE, TRUE, FALSE); | |
2029 vflist_listview_add_column(vfl, FILE_COLUMN_DATE, _("Date"), FALSE, TRUE, FALSE); | |
2030 | |
132 | 2031 |
139 | 2032 g_signal_connect(G_OBJECT(vfl->listview), "key_press_event", |
9 | 2033 G_CALLBACK(vflist_press_key_cb), vfl); |
2034 | |
2035 gtk_container_add (GTK_CONTAINER(vfl->widget), vfl->listview); | |
2036 gtk_widget_show(vfl->listview); | |
2037 | |
2038 vflist_dnd_init(vfl); | |
132 | 2039 |
9 | 2040 g_signal_connect(G_OBJECT(vfl->listview), "button_press_event", |
2041 G_CALLBACK(vflist_press_cb), vfl); | |
2042 g_signal_connect(G_OBJECT(vfl->listview), "button_release_event", | |
2043 G_CALLBACK(vflist_release_cb), vfl); | |
132 | 2044 |
2045 | |
9 | 2046 if (path) vflist_set_path(vfl, path); |
2047 | |
2048 return vfl; | |
2049 } | |
2050 | |
2051 void vflist_set_status_func(ViewFileList *vfl, | |
2052 void (*func)(ViewFileList *vfl, gpointer data), gpointer data) | |
2053 { | |
2054 vfl->func_status = func; | |
2055 vfl->data_status = data; | |
2056 } | |
2057 | |
2058 void vflist_set_thumb_status_func(ViewFileList *vfl, | |
2059 void (*func)(ViewFileList *vfl, gdouble val, const gchar *text, gpointer data), | |
2060 gpointer data) | |
2061 { | |
2062 vfl->func_thumb_status = func; | |
2063 vfl->data_thumb_status = data; | |
2064 } | |
2065 | |
2066 void vflist_thumb_set(ViewFileList *vfl, gint enable) | |
2067 { | |
2068 if (vfl->thumbs_enabled == enable) return; | |
2069 | |
2070 vfl->thumbs_enabled = enable; | |
2071 vflist_refresh(vfl); | |
2072 } | |
2073 | |
132 | 2074 void vflist_marks_set(ViewFileList *vfl, gint enable) |
2075 { | |
149 | 2076 GList *columns, *work; |
132 | 2077 |
2078 if (vfl->marks_enabled == enable) return; | |
2079 | |
2080 vfl->marks_enabled = enable; | |
2081 | |
149 | 2082 columns = gtk_tree_view_get_columns(GTK_TREE_VIEW(vfl->listview)); |
2083 | |
2084 work = columns; | |
2085 while (work) | |
2086 { | |
2087 GtkTreeViewColumn *column = work->data; | |
2088 gint col_idx = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(column), "column_store_idx")); | |
2089 work = work->next; | |
2090 | |
2091 if (col_idx <= FILE_COLUMN_MARKS_LAST && col_idx >= FILE_COLUMN_MARKS) | |
2092 gtk_tree_view_column_set_visible(column, enable); | |
2093 } | |
132 | 2094 |
149 | 2095 g_list_free(columns); |
2096 //vflist_refresh(vfl); | |
132 | 2097 } |
2098 | |
9 | 2099 void vflist_set_layout(ViewFileList *vfl, LayoutWindow *layout) |
2100 { | |
2101 vfl->layout = layout; | |
2102 } | |
2103 | |
2104 /* | |
2105 *----------------------------------------------------------------------------- | |
2106 * maintenance (for rename, move, remove) | |
2107 *----------------------------------------------------------------------------- | |
2108 */ | |
2109 | |
2110 static gint vflist_maint_find_closest(ViewFileList *vfl, gint row, gint count, GList *ignore_list) | |
2111 { | |
2112 GList *list = NULL; | |
2113 GList *work; | |
2114 gint rev = row - 1; | |
2115 row ++; | |
2116 | |
2117 work = ignore_list; | |
2118 while (work) | |
2119 { | |
2120 gint f = vflist_index_by_path(vfl, work->data); | |
2121 if (f >= 0) list = g_list_prepend(list, GINT_TO_POINTER(f)); | |
2122 work = work->next; | |
2123 } | |
2124 | |
2125 while (list) | |
2126 { | |
2127 gint c = TRUE; | |
2128 work = list; | |
2129 while (work && c) | |
2130 { | |
2131 gpointer p = work->data; | |
2132 work = work->next; | |
2133 if (row == GPOINTER_TO_INT(p)) | |
2134 { | |
2135 row++; | |
2136 c = FALSE; | |
2137 } | |
2138 if (rev == GPOINTER_TO_INT(p)) | |
2139 { | |
2140 rev--; | |
2141 c = FALSE; | |
2142 } | |
2143 if (!c) list = g_list_remove(list, p); | |
2144 } | |
2145 if (c && list) | |
2146 { | |
2147 g_list_free(list); | |
2148 list = NULL; | |
2149 } | |
2150 } | |
2151 if (row > count - 1) | |
2152 { | |
2153 if (rev < 0) | |
2154 return -1; | |
2155 else | |
2156 return rev; | |
2157 } | |
2158 else | |
2159 { | |
2160 return row; | |
2161 } | |
2162 } | |
2163 | |
138 | 2164 gint vflist_maint_renamed(ViewFileList *vfl, FileData *fd) |
9 | 2165 { |
2166 gint ret = FALSE; | |
2167 gchar *source_base; | |
2168 gchar *dest_base; | |
2169 | |
168
a55ada12322a
fixed vflist_find_row and vflist_sort_set to work correctly with sidecar
nadvornik
parents:
167
diff
changeset
|
2170 if (g_list_index(vfl->list, fd) < 0) return FALSE; |
9 | 2171 |
138 | 2172 source_base = remove_level_from_path(fd->change->source); |
2173 dest_base = remove_level_from_path(fd->change->dest); | |
9 | 2174 |
2175 | |
2176 if (strcmp(source_base, dest_base) == 0) | |
2177 { | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
2178 GtkTreeStore *store; |
9 | 2179 GtkTreeIter iter; |
2180 GtkTreeIter position; | |
2181 gint old_row; | |
2182 gint n; | |
2183 | |
2184 old_row = g_list_index(vfl->list, fd); | |
2185 | |
2186 vfl->list = g_list_remove(vfl->list, fd); | |
2187 | |
2188 vfl->list = filelist_insert_sort(vfl->list, fd, vfl->sort_method, vfl->sort_ascend); | |
2189 n = g_list_index(vfl->list, fd); | |
2190 | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
2191 store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview))); |
9 | 2192 if (vflist_find_row(vfl, fd, &iter) >= 0 && |
2193 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &position, NULL, n)) | |
2194 { | |
2195 if (old_row >= n) | |
2196 { | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
2197 gtk_tree_store_move_before(store, &iter, &position); |
9 | 2198 } |
2199 else | |
2200 { | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
2201 gtk_tree_store_move_after(store, &iter, &position); |
9 | 2202 } |
2203 } | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
2204 gtk_tree_store_set(store, &iter, FILE_COLUMN_NAME, fd->name, -1); |
9 | 2205 |
2206 ret = TRUE; | |
2207 } | |
2208 else | |
2209 { | |
138 | 2210 ret = vflist_maint_removed(vfl, fd, NULL); |
9 | 2211 } |
2212 | |
2213 g_free(source_base); | |
2214 g_free(dest_base); | |
2215 | |
2216 return ret; | |
2217 } | |
2218 | |
138 | 2219 gint vflist_maint_removed(ViewFileList *vfl, FileData *fd, GList *ignore_list) |
9 | 2220 { |
2221 GtkTreeIter iter; | |
2222 GList *list; | |
2223 gint row; | |
2224 gint new_row = -1; | |
2225 | |
138 | 2226 row = g_list_index(vfl->list, fd); |
9 | 2227 if (row < 0) return FALSE; |
2228 | |
2229 if (vflist_index_is_selected(vfl, row) && | |
2230 layout_image_get_collection(vfl->layout, NULL) == NULL) | |
2231 { | |
2232 gint n; | |
2233 | |
2234 n = vflist_count(vfl, NULL); | |
2235 if (ignore_list) | |
2236 { | |
2237 new_row = vflist_maint_find_closest(vfl, row, n, ignore_list); | |
2238 if (debug) printf("row = %d, closest is %d\n", row, new_row); | |
2239 } | |
2240 else | |
2241 { | |
2242 if (row + 1 < n) | |
2243 { | |
2244 new_row = row + 1; | |
2245 } | |
2246 else if (row > 0) | |
2247 { | |
2248 new_row = row - 1; | |
2249 } | |
2250 } | |
2251 vflist_select_none(vfl); | |
2252 if (new_row >= 0) | |
2253 { | |
2254 fd = vflist_index_get_data(vfl, new_row); | |
2255 if (vflist_find_row(vfl, fd, &iter) >= 0) | |
2256 { | |
2257 GtkTreeSelection *selection; | |
2258 | |
2259 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); | |
2260 gtk_tree_selection_select_iter(selection, &iter); | |
2261 vflist_move_cursor(vfl, &iter); | |
2262 } | |
2263 } | |
2264 } | |
2265 | |
2266 fd = vflist_index_get_data(vfl, row); | |
2267 if (vflist_find_row(vfl, fd, &iter) >= 0) | |
2268 { | |
142
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
2269 GtkTreeStore *store; |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
2270 store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview))); |
b5aa95241859
display sidecar files (jpeg + raw) using gtk_tree_store
nadvornik
parents:
139
diff
changeset
|
2271 gtk_tree_store_remove(store, &iter); |
9 | 2272 } |
2273 list = g_list_nth(vfl->list, row); | |
2274 fd = list->data; | |
2275 | |
2276 /* thumbnail loader check */ | |
2277 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
|
2278 if (vfl->thumbs_count > 0) vfl->thumbs_count--; |
9 | 2279 |
2280 vfl->list = g_list_remove(vfl->list, fd); | |
138 | 2281 file_data_unref(fd); |
9 | 2282 |
2283 vflist_send_update(vfl); | |
2284 | |
2285 return TRUE; | |
2286 } | |
2287 | |
138 | 2288 gint vflist_maint_moved(ViewFileList *vfl, FileData *fd, GList *ignore_list) |
9 | 2289 { |
2290 gint ret = FALSE; | |
2291 gchar *buf; | |
2292 | |
138 | 2293 if (!fd->change->source || !vfl->path) return FALSE; |
9 | 2294 |
138 | 2295 buf = remove_level_from_path(fd->change->source); |
9 | 2296 |
2297 if (strcmp(buf, vfl->path) == 0) | |
2298 { | |
138 | 2299 ret = vflist_maint_removed(vfl, fd, ignore_list); |
9 | 2300 } |
2301 | |
2302 g_free(buf); | |
2303 | |
2304 return ret; | |
2305 } | |
2306 |