Mercurial > geeqie
annotate src/collect.c @ 1503:331e2d60d447
improved next/prev operation on sidecar files
all operations with list index seem to be broken but IMHO this fix is
sufficient for 1.0. Then it definitely needs a better interface.
author | nadvornik |
---|---|
date | Tue, 31 Mar 2009 21:33:54 +0000 |
parents | 5f49f305a6b6 |
children | 760f585d9fa0 |
rev | line source |
---|---|
9 | 1 /* |
196 | 2 * Geeqie |
94
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
3 * (C) 2006 John Ellis |
1284 | 4 * Copyright (C) 2008 - 2009 The Geeqie Team |
9 | 5 * |
6 * Author: John Ellis | |
7 * | |
8 * This software is released under the GNU General Public License (GNU GPL). | |
9 * Please read the included file COPYING for more information. | |
10 * This software comes with no warranty of any kind, use at your own risk! | |
11 */ | |
12 | |
13 | |
281 | 14 #include "main.h" |
9 | 15 #include "collect.h" |
16 | |
17 #include "collect-dlg.h" | |
18 #include "collect-io.h" | |
19 #include "collect-table.h" | |
20 #include "editors.h" | |
586 | 21 #include "filedata.h" |
9 | 22 #include "img-view.h" |
23 #include "layout.h" | |
24 #include "layout_image.h" | |
1022
9962b24b6b43
Move miscellaneous functions to their own files (new misc.[ch]).
zas_
parents:
816
diff
changeset
|
25 #include "misc.h" |
91
d063f97503b7
Wed Nov 1 11:39:48 2006 John Ellis <johne@verizon.net>
gqview
parents:
85
diff
changeset
|
26 #include "pixbuf_util.h" |
94
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
27 #include "print.h" |
9 | 28 #include "ui_fileops.h" |
29 #include "ui_tree_edit.h" | |
1022
9962b24b6b43
Move miscellaneous functions to their own files (new misc.[ch]).
zas_
parents:
816
diff
changeset
|
30 #include "utilops.h" |
648
e34c1002e553
Move some functions from main.[ch] to new window.[ch].
zas_
parents:
586
diff
changeset
|
31 #include "window.h" |
9 | 32 |
33 #include <gdk/gdkkeysyms.h> /* for keyboard values */ | |
34 | |
35 | |
36 #define COLLECT_DEF_WIDTH 440 | |
37 #define COLLECT_DEF_HEIGHT 450 | |
38 | |
39 static GList *collection_list = NULL; | |
40 static GList *collection_window_list = NULL; | |
41 | |
42 static void collection_window_get_geometry(CollectWindow *cw); | |
43 static void collection_window_refresh(CollectWindow *cw); | |
44 static void collection_window_update_title(CollectWindow *cw); | |
45 static void collection_window_add(CollectWindow *cw, CollectInfo *ci); | |
46 static void collection_window_insert(CollectWindow *cw, CollectInfo *ci); | |
47 static void collection_window_remove(CollectWindow *cw, CollectInfo *ci); | |
48 static void collection_window_update(CollectWindow *cw, CollectInfo *ci); | |
49 | |
50 static void collection_window_close(CollectWindow *cw); | |
51 | |
799 | 52 static void collection_notify_cb(FileData *fd, NotifyType type, gpointer data); |
53 | |
9 | 54 /* |
55 *------------------------------------------------------------------- | |
56 * data, list handling | |
57 *------------------------------------------------------------------- | |
58 */ | |
59 | |
138 | 60 CollectInfo *collection_info_new(FileData *fd, struct stat *st, GdkPixbuf *pixbuf) |
9 | 61 { |
62 CollectInfo *ci; | |
63 | |
138 | 64 if (!fd) return NULL; |
9 | 65 |
66 ci = g_new0(CollectInfo, 1); | |
138 | 67 ci->fd = file_data_ref(fd); |
9 | 68 |
69 ci->pixbuf = pixbuf; | |
70 if (ci->pixbuf) g_object_ref(ci->pixbuf); | |
71 | |
72 return ci; | |
73 } | |
74 | |
75 void collection_info_free_thumb(CollectInfo *ci) | |
76 { | |
77 if (ci->pixbuf) g_object_unref(ci->pixbuf); | |
78 ci->pixbuf = NULL; | |
79 } | |
80 | |
81 void collection_info_free(CollectInfo *ci) | |
82 { | |
83 if (!ci) return; | |
84 | |
138 | 85 file_data_unref(ci->fd); |
9 | 86 collection_info_free_thumb(ci); |
87 g_free(ci); | |
88 } | |
89 | |
90 void collection_info_set_thumb(CollectInfo *ci, GdkPixbuf *pixbuf) | |
91 { | |
92 if (pixbuf) g_object_ref(pixbuf); | |
93 collection_info_free_thumb(ci); | |
94 ci->pixbuf = pixbuf; | |
95 } | |
96 | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
97 gboolean collection_info_load_thumb(CollectInfo *ci) |
9 | 98 { |
99 if (!ci) return FALSE; | |
100 | |
101 collection_info_free_thumb(ci); | |
102 | |
673
fbebf5cf4a55
Do not use printf() directly but use new wrapper function log_printf() instead.
zas_
parents:
671
diff
changeset
|
103 log_printf("collection_info_load_thumb not implemented!\n(because an instant thumb loader not implemented)"); |
9 | 104 return FALSE; |
442 | 105 #if 0 |
138 | 106 if (create_thumbnail(ci->fd->path, &ci->pixmap, &ci->mask) < 0) return FALSE; |
9 | 107 |
108 if (ci->pixmap) gdk_pixmap_ref(ci->pixmap); | |
109 if (ci->mask) gdk_bitmap_ref(ci->mask); | |
110 | |
111 return TRUE; | |
112 #endif | |
113 } | |
114 | |
115 void collection_list_free(GList *list) | |
116 { | |
117 GList *work; | |
118 work = list; | |
516 | 119 while (work) |
9 | 120 { |
121 collection_info_free((CollectInfo *)work->data); | |
122 work = work->next; | |
123 } | |
124 g_list_free(list); | |
125 } | |
126 | |
127 /* an ugly static var, well what ya gonna do ? */ | |
128 static SortType collection_list_sort_method = SORT_NAME; | |
129 | |
130 static gint collection_list_sort_cb(gconstpointer a, gconstpointer b) | |
131 { | |
132 const CollectInfo *cia = a; | |
133 const CollectInfo *cib = b; | |
134 | |
1347
79937bc55f3a
Add missing space between switch and first parenthesis.
zas_
parents:
1292
diff
changeset
|
135 switch (collection_list_sort_method) |
9 | 136 { |
785 | 137 case SORT_NAME: |
138 break; | |
9 | 139 case SORT_NONE: |
140 return 0; | |
141 break; | |
142 case SORT_SIZE: | |
138 | 143 if (cia->fd->size < cib->fd->size) return -1; |
144 if (cia->fd->size > cib->fd->size) return 1; | |
9 | 145 return 0; |
146 break; | |
147 case SORT_TIME: | |
138 | 148 if (cia->fd->date < cib->fd->date) return -1; |
149 if (cia->fd->date > cib->fd->date) return 1; | |
9 | 150 return 0; |
151 break; | |
152 case SORT_PATH: | |
786
a20ff446347e
Compare paths using utf8_collate_key() since paths are utf8-encoded.
zas_
parents:
785
diff
changeset
|
153 return utf8_compare(cia->fd->path, cib->fd->path, options->file_sort.case_sensitive); |
9 | 154 break; |
155 #ifdef HAVE_STRVERSCMP | |
156 case SORT_NUMBER: | |
138 | 157 return strverscmp(cia->fd->name, cib->fd->name); |
9 | 158 break; |
159 #endif | |
160 default: | |
161 break; | |
162 } | |
163 | |
785 | 164 if (options->file_sort.case_sensitive) |
165 return strcmp(cia->fd->collate_key_name, cib->fd->collate_key_name); | |
166 else | |
167 return strcmp(cia->fd->collate_key_name_nocase, cib->fd->collate_key_name_nocase); | |
9 | 168 } |
169 | |
170 GList *collection_list_sort(GList *list, SortType method) | |
171 { | |
172 if (method == SORT_NONE) return list; | |
173 | |
174 collection_list_sort_method = method; | |
175 | |
176 return g_list_sort(list, collection_list_sort_cb); | |
177 } | |
178 | |
179 GList *collection_list_add(GList *list, CollectInfo *ci, SortType method) | |
180 { | |
181 if (method != SORT_NONE) | |
182 { | |
183 collection_list_sort_method = method; | |
184 list = g_list_insert_sorted(list, ci, collection_list_sort_cb); | |
185 } | |
186 else | |
187 { | |
188 list = g_list_append(list, ci); | |
189 } | |
190 | |
191 return list; | |
192 } | |
193 | |
194 GList *collection_list_insert(GList *list, CollectInfo *ci, CollectInfo *insert_ci, SortType method) | |
195 { | |
196 if (method != SORT_NONE) | |
197 { | |
198 collection_list_sort_method = method; | |
199 list = g_list_insert_sorted(list, ci, collection_list_sort_cb); | |
200 } | |
201 else | |
202 { | |
203 GList *point; | |
204 | |
205 point = g_list_find(list, insert_ci); | |
206 list = uig_list_insert_link(list, point, ci); | |
207 } | |
208 | |
209 return list; | |
210 } | |
211 | |
212 GList *collection_list_remove(GList *list, CollectInfo *ci) | |
213 { | |
214 list = g_list_remove(list, ci); | |
215 collection_info_free(ci); | |
216 return list; | |
217 } | |
218 | |
799 | 219 CollectInfo *collection_list_find_fd(GList *list, FileData *fd) |
9 | 220 { |
221 GList *work = list; | |
222 | |
516 | 223 while (work) |
9 | 224 { |
225 CollectInfo *ci = work->data; | |
799 | 226 if (ci->fd == fd) return ci; |
9 | 227 work = work->next; |
228 } | |
229 | |
230 return NULL; | |
231 } | |
232 | |
233 #if 0 | |
234 static GList *collection_list_find_link(GList *list, gchar *path) | |
235 { | |
236 GList *work = list; | |
237 | |
516 | 238 while (work) |
9 | 239 { |
240 CollectInfo *ci = work->data; | |
138 | 241 if (strcmp(ci->fd->path, path) == 0) return work; |
9 | 242 work = work->next; |
243 } | |
244 | |
245 return NULL; | |
246 } | |
247 | |
248 static gint collection_list_find_index(GList *list, gchar *path) | |
249 { | |
250 gint c = 0; | |
251 GList *work = list; | |
252 | |
516 | 253 while (work) |
9 | 254 { |
255 CollectInfo *ci = work->data; | |
138 | 256 if (strcmp(ci->fd->path, path) == 0) return c; |
9 | 257 work = work->next; |
258 c++; | |
259 } | |
260 | |
261 return -1; | |
262 } | |
263 #endif | |
264 | |
138 | 265 GList *collection_list_to_filelist(GList *list) |
9 | 266 { |
138 | 267 GList *filelist = NULL; |
9 | 268 GList *work = list; |
269 | |
270 while (work) | |
271 { | |
272 CollectInfo *info = work->data; | |
138 | 273 filelist = g_list_prepend(filelist, file_data_ref(info->fd)); |
9 | 274 work = work->next; |
275 } | |
276 | |
138 | 277 filelist = g_list_reverse(filelist); |
278 return filelist; | |
9 | 279 } |
280 | |
281 CollectWindow *collection_window_find(CollectionData *cd) | |
282 { | |
283 GList *work; | |
284 | |
285 work = collection_window_list; | |
286 while (work) | |
287 { | |
288 CollectWindow *cw = work->data; | |
289 if (cw->cd == cd) return cw; | |
290 work = work->next; | |
291 } | |
292 | |
293 return NULL; | |
294 } | |
295 | |
296 CollectWindow *collection_window_find_by_path(const gchar *path) | |
297 { | |
298 GList *work; | |
299 | |
300 if (!path) return NULL; | |
301 | |
302 work = collection_window_list; | |
303 while (work) | |
304 { | |
305 CollectWindow *cw = work->data; | |
306 if (cw->cd->path && strcmp(cw->cd->path, path) == 0) return cw; | |
307 work = work->next; | |
308 } | |
309 | |
310 return NULL; | |
311 } | |
312 | |
313 /* | |
314 *------------------------------------------------------------------- | |
315 * please use these to actually add/remove stuff | |
316 *------------------------------------------------------------------- | |
317 */ | |
318 | |
319 CollectionData *collection_new(const gchar *path) | |
320 { | |
321 CollectionData *cd; | |
322 static gint untitled_counter = 0; | |
323 | |
324 cd = g_new0(CollectionData, 1); | |
325 | |
326 cd->ref = 1; /* starts with a ref of 1 */ | |
327 cd->sort_method = SORT_NONE; | |
328 cd->window_w = COLLECT_DEF_WIDTH; | |
329 cd->window_h = COLLECT_DEF_HEIGHT; | |
303
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
330 cd->existence = g_hash_table_new(NULL, NULL); |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
331 |
9 | 332 if (path) |
333 { | |
334 cd->path = g_strdup(path); | |
335 cd->name = g_strdup(filename_from_path(cd->path)); | |
336 /* load it */ | |
337 } | |
338 else | |
339 { | |
340 if (untitled_counter == 0) | |
341 { | |
342 cd->name = g_strdup(_("Untitled")); | |
343 } | |
344 else | |
345 { | |
346 cd->name = g_strdup_printf(_("Untitled (%d)"), untitled_counter + 1); | |
347 } | |
348 | |
349 untitled_counter++; | |
350 } | |
351 | |
799 | 352 file_data_register_notify_func(collection_notify_cb, cd, NOTIFY_PRIORITY_MEDIUM); |
353 | |
1367
fe4da037be21
When g_new0() is used, drop redundant initializations to NULL, FALSE or 0, second pass.
zas_
parents:
1347
diff
changeset
|
354 |
fe4da037be21
When g_new0() is used, drop redundant initializations to NULL, FALSE or 0, second pass.
zas_
parents:
1347
diff
changeset
|
355 collection_list = g_list_append(collection_list, cd); |
fe4da037be21
When g_new0() is used, drop redundant initializations to NULL, FALSE or 0, second pass.
zas_
parents:
1347
diff
changeset
|
356 |
9 | 357 return cd; |
358 } | |
359 | |
360 void collection_free(CollectionData *cd) | |
361 { | |
362 if (!cd) return; | |
363 | |
506
fc9c8a3e1a8b
Handle the newline in DEBUG_N() macro instead of adding one
zas_
parents:
495
diff
changeset
|
364 DEBUG_1("collection \"%s\" freed", cd->name); |
9 | 365 |
366 collection_load_stop(cd); | |
367 collection_list_free(cd->list); | |
799 | 368 |
369 file_data_unregister_notify_func(collection_notify_cb, cd); | |
9 | 370 |
371 collection_list = g_list_remove(collection_list, cd); | |
372 | |
303
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
373 g_hash_table_destroy(cd->existence); |
442 | 374 |
9 | 375 g_free(cd->path); |
376 g_free(cd->name); | |
377 | |
378 g_free(cd); | |
379 } | |
380 | |
381 void collection_ref(CollectionData *cd) | |
382 { | |
383 cd->ref++; | |
384 | |
506
fc9c8a3e1a8b
Handle the newline in DEBUG_N() macro instead of adding one
zas_
parents:
495
diff
changeset
|
385 DEBUG_1("collection \"%s\" ref count = %d", cd->name, cd->ref); |
9 | 386 } |
387 | |
388 void collection_unref(CollectionData *cd) | |
389 { | |
390 cd->ref--; | |
391 | |
506
fc9c8a3e1a8b
Handle the newline in DEBUG_N() macro instead of adding one
zas_
parents:
495
diff
changeset
|
392 DEBUG_1("collection \"%s\" ref count = %d", cd->name, cd->ref); |
9 | 393 |
394 if (cd->ref < 1) | |
395 { | |
396 collection_free(cd); | |
397 } | |
398 } | |
399 | |
400 void collection_path_changed(CollectionData *cd) | |
401 { | |
402 collection_window_update_title(collection_window_find(cd)); | |
403 } | |
404 | |
405 gint collection_to_number(CollectionData *cd) | |
406 { | |
407 return g_list_index(collection_list, cd); | |
408 } | |
409 | |
410 CollectionData *collection_from_number(gint n) | |
411 { | |
412 return g_list_nth_data(collection_list, n); | |
413 } | |
414 | |
415 CollectionData *collection_from_dnd_data(const gchar *data, GList **list, GList **info_list) | |
416 { | |
417 CollectionData *cd; | |
816 | 418 gint collection_number; |
419 const gchar *ptr; | |
420 | |
421 if (list) *list = NULL; | |
422 if (info_list) *info_list = NULL; | |
9 | 423 |
424 if (strncmp(data, "COLLECTION:", 11) != 0) return NULL; | |
816 | 425 |
426 ptr = data + 11; | |
427 | |
428 collection_number = atoi(ptr); | |
429 cd = collection_from_number(collection_number); | |
430 if (!cd) return NULL; | |
9 | 431 |
816 | 432 if (!list && !info_list) return cd; |
433 | |
434 while (*ptr != '\0' && *ptr != '\n' ) ptr++; | |
435 if (*ptr == '\0') return cd; | |
436 ptr++; | |
9 | 437 |
816 | 438 while (*ptr != '\0') |
439 { | |
440 guint item_number; | |
441 CollectInfo *info; | |
442 | |
443 item_number = (guint) atoi(ptr); | |
444 while (*ptr != '\n' && *ptr != '\0') ptr++; | |
445 if (*ptr == '\0') | |
446 break; | |
447 else | |
448 while (*ptr == '\n') ptr++; | |
9 | 449 |
816 | 450 info = g_list_nth_data(cd->list, item_number); |
451 if (!info) continue; | |
9 | 452 |
816 | 453 if (list) *list = g_list_append(*list, file_data_ref(info->fd)); |
454 if (info_list) *info_list = g_list_append(*info_list, info); | |
9 | 455 } |
816 | 456 |
9 | 457 return cd; |
458 } | |
459 | |
460 gchar *collection_info_list_to_dnd_data(CollectionData *cd, GList *list, gint *length) | |
461 { | |
462 GList *work; | |
815
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
463 GList *temp = NULL; |
9 | 464 gchar *ptr; |
815
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
465 gchar *text; |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
466 gchar *uri_text; |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
467 gint collection_number; |
9 | 468 |
815
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
469 *length = 0; |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
470 if (!list) return NULL; |
9 | 471 |
815
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
472 collection_number = collection_to_number(cd); |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
473 if (collection_number < 0) return NULL; |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
474 |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
475 text = g_strdup_printf("COLLECTION:%d\n", collection_number); |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
476 *length += strlen(text); |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
477 temp = g_list_prepend(temp, text); |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
478 |
9 | 479 work = list; |
516 | 480 while (work) |
9 | 481 { |
815
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
482 gint item_number = g_list_index(cd->list, work->data); |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
483 |
9 | 484 work = work->next; |
815
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
485 |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
486 if (item_number < 0) continue; |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
487 |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
488 text = g_strdup_printf("%d\n", item_number); |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
489 temp = g_list_prepend(temp, text); |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
490 *length += strlen(text); |
9 | 491 } |
492 | |
815
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
493 *length += 1; /* ending nul char */ |
9 | 494 |
815
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
495 uri_text = g_malloc(*length); |
9 | 496 ptr = uri_text; |
497 | |
498 work = g_list_last(temp); | |
516 | 499 while (work) |
9 | 500 { |
815
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
501 gint len; |
9 | 502 gchar *text = work->data; |
503 | |
504 work = work->prev; | |
505 | |
815
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
506 len = strlen(text); |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
507 memcpy(ptr, text, len); |
7daea970a89a
collection_info_list_to_dnd_data(): simplify and optimize.
zas_
parents:
803
diff
changeset
|
508 ptr += len; |
9 | 509 } |
510 | |
511 ptr[0] = '\0'; | |
512 | |
138 | 513 string_list_free(temp); |
9 | 514 |
515 return uri_text; | |
516 } | |
517 | |
518 gint collection_info_valid(CollectionData *cd, CollectInfo *info) | |
519 { | |
520 if (collection_to_number(cd) < 0) return FALSE; | |
521 | |
522 return (g_list_index(cd->list, info) != 0); | |
523 } | |
524 | |
525 CollectInfo *collection_next_by_info(CollectionData *cd, CollectInfo *info) | |
526 { | |
527 GList *work; | |
528 | |
529 work = g_list_find(cd->list, info); | |
530 | |
531 if (!work) return NULL; | |
532 work = work->next; | |
533 if (work) return work->data; | |
534 return NULL; | |
535 } | |
536 | |
537 CollectInfo *collection_prev_by_info(CollectionData *cd, CollectInfo *info) | |
538 { | |
539 GList *work; | |
540 | |
541 work = g_list_find(cd->list, info); | |
542 | |
543 if (!work) return NULL; | |
544 work = work->prev; | |
545 if (work) return work->data; | |
546 return NULL; | |
547 } | |
548 | |
549 CollectInfo *collection_get_first(CollectionData *cd) | |
550 { | |
551 if (cd->list) return cd->list->data; | |
552 | |
553 return NULL; | |
554 } | |
555 | |
556 CollectInfo *collection_get_last(CollectionData *cd) | |
557 { | |
558 GList *list; | |
559 | |
560 list = g_list_last(cd->list); | |
561 | |
562 if (list) return list->data; | |
563 | |
564 return NULL; | |
565 } | |
566 | |
567 void collection_set_sort_method(CollectionData *cd, SortType method) | |
568 { | |
569 if (!cd) return; | |
570 | |
571 if (cd->sort_method == method) return; | |
572 | |
573 cd->sort_method = method; | |
574 cd->list = collection_list_sort(cd->list, cd->sort_method); | |
575 if (cd->list) cd->changed = TRUE; | |
576 | |
577 collection_window_refresh(collection_window_find(cd)); | |
578 } | |
579 | |
580 void collection_set_update_info_func(CollectionData *cd, | |
581 void (*func)(CollectionData *, CollectInfo *, gpointer), gpointer data) | |
582 { | |
583 cd->info_updated_func = func; | |
584 cd->info_updated_data = data; | |
585 } | |
586 | |
303
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
587 static CollectInfo *collection_info_new_if_not_exists(CollectionData *cd, struct stat *st, FileData *fd) |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
588 { |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
589 CollectInfo *ci; |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
590 |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
591 if (g_hash_table_lookup(cd->existence, fd->path)) return NULL; |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
592 |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
593 ci = collection_info_new(fd, st, NULL); |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
594 if (ci) g_hash_table_insert(cd->existence, fd->path, ""); |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
595 return ci; |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
596 } |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
597 |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
598 gboolean collection_add_check(CollectionData *cd, FileData *fd, gboolean sorted, gboolean must_exist) |
9 | 599 { |
600 struct stat st; | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
601 gboolean valid; |
9 | 602 |
603 if (must_exist) | |
604 { | |
138 | 605 valid = (stat_utf8(fd->path, &st) && !S_ISDIR(st.st_mode)); |
9 | 606 } |
607 else | |
608 { | |
609 valid = TRUE; | |
610 st.st_size = 0; | |
611 st.st_mtime = 0; | |
612 } | |
613 | |
614 if (valid) | |
615 { | |
616 CollectInfo *ci; | |
303
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
617 |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
618 ci = collection_info_new_if_not_exists(cd, &st, fd); |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
619 if (!ci) return FALSE; |
506
fc9c8a3e1a8b
Handle the newline in DEBUG_N() macro instead of adding one
zas_
parents:
495
diff
changeset
|
620 DEBUG_3("add to collection: %s", fd->path); |
303
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
621 |
9 | 622 cd->list = collection_list_add(cd->list, ci, sorted ? cd->sort_method : SORT_NONE); |
623 cd->changed = TRUE; | |
624 | |
625 if (!sorted || cd->sort_method == SORT_NONE) | |
626 { | |
627 collection_window_add(collection_window_find(cd), ci); | |
628 } | |
629 else | |
630 { | |
631 collection_window_insert(collection_window_find(cd), ci); | |
632 } | |
633 } | |
634 | |
635 return valid; | |
636 } | |
637 | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
638 gboolean collection_add(CollectionData *cd, FileData *fd, gboolean sorted) |
9 | 639 { |
138 | 640 return collection_add_check(cd, fd, sorted, TRUE); |
9 | 641 } |
642 | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
643 gboolean collection_insert(CollectionData *cd, FileData *fd, CollectInfo *insert_ci, gboolean sorted) |
9 | 644 { |
645 struct stat st; | |
646 | |
138 | 647 if (!insert_ci) return collection_add(cd, fd, sorted); |
9 | 648 |
138 | 649 if (stat_utf8(fd->path, &st) >= 0 && !S_ISDIR(st.st_mode)) |
9 | 650 { |
651 CollectInfo *ci; | |
303
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
652 |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
653 ci = collection_info_new_if_not_exists(cd, &st, fd); |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
654 if (!ci) return FALSE; |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
655 |
506
fc9c8a3e1a8b
Handle the newline in DEBUG_N() macro instead of adding one
zas_
parents:
495
diff
changeset
|
656 DEBUG_3("insert in collection: %s", fd->path); |
303
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
657 |
9 | 658 cd->list = collection_list_insert(cd->list, ci, insert_ci, sorted ? cd->sort_method : SORT_NONE); |
659 cd->changed = TRUE; | |
660 | |
661 collection_window_insert(collection_window_find(cd), ci); | |
662 | |
663 return TRUE; | |
664 } | |
665 | |
666 return FALSE; | |
667 } | |
668 | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
669 gboolean collection_remove(CollectionData *cd, FileData *fd) |
9 | 670 { |
671 CollectInfo *ci; | |
672 | |
799 | 673 ci = collection_list_find_fd(cd->list, fd); |
9 | 674 |
675 if (!ci) return FALSE; | |
676 | |
303
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
677 g_hash_table_remove(cd->existence, fd->path); |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
678 |
9 | 679 cd->list = g_list_remove(cd->list, ci); |
680 cd->changed = TRUE; | |
681 | |
682 collection_window_remove(collection_window_find(cd), ci); | |
683 collection_info_free(ci); | |
684 | |
685 return TRUE; | |
686 } | |
687 | |
688 static void collection_remove_by_info(CollectionData *cd, CollectInfo *info) | |
689 { | |
690 if (!info || !g_list_find(cd->list, info)) return; | |
691 | |
692 cd->list = g_list_remove(cd->list, info); | |
693 cd->changed = (cd->list != NULL); | |
694 | |
695 collection_window_remove(collection_window_find(cd), info); | |
696 collection_info_free(info); | |
697 } | |
698 | |
699 void collection_remove_by_info_list(CollectionData *cd, GList *list) | |
700 { | |
701 GList *work; | |
702 | |
703 if (!list) return; | |
704 | |
705 if (!list->next) | |
706 { | |
707 /* more efficient (in collect-table) to remove a single item this way */ | |
708 collection_remove_by_info(cd, (CollectInfo *)list->data); | |
709 return; | |
710 } | |
711 | |
712 work = list; | |
516 | 713 while (work) |
9 | 714 { |
715 cd->list = collection_list_remove(cd->list, work->data); | |
716 work = work->next; | |
717 } | |
718 cd->changed = (cd->list != NULL); | |
719 | |
720 collection_window_refresh(collection_window_find(cd)); | |
721 } | |
722 | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
723 gboolean collection_rename(CollectionData *cd, FileData *fd) |
9 | 724 { |
725 CollectInfo *ci; | |
799 | 726 ci = collection_list_find_fd(cd->list, fd); |
9 | 727 |
728 if (!ci) return FALSE; | |
729 | |
730 cd->changed = TRUE; | |
731 | |
732 collection_window_update(collection_window_find(cd), ci); | |
733 | |
734 return TRUE; | |
735 } | |
736 | |
737 void collection_update_geometry(CollectionData *cd) | |
738 { | |
739 collection_window_get_geometry(collection_window_find(cd)); | |
740 } | |
741 | |
742 /* | |
743 *------------------------------------------------------------------- | |
744 * simple maintenance for renaming, deleting | |
745 *------------------------------------------------------------------- | |
746 */ | |
747 | |
799 | 748 static void collection_notify_cb(FileData *fd, NotifyType type, gpointer data) |
9 | 749 { |
799 | 750 CollectionData *cd = data; |
9 | 751 |
1432 | 752 if (!(type & NOTIFY_CHANGE) || !fd->change) return; |
1498 | 753 |
754 DEBUG_1("Notify collection: %s %04x", fd->path, type); | |
799 | 755 |
1347
79937bc55f3a
Add missing space between switch and first parenthesis.
zas_
parents:
1292
diff
changeset
|
756 switch (fd->change->type) |
9 | 757 { |
799 | 758 case FILEDATA_CHANGE_MOVE: |
759 case FILEDATA_CHANGE_RENAME: | |
760 collection_rename(cd, fd); | |
761 break; | |
762 case FILEDATA_CHANGE_COPY: | |
763 break; | |
764 case FILEDATA_CHANGE_DELETE: | |
765 while (collection_remove(cd, fd)); | |
766 break; | |
767 case FILEDATA_CHANGE_UNSPECIFIED: | |
1211 | 768 case FILEDATA_CHANGE_WRITE_METADATA: |
799 | 769 break; |
9 | 770 } |
799 | 771 |
9 | 772 } |
773 | |
774 | |
775 /* | |
776 *------------------------------------------------------------------- | |
777 * window key presses | |
778 *------------------------------------------------------------------- | |
779 */ | |
780 | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
781 static gboolean collection_window_keypress(GtkWidget *widget, GdkEventKey *event, gpointer data) |
9 | 782 { |
783 CollectWindow *cw = data; | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
784 gboolean stop_signal = FALSE; |
9 | 785 gint edit_val = -1; |
786 GList *list; | |
787 | |
788 if (event->state & GDK_CONTROL_MASK) | |
789 { | |
85
9d5c75b5ec28
Fri Oct 20 09:20:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
790 stop_signal = TRUE; |
9 | 791 switch (event->keyval) |
792 { | |
793 case '1': | |
794 edit_val = 0; | |
795 break; | |
796 case '2': | |
797 edit_val = 1; | |
798 break; | |
799 case '3': | |
800 edit_val = 2; | |
801 break; | |
802 case '4': | |
803 edit_val = 3; | |
804 break; | |
805 case '5': | |
806 edit_val = 4; | |
807 break; | |
808 case '6': | |
809 edit_val = 5; | |
810 break; | |
811 case '7': | |
812 edit_val = 6; | |
813 break; | |
814 case '8': | |
815 edit_val = 7; | |
816 break; | |
817 case '9': | |
818 edit_val = 8; | |
819 break; | |
820 case '0': | |
821 edit_val = 9; | |
822 break; | |
823 case 'A': case 'a': | |
824 if (event->state & GDK_SHIFT_MASK) | |
825 { | |
826 collection_table_unselect_all(cw->table); | |
827 } | |
828 else | |
829 { | |
830 collection_table_select_all(cw->table); | |
831 } | |
832 break; | |
833 case 'L': case 'l': | |
834 list = layout_list(NULL); | |
835 if (list) | |
836 { | |
138 | 837 collection_table_add_filelist(cw->table, list); |
838 filelist_free(list); | |
9 | 839 } |
840 break; | |
841 case 'C': case 'c': | |
842 file_util_copy(NULL, collection_table_selection_get_list(cw->table), NULL, cw->window); | |
843 break; | |
844 case 'M': case 'm': | |
845 file_util_move(NULL, collection_table_selection_get_list(cw->table), NULL, cw->window); | |
846 break; | |
847 case 'R': case 'r': | |
848 file_util_rename(NULL, collection_table_selection_get_list(cw->table), cw->window); | |
849 break; | |
850 case 'D': case 'd': | |
851 file_util_delete(NULL, collection_table_selection_get_list(cw->table), cw->window); | |
852 break; | |
853 case 'S': case 's': | |
854 collection_dialog_save_as(NULL, cw->cd); | |
855 break; | |
856 case 'W': case 'w': | |
857 collection_window_close(cw); | |
858 break; | |
859 default: | |
85
9d5c75b5ec28
Fri Oct 20 09:20:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
860 stop_signal = FALSE; |
9 | 861 break; |
862 } | |
863 } | |
864 else | |
865 { | |
85
9d5c75b5ec28
Fri Oct 20 09:20:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
866 stop_signal = TRUE; |
9 | 867 switch (event->keyval) |
868 { | |
869 case GDK_Return: case GDK_KP_Enter: | |
870 layout_image_set_collection(NULL, cw->cd, | |
871 collection_table_get_focus_info(cw->table)); | |
872 break; | |
873 case 'V': case 'v': | |
874 view_window_new_from_collection(cw->cd, | |
875 collection_table_get_focus_info(cw->table)); | |
876 break; | |
877 case 'S': case 's': | |
878 if (!cw->cd->path) | |
879 { | |
880 collection_dialog_save_as(NULL, cw->cd); | |
442 | 881 } |
9 | 882 else if (!collection_save(cw->cd, cw->cd->path)) |
883 { | |
673
fbebf5cf4a55
Do not use printf() directly but use new wrapper function log_printf() instead.
zas_
parents:
671
diff
changeset
|
884 log_printf("failed saving to collection path: %s\n", cw->cd->path); |
9 | 885 } |
886 break; | |
887 case 'A': case 'a': | |
85
9d5c75b5ec28
Fri Oct 20 09:20:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
888 collection_dialog_append(NULL, cw->cd); |
9 | 889 break; |
890 case 'N': case 'n': | |
891 collection_set_sort_method(cw->cd, SORT_NAME); | |
892 break; | |
893 #ifdef HAVE_STRVERSCMP | |
894 case 'I': case 'i': | |
895 collection_set_sort_method(cw->cd, SORT_NUMBER); | |
896 break; | |
897 #endif | |
898 case 'D': case 'd': | |
899 collection_set_sort_method(cw->cd, SORT_TIME); | |
900 break; | |
901 case 'B': case 'b': | |
902 collection_set_sort_method(cw->cd, SORT_SIZE); | |
903 break; | |
904 case 'P': case 'p': | |
94
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
905 if (event->state & GDK_SHIFT_MASK) |
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
906 { |
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
907 CollectInfo *info; |
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
908 |
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
909 info = collection_table_get_focus_info(cw->table); |
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
910 |
138 | 911 print_window_new(info->fd, collection_table_selection_get_list(cw->table), |
912 collection_list_to_filelist(cw->cd->list), cw->window); | |
94
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
913 } |
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
914 else |
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
915 { |
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
916 collection_set_sort_method(cw->cd, SORT_PATH); |
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
917 } |
9 | 918 break; |
919 case GDK_Delete: case GDK_KP_Delete: | |
920 list = g_list_copy(cw->table->selection); | |
921 if (list) | |
922 { | |
923 collection_remove_by_info_list(cw->cd, list); | |
924 g_list_free(list); | |
925 } | |
926 else | |
927 { | |
928 collection_remove_by_info(cw->cd, collection_table_get_focus_info(cw->table)); | |
929 } | |
930 break; | |
931 default: | |
85
9d5c75b5ec28
Fri Oct 20 09:20:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
932 stop_signal = FALSE; |
9 | 933 break; |
934 } | |
935 } | |
1272 | 936 #if 0 |
9 | 937 if (edit_val != -1) |
938 { | |
939 list = collection_table_selection_get_list(cw->table); | |
753 | 940 file_util_start_editor_from_filelist(edit_val, list, cw->window); |
138 | 941 filelist_free(list); |
9 | 942 } |
1272 | 943 #endif |
9 | 944 return stop_signal; |
945 } | |
946 | |
947 /* | |
948 *------------------------------------------------------------------- | |
949 * window | |
950 *------------------------------------------------------------------- | |
951 */ | |
952 static void collection_window_get_geometry(CollectWindow *cw) | |
953 { | |
954 CollectionData *cd; | |
955 | |
956 if (!cw) return; | |
957 | |
958 cd = cw->cd; | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
507
diff
changeset
|
959 gdk_window_get_position(cw->window->window, &cd->window_x, &cd->window_y); |
9 | 960 gdk_drawable_get_size(cw->window->window, &cd->window_w, &cd->window_h); |
961 cd->window_read = TRUE; | |
962 } | |
963 | |
964 static void collection_window_refresh(CollectWindow *cw) | |
965 { | |
966 if (!cw) return; | |
967 | |
968 collection_table_refresh(cw->table); | |
969 } | |
970 | |
971 static void collection_window_update_title(CollectWindow *cw) | |
972 { | |
1176
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
973 gboolean free_name = FALSE; |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
974 gchar *name; |
9 | 975 gchar *buf; |
976 | |
977 if (!cw) return; | |
978 | |
1176
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
979 if (file_extension_match(cw->cd->name, GQ_COLLECTION_EXT)) |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
980 { |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
981 name = remove_extension_from_path(cw->cd->name); |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
982 free_name = TRUE; |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
983 } |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
984 else |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
985 { |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
986 name = cw->cd->name; |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
987 } |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
988 |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
989 buf = g_strdup_printf(_("%s - Collection - %s"), name, GQ_APPNAME); |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
990 if (free_name) g_free(name); |
9 | 991 gtk_window_set_title(GTK_WINDOW(cw->window), buf); |
992 g_free(buf); | |
993 } | |
994 | |
995 static void collection_window_update_info(CollectionData *cd, CollectInfo *ci, gpointer data) | |
996 { | |
997 CollectWindow *cw = data; | |
998 | |
999 collection_table_file_update(cw->table, ci); | |
1000 } | |
1001 | |
1002 static void collection_window_add(CollectWindow *cw, CollectInfo *ci) | |
1003 { | |
1004 if (!cw) return; | |
1005 | |
1006 if (!ci->pixbuf) collection_load_thumb_idle(cw->cd); | |
1007 collection_table_file_add(cw->table, ci); | |
1008 } | |
1009 | |
1010 static void collection_window_insert(CollectWindow *cw, CollectInfo *ci) | |
1011 { | |
1012 if (!cw) return; | |
1013 | |
1014 if (!ci->pixbuf) collection_load_thumb_idle(cw->cd); | |
1015 collection_table_file_insert(cw->table, ci); | |
1016 if (!cw) return; | |
1017 } | |
1018 | |
1019 #if 0 | |
1020 static void collection_window_move(CollectWindow *cw, CollectInfo *ci) | |
1021 { | |
1022 if (!cw) return; | |
1023 } | |
1024 #endif | |
1025 | |
1026 static void collection_window_remove(CollectWindow *cw, CollectInfo *ci) | |
1027 { | |
1028 if (!cw) return; | |
1029 | |
1030 collection_table_file_remove(cw->table, ci); | |
1031 } | |
1032 | |
1033 static void collection_window_update(CollectWindow *cw, CollectInfo *ci) | |
1034 { | |
1035 if (!cw) return; | |
1036 | |
1037 collection_table_file_update(cw->table, ci); | |
1038 collection_table_file_update(cw->table, NULL); | |
1039 } | |
1040 | |
1041 static void collection_window_close_final(CollectWindow *cw) | |
1042 { | |
1043 if (cw->close_dialog) return; | |
1044 | |
1045 collection_window_list = g_list_remove(collection_window_list, cw); | |
1046 collection_window_get_geometry(cw); | |
1047 | |
1048 gtk_widget_destroy(cw->window); | |
1049 | |
1050 collection_set_update_info_func(cw->cd, NULL, NULL); | |
1051 collection_unref(cw->cd); | |
1052 | |
1053 g_free(cw); | |
1054 } | |
1055 | |
1056 static void collection_close_save_cb(GenericDialog *gd, gpointer data) | |
1057 { | |
1058 CollectWindow *cw = data; | |
1059 | |
1060 cw->close_dialog = NULL; | |
1061 generic_dialog_close(gd); | |
1062 | |
1063 if (!cw->cd->path) | |
442 | 1064 { |
9 | 1065 collection_dialog_save_close(NULL, cw->cd); |
1066 return; | |
1067 } | |
1068 else if (!collection_save(cw->cd, cw->cd->path)) | |
1069 { | |
1070 gchar *buf; | |
1071 buf = g_strdup_printf(_("Failed to save the collection:\n%s"), cw->cd->path); | |
1072 warning_dialog(_("Save Failed"), buf, GTK_STOCK_DIALOG_ERROR, cw->window); | |
1073 g_free(buf); | |
1074 return; | |
1075 } | |
1076 | |
1077 collection_window_close_final(cw); | |
1078 } | |
1079 | |
1080 static void collection_close_close_cb(GenericDialog *gd, gpointer data) | |
1081 { | |
1082 CollectWindow *cw = data; | |
1083 | |
1084 cw->close_dialog = NULL; | |
1085 generic_dialog_close(gd); | |
1086 | |
1087 collection_window_close_final(cw); | |
1088 } | |
1089 | |
1090 static void collection_close_cancel_cb(GenericDialog *gd, gpointer data) | |
1091 { | |
1092 CollectWindow *cw = data; | |
1093 | |
1094 cw->close_dialog = NULL; | |
1095 generic_dialog_close(gd); | |
1096 } | |
1097 | |
1098 static void collection_close_dlg_show(CollectWindow *cw) | |
1099 { | |
1100 GenericDialog *gd; | |
1101 | |
1102 if (cw->close_dialog) | |
1103 { | |
1104 gtk_window_present(GTK_WINDOW(cw->close_dialog)); | |
1105 return; | |
1106 } | |
1107 | |
1108 gd = generic_dialog_new(_("Close collection"), | |
1174
0bea79d87065
Drop useless wmclass stuff. Gtk will take care of it and as said in the documentation using gtk_window_set_wmclass() is sort of pointless.
zas_
parents:
1055
diff
changeset
|
1109 "close_collection", cw->window, FALSE, |
9 | 1110 collection_close_cancel_cb, cw); |
1111 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, | |
1112 _("Close collection"), | |
1113 _("Collection has been modified.\nSave first?")); | |
1114 | |
1115 generic_dialog_add_button(gd, GTK_STOCK_SAVE, NULL, collection_close_save_cb, TRUE); | |
1116 generic_dialog_add_button(gd, GTK_STOCK_DELETE, _("_Discard"), collection_close_close_cb, FALSE); | |
1117 | |
1118 cw->close_dialog = gd->dialog; | |
1119 | |
1120 gtk_widget_show(gd->dialog); | |
1121 } | |
1122 | |
1123 static void collection_window_close(CollectWindow *cw) | |
1124 { | |
1125 if (!cw->cd->changed && !cw->close_dialog) | |
1126 { | |
1127 collection_window_close_final(cw); | |
1128 return; | |
1129 } | |
1130 | |
1131 collection_close_dlg_show(cw); | |
1132 } | |
1133 | |
1134 void collection_window_close_by_collection(CollectionData *cd) | |
1135 { | |
1136 CollectWindow *cw; | |
1137 | |
1138 cw = collection_window_find(cd); | |
1139 if (cw) collection_window_close_final(cw); | |
1140 } | |
1141 | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
1142 gboolean collection_window_modified_exists(void) |
9 | 1143 { |
1144 GList *work; | |
1145 | |
1146 work = collection_window_list; | |
1147 while (work) | |
1148 { | |
1149 CollectWindow *cw = work->data; | |
1150 if (cw->cd->changed) return TRUE; | |
1151 work = work->next; | |
1152 } | |
1153 | |
1154 return FALSE; | |
1155 } | |
1156 | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
1157 static gboolean collection_window_delete(GtkWidget *widget, GdkEvent *event, gpointer data) |
9 | 1158 { |
1159 CollectWindow *cw = data; | |
1160 collection_window_close(cw); | |
1161 | |
1162 return TRUE; | |
1163 } | |
1164 | |
1165 CollectWindow *collection_window_new(const gchar *path) | |
1166 { | |
1167 CollectWindow *cw; | |
1168 GtkWidget *vbox; | |
1169 GtkWidget *frame; | |
1170 GtkWidget *status_label; | |
1171 GtkWidget *extra_label; | |
1172 GdkGeometry geometry; | |
1173 | |
1174 cw = g_new0(CollectWindow, 1); | |
1175 | |
1176 collection_window_list = g_list_append(collection_window_list, cw); | |
1177 | |
1178 cw->cd = collection_new(path); | |
1179 | |
289
6a7298988a7a
Simplify and unify gtk_window creation with the help of
zas_
parents:
288
diff
changeset
|
1180 cw->window = window_new(GTK_WINDOW_TOPLEVEL, "collection", PIXBUF_INLINE_ICON_BOOK, NULL, NULL); |
9 | 1181 |
1029
1a4b18c58556
Use a constant for minimal window size. Set it to 32 for all dialogs.
zas_
parents:
1022
diff
changeset
|
1182 geometry.min_width = DEFAULT_MINIMAL_WINDOW_SIZE; |
1a4b18c58556
Use a constant for minimal window size. Set it to 32 for all dialogs.
zas_
parents:
1022
diff
changeset
|
1183 geometry.min_height = DEFAULT_MINIMAL_WINDOW_SIZE; |
9 | 1184 geometry.base_width = COLLECT_DEF_WIDTH; |
1185 geometry.base_height = COLLECT_DEF_HEIGHT; | |
1186 gtk_window_set_geometry_hints(GTK_WINDOW(cw->window), NULL, &geometry, | |
1187 GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE); | |
1188 | |
1189 | |
1436
d7a6fb7a90dd
completely separated global and layout window options
nadvornik
parents:
1432
diff
changeset
|
1190 if (options->save_window_positions && path && collection_load_only_geometry(cw->cd, path)) |
9 | 1191 { |
1192 /* FIXME: x, y is not implemented */ | |
1193 gtk_window_set_default_size(GTK_WINDOW(cw->window), cw->cd->window_w, cw->cd->window_h); | |
1194 } | |
1195 else | |
1196 { | |
1197 gtk_window_set_default_size(GTK_WINDOW(cw->window), COLLECT_DEF_WIDTH, COLLECT_DEF_HEIGHT); | |
1198 } | |
1199 | |
1200 gtk_window_set_resizable(GTK_WINDOW(cw->window), TRUE); | |
1201 collection_window_update_title(cw); | |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
512
diff
changeset
|
1202 gtk_container_set_border_width(GTK_CONTAINER(cw->window), 0); |
9 | 1203 |
1204 g_signal_connect(G_OBJECT(cw->window), "delete_event", | |
1205 G_CALLBACK(collection_window_delete), cw); | |
1206 | |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
512
diff
changeset
|
1207 g_signal_connect(G_OBJECT(cw->window), "key_press_event", |
9 | 1208 G_CALLBACK(collection_window_keypress), cw); |
1209 | |
1210 vbox = gtk_vbox_new(FALSE, 0); | |
1211 gtk_container_add(GTK_CONTAINER(cw->window), vbox); | |
1212 gtk_widget_show(vbox); | |
1213 | |
1214 cw->table = collection_table_new(cw->cd); | |
1215 gtk_box_pack_start(GTK_BOX(vbox), cw->table->scrolled, TRUE, TRUE, 0); | |
1216 gtk_widget_show(cw->table->scrolled); | |
1217 | |
1218 cw->status_box = gtk_hbox_new(TRUE, 0); | |
1219 gtk_box_pack_start(GTK_BOX(vbox), cw->status_box, FALSE, FALSE, 0); | |
1220 gtk_widget_show(cw->status_box); | |
1221 | |
1222 frame = gtk_frame_new(NULL); | |
1223 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); | |
1224 gtk_box_pack_start(GTK_BOX(cw->status_box), frame, TRUE, TRUE, 0); | |
1225 gtk_widget_show(frame); | |
1226 | |
1227 status_label = gtk_label_new(""); | |
1228 gtk_container_add(GTK_CONTAINER(frame), status_label); | |
1229 gtk_widget_show(status_label); | |
1230 | |
1231 extra_label = gtk_progress_bar_new(); | |
1232 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(extra_label), 0.0); | |
1233 gtk_box_pack_start(GTK_BOX(cw->status_box), extra_label, TRUE, TRUE, 0); | |
1234 gtk_widget_show(extra_label); | |
1235 | |
1236 collection_table_set_labels(cw->table, status_label, extra_label); | |
1237 | |
1238 gtk_widget_show(cw->window); | |
1239 gtk_widget_grab_focus(cw->table->listview); | |
1240 | |
1241 collection_set_update_info_func(cw->cd, collection_window_update_info, cw); | |
1242 | |
726 | 1243 if (path && *path == G_DIR_SEPARATOR) collection_load_begin(cw->cd, NULL, COLLECTION_LOAD_NONE); |
9 | 1244 |
1245 return cw; | |
1246 } | |
1055
1646720364cf
Adding a vim modeline to all files - patch by Klaus Ethgen
nadvornik
parents:
1029
diff
changeset
|
1247 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ |