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