Mercurial > geeqie.yaz
annotate src/collect.c @ 1535:760f585d9fa0
Implement random sort method for collections
This patch allows to randomize the collections. (Closes: #2497413)
https://sourceforge.net/tracker/?func=detail&aid=2497413&group_id=222125&atid=1054683
author | mow |
---|---|
date | Fri, 10 Apr 2009 13:44:37 +0000 |
parents | 5f49f305a6b6 |
children | b1e622788c4a |
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); | |
609 if (cd->list) cd->changed = TRUE; | |
610 | |
611 collection_window_refresh(collection_window_find(cd)); | |
612 } | |
613 | |
9 | 614 void collection_set_update_info_func(CollectionData *cd, |
615 void (*func)(CollectionData *, CollectInfo *, gpointer), gpointer data) | |
616 { | |
617 cd->info_updated_func = func; | |
618 cd->info_updated_data = data; | |
619 } | |
620 | |
303
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
621 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
|
622 { |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
623 CollectInfo *ci; |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
624 |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
625 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
|
626 |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
627 ci = collection_info_new(fd, st, NULL); |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
628 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
|
629 return ci; |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
630 } |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
631 |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
632 gboolean collection_add_check(CollectionData *cd, FileData *fd, gboolean sorted, gboolean must_exist) |
9 | 633 { |
634 struct stat st; | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
635 gboolean valid; |
9 | 636 |
637 if (must_exist) | |
638 { | |
138 | 639 valid = (stat_utf8(fd->path, &st) && !S_ISDIR(st.st_mode)); |
9 | 640 } |
641 else | |
642 { | |
643 valid = TRUE; | |
644 st.st_size = 0; | |
645 st.st_mtime = 0; | |
646 } | |
647 | |
648 if (valid) | |
649 { | |
650 CollectInfo *ci; | |
303
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
651 |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
652 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
|
653 if (!ci) return FALSE; |
506
fc9c8a3e1a8b
Handle the newline in DEBUG_N() macro instead of adding one
zas_
parents:
495
diff
changeset
|
654 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
|
655 |
9 | 656 cd->list = collection_list_add(cd->list, ci, sorted ? cd->sort_method : SORT_NONE); |
657 cd->changed = TRUE; | |
658 | |
659 if (!sorted || cd->sort_method == SORT_NONE) | |
660 { | |
661 collection_window_add(collection_window_find(cd), ci); | |
662 } | |
663 else | |
664 { | |
665 collection_window_insert(collection_window_find(cd), ci); | |
666 } | |
667 } | |
668 | |
669 return valid; | |
670 } | |
671 | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
672 gboolean collection_add(CollectionData *cd, FileData *fd, gboolean sorted) |
9 | 673 { |
138 | 674 return collection_add_check(cd, fd, sorted, TRUE); |
9 | 675 } |
676 | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
677 gboolean collection_insert(CollectionData *cd, FileData *fd, CollectInfo *insert_ci, gboolean sorted) |
9 | 678 { |
679 struct stat st; | |
680 | |
138 | 681 if (!insert_ci) return collection_add(cd, fd, sorted); |
9 | 682 |
138 | 683 if (stat_utf8(fd->path, &st) >= 0 && !S_ISDIR(st.st_mode)) |
9 | 684 { |
685 CollectInfo *ci; | |
303
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
686 |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
687 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
|
688 if (!ci) return FALSE; |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
689 |
506
fc9c8a3e1a8b
Handle the newline in DEBUG_N() macro instead of adding one
zas_
parents:
495
diff
changeset
|
690 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
|
691 |
9 | 692 cd->list = collection_list_insert(cd->list, ci, insert_ci, sorted ? cd->sort_method : SORT_NONE); |
693 cd->changed = TRUE; | |
694 | |
695 collection_window_insert(collection_window_find(cd), ci); | |
696 | |
697 return TRUE; | |
698 } | |
699 | |
700 return FALSE; | |
701 } | |
702 | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
703 gboolean collection_remove(CollectionData *cd, FileData *fd) |
9 | 704 { |
705 CollectInfo *ci; | |
706 | |
799 | 707 ci = collection_list_find_fd(cd->list, fd); |
9 | 708 |
709 if (!ci) return FALSE; | |
710 | |
303
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
711 g_hash_table_remove(cd->existence, fd->path); |
6ff0bc50ac46
Prevent multiple insertion of the same file in a collection.
zas_
parents:
289
diff
changeset
|
712 |
9 | 713 cd->list = g_list_remove(cd->list, ci); |
714 cd->changed = TRUE; | |
715 | |
716 collection_window_remove(collection_window_find(cd), ci); | |
717 collection_info_free(ci); | |
718 | |
719 return TRUE; | |
720 } | |
721 | |
722 static void collection_remove_by_info(CollectionData *cd, CollectInfo *info) | |
723 { | |
724 if (!info || !g_list_find(cd->list, info)) return; | |
725 | |
726 cd->list = g_list_remove(cd->list, info); | |
727 cd->changed = (cd->list != NULL); | |
728 | |
729 collection_window_remove(collection_window_find(cd), info); | |
730 collection_info_free(info); | |
731 } | |
732 | |
733 void collection_remove_by_info_list(CollectionData *cd, GList *list) | |
734 { | |
735 GList *work; | |
736 | |
737 if (!list) return; | |
738 | |
739 if (!list->next) | |
740 { | |
741 /* more efficient (in collect-table) to remove a single item this way */ | |
742 collection_remove_by_info(cd, (CollectInfo *)list->data); | |
743 return; | |
744 } | |
745 | |
746 work = list; | |
516 | 747 while (work) |
9 | 748 { |
749 cd->list = collection_list_remove(cd->list, work->data); | |
750 work = work->next; | |
751 } | |
752 cd->changed = (cd->list != NULL); | |
753 | |
754 collection_window_refresh(collection_window_find(cd)); | |
755 } | |
756 | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
757 gboolean collection_rename(CollectionData *cd, FileData *fd) |
9 | 758 { |
759 CollectInfo *ci; | |
799 | 760 ci = collection_list_find_fd(cd->list, fd); |
9 | 761 |
762 if (!ci) return FALSE; | |
763 | |
764 cd->changed = TRUE; | |
765 | |
766 collection_window_update(collection_window_find(cd), ci); | |
767 | |
768 return TRUE; | |
769 } | |
770 | |
771 void collection_update_geometry(CollectionData *cd) | |
772 { | |
773 collection_window_get_geometry(collection_window_find(cd)); | |
774 } | |
775 | |
776 /* | |
777 *------------------------------------------------------------------- | |
778 * simple maintenance for renaming, deleting | |
779 *------------------------------------------------------------------- | |
780 */ | |
781 | |
799 | 782 static void collection_notify_cb(FileData *fd, NotifyType type, gpointer data) |
9 | 783 { |
799 | 784 CollectionData *cd = data; |
9 | 785 |
1432 | 786 if (!(type & NOTIFY_CHANGE) || !fd->change) return; |
1498 | 787 |
788 DEBUG_1("Notify collection: %s %04x", fd->path, type); | |
799 | 789 |
1347
79937bc55f3a
Add missing space between switch and first parenthesis.
zas_
parents:
1292
diff
changeset
|
790 switch (fd->change->type) |
9 | 791 { |
799 | 792 case FILEDATA_CHANGE_MOVE: |
793 case FILEDATA_CHANGE_RENAME: | |
794 collection_rename(cd, fd); | |
795 break; | |
796 case FILEDATA_CHANGE_COPY: | |
797 break; | |
798 case FILEDATA_CHANGE_DELETE: | |
799 while (collection_remove(cd, fd)); | |
800 break; | |
801 case FILEDATA_CHANGE_UNSPECIFIED: | |
1211 | 802 case FILEDATA_CHANGE_WRITE_METADATA: |
799 | 803 break; |
9 | 804 } |
799 | 805 |
9 | 806 } |
807 | |
808 | |
809 /* | |
810 *------------------------------------------------------------------- | |
811 * window key presses | |
812 *------------------------------------------------------------------- | |
813 */ | |
814 | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
815 static gboolean collection_window_keypress(GtkWidget *widget, GdkEventKey *event, gpointer data) |
9 | 816 { |
817 CollectWindow *cw = data; | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
818 gboolean stop_signal = FALSE; |
9 | 819 gint edit_val = -1; |
820 GList *list; | |
821 | |
822 if (event->state & GDK_CONTROL_MASK) | |
823 { | |
85
9d5c75b5ec28
Fri Oct 20 09:20:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
824 stop_signal = TRUE; |
9 | 825 switch (event->keyval) |
826 { | |
827 case '1': | |
828 edit_val = 0; | |
829 break; | |
830 case '2': | |
831 edit_val = 1; | |
832 break; | |
833 case '3': | |
834 edit_val = 2; | |
835 break; | |
836 case '4': | |
837 edit_val = 3; | |
838 break; | |
839 case '5': | |
840 edit_val = 4; | |
841 break; | |
842 case '6': | |
843 edit_val = 5; | |
844 break; | |
845 case '7': | |
846 edit_val = 6; | |
847 break; | |
848 case '8': | |
849 edit_val = 7; | |
850 break; | |
851 case '9': | |
852 edit_val = 8; | |
853 break; | |
854 case '0': | |
855 edit_val = 9; | |
856 break; | |
857 case 'A': case 'a': | |
858 if (event->state & GDK_SHIFT_MASK) | |
859 { | |
860 collection_table_unselect_all(cw->table); | |
861 } | |
862 else | |
863 { | |
864 collection_table_select_all(cw->table); | |
865 } | |
866 break; | |
867 case 'L': case 'l': | |
868 list = layout_list(NULL); | |
869 if (list) | |
870 { | |
138 | 871 collection_table_add_filelist(cw->table, list); |
872 filelist_free(list); | |
9 | 873 } |
874 break; | |
875 case 'C': case 'c': | |
876 file_util_copy(NULL, collection_table_selection_get_list(cw->table), NULL, cw->window); | |
877 break; | |
878 case 'M': case 'm': | |
879 file_util_move(NULL, collection_table_selection_get_list(cw->table), NULL, cw->window); | |
880 break; | |
881 case 'R': case 'r': | |
882 file_util_rename(NULL, collection_table_selection_get_list(cw->table), cw->window); | |
883 break; | |
884 case 'D': case 'd': | |
885 file_util_delete(NULL, collection_table_selection_get_list(cw->table), cw->window); | |
886 break; | |
887 case 'S': case 's': | |
888 collection_dialog_save_as(NULL, cw->cd); | |
889 break; | |
890 case 'W': case 'w': | |
891 collection_window_close(cw); | |
892 break; | |
893 default: | |
85
9d5c75b5ec28
Fri Oct 20 09:20:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
894 stop_signal = FALSE; |
9 | 895 break; |
896 } | |
897 } | |
898 else | |
899 { | |
85
9d5c75b5ec28
Fri Oct 20 09:20:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
900 stop_signal = TRUE; |
9 | 901 switch (event->keyval) |
902 { | |
903 case GDK_Return: case GDK_KP_Enter: | |
904 layout_image_set_collection(NULL, cw->cd, | |
905 collection_table_get_focus_info(cw->table)); | |
906 break; | |
907 case 'V': case 'v': | |
908 view_window_new_from_collection(cw->cd, | |
909 collection_table_get_focus_info(cw->table)); | |
910 break; | |
911 case 'S': case 's': | |
912 if (!cw->cd->path) | |
913 { | |
914 collection_dialog_save_as(NULL, cw->cd); | |
442 | 915 } |
9 | 916 else if (!collection_save(cw->cd, cw->cd->path)) |
917 { | |
673
fbebf5cf4a55
Do not use printf() directly but use new wrapper function log_printf() instead.
zas_
parents:
671
diff
changeset
|
918 log_printf("failed saving to collection path: %s\n", cw->cd->path); |
9 | 919 } |
920 break; | |
921 case 'A': case 'a': | |
85
9d5c75b5ec28
Fri Oct 20 09:20:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
922 collection_dialog_append(NULL, cw->cd); |
9 | 923 break; |
924 case 'N': case 'n': | |
925 collection_set_sort_method(cw->cd, SORT_NAME); | |
926 break; | |
927 #ifdef HAVE_STRVERSCMP | |
928 case 'I': case 'i': | |
929 collection_set_sort_method(cw->cd, SORT_NUMBER); | |
930 break; | |
931 #endif | |
932 case 'D': case 'd': | |
933 collection_set_sort_method(cw->cd, SORT_TIME); | |
934 break; | |
935 case 'B': case 'b': | |
936 collection_set_sort_method(cw->cd, SORT_SIZE); | |
937 break; | |
938 case 'P': case 'p': | |
94
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
939 if (event->state & GDK_SHIFT_MASK) |
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
940 { |
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
941 CollectInfo *info; |
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
942 |
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
943 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
|
944 |
138 | 945 print_window_new(info->fd, collection_table_selection_get_list(cw->table), |
946 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
|
947 } |
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
948 else |
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
949 { |
50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
gqview
parents:
91
diff
changeset
|
950 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
|
951 } |
9 | 952 break; |
953 case GDK_Delete: case GDK_KP_Delete: | |
954 list = g_list_copy(cw->table->selection); | |
955 if (list) | |
956 { | |
957 collection_remove_by_info_list(cw->cd, list); | |
958 g_list_free(list); | |
959 } | |
960 else | |
961 { | |
962 collection_remove_by_info(cw->cd, collection_table_get_focus_info(cw->table)); | |
963 } | |
964 break; | |
965 default: | |
85
9d5c75b5ec28
Fri Oct 20 09:20:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
966 stop_signal = FALSE; |
9 | 967 break; |
968 } | |
969 } | |
1272 | 970 #if 0 |
9 | 971 if (edit_val != -1) |
972 { | |
973 list = collection_table_selection_get_list(cw->table); | |
753 | 974 file_util_start_editor_from_filelist(edit_val, list, cw->window); |
138 | 975 filelist_free(list); |
9 | 976 } |
1272 | 977 #endif |
9 | 978 return stop_signal; |
979 } | |
980 | |
981 /* | |
982 *------------------------------------------------------------------- | |
983 * window | |
984 *------------------------------------------------------------------- | |
985 */ | |
986 static void collection_window_get_geometry(CollectWindow *cw) | |
987 { | |
988 CollectionData *cd; | |
989 | |
990 if (!cw) return; | |
991 | |
992 cd = cw->cd; | |
512
f9bf33be53ff
Remove whitespace between function name and first parenthesis for the sake of consistency.
zas_
parents:
507
diff
changeset
|
993 gdk_window_get_position(cw->window->window, &cd->window_x, &cd->window_y); |
9 | 994 gdk_drawable_get_size(cw->window->window, &cd->window_w, &cd->window_h); |
995 cd->window_read = TRUE; | |
996 } | |
997 | |
998 static void collection_window_refresh(CollectWindow *cw) | |
999 { | |
1000 if (!cw) return; | |
1001 | |
1002 collection_table_refresh(cw->table); | |
1003 } | |
1004 | |
1005 static void collection_window_update_title(CollectWindow *cw) | |
1006 { | |
1176
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
1007 gboolean free_name = FALSE; |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
1008 gchar *name; |
9 | 1009 gchar *buf; |
1010 | |
1011 if (!cw) return; | |
1012 | |
1176
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
1013 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
|
1014 { |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
1015 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
|
1016 free_name = TRUE; |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
1017 } |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
1018 else |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
1019 { |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
1020 name = cw->cd->name; |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
1021 } |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
1022 |
d3e51e1a02f8
Hide .gqv extension from collection name in collection window title and recent menu list.
zas_
parents:
1174
diff
changeset
|
1023 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
|
1024 if (free_name) g_free(name); |
9 | 1025 gtk_window_set_title(GTK_WINDOW(cw->window), buf); |
1026 g_free(buf); | |
1027 } | |
1028 | |
1029 static void collection_window_update_info(CollectionData *cd, CollectInfo *ci, gpointer data) | |
1030 { | |
1031 CollectWindow *cw = data; | |
1032 | |
1033 collection_table_file_update(cw->table, ci); | |
1034 } | |
1035 | |
1036 static void collection_window_add(CollectWindow *cw, CollectInfo *ci) | |
1037 { | |
1038 if (!cw) return; | |
1039 | |
1040 if (!ci->pixbuf) collection_load_thumb_idle(cw->cd); | |
1041 collection_table_file_add(cw->table, ci); | |
1042 } | |
1043 | |
1044 static void collection_window_insert(CollectWindow *cw, CollectInfo *ci) | |
1045 { | |
1046 if (!cw) return; | |
1047 | |
1048 if (!ci->pixbuf) collection_load_thumb_idle(cw->cd); | |
1049 collection_table_file_insert(cw->table, ci); | |
1050 if (!cw) return; | |
1051 } | |
1052 | |
1053 #if 0 | |
1054 static void collection_window_move(CollectWindow *cw, CollectInfo *ci) | |
1055 { | |
1056 if (!cw) return; | |
1057 } | |
1058 #endif | |
1059 | |
1060 static void collection_window_remove(CollectWindow *cw, CollectInfo *ci) | |
1061 { | |
1062 if (!cw) return; | |
1063 | |
1064 collection_table_file_remove(cw->table, ci); | |
1065 } | |
1066 | |
1067 static void collection_window_update(CollectWindow *cw, CollectInfo *ci) | |
1068 { | |
1069 if (!cw) return; | |
1070 | |
1071 collection_table_file_update(cw->table, ci); | |
1072 collection_table_file_update(cw->table, NULL); | |
1073 } | |
1074 | |
1075 static void collection_window_close_final(CollectWindow *cw) | |
1076 { | |
1077 if (cw->close_dialog) return; | |
1078 | |
1079 collection_window_list = g_list_remove(collection_window_list, cw); | |
1080 collection_window_get_geometry(cw); | |
1081 | |
1082 gtk_widget_destroy(cw->window); | |
1083 | |
1084 collection_set_update_info_func(cw->cd, NULL, NULL); | |
1085 collection_unref(cw->cd); | |
1086 | |
1087 g_free(cw); | |
1088 } | |
1089 | |
1090 static void collection_close_save_cb(GenericDialog *gd, gpointer data) | |
1091 { | |
1092 CollectWindow *cw = data; | |
1093 | |
1094 cw->close_dialog = NULL; | |
1095 generic_dialog_close(gd); | |
1096 | |
1097 if (!cw->cd->path) | |
442 | 1098 { |
9 | 1099 collection_dialog_save_close(NULL, cw->cd); |
1100 return; | |
1101 } | |
1102 else if (!collection_save(cw->cd, cw->cd->path)) | |
1103 { | |
1104 gchar *buf; | |
1105 buf = g_strdup_printf(_("Failed to save the collection:\n%s"), cw->cd->path); | |
1106 warning_dialog(_("Save Failed"), buf, GTK_STOCK_DIALOG_ERROR, cw->window); | |
1107 g_free(buf); | |
1108 return; | |
1109 } | |
1110 | |
1111 collection_window_close_final(cw); | |
1112 } | |
1113 | |
1114 static void collection_close_close_cb(GenericDialog *gd, gpointer data) | |
1115 { | |
1116 CollectWindow *cw = data; | |
1117 | |
1118 cw->close_dialog = NULL; | |
1119 generic_dialog_close(gd); | |
1120 | |
1121 collection_window_close_final(cw); | |
1122 } | |
1123 | |
1124 static void collection_close_cancel_cb(GenericDialog *gd, gpointer data) | |
1125 { | |
1126 CollectWindow *cw = data; | |
1127 | |
1128 cw->close_dialog = NULL; | |
1129 generic_dialog_close(gd); | |
1130 } | |
1131 | |
1132 static void collection_close_dlg_show(CollectWindow *cw) | |
1133 { | |
1134 GenericDialog *gd; | |
1135 | |
1136 if (cw->close_dialog) | |
1137 { | |
1138 gtk_window_present(GTK_WINDOW(cw->close_dialog)); | |
1139 return; | |
1140 } | |
1141 | |
1142 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
|
1143 "close_collection", cw->window, FALSE, |
9 | 1144 collection_close_cancel_cb, cw); |
1145 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, | |
1146 _("Close collection"), | |
1147 _("Collection has been modified.\nSave first?")); | |
1148 | |
1149 generic_dialog_add_button(gd, GTK_STOCK_SAVE, NULL, collection_close_save_cb, TRUE); | |
1150 generic_dialog_add_button(gd, GTK_STOCK_DELETE, _("_Discard"), collection_close_close_cb, FALSE); | |
1151 | |
1152 cw->close_dialog = gd->dialog; | |
1153 | |
1154 gtk_widget_show(gd->dialog); | |
1155 } | |
1156 | |
1157 static void collection_window_close(CollectWindow *cw) | |
1158 { | |
1159 if (!cw->cd->changed && !cw->close_dialog) | |
1160 { | |
1161 collection_window_close_final(cw); | |
1162 return; | |
1163 } | |
1164 | |
1165 collection_close_dlg_show(cw); | |
1166 } | |
1167 | |
1168 void collection_window_close_by_collection(CollectionData *cd) | |
1169 { | |
1170 CollectWindow *cw; | |
1171 | |
1172 cw = collection_window_find(cd); | |
1173 if (cw) collection_window_close_final(cw); | |
1174 } | |
1175 | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
1176 gboolean collection_window_modified_exists(void) |
9 | 1177 { |
1178 GList *work; | |
1179 | |
1180 work = collection_window_list; | |
1181 while (work) | |
1182 { | |
1183 CollectWindow *cw = work->data; | |
1184 if (cw->cd->changed) return TRUE; | |
1185 work = work->next; | |
1186 } | |
1187 | |
1188 return FALSE; | |
1189 } | |
1190 | |
1420
3a9fb1b52559
Use gboolean where applicable, for the sake of consistency.
zas_
parents:
1367
diff
changeset
|
1191 static gboolean collection_window_delete(GtkWidget *widget, GdkEvent *event, gpointer data) |
9 | 1192 { |
1193 CollectWindow *cw = data; | |
1194 collection_window_close(cw); | |
1195 | |
1196 return TRUE; | |
1197 } | |
1198 | |
1199 CollectWindow *collection_window_new(const gchar *path) | |
1200 { | |
1201 CollectWindow *cw; | |
1202 GtkWidget *vbox; | |
1203 GtkWidget *frame; | |
1204 GtkWidget *status_label; | |
1205 GtkWidget *extra_label; | |
1206 GdkGeometry geometry; | |
1207 | |
1208 cw = g_new0(CollectWindow, 1); | |
1209 | |
1210 collection_window_list = g_list_append(collection_window_list, cw); | |
1211 | |
1212 cw->cd = collection_new(path); | |
1213 | |
289
6a7298988a7a
Simplify and unify gtk_window creation with the help of
zas_
parents:
288
diff
changeset
|
1214 cw->window = window_new(GTK_WINDOW_TOPLEVEL, "collection", PIXBUF_INLINE_ICON_BOOK, NULL, NULL); |
9 | 1215 |
1029
1a4b18c58556
Use a constant for minimal window size. Set it to 32 for all dialogs.
zas_
parents:
1022
diff
changeset
|
1216 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
|
1217 geometry.min_height = DEFAULT_MINIMAL_WINDOW_SIZE; |
9 | 1218 geometry.base_width = COLLECT_DEF_WIDTH; |
1219 geometry.base_height = COLLECT_DEF_HEIGHT; | |
1220 gtk_window_set_geometry_hints(GTK_WINDOW(cw->window), NULL, &geometry, | |
1221 GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE); | |
1222 | |
1223 | |
1436
d7a6fb7a90dd
completely separated global and layout window options
nadvornik
parents:
1432
diff
changeset
|
1224 if (options->save_window_positions && path && collection_load_only_geometry(cw->cd, path)) |
9 | 1225 { |
1226 /* FIXME: x, y is not implemented */ | |
1227 gtk_window_set_default_size(GTK_WINDOW(cw->window), cw->cd->window_w, cw->cd->window_h); | |
1228 } | |
1229 else | |
1230 { | |
1231 gtk_window_set_default_size(GTK_WINDOW(cw->window), COLLECT_DEF_WIDTH, COLLECT_DEF_HEIGHT); | |
1232 } | |
1233 | |
1234 gtk_window_set_resizable(GTK_WINDOW(cw->window), TRUE); | |
1235 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
|
1236 gtk_container_set_border_width(GTK_CONTAINER(cw->window), 0); |
9 | 1237 |
1238 g_signal_connect(G_OBJECT(cw->window), "delete_event", | |
1239 G_CALLBACK(collection_window_delete), cw); | |
1240 | |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
512
diff
changeset
|
1241 g_signal_connect(G_OBJECT(cw->window), "key_press_event", |
9 | 1242 G_CALLBACK(collection_window_keypress), cw); |
1243 | |
1244 vbox = gtk_vbox_new(FALSE, 0); | |
1245 gtk_container_add(GTK_CONTAINER(cw->window), vbox); | |
1246 gtk_widget_show(vbox); | |
1247 | |
1248 cw->table = collection_table_new(cw->cd); | |
1249 gtk_box_pack_start(GTK_BOX(vbox), cw->table->scrolled, TRUE, TRUE, 0); | |
1250 gtk_widget_show(cw->table->scrolled); | |
1251 | |
1252 cw->status_box = gtk_hbox_new(TRUE, 0); | |
1253 gtk_box_pack_start(GTK_BOX(vbox), cw->status_box, FALSE, FALSE, 0); | |
1254 gtk_widget_show(cw->status_box); | |
1255 | |
1256 frame = gtk_frame_new(NULL); | |
1257 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); | |
1258 gtk_box_pack_start(GTK_BOX(cw->status_box), frame, TRUE, TRUE, 0); | |
1259 gtk_widget_show(frame); | |
1260 | |
1261 status_label = gtk_label_new(""); | |
1262 gtk_container_add(GTK_CONTAINER(frame), status_label); | |
1263 gtk_widget_show(status_label); | |
1264 | |
1265 extra_label = gtk_progress_bar_new(); | |
1266 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(extra_label), 0.0); | |
1267 gtk_box_pack_start(GTK_BOX(cw->status_box), extra_label, TRUE, TRUE, 0); | |
1268 gtk_widget_show(extra_label); | |
1269 | |
1270 collection_table_set_labels(cw->table, status_label, extra_label); | |
1271 | |
1272 gtk_widget_show(cw->window); | |
1273 gtk_widget_grab_focus(cw->table->listview); | |
1274 | |
1275 collection_set_update_info_func(cw->cd, collection_window_update_info, cw); | |
1276 | |
726 | 1277 if (path && *path == G_DIR_SEPARATOR) collection_load_begin(cw->cd, NULL, COLLECTION_LOAD_NONE); |
9 | 1278 |
1279 return cw; | |
1280 } | |
1055
1646720364cf
Adding a vim modeline to all files - patch by Klaus Ethgen
nadvornik
parents:
1029
diff
changeset
|
1281 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ |