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