Mercurial > geeqie
comparison src/filelist.c @ 1:b3e0e515fabf
Initial revision
author | gqview |
---|---|
date | Mon, 03 Apr 2000 18:24:05 +0000 |
parents | |
children | c0e337a01cb7 |
comparison
equal
deleted
inserted
replaced
0:513c7c01b50c | 1:b3e0e515fabf |
---|---|
1 /* | |
2 * GQview image viewer | |
3 * (C)1999 John Ellis | |
4 * | |
5 * Author: John Ellis | |
6 * | |
7 */ | |
8 | |
9 #include "gqview.h" | |
10 | |
11 static gint filelist_click_row = -1; | |
12 | |
13 static void update_progressbar(gfloat val); | |
14 | |
15 static gint file_is_hidden(gchar *name); | |
16 static gint file_is_in_filter(gchar *name); | |
17 static void add_to_filter(gchar *text, gint add); | |
18 | |
19 static gint sort_list_cb(void *a, void *b); | |
20 static void filelist_read(gchar *path); | |
21 | |
22 static gint file_find_closest_unaccounted(gint row, gint count, GList *ignore_list); | |
23 | |
24 static void history_menu_select_cb(GtkWidget *widget, gpointer data); | |
25 static gchar *truncate_hist_text(gchar *t, gint l); | |
26 static void filelist_set_history(gchar *path); | |
27 | |
28 /* | |
29 *----------------------------------------------------------------------------- | |
30 * file status information (private) | |
31 *----------------------------------------------------------------------------- | |
32 */ | |
33 | |
34 static void update_progressbar(gfloat val) | |
35 { | |
36 gtk_progress_bar_update (GTK_PROGRESS_BAR(info_progress_bar), val); | |
37 } | |
38 | |
39 void update_status_label(gchar *text) | |
40 { | |
41 gchar *buf; | |
42 gint count; | |
43 gchar *ss = ""; | |
44 | |
45 if (text) | |
46 { | |
47 gtk_label_set(GTK_LABEL(info_status), text); | |
48 return; | |
49 } | |
50 | |
51 if (slideshow_is_running()) ss = _(" Slideshow"); | |
52 | |
53 count = file_selection_count(); | |
54 if (count > 0) | |
55 buf = g_strdup_printf(_("%d files (%d)%s"), file_count(), count, ss); | |
56 else | |
57 buf = g_strdup_printf(_("%d files%s"), file_count(), ss); | |
58 | |
59 gtk_label_set(GTK_LABEL(info_status), buf); | |
60 g_free(buf); | |
61 } | |
62 | |
63 /* | |
64 *----------------------------------------------------------------------------- | |
65 * file filtering | |
66 *----------------------------------------------------------------------------- | |
67 */ | |
68 | |
69 static gint file_is_hidden(gchar *name) | |
70 { | |
71 if (name[0] != '.') return FALSE; | |
72 if (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')) return FALSE; | |
73 return TRUE; | |
74 } | |
75 | |
76 static gint file_is_in_filter(gchar *name) | |
77 { | |
78 GList *work; | |
79 if (!filename_filter || file_filter_disable) return TRUE; | |
80 | |
81 work = filename_filter; | |
82 while (work) | |
83 { | |
84 gchar *filter = work->data; | |
85 gint lf = strlen(filter); | |
86 gint ln = strlen(name); | |
87 if (ln >= lf) | |
88 { | |
89 if (strncasecmp(name + ln - lf, filter, lf) == 0) return TRUE; | |
90 } | |
91 work = work->next; | |
92 } | |
93 | |
94 return FALSE; | |
95 } | |
96 | |
97 static void add_to_filter(gchar *text, gint add) | |
98 { | |
99 if (add) filename_filter = g_list_append(filename_filter, g_strdup(text)); | |
100 } | |
101 | |
102 void rebuild_file_filter() | |
103 { | |
104 if (filename_filter) | |
105 { | |
106 g_list_foreach(filename_filter,(GFunc)g_free,NULL); | |
107 g_list_free(filename_filter); | |
108 filename_filter = NULL; | |
109 } | |
110 | |
111 add_to_filter(".jpg", filter_include_jpg); | |
112 add_to_filter(".jpeg", filter_include_jpg); | |
113 add_to_filter(".xpm", filter_include_xpm); | |
114 add_to_filter(".tif", filter_include_tif); | |
115 add_to_filter(".tiff", filter_include_tif); | |
116 add_to_filter(".gif", filter_include_gif); | |
117 add_to_filter(".png", filter_include_png); | |
118 add_to_filter(".ppm", filter_include_ppm); | |
119 add_to_filter(".pgm", filter_include_pgm); | |
120 add_to_filter(".pcx", filter_include_pcx); | |
121 add_to_filter(".bmp", filter_include_bmp); | |
122 | |
123 if (custom_filter) | |
124 { | |
125 gchar *buf = g_strdup(custom_filter); | |
126 gchar *pos_ptr_b; | |
127 gchar *pos_ptr_e = custom_filter; | |
128 while(pos_ptr_e[0] != '\0') | |
129 { | |
130 pos_ptr_b = pos_ptr_e; | |
131 while (pos_ptr_e[0] != ';' && pos_ptr_e[0] != '\0') pos_ptr_e++; | |
132 if (pos_ptr_e[0] == ';') | |
133 { | |
134 pos_ptr_e[0] = '\0'; | |
135 pos_ptr_e++; | |
136 } | |
137 add_to_filter(pos_ptr_b, TRUE); | |
138 } | |
139 g_free(buf); | |
140 } | |
141 } | |
142 | |
143 /* | |
144 *----------------------------------------------------------------------------- | |
145 * load file list (private) | |
146 *----------------------------------------------------------------------------- | |
147 */ | |
148 | |
149 static gint sort_list_cb(void *a, void *b) | |
150 { | |
151 return strcmp((gchar *)a, (gchar *)b); | |
152 } | |
153 | |
154 static void filelist_read(gchar *path) | |
155 { | |
156 DIR *dp; | |
157 struct dirent *dir; | |
158 struct stat ent_sbuf; | |
159 | |
160 if((dp = opendir(path))==NULL) | |
161 { | |
162 /* dir not found */ | |
163 return; | |
164 } | |
165 | |
166 g_list_foreach(dir_list,(GFunc)g_free,NULL); | |
167 g_list_free(dir_list); | |
168 dir_list = NULL; | |
169 | |
170 g_list_foreach(file_list,(GFunc)g_free,NULL); | |
171 g_list_free(file_list); | |
172 file_list = NULL; | |
173 | |
174 while ((dir = readdir(dp)) != NULL) | |
175 { | |
176 /* skips removed files */ | |
177 if (dir->d_ino > 0) | |
178 { | |
179 gchar *name = dir->d_name; | |
180 if (show_dot_files || !file_is_hidden(name)) | |
181 { | |
182 gchar *filepath = g_strconcat(path, "/", name, NULL); | |
183 if (stat(filepath,&ent_sbuf) >= 0 && S_ISDIR(ent_sbuf.st_mode)) | |
184 { | |
185 dir_list = g_list_prepend(dir_list, g_strdup(name)); | |
186 } | |
187 else | |
188 { | |
189 if (file_is_in_filter(name)) | |
190 file_list = g_list_prepend(file_list, g_strdup(name)); | |
191 } | |
192 g_free(filepath); | |
193 } | |
194 } | |
195 } | |
196 | |
197 closedir(dp); | |
198 | |
199 dir_list = g_list_sort(dir_list, (GCompareFunc) sort_list_cb); | |
200 file_list = g_list_sort(file_list, (GCompareFunc) sort_list_cb); | |
201 } | |
202 | |
203 /* | |
204 *----------------------------------------------------------------------------- | |
205 * file list utilities to retrieve information (public) | |
206 *----------------------------------------------------------------------------- | |
207 */ | |
208 | |
209 gint file_count() | |
210 { | |
211 return g_list_length(file_list); | |
212 } | |
213 | |
214 gint file_selection_count() | |
215 { | |
216 gint count = 0; | |
217 GList *work = GTK_CLIST(file_clist)->selection; | |
218 while(work) | |
219 { | |
220 count++; | |
221 if (debug) printf("s = %d\n", GPOINTER_TO_INT(work->data)); | |
222 work = work->next; | |
223 } | |
224 | |
225 if (debug) printf("files selected = %d\n", count); | |
226 | |
227 return count; | |
228 } | |
229 | |
230 gint find_file_in_list(gchar *path) | |
231 { | |
232 GList *work = file_list; | |
233 gchar *buf; | |
234 gchar *name; | |
235 gint count = -1; | |
236 | |
237 if (!path) return -1; | |
238 | |
239 buf = remove_level_from_path(path); | |
240 if (strcmp(buf, current_path) != 0) | |
241 { | |
242 g_free(buf); | |
243 return -1; | |
244 } | |
245 g_free(buf); | |
246 | |
247 name = filename_from_path(path); | |
248 while(work) | |
249 { | |
250 count++; | |
251 if (strcmp(name, work->data) == 0) return count; | |
252 work = work->next; | |
253 } | |
254 | |
255 return -1; | |
256 } | |
257 | |
258 gchar *file_get_path(gint row) | |
259 { | |
260 gchar *path = NULL; | |
261 gchar *name = gtk_clist_get_row_data(GTK_CLIST(file_clist), row); | |
262 | |
263 if (name) path = g_strconcat(current_path, "/", name, NULL); | |
264 | |
265 return path; | |
266 } | |
267 | |
268 gint file_is_selected(gint row) | |
269 { | |
270 GList *work = GTK_CLIST(file_clist)->selection; | |
271 | |
272 while(work) | |
273 { | |
274 if (GPOINTER_TO_INT(work->data) == row) return TRUE; | |
275 work = work->next; | |
276 } | |
277 | |
278 return FALSE; | |
279 } | |
280 | |
281 /* | |
282 *----------------------------------------------------------------------------- | |
283 * utilities to retrieve list of selected files (public) | |
284 *----------------------------------------------------------------------------- | |
285 */ | |
286 | |
287 GList *file_get_selected_list() | |
288 { | |
289 GList *list = NULL; | |
290 GList *work = GTK_CLIST(file_clist)->selection; | |
291 | |
292 while(work) | |
293 { | |
294 gchar *name = gtk_clist_get_row_data(GTK_CLIST(file_clist), | |
295 GPOINTER_TO_INT(work->data)); | |
296 list = g_list_prepend(list, g_strconcat(current_path, "/", name, NULL)); | |
297 work = work->next; | |
298 } | |
299 | |
300 list = g_list_reverse(list); | |
301 | |
302 return list; | |
303 } | |
304 | |
305 void free_selected_list(GList *list) | |
306 { | |
307 g_list_foreach(list, (GFunc)g_free, NULL); | |
308 g_list_free(list); | |
309 } | |
310 | |
311 gint file_clicked_is_selected() | |
312 { | |
313 return file_is_selected(filelist_click_row); | |
314 } | |
315 | |
316 gchar *file_clicked_get_path() | |
317 { | |
318 return file_get_path(filelist_click_row); | |
319 } | |
320 | |
321 /* | |
322 *----------------------------------------------------------------------------- | |
323 * image change routines | |
324 *----------------------------------------------------------------------------- | |
325 */ | |
326 | |
327 void file_image_change_to(gint row) | |
328 { | |
329 gtk_clist_unselect_all(GTK_CLIST(file_clist)); | |
330 gtk_clist_select_row(GTK_CLIST(file_clist), row, -1); | |
331 if (gtk_clist_row_is_visible(GTK_CLIST(file_clist), row) != GTK_VISIBILITY_FULL) | |
332 { | |
333 gtk_clist_moveto(GTK_CLIST(file_clist), row, -1, 0.5, 0.0); | |
334 } | |
335 } | |
336 | |
337 void file_next_image() | |
338 { | |
339 gint current = find_file_in_list(image_get_path()); | |
340 gint total = file_count(); | |
341 | |
342 if (current >= 0) | |
343 { | |
344 if (current < total - 1) | |
345 { | |
346 file_image_change_to(current + 1); | |
347 } | |
348 } | |
349 else | |
350 { | |
351 file_image_change_to(0); | |
352 } | |
353 } | |
354 | |
355 void file_prev_image() | |
356 { | |
357 gint current = find_file_in_list(image_get_path()); | |
358 | |
359 if (current >= 0) | |
360 { | |
361 if (current > 0) | |
362 { | |
363 file_image_change_to(current - 1); | |
364 } | |
365 } | |
366 else | |
367 { | |
368 file_image_change_to(file_count() - 1); | |
369 } | |
370 } | |
371 | |
372 void file_first_image() | |
373 { | |
374 gint current = find_file_in_list(image_get_path()); | |
375 if (current != 0 && file_count() > 0) | |
376 { | |
377 file_image_change_to(0); | |
378 } | |
379 } | |
380 | |
381 void file_last_image() | |
382 { | |
383 gint current = find_file_in_list(image_get_path()); | |
384 gint count = file_count(); | |
385 if (current != count - 1 && count > 0) | |
386 { | |
387 file_image_change_to(count - 1); | |
388 } | |
389 } | |
390 | |
391 /* | |
392 *----------------------------------------------------------------------------- | |
393 * file delete/rename update routines | |
394 *----------------------------------------------------------------------------- | |
395 */ | |
396 | |
397 static gint file_find_closest_unaccounted(gint row, gint count, GList *ignore_list) | |
398 { | |
399 GList *list = NULL; | |
400 GList *work; | |
401 gint rev = row - 1; | |
402 row ++; | |
403 | |
404 work = ignore_list; | |
405 while(work) | |
406 { | |
407 gint f = find_file_in_list(work->data); | |
408 if (f >= 0) list = g_list_append(list, GINT_TO_POINTER(f)); | |
409 work = work->next; | |
410 } | |
411 | |
412 while(list) | |
413 { | |
414 gint c = TRUE; | |
415 work = list; | |
416 while(work && c) | |
417 { | |
418 gpointer p = work->data; | |
419 work = work->next; | |
420 if (row == GPOINTER_TO_INT(p)) | |
421 { | |
422 row++; | |
423 c = FALSE; | |
424 } | |
425 if (rev == GPOINTER_TO_INT(p)) | |
426 { | |
427 rev--; | |
428 c = FALSE; | |
429 } | |
430 if (!c) list = g_list_remove(list, p); | |
431 } | |
432 if (c && list) | |
433 { | |
434 g_list_free(list); | |
435 list = NULL; | |
436 } | |
437 } | |
438 if (row > count - 1) | |
439 { | |
440 if (rev < 0) | |
441 return -1; | |
442 else | |
443 return rev; | |
444 } | |
445 else | |
446 { | |
447 return row; | |
448 } | |
449 } | |
450 | |
451 void file_is_gone(gchar *path, GList *ignore_list) | |
452 { | |
453 GList *list; | |
454 gchar *name; | |
455 gint row; | |
456 gint new_row = -1; | |
457 row = find_file_in_list(path); | |
458 if (row < 0) return; | |
459 | |
460 if (file_is_selected(row) /* && file_selection_count() == 1 */) | |
461 { | |
462 gint n = file_count(); | |
463 if (ignore_list) | |
464 { | |
465 new_row = file_find_closest_unaccounted(row, n, ignore_list); | |
466 if (debug) printf("row = %d, closest is %d\n", row, new_row); | |
467 } | |
468 else | |
469 { | |
470 if (row + 1 < n) | |
471 { | |
472 new_row = row + 1; | |
473 } | |
474 else if (row > 0) | |
475 { | |
476 new_row = row - 1; | |
477 } | |
478 } | |
479 gtk_clist_unselect_all(GTK_CLIST(file_clist)); | |
480 if (new_row >= 0) | |
481 { | |
482 gtk_clist_select_row(GTK_CLIST(file_clist), new_row, -1); | |
483 file_image_change_to(new_row); | |
484 } | |
485 else | |
486 { | |
487 image_change_to(NULL); | |
488 } | |
489 } | |
490 | |
491 gtk_clist_remove(GTK_CLIST(file_clist), row); | |
492 list = g_list_nth(file_list, row); | |
493 name = list->data; | |
494 file_list = g_list_remove(file_list, name); | |
495 g_free(name); | |
496 update_status_label(NULL); | |
497 } | |
498 | |
499 void file_is_renamed(gchar *source, gchar *dest) | |
500 { | |
501 gint row; | |
502 gchar *source_base; | |
503 gchar *dest_base; | |
504 | |
505 if (image_get_path() && !strcmp(source, image_get_path())) | |
506 { | |
507 image_set_path(dest); | |
508 } | |
509 | |
510 row = find_file_in_list(source); | |
511 if (row < 0) return; | |
512 | |
513 source_base = remove_level_from_path(source); | |
514 dest_base = remove_level_from_path(dest); | |
515 | |
516 if (strcmp(source_base, dest_base) == 0) | |
517 { | |
518 gchar *name; | |
519 gint n; | |
520 GList *work = g_list_nth(file_list, row); | |
521 name = work->data; | |
522 file_list = g_list_remove(file_list, name); | |
523 g_free(name); | |
524 name = g_strdup(filename_from_path(dest)); | |
525 file_list = g_list_insert_sorted(file_list, name, (GCompareFunc) sort_list_cb); | |
526 n = g_list_index(file_list, name); | |
527 | |
528 if (gtk_clist_get_cell_type(GTK_CLIST(file_clist), row, 0) != GTK_CELL_PIXTEXT) | |
529 { | |
530 gtk_clist_set_text (GTK_CLIST(file_clist), row, 0, name); | |
531 } | |
532 else | |
533 { | |
534 guint8 spacing = 0; | |
535 GdkPixmap *pixmap = NULL; | |
536 GdkBitmap *mask = NULL; | |
537 gtk_clist_get_pixtext(GTK_CLIST(file_clist), row, 0, | |
538 NULL, &spacing, &pixmap, &mask); | |
539 gtk_clist_set_pixtext(GTK_CLIST(file_clist), row, 0, | |
540 name, spacing, pixmap, mask); | |
541 } | |
542 | |
543 gtk_clist_set_row_data(GTK_CLIST(file_clist), row, name); | |
544 gtk_clist_row_move(GTK_CLIST(file_clist), row, n); | |
545 } | |
546 else | |
547 { | |
548 GList *work = g_list_nth(file_list, row); | |
549 gchar *name = work->data; | |
550 file_list = g_list_remove(file_list, name); | |
551 gtk_clist_remove(GTK_CLIST(file_clist), row); | |
552 g_free(name); | |
553 update_status_label(NULL); | |
554 } | |
555 | |
556 g_free(source_base); | |
557 g_free(dest_base); | |
558 | |
559 } | |
560 | |
561 /* | |
562 *----------------------------------------------------------------------------- | |
563 * directory list callbacks | |
564 *----------------------------------------------------------------------------- | |
565 */ | |
566 | |
567 void dir_select_cb(GtkWidget *widget, gint row, gint col, | |
568 GdkEvent *event, gpointer data) | |
569 { | |
570 gchar *name; | |
571 gchar *new_path; | |
572 name = gtk_clist_get_row_data (GTK_CLIST(dir_clist), row); | |
573 if (strcmp(name, ".") == 0) | |
574 { | |
575 new_path = g_strdup(current_path); | |
576 } | |
577 else if (strcmp(name, "..") == 0) | |
578 { | |
579 new_path = remove_level_from_path(current_path); | |
580 } | |
581 else | |
582 { | |
583 if (strcmp(current_path, "/") == 0) | |
584 new_path = g_strconcat(current_path, name, NULL); | |
585 else | |
586 new_path = g_strconcat(current_path, "/", name, NULL); | |
587 } | |
588 filelist_change_to(new_path); | |
589 g_free(new_path); | |
590 } | |
591 | |
592 void dir_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) | |
593 { | |
594 gint row = -1; | |
595 gint col = -1; | |
596 | |
597 gtk_clist_get_selection_info (GTK_CLIST (widget), bevent->x, bevent->y, &row, &col); | |
598 | |
599 if (bevent->button == 2) | |
600 { | |
601 gtk_object_set_user_data(GTK_OBJECT(dir_clist), GINT_TO_POINTER(row)); | |
602 } | |
603 } | |
604 | |
605 /* | |
606 *----------------------------------------------------------------------------- | |
607 * file list callbacks | |
608 *----------------------------------------------------------------------------- | |
609 */ | |
610 | |
611 void file_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) | |
612 { | |
613 gint row = -1; | |
614 gint col = -1; | |
615 | |
616 gtk_clist_get_selection_info (GTK_CLIST (widget), bevent->x, bevent->y, &row, &col); | |
617 if (row == -1 || col == -1) | |
618 { | |
619 filelist_click_row = -1; | |
620 return; | |
621 } | |
622 | |
623 filelist_click_row = row; | |
624 | |
625 if (bevent->button == 3) | |
626 { | |
627 file_clist_highlight_set(); | |
628 gtk_menu_popup (GTK_MENU(menu_file_popup), NULL, NULL, NULL, NULL, | |
629 bevent->button, bevent->time); | |
630 } | |
631 } | |
632 | |
633 void file_select_cb(GtkWidget *widget, gint row, gint col, | |
634 GdkEvent *event, gpointer data) | |
635 { | |
636 gchar *name; | |
637 gchar *path; | |
638 | |
639 if (file_selection_count() != 1) | |
640 { | |
641 update_status_label(NULL); | |
642 return; | |
643 } | |
644 | |
645 name = gtk_clist_get_row_data(GTK_CLIST(file_clist), row); | |
646 path = g_strconcat(current_path, "/", name, NULL); | |
647 image_change_to(path); | |
648 update_status_label(NULL); | |
649 g_free(path); | |
650 } | |
651 | |
652 void file_unselect_cb(GtkWidget *widget, gint row, gint col, | |
653 GdkEvent *event, gpointer data) | |
654 { | |
655 #if 0 | |
656 gchar *name; | |
657 gchar *path; | |
658 | |
659 name = gtk_clist_get_row_data(GTK_CLIST(file_clist), row); | |
660 path = g_strconcat(current_path, "/", name, NULL); | |
661 | |
662 if (strcmp(path, image_get_path()) == 0) | |
663 { | |
664 if (file_selection_count() > 0 && !file_is_selected(find_file_in_list(image_get_path())) ) | |
665 { | |
666 gint new_row = GPOINTER_TO_INT(GTK_CLIST(file_clist)->selection->data); | |
667 gchar *new_name = gtk_clist_get_row_data(GTK_CLIST(file_clist), new_row); | |
668 gchar *new_path = g_strconcat(current_path, "/", new_name, NULL); | |
669 image_change_to(new_path); | |
670 g_free(new_path); | |
671 } | |
672 } | |
673 g_free(path); | |
674 #endif | |
675 update_status_label(NULL); | |
676 } | |
677 | |
678 /* | |
679 *----------------------------------------------------------------------------- | |
680 * file list highlight utils | |
681 *----------------------------------------------------------------------------- | |
682 */ | |
683 | |
684 void file_clist_highlight_set() | |
685 { | |
686 if (file_clicked_is_selected()) return; | |
687 | |
688 gtk_clist_set_background(GTK_CLIST(file_clist), filelist_click_row, | |
689 >K_WIDGET (file_clist)->style->bg[GTK_STATE_PRELIGHT]); | |
690 gtk_clist_set_foreground(GTK_CLIST(file_clist), filelist_click_row, | |
691 >K_WIDGET (file_clist)->style->fg[GTK_STATE_PRELIGHT]); | |
692 } | |
693 | |
694 void file_clist_highlight_unset() | |
695 { | |
696 if (file_clicked_is_selected()) return; | |
697 | |
698 gtk_clist_set_background(GTK_CLIST(file_clist), filelist_click_row, NULL); | |
699 gtk_clist_set_foreground(GTK_CLIST(file_clist), filelist_click_row, NULL); | |
700 } | |
701 | |
702 /* | |
703 *----------------------------------------------------------------------------- | |
704 * path entry and history menu | |
705 *----------------------------------------------------------------------------- | |
706 */ | |
707 | |
708 void path_entry_cb(gchar *newdir, gpointer data) | |
709 { | |
710 gchar *new_path = g_strdup(newdir); | |
711 parse_out_relatives(new_path); | |
712 if (isdir(new_path)) | |
713 filelist_change_to(new_path); | |
714 else if (isfile(new_path)) | |
715 { | |
716 gchar *path = remove_level_from_path(new_path); | |
717 filelist_change_to(path); | |
718 g_free(path); | |
719 image_change_to(new_path); | |
720 } | |
721 g_free(new_path); | |
722 } | |
723 | |
724 static void history_menu_select_cb(GtkWidget *widget, gpointer data) | |
725 { | |
726 gchar *new_path = data; | |
727 filelist_change_to(new_path); | |
728 } | |
729 | |
730 static gchar *truncate_hist_text(gchar *t, gint l) | |
731 { | |
732 gchar *tp; | |
733 gchar *tbuf; | |
734 if (l >= strlen(t)) return g_strdup(t); | |
735 tp = t + strlen(t) - l; | |
736 while (tp[0] != '/' && tp < t + strlen(t)) tp++; | |
737 /* this checks to see if directory name is longer than l, if so | |
738 * reset the length of name to l, it's better to have a partial | |
739 * name than no name at all. | |
740 */ | |
741 if (tp >= t + strlen(t)) tp = t + strlen(t) - l; | |
742 tbuf = g_strconcat("/...", tp, NULL); | |
743 return tbuf; | |
744 } | |
745 | |
746 static void filelist_set_history(gchar *path) | |
747 { | |
748 static GList *history_list = NULL; | |
749 gchar *buf; | |
750 gchar *buf_ptr; | |
751 GtkWidget *menu; | |
752 GtkWidget *item; | |
753 | |
754 if (!path) return; | |
755 | |
756 gtk_entry_set_text(GTK_ENTRY(path_entry), current_path); | |
757 | |
758 if (history_list) | |
759 { | |
760 g_list_foreach(history_list, (GFunc)g_free, NULL); | |
761 g_list_free(history_list); | |
762 history_list = NULL; | |
763 } | |
764 | |
765 menu = gtk_menu_new(); | |
766 | |
767 buf = g_strdup(path); | |
768 buf_ptr = buf + strlen(buf) - 1 ; | |
769 while (buf_ptr > buf) | |
770 { | |
771 gchar *full_path; | |
772 gchar *truncated; | |
773 truncated = truncate_hist_text(buf, 32); | |
774 | |
775 full_path = g_strdup(buf); | |
776 history_list = g_list_append(history_list, full_path); | |
777 | |
778 item = gtk_menu_item_new_with_label (truncated); | |
779 gtk_signal_connect (GTK_OBJECT (item), "activate", | |
780 (GtkSignalFunc) history_menu_select_cb, full_path); | |
781 | |
782 gtk_menu_append (GTK_MENU (menu), item); | |
783 gtk_widget_show (item); | |
784 | |
785 g_free(truncated); | |
786 | |
787 while (buf_ptr[0] != '/' && buf_ptr > buf) buf_ptr--; | |
788 buf_ptr[0] = '\0'; | |
789 } | |
790 g_free(buf); | |
791 | |
792 item = gtk_menu_item_new_with_label ("/"); | |
793 | |
794 gtk_signal_connect (GTK_OBJECT (item), "activate", | |
795 (GtkSignalFunc) history_menu_select_cb, "/"); | |
796 | |
797 gtk_menu_append (GTK_MENU (menu), item); | |
798 gtk_widget_show (item); | |
799 | |
800 gtk_option_menu_set_menu(GTK_OPTION_MENU(history_menu), menu); | |
801 } | |
802 | |
803 /* | |
804 *----------------------------------------------------------------------------- | |
805 * list update routines (public) | |
806 *----------------------------------------------------------------------------- | |
807 */ | |
808 | |
809 static gint thumbs_running = 0; | |
810 | |
811 void interrupt_thumbs() | |
812 { | |
813 if (thumbs_running > 0) thumbs_running ++; | |
814 } | |
815 | |
816 void filelist_populate_clist() | |
817 { | |
818 GList *work; | |
819 gint width; | |
820 gint tmp_width; | |
821 gint row; | |
822 gchar *image_name = NULL; | |
823 gchar *buf; | |
824 | |
825 gint row_p = 0; | |
826 gchar *text; | |
827 guint8 spacing; | |
828 GdkPixmap *nopixmap; | |
829 GdkBitmap *nomask; | |
830 | |
831 interrupt_thumbs(); | |
832 | |
833 filelist_set_history(current_path); | |
834 | |
835 gtk_clist_freeze (GTK_CLIST (dir_clist)); | |
836 gtk_clist_clear (GTK_CLIST (dir_clist)); | |
837 | |
838 width = 0; | |
839 work = dir_list; | |
840 while(work) | |
841 { | |
842 gchar *buf[2]; | |
843 buf[0] = work->data; | |
844 buf[1] = NULL; | |
845 row = gtk_clist_append(GTK_CLIST(dir_clist), buf); | |
846 gtk_clist_set_row_data (GTK_CLIST(dir_clist), row, work->data); | |
847 tmp_width = gdk_string_width(dir_clist->style->font, buf[0]); | |
848 if (tmp_width > width) width = tmp_width; | |
849 work = work->next; | |
850 } | |
851 | |
852 gtk_clist_set_column_width(GTK_CLIST(dir_clist), 0, width); | |
853 gtk_clist_thaw(GTK_CLIST (dir_clist)); | |
854 | |
855 buf = remove_level_from_path(image_get_path()); | |
856 if (buf && strcmp(buf, current_path) == 0) | |
857 { | |
858 image_name = image_get_name(); | |
859 } | |
860 g_free(buf); | |
861 | |
862 gtk_clist_freeze (GTK_CLIST (file_clist)); | |
863 | |
864 if (!thumbnails_enabled) | |
865 { | |
866 gtk_clist_set_row_height (GTK_CLIST(file_clist), | |
867 GTK_WIDGET(file_clist)->style->font->ascent + | |
868 GTK_WIDGET(file_clist)->style->font->descent + 1); | |
869 } | |
870 else | |
871 { | |
872 gtk_clist_set_row_height (GTK_CLIST(file_clist), thumb_max_height + 2); | |
873 maintain_thumbnail_dir(current_path, FALSE); | |
874 } | |
875 | |
876 width = 0; | |
877 work = file_list; | |
878 | |
879 while(work) | |
880 { | |
881 gint has_pixmap; | |
882 gint match; | |
883 gchar *name = work->data; | |
884 gint done = FALSE; | |
885 | |
886 while (!done) | |
887 { | |
888 if (GTK_CLIST(file_clist)->rows > row_p) | |
889 { | |
890 if (gtk_clist_get_cell_type(GTK_CLIST(file_clist),row_p, 0) == GTK_CELL_PIXTEXT) | |
891 { | |
892 gtk_clist_get_pixtext(GTK_CLIST(file_clist), row_p, 0, &text, &spacing, &nopixmap, &nomask); | |
893 has_pixmap = TRUE; | |
894 } | |
895 else | |
896 { | |
897 gtk_clist_get_text(GTK_CLIST(file_clist), row_p, 0, &text); | |
898 has_pixmap = FALSE; | |
899 } | |
900 match = strcmp(name, text); | |
901 } | |
902 else | |
903 { | |
904 match = -1; | |
905 } | |
906 | |
907 if (match < 0) | |
908 { | |
909 gchar *buf[2]; | |
910 buf[0] = name; | |
911 buf[1] = NULL; | |
912 row = gtk_clist_insert(GTK_CLIST(file_clist), row_p, buf); | |
913 gtk_clist_set_row_data (GTK_CLIST(file_clist), row, name); | |
914 if (thumbnails_enabled) | |
915 gtk_clist_set_shift(GTK_CLIST(file_clist), row, 0, 0, 5 + thumb_max_width); | |
916 done = TRUE; | |
917 if (image_name && strcmp(name, image_name) == 0) | |
918 gtk_clist_select_row(GTK_CLIST(file_clist), row, 0); | |
919 } | |
920 else if (match > 0) | |
921 { | |
922 gtk_clist_remove(GTK_CLIST(file_clist), row_p); | |
923 } | |
924 else | |
925 { | |
926 if (thumbnails_enabled && !has_pixmap) | |
927 gtk_clist_set_shift(GTK_CLIST(file_clist), row_p, 0, 0, 5 + thumb_max_width); | |
928 if (!thumbnails_enabled/* && has_pixmap*/) | |
929 { | |
930 gtk_clist_set_text(GTK_CLIST(file_clist), row_p, 0, name); | |
931 gtk_clist_set_shift(GTK_CLIST(file_clist), row_p, 0, 0, 0); | |
932 } | |
933 gtk_clist_set_row_data (GTK_CLIST(file_clist), row_p, name); | |
934 done = TRUE; | |
935 } | |
936 } | |
937 row_p++; | |
938 | |
939 if (thumbnails_enabled) | |
940 tmp_width = gdk_string_width(file_clist->style->font, name) + thumb_max_width + 5; | |
941 else | |
942 tmp_width = gdk_string_width(file_clist->style->font, name); | |
943 if (tmp_width > width) width = tmp_width; | |
944 work = work->next; | |
945 } | |
946 | |
947 while (GTK_CLIST(file_clist)->rows > row_p) | |
948 gtk_clist_remove(GTK_CLIST(file_clist), row_p); | |
949 | |
950 gtk_clist_set_column_width(GTK_CLIST(file_clist), 0, width); | |
951 gtk_clist_thaw(GTK_CLIST (file_clist)); | |
952 | |
953 if (thumbnails_enabled) | |
954 { | |
955 GList *done_list = NULL; | |
956 gint past_run; | |
957 gint finished = FALSE; | |
958 gint j; | |
959 gint count = 0; | |
960 update_status_label(_("Loading thumbs...")); | |
961 | |
962 for (j = 0; j < GTK_CLIST(file_clist)->rows; j++) | |
963 { | |
964 done_list = g_list_prepend(done_list, GINT_TO_POINTER(FALSE)); | |
965 } | |
966 | |
967 /* load thumbs */ | |
968 | |
969 while (!finished && done_list) | |
970 { | |
971 gint p = -1; | |
972 gint r = -1; | |
973 gint c = -1; | |
974 gtk_clist_get_selection_info (GTK_CLIST(file_clist), 1, 1, &r, &c); | |
975 if (r != -1) | |
976 { | |
977 work = g_list_nth(done_list, r); | |
978 while (work) | |
979 { | |
980 if (gtk_clist_row_is_visible(GTK_CLIST(file_clist), r)) | |
981 { | |
982 if (!GPOINTER_TO_INT(work->data)) | |
983 { | |
984 work->data = GINT_TO_POINTER(TRUE); | |
985 p = r; | |
986 work = NULL; | |
987 } | |
988 else | |
989 { | |
990 r++; | |
991 work = work->next; | |
992 } | |
993 } | |
994 else | |
995 { | |
996 work = NULL; | |
997 } | |
998 } | |
999 } | |
1000 if (p == -1) | |
1001 { | |
1002 work = done_list; | |
1003 r = 0; | |
1004 while(work && p == -1) | |
1005 { | |
1006 if (!GPOINTER_TO_INT(work->data)) | |
1007 { | |
1008 p = r; | |
1009 work->data = GINT_TO_POINTER(TRUE); | |
1010 } | |
1011 else | |
1012 { | |
1013 r++; | |
1014 work = work->next; | |
1015 if (!work) finished = TRUE; | |
1016 } | |
1017 } | |
1018 } | |
1019 | |
1020 count++; | |
1021 | |
1022 if (!finished && gtk_clist_get_cell_type(GTK_CLIST(file_clist), p, 0) != GTK_CELL_PIXTEXT) | |
1023 { | |
1024 GdkPixmap *pixmap = NULL; | |
1025 GdkBitmap *mask = NULL; | |
1026 gchar *name; | |
1027 gchar *path; | |
1028 | |
1029 thumbs_running ++; | |
1030 past_run = thumbs_running; | |
1031 while(gtk_events_pending()) gtk_main_iteration(); | |
1032 if (thumbs_running > past_run) | |
1033 { | |
1034 thumbs_running -= 2; | |
1035 update_progressbar(0.0); | |
1036 update_status_label(NULL); | |
1037 g_list_free(done_list); | |
1038 return; | |
1039 } | |
1040 thumbs_running --; | |
1041 | |
1042 name = gtk_clist_get_row_data(GTK_CLIST(file_clist), p); | |
1043 path = g_strconcat (current_path, "/", name, NULL); | |
1044 spacing = create_thumbnail(path, &pixmap, &mask); | |
1045 g_free(path); | |
1046 gtk_clist_set_pixtext (GTK_CLIST(file_clist), p, 0, name, spacing + 5, pixmap, mask); | |
1047 gtk_clist_set_shift(GTK_CLIST(file_clist), p, 0, 0, 0); | |
1048 | |
1049 update_progressbar((gfloat)(count) / GTK_CLIST(file_clist)->rows); | |
1050 } | |
1051 } | |
1052 update_progressbar(0.0); | |
1053 g_list_free(done_list); | |
1054 } | |
1055 | |
1056 update_status_label(NULL); | |
1057 } | |
1058 | |
1059 void filelist_refresh() | |
1060 { | |
1061 filelist_read(current_path); | |
1062 filelist_populate_clist(); | |
1063 filelist_click_row = -1; | |
1064 } | |
1065 | |
1066 void filelist_change_to(gchar *path) | |
1067 { | |
1068 if (!isdir(path)) return; | |
1069 | |
1070 g_free(current_path); | |
1071 current_path = g_strdup(path); | |
1072 | |
1073 filelist_refresh(); | |
1074 } |