Add a way to invert the current selection.
[geeqie.git] / src / view_file.c
1 /*
2  * Geeqie
3  * Copyright (C) 2008 The Geeqie Team
4  *
5  * Author: Laurent Monin
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 "main.h"
13 #include "view_file.h"
14
15 #include "debug.h"
16 #include "view_file_list.h"
17 #include "view_file_icon.h"
18
19
20 /*
21  *-----------------------------------------------------------------------------
22  * misc
23  *-----------------------------------------------------------------------------
24  */
25
26 void vf_sort_set(ViewFile *vf, SortType type, gint ascend)
27 {
28         switch(vf->type)
29         {
30         case FILEVIEW_LIST: vflist_sort_set(vf, type, ascend); break;
31         case FILEVIEW_ICON: vficon_sort_set(vf, type, ascend); break;
32         }
33 }
34
35 /*
36  *-----------------------------------------------------------------------------
37  * row stuff
38  *-----------------------------------------------------------------------------
39  */
40
41 FileData *vf_index_get_data(ViewFile *vf, gint row)
42 {
43         FileData *fd = NULL;
44
45         switch(vf->type)
46         {
47         case FILEVIEW_LIST: fd = vflist_index_get_data(vf, row); break;
48         case FILEVIEW_ICON: fd = vficon_index_get_data(vf, row); break;
49         }
50
51         return fd;
52 }
53
54 gchar *vf_index_get_path(ViewFile *vf, gint row)
55 {
56         gchar *path = NULL;
57         
58         switch(vf->type)
59         {
60         case FILEVIEW_LIST: path = vflist_index_get_path(vf, row); break;
61         case FILEVIEW_ICON: path = vficon_index_get_path(vf, row); break;
62         }
63
64         return path;
65 }
66
67 gint vf_index_by_path(ViewFile *vf, const gchar *path)
68 {
69         gint index = -1;
70
71         switch(vf->type)
72         {
73         case FILEVIEW_LIST: index = vflist_index_by_path(vf, path); break;
74         case FILEVIEW_ICON: index = vficon_index_by_path(vf, path); break;
75         }
76
77         return index;
78 }
79
80 gint vf_count(ViewFile *vf, gint64 *bytes)
81 {
82         gint count = 0;
83
84         switch(vf->type)
85         {
86         case FILEVIEW_LIST: count = vflist_count(vf, bytes); break;
87         case FILEVIEW_ICON: count = vficon_count(vf, bytes); break;
88         }
89
90         return count;
91 }
92
93 GList *vf_get_list(ViewFile *vf)
94 {
95         GList *list = NULL;
96
97         switch(vf->type)
98         {
99         case FILEVIEW_LIST: list = vflist_get_list(vf); break;
100         case FILEVIEW_ICON: list = vficon_get_list(vf); break;
101         }
102
103         return list;
104 }
105
106
107 /*
108  *-------------------------------------------------------------------
109  * keyboard
110  *-------------------------------------------------------------------
111  */
112
113 static gint vf_press_key_cb(GtkWidget *widget, GdkEventKey *event, gpointer data)
114 {
115         ViewFile *vf = data;
116         gint ret = FALSE;
117
118         switch(vf->type)
119         {
120         case FILEVIEW_LIST: ret = vflist_press_key_cb(widget, event, data); break;
121         case FILEVIEW_ICON: ret = vficon_press_key_cb(widget, event, data); break;
122         }
123
124         return ret;
125 }
126
127 /*
128  *-------------------------------------------------------------------
129  * mouse
130  *-------------------------------------------------------------------
131  */
132
133 static gint vf_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data)
134 {
135         ViewFile *vf = data;
136         gint ret = FALSE;
137
138         switch(vf->type)
139         {
140         case FILEVIEW_LIST: ret = vflist_press_cb(widget, bevent, data); break;
141         case FILEVIEW_ICON: ret = vficon_press_cb(widget, bevent, data); break;
142         }
143
144         return ret;
145 }
146
147 static gint vf_release_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data)
148 {
149         ViewFile *vf = data;
150         gint ret = FALSE;
151
152         switch(vf->type)
153         {
154         case FILEVIEW_LIST: ret = vflist_release_cb(widget, bevent, data); break;
155         case FILEVIEW_ICON: ret = vficon_release_cb(widget, bevent, data); break;
156         }
157
158         return ret;
159 }
160
161
162 /*
163  *-----------------------------------------------------------------------------
164  * selections
165  *-----------------------------------------------------------------------------
166  */
167
168 gint vf_selection_count(ViewFile *vf, gint64 *bytes)
169 {
170         gint count = 0;
171
172         switch(vf->type)
173         {
174         case FILEVIEW_LIST: count = vflist_selection_count(vf, bytes); break;
175         case FILEVIEW_ICON: count = vficon_selection_count(vf, bytes); break;
176         }
177
178         return count;
179 }
180
181 GList *vf_selection_get_list(ViewFile *vf)
182 {
183         GList *list = NULL;
184
185         switch(vf->type)
186         {
187         case FILEVIEW_LIST: list = vflist_selection_get_list(vf); break;
188         case FILEVIEW_ICON: list = vficon_selection_get_list(vf); break;
189         }
190
191         return list;
192 }
193
194 GList *vf_selection_get_list_by_index(ViewFile *vf)
195 {
196         GList *list = NULL;
197
198         switch(vf->type)
199         {
200         case FILEVIEW_LIST: list = vflist_selection_get_list_by_index(vf); break;
201         case FILEVIEW_ICON: list = vficon_selection_get_list_by_index(vf); break;
202         }
203
204         return list;
205 }
206
207 void vf_select_all(ViewFile *vf)
208 {
209         switch(vf->type)
210         {
211         case FILEVIEW_LIST: vflist_select_all(vf); break;
212         case FILEVIEW_ICON: vficon_select_all(vf); break;
213         }
214 }
215
216 void vf_select_none(ViewFile *vf)
217 {
218         switch(vf->type)
219         {
220         case FILEVIEW_LIST: vflist_select_none(vf); break;
221         case FILEVIEW_ICON: vficon_select_none(vf); break;
222         }
223 }
224
225 void vf_select_invert(ViewFile *vf)
226 {
227         switch(vf->type)
228         {
229         case FILEVIEW_LIST: vflist_select_invert(vf); break;
230         case FILEVIEW_ICON: vficon_select_invert(vf); break;
231         }
232 }
233
234 void vf_select_by_fd(ViewFile *vf, FileData *fd)
235 {
236         switch(vf->type)
237         {
238         case FILEVIEW_LIST: vflist_select_by_fd(vf, fd); break;
239         case FILEVIEW_ICON: vficon_select_by_fd(vf, fd); break;
240         }
241 }
242
243 void vf_mark_to_selection(ViewFile *vf, gint mark, MarkToSelectionMode mode)
244 {
245         switch(vf->type)
246         {
247         case FILEVIEW_LIST: vflist_mark_to_selection(vf, mark, mode); break;
248         case FILEVIEW_ICON: vficon_mark_to_selection(vf, mark, mode); break;
249         }
250 }
251
252 void vf_selection_to_mark(ViewFile *vf, gint mark, SelectionToMarkMode mode)
253 {
254         switch(vf->type)
255         {
256         case FILEVIEW_LIST: vflist_selection_to_mark(vf, mark, mode); break;
257         case FILEVIEW_ICON: vficon_selection_to_mark(vf, mark, mode); break;
258         }
259 }
260
261 /*
262  *-----------------------------------------------------------------------------
263  * dnd
264  *-----------------------------------------------------------------------------
265  */
266
267
268 static void vf_dnd_init(ViewFile *vf)
269 {
270         switch(vf->type)
271         {
272         case FILEVIEW_LIST: vflist_dnd_init(vf); break;
273         case FILEVIEW_ICON: vficon_dnd_init(vf); break;
274         }
275 }
276
277 gint vf_refresh(ViewFile *vf)
278 {
279         gint ret = FALSE;
280
281         switch(vf->type)
282         {
283         case FILEVIEW_LIST: ret = vflist_refresh(vf); break;
284         case FILEVIEW_ICON: ret = vficon_refresh(vf); break;
285         }
286
287         return ret;
288 }
289
290 gint vf_set_path(ViewFile *vf, const gchar *path)
291 {
292         gint ret = FALSE;
293
294         switch(vf->type)
295         {
296         case FILEVIEW_LIST: ret = vflist_set_path(vf, path); break;
297         case FILEVIEW_ICON: ret = vficon_set_path(vf, path); break;
298         }
299         
300         return ret;
301 }
302
303 static void vf_destroy_cb(GtkWidget *widget, gpointer data)
304 {
305         ViewFile *vf = data;
306
307         switch(vf->type)
308         {
309         case FILEVIEW_LIST: vflist_destroy_cb(widget, data); break;
310         case FILEVIEW_ICON: vficon_destroy_cb(widget, data); break;
311         }
312
313         if (vf->popup)
314                 {
315                 g_signal_handlers_disconnect_matched(G_OBJECT(vf->popup), G_SIGNAL_MATCH_DATA,
316                                                      0, 0, 0, NULL, vf);
317                 gtk_widget_destroy(vf->popup);
318                 }
319
320         g_free(vf->path);
321         g_free(vf->info);
322         g_free(vf);
323 }
324
325 ViewFile *vf_new(FileViewType type, const gchar *path)
326 {
327         ViewFile *vf;
328
329         vf = g_new0(ViewFile, 1);
330         vf->type = type;
331
332         vf->info = NULL;
333         vf->path = NULL;
334         vf->list = NULL;
335
336         vf->sort_method = SORT_NAME;
337         vf->sort_ascend = TRUE;
338         
339         vf->thumbs_running = FALSE;
340         vf->thumbs_count = 0;
341         vf->thumbs_loader = NULL;
342         vf->thumbs_filedata = NULL;
343
344         vf->popup = NULL;
345
346         vf->widget = gtk_scrolled_window_new(NULL, NULL);
347         gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(vf->widget), GTK_SHADOW_IN);
348         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(vf->widget),
349                                        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
350         
351         g_signal_connect(G_OBJECT(vf->widget), "destroy",
352                          G_CALLBACK(vf_destroy_cb), vf);
353
354         switch(type)
355         {
356         case FILEVIEW_LIST: vf = vflist_new(vf, path); break;
357         case FILEVIEW_ICON: vf = vficon_new(vf, path); break;
358         }
359
360         vf_dnd_init(vf);
361
362         g_signal_connect(G_OBJECT(vf->listview), "key_press_event",
363                          G_CALLBACK(vf_press_key_cb), vf);
364         g_signal_connect(G_OBJECT(vf->listview), "button_press_event",
365                          G_CALLBACK(vf_press_cb), vf);
366         g_signal_connect(G_OBJECT(vf->listview), "button_release_event",
367                          G_CALLBACK(vf_release_cb), vf);
368
369         gtk_container_add(GTK_CONTAINER(vf->widget), vf->listview);
370         gtk_widget_show(vf->listview);
371
372         if (path) vf_set_path(vf, path);
373
374         return vf;
375 }
376
377 void vf_set_status_func(ViewFile *vf, void (*func)(ViewFile *vf, gpointer data), gpointer data)
378 {
379         vf->func_status = func;
380         vf->data_status = data;
381 }
382
383 void vf_set_thumb_status_func(ViewFile *vf, void (*func)(ViewFile *vf, gdouble val, const gchar *text, gpointer data), gpointer data)
384 {
385         vf->func_thumb_status = func;
386         vf->data_thumb_status = data;
387 }
388
389 void vf_thumb_set(ViewFile *vf, gint enable)
390 {
391         switch(vf->type)
392         {
393         case FILEVIEW_LIST: vflist_thumb_set(vf, enable); break;
394         case FILEVIEW_ICON: /*vficon_thumb_set(vf, enable);*/ break;
395         }
396 }
397
398 void vf_marks_set(ViewFile *vf, gint enable)
399 {
400         switch(vf->type)
401         {
402         case FILEVIEW_LIST: vflist_marks_set(vf, enable); break;
403         case FILEVIEW_ICON: /*vficon_marks_set(vf, enable);*/ break;
404         }
405 }
406
407 void vf_set_layout(ViewFile *vf, LayoutWindow *layout)
408 {
409         vf->layout = layout;
410 }
411
412 /*
413  *-----------------------------------------------------------------------------
414  * maintenance (for rename, move, remove)
415  *-----------------------------------------------------------------------------
416  */
417
418 gint vf_maint_renamed(ViewFile *vf, FileData *fd)
419 {
420         gint ret = FALSE;
421
422         switch(vf->type)
423         {
424         case FILEVIEW_LIST: ret = vflist_maint_renamed(vf, fd); break;
425         case FILEVIEW_ICON: ret = vficon_maint_renamed(vf, fd); break;
426         }
427
428         return ret;
429 }
430
431 gint vf_maint_removed(ViewFile *vf, FileData *fd, GList *ignore_list)
432 {
433         gint ret = FALSE;
434
435         switch(vf->type)
436         {
437         case FILEVIEW_LIST: ret = vflist_maint_removed(vf, fd, ignore_list); break;
438         case FILEVIEW_ICON: ret = vficon_maint_removed(vf, fd, ignore_list); break;
439         }
440
441         return ret;
442 }
443
444 gint vf_maint_moved(ViewFile *vf, FileData *fd, GList *ignore_list)
445 {
446         gint ret = FALSE;
447
448         switch(vf->type)
449         {
450         case FILEVIEW_LIST: ret = vflist_maint_moved(vf, fd, ignore_list); break;
451         case FILEVIEW_ICON: ret = vficon_maint_moved(vf, fd, ignore_list); break;
452         }
453
454         return ret;
455 }