comparison src/layout_util.c @ 9:d907d608745f

Sync to GQview 1.5.9 release. ######## DO NOT BASE ENHANCEMENTS OR TRANSLATION UPDATES ON CODE IN THIS CVS! This CVS is never up to date with current development and is provided solely for reference purposes, please use the latest official release package when making any changes or translation updates. ########
author gqview
date Sat, 26 Feb 2005 00:13:35 +0000
parents
children 147f4c4b9025
comparison
equal deleted inserted replaced
8:e0d0593d519e 9:d907d608745f
1 /*
2 * GQview
3 * (C) 2004 John Ellis
4 *
5 * Author: John Ellis
6 *
7 * This software is released under the GNU General Public License (GNU GPL).
8 * Please read the included file COPYING for more information.
9 * This software comes with no warranty of any kind, use at your own risk!
10 */
11
12
13 #include "gqview.h"
14 #include "layout_util.h"
15
16 #include "bar_info.h"
17 #include "bar_exif.h"
18 #include "bar_sort.h"
19 #include "cache_maint.h"
20 #include "collect.h"
21 #include "collect-dlg.h"
22 #include "dupe.h"
23 #include "editors.h"
24 #include "info.h"
25 #include "layout_image.h"
26 #include "pixbuf_util.h"
27 #include "preferences.h"
28 #include "print.h"
29 #include "search.h"
30 #include "utilops.h"
31 #include "ui_bookmark.h"
32 #include "ui_fileops.h"
33 #include "ui_menu.h"
34 #include "ui_misc.h"
35 #include "ui_tabcomp.h"
36
37 #include <gdk/gdkkeysyms.h> /* for keyboard values */
38
39 #include "icons/icon_thumb.xpm"
40 #include "icons/icon_float.xpm"
41
42
43 #define MENU_EDIT_ACTION_OFFSET 16
44
45
46 /*
47 *-----------------------------------------------------------------------------
48 * keyboard handler
49 *-----------------------------------------------------------------------------
50 */
51
52 static guint tree_key_overrides[] = {
53 GDK_Page_Up, GDK_KP_Page_Up,
54 GDK_Page_Down, GDK_KP_Page_Down,
55 GDK_Home, GDK_KP_Home,
56 GDK_End, GDK_KP_End
57 };
58
59 static gint layout_key_match(guint keyval)
60 {
61 gint i;
62
63 for (i = 0; i < sizeof(tree_key_overrides) / sizeof(guint); i++)
64 {
65 if (keyval == tree_key_overrides[i]) return TRUE;
66 }
67
68 return FALSE;
69 }
70
71 static gint layout_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer data)
72 {
73 LayoutWindow *lw = data;
74 gint stop_signal = FALSE;
75 gint x = 0;
76 gint y = 0;
77
78 if (lw->path_entry && GTK_WIDGET_HAS_FOCUS(lw->path_entry))
79 {
80 if (event->keyval == GDK_Escape && lw->path)
81 {
82 gtk_entry_set_text(GTK_ENTRY(lw->path_entry), lw->path);
83 }
84
85 /* the gtkaccelgroup of the window is stealing presses before they get to the entry (and more),
86 * so when the some widgets have focus, give them priority (HACK)
87 */
88 if (gtk_widget_event(lw->path_entry, (GdkEvent *)event))
89 {
90 return TRUE;
91 }
92 }
93 if (lw->vdt && GTK_WIDGET_HAS_FOCUS(lw->vdt->treeview) &&
94 !layout_key_match(event->keyval) &&
95 gtk_widget_event(lw->vdt->treeview, (GdkEvent *)event))
96 {
97 return TRUE;
98 }
99 if (lw->bar_info &&
100 bar_info_event(lw->bar_info, (GdkEvent *)event))
101 {
102 return TRUE;
103 }
104
105 if (lw->image &&
106 (GTK_WIDGET_HAS_FOCUS(lw->image->widget) || (lw->tools && widget == lw->window)) )
107 {
108 switch (event->keyval)
109 {
110 case GDK_Left: case GDK_KP_Left:
111 x -= 1;
112 stop_signal = TRUE;
113 break;
114 case GDK_Right: case GDK_KP_Right:
115 x += 1;
116 stop_signal = TRUE;
117 break;
118 case GDK_Up: case GDK_KP_Up:
119 y -= 1;
120 stop_signal = TRUE;
121 break;
122 case GDK_Down: case GDK_KP_Down:
123 y += 1;
124 stop_signal = TRUE;
125 break;
126 case GDK_BackSpace:
127 case 'B': case 'b':
128 layout_image_prev(lw);
129 stop_signal = TRUE;
130 break;
131 case GDK_space:
132 case 'N': case 'n':
133 layout_image_next(lw);
134 stop_signal = TRUE;
135 break;
136 case GDK_Menu:
137 layout_image_menu_popup(lw);
138 stop_signal = TRUE;
139 break;
140 }
141 }
142
143 if (!stop_signal && !(event->state & GDK_CONTROL_MASK) )
144 switch (event->keyval)
145 {
146 case '+': case GDK_KP_Add:
147 layout_image_zoom_adjust(lw, get_zoom_increment());
148 stop_signal = TRUE;
149 break;
150 case GDK_KP_Subtract:
151 layout_image_zoom_adjust(lw, -get_zoom_increment());
152 stop_signal = TRUE;
153 break;
154 case GDK_KP_Multiply:
155 layout_image_zoom_set(lw, 0.0);
156 stop_signal = TRUE;
157 break;
158 case GDK_KP_Divide:
159 case '1':
160 layout_image_zoom_set(lw, 1.0);
161 stop_signal = TRUE;
162 break;
163 case '2':
164 layout_image_zoom_set(lw, 2.0);
165 stop_signal = TRUE;
166 break;
167 case '3':
168 layout_image_zoom_set(lw, 3.0);
169 stop_signal = TRUE;
170 break;
171 case '4':
172 layout_image_zoom_set(lw, 4.0);
173 stop_signal = TRUE;
174 break;
175 case '7':
176 layout_image_zoom_set(lw, -4.0);
177 stop_signal = TRUE;
178 break;
179 case '8':
180 layout_image_zoom_set(lw, -3.0);
181 stop_signal = TRUE;
182 break;
183 case '9':
184 layout_image_zoom_set(lw, -2.0);
185 stop_signal = TRUE;
186 break;
187 case 'W': case 'w':
188 layout_image_zoom_set_fill_geometry(lw, FALSE);
189 break;
190 case 'H': case 'h':
191 layout_image_zoom_set_fill_geometry(lw, TRUE);
192 break;
193 case GDK_Page_Up: case GDK_KP_Page_Up:
194 layout_image_prev(lw);
195 stop_signal = TRUE;
196 break;
197 case GDK_Page_Down: case GDK_KP_Page_Down:
198 layout_image_next(lw);
199 stop_signal = TRUE;
200 break;
201 case GDK_Home: case GDK_KP_Home:
202 layout_image_first(lw);
203 stop_signal = TRUE;
204 break;
205 case GDK_End: case GDK_KP_End:
206 layout_image_last(lw);
207 stop_signal = TRUE;
208 break;
209 case GDK_Delete: case GDK_KP_Delete:
210 if (enable_delete_key)
211 {
212 file_util_delete(NULL, layout_selection_list(lw), widget);
213 stop_signal = TRUE;
214 }
215 break;
216 case GDK_Escape:
217 /* FIXME:interrupting thumbs no longer allowed */
218 #if 0
219 interrupt_thumbs();
220 #endif
221 stop_signal = TRUE;
222 break;
223 case 'P': case 'p':
224 layout_image_slideshow_pause_toggle(lw);
225 break;
226 case 'V': case 'v':
227 if (!(event->state & GDK_MOD1_MASK)) layout_image_full_screen_toggle(lw);
228 break;
229 }
230
231 if (event->state & GDK_SHIFT_MASK)
232 {
233 x *= 3;
234 y *= 3;
235 }
236
237 if (x != 0 || y!= 0)
238 {
239 keyboard_scroll_calc(&x, &y, event);
240 layout_image_scroll(lw, x, y);
241 }
242
243 if (stop_signal) g_signal_stop_emission_by_name(G_OBJECT(widget), "key_press_event");
244
245 return stop_signal;
246 }
247
248 void layout_keyboard_init(LayoutWindow *lw, GtkWidget *window)
249 {
250 g_signal_connect(G_OBJECT(window), "key_press_event",
251 G_CALLBACK(layout_key_press_cb), lw);
252 }
253
254 /*
255 *-----------------------------------------------------------------------------
256 * menu callbacks
257 *-----------------------------------------------------------------------------
258 */
259
260 static void layout_menu_new_window_cb(GtkAction *action, gpointer data)
261 {
262 LayoutWindow *lw = data;
263 LayoutWindow *nw;
264
265 nw = layout_new(NULL, FALSE, FALSE);
266 layout_sort_set(nw, file_sort_method, file_sort_ascending);
267 layout_set_path(nw, layout_get_path(lw));
268 }
269
270 static void layout_menu_new_cb(GtkAction *action, gpointer data)
271 {
272 collection_window_new(NULL);
273 }
274
275 static void layout_menu_open_cb(GtkAction *action, gpointer data)
276 {
277 collection_dialog_load(NULL);
278 }
279
280 static void layout_menu_search_cb(GtkAction *action, gpointer data)
281 {
282 LayoutWindow *lw = data;
283
284 search_new(lw->path, layout_image_get_path(lw));
285 }
286
287 static void layout_menu_dupes_cb(GtkAction *action, gpointer data)
288 {
289 dupe_window_new(DUPE_MATCH_NAME);
290 }
291
292 static void layout_menu_print_cb(GtkAction *action, gpointer data)
293 {
294 LayoutWindow *lw = data;
295
296 print_window_new(layout_image_get_path(lw), layout_selection_list(lw), layout_list(lw), lw->window);
297 }
298
299 static void layout_menu_dir_cb(GtkAction *action, gpointer data)
300 {
301 LayoutWindow *lw = data;
302
303 file_util_create_dir(lw->path, lw->window);
304 }
305
306 static void layout_menu_copy_cb(GtkAction *action, gpointer data)
307 {
308 LayoutWindow *lw = data;
309
310 file_util_copy(NULL, layout_selection_list(lw), NULL, lw->window);
311 }
312
313 static void layout_menu_move_cb(GtkAction *action, gpointer data)
314 {
315 LayoutWindow *lw = data;
316
317 file_util_move(NULL, layout_selection_list(lw), NULL, lw->window);
318 }
319
320 static void layout_menu_rename_cb(GtkAction *action, gpointer data)
321 {
322 LayoutWindow *lw = data;
323
324 file_util_rename(NULL, layout_selection_list(lw), lw->window);
325 }
326
327 static void layout_menu_delete_cb(GtkAction *action, gpointer data)
328 {
329 LayoutWindow *lw = data;
330
331 file_util_delete(NULL, layout_selection_list(lw), lw->window);
332 }
333
334 static void layout_menu_close_cb(GtkAction *action, gpointer data)
335 {
336 LayoutWindow *lw = data;
337
338 layout_close(lw);
339 }
340
341 static void layout_menu_exit_cb(GtkAction *action, gpointer data)
342 {
343 exit_gqview();
344 }
345
346 static void layout_menu_alter_90_cb(GtkAction *action, gpointer data)
347 {
348 LayoutWindow *lw = data;
349
350 layout_image_alter(lw, ALTER_ROTATE_90);
351 }
352
353 static void layout_menu_alter_90cc_cb(GtkAction *action, gpointer data)
354 {
355 LayoutWindow *lw = data;
356
357 layout_image_alter(lw, ALTER_ROTATE_90_CC);
358 }
359
360 static void layout_menu_alter_180_cb(GtkAction *action, gpointer data)
361 {
362 LayoutWindow *lw = data;
363
364 layout_image_alter(lw, ALTER_ROTATE_180);
365 }
366
367 static void layout_menu_alter_mirror_cb(GtkAction *action, gpointer data)
368 {
369 LayoutWindow *lw = data;
370
371 layout_image_alter(lw, ALTER_MIRROR);
372 }
373
374 static void layout_menu_alter_flip_cb(GtkAction *action, gpointer data)
375 {
376 LayoutWindow *lw = data;
377
378 layout_image_alter(lw, ALTER_FLIP);
379 }
380
381 static void layout_menu_info_cb(GtkAction *action, gpointer data)
382 {
383 LayoutWindow *lw = data;
384 GList *list;
385 const gchar *path = NULL;
386
387 list = layout_selection_list(lw);
388 if (!list) path = layout_image_get_path(lw);
389
390 info_window_new(path, list);
391 }
392
393 static void layout_menu_select_all_cb(GtkAction *action, gpointer data)
394 {
395 LayoutWindow *lw = data;
396
397 layout_select_all(lw);
398 }
399
400 static void layout_menu_unselect_all_cb(GtkAction *action, gpointer data)
401 {
402 LayoutWindow *lw = data;
403
404 layout_select_none(lw);
405 }
406
407 static void layout_menu_config_cb(GtkAction *action, gpointer data)
408 {
409 show_config_window();
410 }
411
412 static void layout_menu_remove_thumb_cb(GtkAction *action, gpointer data)
413 {
414 cache_manager_show();
415 }
416
417 static void layout_menu_wallpaper_cb(GtkAction *action, gpointer data)
418 {
419 LayoutWindow *lw = data;
420
421 layout_image_to_root(lw);
422 }
423
424 static void layout_menu_zoom_in_cb(GtkAction *action, gpointer data)
425 {
426 LayoutWindow *lw = data;
427
428 layout_image_zoom_adjust(lw, get_zoom_increment());
429 }
430
431 static void layout_menu_zoom_out_cb(GtkAction *action, gpointer data)
432 {
433 LayoutWindow *lw = data;
434
435 layout_image_zoom_adjust(lw, -get_zoom_increment());
436 }
437
438 static void layout_menu_zoom_1_1_cb(GtkAction *action, gpointer data)
439 {
440 LayoutWindow *lw = data;
441
442 layout_image_zoom_set(lw, 1.0);
443 }
444
445 static void layout_menu_zoom_fit_cb(GtkAction *action, gpointer data)
446 {
447 LayoutWindow *lw = data;
448
449 layout_image_zoom_set(lw, 0.0);
450 }
451
452 static void layout_menu_thumb_cb(GtkToggleAction *action, gpointer data)
453 {
454 LayoutWindow *lw = data;
455
456 layout_thumb_set(lw, gtk_toggle_action_get_active(action));
457 }
458
459 static void layout_menu_list_cb(GtkRadioAction *action, GtkRadioAction *current, gpointer data)
460 {
461 LayoutWindow *lw = data;
462
463 layout_views_set(lw, lw->tree_view, (gtk_radio_action_get_current_value(action) == 1));
464 }
465
466 #if 0
467 static void layout_menu_icon_cb(gpointer data, guint action, GtkWidget *widget)
468 {
469 LayoutWindow *lw = data;
470
471 if (!GTK_CHECK_MENU_ITEM(widget)->active) return;
472
473 layout_views_set(lw, lw->tree_view, TRUE);
474 }
475 #endif
476
477 static void layout_menu_tree_cb(GtkToggleAction *action, gpointer data)
478 {
479 LayoutWindow *lw = data;
480
481 layout_views_set(lw, gtk_toggle_action_get_active(action), lw->icon_view);
482 }
483
484 static void layout_menu_fullscreen_cb(GtkAction *action, gpointer data)
485 {
486 LayoutWindow *lw = data;
487
488 layout_image_full_screen_toggle(lw);
489 }
490
491 static void layout_menu_refresh_cb(GtkAction *action, gpointer data)
492 {
493 LayoutWindow *lw = data;
494
495 layout_refresh(lw);
496 }
497
498 static void layout_menu_float_cb(GtkToggleAction *action, gpointer data)
499 {
500 LayoutWindow *lw = data;
501
502 if (lw->tools_float != gtk_toggle_action_get_active(action))
503 {
504 layout_tools_float_toggle(lw);
505 }
506 }
507
508 static void layout_menu_hide_cb(GtkAction *action, gpointer data)
509 {
510 LayoutWindow *lw = data;
511
512 layout_tools_hide_toggle(lw);
513 }
514
515 static void layout_menu_toolbar_cb(GtkToggleAction *action, gpointer data)
516 {
517 LayoutWindow *lw = data;
518
519 if (lw->toolbar_hidden != gtk_toggle_action_get_active(action))
520 {
521 layout_toolbar_toggle(lw);
522 }
523 }
524
525 static void layout_menu_bar_info_cb(GtkToggleAction *action, gpointer data)
526 {
527 LayoutWindow *lw = data;
528
529 if (lw->bar_info_enabled != gtk_toggle_action_get_active(action))
530 {
531 layout_bar_info_toggle(lw);
532 }
533 }
534
535 static void layout_menu_bar_exif_cb(GtkToggleAction *action, gpointer data)
536 {
537 LayoutWindow *lw = data;
538
539 if (lw->bar_exif_enabled != gtk_toggle_action_get_active(action))
540 {
541 layout_bar_exif_toggle(lw);
542 }
543 }
544
545 static void layout_menu_bar_sort_cb(GtkToggleAction *action, gpointer data)
546 {
547 LayoutWindow *lw = data;
548
549 if (lw->bar_sort_enabled != gtk_toggle_action_get_active(action))
550 {
551 layout_bar_sort_toggle(lw);
552 }
553 }
554
555 static void layout_menu_slideshow_cb(GtkAction *action, gpointer data)
556 {
557 LayoutWindow *lw = data;
558
559 layout_image_slideshow_toggle(lw);
560 }
561
562 static void layout_menu_help_cb(GtkAction *action, gpointer data)
563 {
564 help_window_show("html_contents");
565 }
566
567 static void layout_menu_help_keys_cb(GtkAction *action, gpointer data)
568 {
569 help_window_show("documentation");
570 }
571
572 static void layout_menu_notes_cb(GtkAction *action, gpointer data)
573 {
574 help_window_show("release_notes");
575 }
576
577 static void layout_menu_about_cb(GtkAction *action, gpointer data)
578 {
579 show_about_window();
580 }
581
582 /*
583 *-----------------------------------------------------------------------------
584 * edit menu
585 *-----------------------------------------------------------------------------
586 */
587
588 static void layout_menu_edit_cb(GtkAction *action, gpointer data)
589 {
590 LayoutWindow *lw = data;
591 GList *list;
592 gint n;
593
594 n = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(action), "edit_index"));
595
596 list = layout_selection_list(lw);
597 start_editor_from_path_list(n, list);
598 path_list_free(list);
599 }
600
601 static void layout_menu_edit_update(LayoutWindow *lw)
602 {
603 gint i;
604
605 /* main edit menu */
606
607 if (!lw->action_group) return;
608
609 for (i = 0; i < 10; i++)
610 {
611 gchar *key;
612 GtkAction *action;
613
614 key = g_strdup_printf("Editor%d", i);
615
616 action = gtk_action_group_get_action(lw->action_group, key);
617 g_object_set_data(G_OBJECT(action), "edit_index", GINT_TO_POINTER(i));
618
619 if (editor_command[i] && strlen(editor_command[i]) > 0)
620 {
621 gchar *text;
622
623 if (editor_name[i] && strlen(editor_name[i]) > 0)
624 {
625 text = g_strdup_printf(_("in %s..."), editor_name[i]);
626 }
627 else
628 {
629 text = g_strdup(_("in (unknown)..."));
630 }
631 g_object_set(action, "label", text,
632 "sensitive", TRUE, NULL);
633 g_free(text);
634 }
635 else
636 {
637 g_object_set(action, "label", _("empty"),
638 "sensitive", FALSE, NULL);
639 }
640
641 g_free(key);
642 }
643 }
644
645 void layout_edit_update_all(void)
646 {
647 GList *work;
648
649 work = layout_window_list;
650 while (work)
651 {
652 LayoutWindow *lw = work->data;
653 work = work->next;
654
655 layout_menu_edit_update(lw);
656 }
657 }
658
659 /*
660 *-----------------------------------------------------------------------------
661 * recent menu
662 *-----------------------------------------------------------------------------
663 */
664
665 static void layout_menu_recent_cb(GtkWidget *widget, gpointer data)
666 {
667 gint n;
668 gchar *path;
669
670 n = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "recent_index"));
671
672 path = g_list_nth_data(history_list_get_by_key("recent"), n);
673
674 if (!path) return;
675
676 /* make a copy of it */
677 path = g_strdup(path);
678 collection_window_new(path);
679 g_free(path);
680 }
681
682 static void layout_menu_recent_update(LayoutWindow *lw)
683 {
684 GtkWidget *menu;
685 GtkWidget *recent;
686 GtkWidget *item;
687 GList *list;
688 gint n;
689
690 if (!lw->ui_manager) return;
691
692 list = history_list_get_by_key("recent");
693 n = 0;
694
695 menu = gtk_menu_new();
696
697 while (list)
698 {
699 item = menu_item_add_simple(menu, filename_from_path((gchar *)list->data),
700 G_CALLBACK(layout_menu_recent_cb), lw);
701 g_object_set_data(G_OBJECT(item), "recent_index", GINT_TO_POINTER(n));
702 list = list->next;
703 n++;
704 }
705
706 if (n == 0)
707 {
708 menu_item_add(menu, _("Empty"), NULL, NULL);
709 }
710
711 recent = gtk_ui_manager_get_widget(lw->ui_manager, "/MainMenu/FileMenu/OpenRecent");
712 gtk_menu_item_set_submenu(GTK_MENU_ITEM(recent), menu);
713 gtk_widget_set_sensitive(recent, (n != 0));
714 }
715
716 void layout_recent_update_all(void)
717 {
718 GList *work;
719
720 work = layout_window_list;
721 while (work)
722 {
723 LayoutWindow *lw = work->data;
724 work = work->next;
725
726 layout_menu_recent_update(lw);
727 }
728 }
729
730 void layout_recent_add_path(const gchar *path)
731 {
732 if (!path) return;
733
734 history_list_add_to_key("recent", path, recent_list_max);
735
736 layout_recent_update_all();
737 }
738
739 /*
740 *-----------------------------------------------------------------------------
741 * menu
742 *-----------------------------------------------------------------------------
743 */
744
745 #define CB G_CALLBACK
746
747 static GtkActionEntry menu_entries[] = {
748 { "FileMenu", NULL, N_("_File") },
749 { "EditMenu", NULL, N_("_Edit") },
750 { "AdjustMenu", NULL, N_("_Adjust") },
751 { "ViewMenu", NULL, N_("_View") },
752 { "HelpMenu", NULL, N_("_Help") },
753
754 { "NewWindow", GTK_STOCK_NEW, N_("New _window"), NULL, NULL, CB(layout_menu_new_window_cb) },
755 { "NewCollection", GTK_STOCK_INDEX,N_("_New collection"), "C", NULL, CB(layout_menu_new_cb) },
756 { "OpenCollection", GTK_STOCK_OPEN, N_("_Open collection..."),"O", NULL, CB(layout_menu_open_cb) },
757 { "OpenRecent", NULL, N_("Open _recent") },
758 { "Search", GTK_STOCK_FIND, N_("_Search..."), "F3", NULL, CB(layout_menu_search_cb) },
759 { "FindDupes", GTK_STOCK_FIND, N_("_Find duplicates..."),"D", NULL, CB(layout_menu_dupes_cb) },
760 { "Print", GTK_STOCK_PRINT,N_("_Print..."), "<shift>P", NULL, CB(layout_menu_print_cb) },
761 { "NewFolder", NULL, N_("N_ew folder..."), "<control>F", NULL, CB(layout_menu_dir_cb) },
762 { "Copy", NULL, N_("_Copy..."), "<control>C", NULL, CB(layout_menu_copy_cb) },
763 { "Move", NULL, N_("_Move..."), "<control>M", NULL, CB(layout_menu_move_cb) },
764 { "Rename", NULL, N_("_Rename..."), "<control>R", NULL, CB(layout_menu_rename_cb) },
765 { "Delete", GTK_STOCK_DELETE, N_("_Delete..."), "<control>D", NULL, CB(layout_menu_delete_cb) },
766 { "CloseWindow", GTK_STOCK_CLOSE,N_("C_lose window"), "<control>W", NULL, CB(layout_menu_close_cb) },
767 { "Quit", GTK_STOCK_QUIT, N_("_Quit"), "<control>Q", NULL, CB(layout_menu_exit_cb) },
768
769 { "Editor0", NULL, "editor0", "<control>1", NULL, CB(layout_menu_edit_cb) },
770 { "Editor1", NULL, "editor1", "<control>2", NULL, CB(layout_menu_edit_cb) },
771 { "Editor2", NULL, "editor2", "<control>3", NULL, CB(layout_menu_edit_cb) },
772 { "Editor3", NULL, "editor3", "<control>4", NULL, CB(layout_menu_edit_cb) },
773 { "Editor4", NULL, "editor4", "<control>5", NULL, CB(layout_menu_edit_cb) },
774 { "Editor5", NULL, "editor5", "<control>6", NULL, CB(layout_menu_edit_cb) },
775 { "Editor6", NULL, "editor6", "<control>7", NULL, CB(layout_menu_edit_cb) },
776 { "Editor7", NULL, "editor7", "<control>8", NULL, CB(layout_menu_edit_cb) },
777 { "Editor8", NULL, "editor8", "<control>9", NULL, CB(layout_menu_edit_cb) },
778 { "Editor9", NULL, "editor9", "<control>0", NULL, CB(layout_menu_edit_cb) },
779 { "RotateCW", NULL, N_("_Rotate clockwise"), "bracketright", NULL, CB(layout_menu_alter_90_cb) },
780 { "RotateCCW", NULL, N_("Rotate _counterclockwise"), "bracketleft", NULL, CB(layout_menu_alter_90cc_cb) },
781 { "Rotate180", NULL, N_("Rotate 1_80"), "<shift>R", NULL, CB(layout_menu_alter_180_cb) },
782 { "Mirror", NULL, N_("_Mirror"), "<shift>M", NULL, CB(layout_menu_alter_mirror_cb) },
783 { "Flip", NULL, N_("_Flip"), "<shift>F", NULL, CB(layout_menu_alter_flip_cb) },
784 { "Properties",GTK_STOCK_PROPERTIES, N_("_Properties"), "<control>P", NULL, CB(layout_menu_info_cb) },
785 { "SelectAll", NULL, N_("Select _all"), "<control>A", NULL, CB(layout_menu_select_all_cb) },
786 { "SelectNone", NULL, N_("Select _none"), "<control><shift>A",NULL, CB(layout_menu_unselect_all_cb) },
787 { "Preferences",GTK_STOCK_PREFERENCES,N_("P_references..."), "<control>O", NULL, CB(layout_menu_config_cb) },
788 { "Maintenance", NULL, N_("_Thumbnail maintenance..."),NULL, NULL, CB(layout_menu_remove_thumb_cb) },
789 { "Wallpaper", NULL, N_("Set as _wallpaper"),NULL, NULL, CB(layout_menu_wallpaper_cb) },
790
791 { "ZoomIn", GTK_STOCK_ZOOM_IN, N_("Zoom _in"), "equal", NULL, CB(layout_menu_zoom_in_cb) },
792 { "ZoomOut", GTK_STOCK_ZOOM_OUT, N_("Zoom _out"), "minus", NULL, CB(layout_menu_zoom_out_cb) },
793 { "Zoom100", GTK_STOCK_ZOOM_100, N_("Zoom _1:1"), "Z", NULL, CB(layout_menu_zoom_1_1_cb) },
794 { "ZoomFit", GTK_STOCK_ZOOM_FIT, N_("_Zoom to fit"), "X", NULL, CB(layout_menu_zoom_fit_cb) },
795 { "FullScreen", NULL, N_("F_ull screen"), "F", NULL, CB(layout_menu_fullscreen_cb) },
796 { "HideTools", NULL, N_("_Hide file list"), "<control>H", NULL, CB(layout_menu_hide_cb) },
797 { "SlideShow", NULL, N_("Toggle _slideshow"),"S", NULL, CB(layout_menu_slideshow_cb) },
798 { "Refresh", GTK_STOCK_REFRESH, N_("_Refresh"), "R", NULL, CB(layout_menu_refresh_cb) },
799
800 { "HelpContents", GTK_STOCK_HELP, N_("_Contents"), "F1", NULL, CB(layout_menu_help_cb) },
801 { "HelpShortcuts", NULL, N_("_Keyboard shortcuts"),NULL, NULL, CB(layout_menu_help_keys_cb) },
802 { "HelpNotes", NULL, N_("_Release notes"), NULL, NULL, CB(layout_menu_notes_cb) },
803 { "About", NULL, N_("_About"), NULL, NULL, CB(layout_menu_about_cb) }
804 };
805
806 static GtkToggleActionEntry menu_toggle_entries[] = {
807 { "Thumbnails", NULL, N_("_Thumbnails"), "T", NULL, CB(layout_menu_thumb_cb) },
808 { "FolderTree", NULL, N_("Tr_ee"), "<control>T", NULL, CB(layout_menu_tree_cb) },
809 { "FloatTools", NULL, N_("_Float file list"), "L", NULL, CB(layout_menu_float_cb) },
810 { "HideToolbar", NULL, N_("Hide tool_bar"), NULL, NULL, CB(layout_menu_toolbar_cb) },
811 { "SBarKeywords", NULL, N_("_Keywords"), "<control>K", NULL, CB(layout_menu_bar_info_cb) },
812 { "SBarExif", NULL, N_("E_xif data"), "<control>E", NULL, CB(layout_menu_bar_exif_cb) },
813 { "SBarSort", NULL, N_("Sort _manager"), "<control>S", NULL, CB(layout_menu_bar_sort_cb) }
814 };
815
816 static GtkRadioActionEntry menu_radio_entries[] = {
817 { "ViewList", NULL, N_("_List"), "<control>L", NULL, 0 },
818 { "ViewIcons", NULL, N_("I_cons"), "<control>I", NULL, 1 }
819 };
820
821 #undef CB
822
823 static const char *menu_ui_description =
824 "<ui>"
825 " <menubar name='MainMenu'>"
826 " <menu action='FileMenu'>"
827 " <menuitem action='NewWindow'/>"
828 " <menuitem action='NewCollection'/>"
829 " <menuitem action='OpenCollection'/>"
830 " <menuitem action='OpenRecent'/>"
831 " <separator/>"
832 " <menuitem action='Search'/>"
833 " <menuitem action='FindDupes'/>"
834 " <separator/>"
835 " <menuitem action='Print'/>"
836 " <menuitem action='NewFolder'/>"
837 " <separator/>"
838 " <menuitem action='Copy'/>"
839 " <menuitem action='Move'/>"
840 " <menuitem action='Rename'/>"
841 " <menuitem action='Delete'/>"
842 " <separator/>"
843 " <menuitem action='CloseWindow'/>"
844 " <menuitem action='Quit'/>"
845 " </menu>"
846 " <menu action='EditMenu'>"
847 " <menuitem action='Editor0'/>"
848 " <menuitem action='Editor1'/>"
849 " <menuitem action='Editor2'/>"
850 " <menuitem action='Editor3'/>"
851 " <menuitem action='Editor4'/>"
852 " <menuitem action='Editor5'/>"
853 " <menuitem action='Editor6'/>"
854 " <menuitem action='Editor7'/>"
855 " <menuitem action='Editor8'/>"
856 " <menuitem action='Editor9'/>"
857 " <separator/>"
858 " <menu action='AdjustMenu'>"
859 " <menuitem action='RotateCW'/>"
860 " <menuitem action='RotateCCW'/>"
861 " <menuitem action='Rotate180'/>"
862 " <menuitem action='Mirror'/>"
863 " <menuitem action='Flip'/>"
864 " </menu>"
865 " <menuitem action='Properties'/>"
866 " <separator/>"
867 " <menuitem action='SelectAll'/>"
868 " <menuitem action='SelectNone'/>"
869 " <separator/>"
870 " <menuitem action='Preferences'/>"
871 " <menuitem action='Maintenance'/>"
872 " <separator/>"
873 " <menuitem action='Wallpaper'/>"
874 " </menu>"
875 " <menu action='ViewMenu'>"
876 " <separator/>"
877 " <menuitem action='ZoomIn'/>"
878 " <menuitem action='ZoomOut'/>"
879 " <menuitem action='Zoom100'/>"
880 " <menuitem action='ZoomFit'/>"
881 " <separator/>"
882 " <menuitem action='Thumbnails'/>"
883 " <menuitem action='ViewList'/>"
884 " <menuitem action='ViewIcons'/>"
885 " <separator/>"
886 " <menuitem action='FolderTree'/>"
887 " <menuitem action='FullScreen'/>"
888 " <separator/>"
889 " <menuitem action='FloatTools'/>"
890 " <menuitem action='HideTools'/>"
891 " <menuitem action='HideToolbar'/>"
892 " <separator/>"
893 " <menuitem action='SBarKeywords'/>"
894 " <menuitem action='SBarExif'/>"
895 " <menuitem action='SBarSort'/>"
896 " <separator/>"
897 " <menuitem action='SlideShow'/>"
898 " <menuitem action='Refresh'/>"
899 " </menu>"
900 " <menu action='HelpMenu'>"
901 " <separator/>"
902 " <menuitem action='HelpContents'/>"
903 " <menuitem action='HelpShortcuts'/>"
904 " <menuitem action='HelpNotes'/>"
905 " <separator/>"
906 " <menuitem action='About'/>"
907 " </menu>"
908 " </menubar>"
909 "</ui>";
910
911
912 static gchar *menu_translate(const gchar *path, gpointer data)
913 {
914 return _(path);
915 }
916
917 void layout_actions_setup(LayoutWindow *lw)
918 {
919 GError *error;
920
921 if (lw->ui_manager) return;
922
923 lw->action_group = gtk_action_group_new ("MenuActions");
924 gtk_action_group_set_translate_func(lw->action_group, menu_translate, NULL, NULL);
925
926 gtk_action_group_add_actions(lw->action_group,
927 menu_entries, G_N_ELEMENTS(menu_entries), lw);
928 gtk_action_group_add_toggle_actions(lw->action_group,
929 menu_toggle_entries, G_N_ELEMENTS(menu_toggle_entries), lw);
930 gtk_action_group_add_radio_actions(lw->action_group,
931 menu_radio_entries, G_N_ELEMENTS(menu_radio_entries),
932 0, G_CALLBACK(layout_menu_list_cb), lw);
933
934 lw->ui_manager = gtk_ui_manager_new();
935 gtk_ui_manager_set_add_tearoffs(lw->ui_manager, TRUE);
936 gtk_ui_manager_insert_action_group(lw->ui_manager, lw->action_group, 0);
937
938 error = NULL;
939 if (!gtk_ui_manager_add_ui_from_string(lw->ui_manager, menu_ui_description, -1, &error))
940 {
941 g_message ("building menus failed: %s", error->message);
942 g_error_free (error);
943 exit (EXIT_FAILURE);
944 }
945 }
946
947 void layout_actions_add_window(LayoutWindow *lw, GtkWidget *window)
948 {
949 GtkAccelGroup *group;
950
951 if (!lw->ui_manager) return;
952
953 group = gtk_ui_manager_get_accel_group(lw->ui_manager);
954 gtk_window_add_accel_group(GTK_WINDOW(window), group);
955 }
956
957 GtkWidget *layout_actions_menu_bar(LayoutWindow *lw)
958 {
959 return gtk_ui_manager_get_widget(lw->ui_manager, "/MainMenu");
960 }
961
962
963 /*
964 *-----------------------------------------------------------------------------
965 * toolbar
966 *-----------------------------------------------------------------------------
967 */
968
969 static void layout_button_thumb_cb(GtkWidget *widget, gpointer data)
970 {
971 LayoutWindow *lw = data;
972
973 layout_thumb_set(lw, GTK_TOGGLE_BUTTON(widget)->active);
974 }
975
976 static void layout_button_home_cb(GtkWidget *widget, gpointer data)
977 {
978 LayoutWindow *lw = data;
979 const gchar *path = homedir();
980
981 if (path) layout_set_path(lw, path);
982 }
983
984 static void layout_button_refresh_cb(GtkWidget *widget, gpointer data)
985 {
986 LayoutWindow *lw = data;
987
988 layout_refresh(lw);
989 }
990
991 static void layout_button_zoom_in_cb(GtkWidget *widget, gpointer data)
992 {
993 LayoutWindow *lw = data;
994
995 layout_image_zoom_adjust(lw, get_zoom_increment());
996 }
997
998 static void layout_button_zoom_out_cb(GtkWidget *widget, gpointer data)
999 {
1000 LayoutWindow *lw = data;
1001
1002 layout_image_zoom_adjust(lw, -get_zoom_increment());
1003 }
1004
1005 static void layout_button_zoom_fit_cb(GtkWidget *widget, gpointer data)
1006 {
1007 LayoutWindow *lw = data;
1008
1009 layout_image_zoom_set(lw, 0.0);
1010 }
1011
1012 static void layout_button_zoom_1_1_cb(GtkWidget *widget, gpointer data)
1013 {
1014 LayoutWindow *lw = data;
1015
1016 layout_image_zoom_set(lw, 1.0);
1017 }
1018
1019 static void layout_button_config_cb(GtkWidget *widget, gpointer data)
1020 {
1021 show_config_window();
1022 }
1023
1024 static void layout_button_float_cb(GtkWidget *widget, gpointer data)
1025 {
1026 LayoutWindow *lw = data;
1027
1028 layout_tools_float_toggle(lw);
1029 }
1030
1031 GtkWidget *layout_button(GtkWidget *box, gchar **pixmap_data, const gchar *stock_id, gint toggle,
1032 GtkTooltips *tooltips, const gchar *tip_text,
1033 GCallback func, gpointer data)
1034 {
1035 GtkWidget *button;
1036 GtkWidget *icon;
1037
1038 if (toggle)
1039 {
1040 button = gtk_toggle_button_new();
1041 }
1042 else
1043 {
1044 button = gtk_button_new();
1045 }
1046
1047 g_signal_connect(G_OBJECT(button), "clicked", func, data);
1048 gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
1049 gtk_widget_show(button);
1050 gtk_tooltips_set_tip(tooltips, button, tip_text, NULL);
1051
1052 if (stock_id)
1053 {
1054 icon = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_BUTTON);
1055 }
1056 else
1057 {
1058 GdkPixbuf *pixbuf;
1059
1060 pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)pixmap_data);
1061 icon = gtk_image_new_from_pixbuf(pixbuf);
1062 gdk_pixbuf_unref(pixbuf);
1063 }
1064
1065 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
1066
1067 gtk_container_add(GTK_CONTAINER(button), icon);
1068 gtk_widget_show(icon);
1069
1070 return button;
1071 }
1072
1073 GtkWidget *layout_button_bar(LayoutWindow *lw)
1074 {
1075 GtkWidget *box;
1076 GtkTooltips *tooltips;
1077
1078 tooltips = lw->tooltips;
1079
1080 box = gtk_hbox_new(FALSE, 0);
1081
1082 lw->thumb_button = layout_button(box, (gchar **)icon_thumb_xpm, NULL, TRUE,
1083 tooltips, _("Show thumbnails"), G_CALLBACK(layout_button_thumb_cb), lw);
1084 layout_button(box, NULL, GTK_STOCK_HOME, FALSE,
1085 tooltips, _("Change to home folder"), G_CALLBACK(layout_button_home_cb), lw);
1086 layout_button(box, NULL, GTK_STOCK_REFRESH, FALSE,
1087 tooltips, _("Refresh file list"), G_CALLBACK(layout_button_refresh_cb), lw);
1088 layout_button(box, NULL, GTK_STOCK_ZOOM_IN, FALSE,
1089 tooltips, _("Zoom in"), G_CALLBACK(layout_button_zoom_in_cb), lw);
1090 layout_button(box, NULL, GTK_STOCK_ZOOM_OUT, FALSE,
1091 tooltips, _("Zoom out"), G_CALLBACK(layout_button_zoom_out_cb), lw);
1092 layout_button(box, NULL, GTK_STOCK_ZOOM_FIT, FALSE,
1093 tooltips, _("Fit image to window"), G_CALLBACK(layout_button_zoom_fit_cb), lw);
1094 layout_button(box, NULL, GTK_STOCK_ZOOM_100, FALSE,
1095 tooltips, _("Set zoom 1:1"), G_CALLBACK(layout_button_zoom_1_1_cb), lw);
1096 layout_button(box, NULL, GTK_STOCK_PREFERENCES, FALSE,
1097 tooltips, _("Configure options"), G_CALLBACK(layout_button_config_cb), lw);
1098 layout_button(box, (gchar **)icon_float_xpm, NULL, FALSE,
1099 tooltips, _("Float Controls"), G_CALLBACK(layout_button_float_cb), lw);
1100
1101 return box;
1102 }
1103
1104 /*
1105 *-----------------------------------------------------------------------------
1106 * misc
1107 *-----------------------------------------------------------------------------
1108 */
1109
1110 static void layout_util_sync_views(LayoutWindow *lw)
1111 {
1112 GtkAction *action;
1113
1114 if (!lw->action_group) return;
1115
1116 action = gtk_action_group_get_action(lw->action_group, "FolderTree");
1117 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->tree_view);
1118
1119 action = gtk_action_group_get_action(lw->action_group, "ViewIcons");
1120 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->icon_view);
1121
1122 action = gtk_action_group_get_action(lw->action_group, "FloatTools");
1123 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->tools_float);
1124
1125 action = gtk_action_group_get_action(lw->action_group, "SBarKeywords");
1126 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->bar_info_enabled);
1127
1128 action = gtk_action_group_get_action(lw->action_group, "SBarExif");
1129 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->bar_exif_enabled);
1130
1131 action = gtk_action_group_get_action(lw->action_group, "SBarSort");
1132 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->bar_sort_enabled);
1133
1134 action = gtk_action_group_get_action(lw->action_group, "HideToolbar");
1135 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->toolbar_hidden);
1136 }
1137
1138 void layout_util_sync_thumb(LayoutWindow *lw)
1139 {
1140 GtkAction *action;
1141
1142 if (!lw->action_group) return;
1143
1144 action = gtk_action_group_get_action(lw->action_group, "Thumbnails");
1145 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->thumbs_enabled);
1146 g_object_set(action, "sensitive", !lw->icon_view, NULL);
1147
1148 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lw->thumb_button), lw->thumbs_enabled);
1149 gtk_widget_set_sensitive(lw->thumb_button, !lw->icon_view);
1150 }
1151
1152 void layout_util_sync(LayoutWindow *lw)
1153 {
1154 layout_util_sync_views(lw);
1155 layout_util_sync_thumb(lw);
1156 layout_menu_recent_update(lw);
1157 layout_menu_edit_update(lw);
1158 }
1159
1160 /*
1161 *-----------------------------------------------------------------------------
1162 * icons (since all the toolbar icons are included here, best place as any)
1163 *-----------------------------------------------------------------------------
1164 */
1165
1166 PixmapFolders *folder_icons_new(void)
1167 {
1168 PixmapFolders *pf;
1169
1170 pf = g_new0(PixmapFolders, 1);
1171
1172 pf->close = pixbuf_inline(PIXBUF_INLINE_FOLDER_CLOSED);
1173 pf->open = pixbuf_inline(PIXBUF_INLINE_FOLDER_OPEN);
1174 pf->deny = pixbuf_inline(PIXBUF_INLINE_FOLDER_LOCKED);
1175 pf->parent = pixbuf_inline(PIXBUF_INLINE_FOLDER_UP);
1176
1177 return pf;
1178 }
1179
1180 void folder_icons_free(PixmapFolders *pf)
1181 {
1182 if (!pf) return;
1183
1184 g_object_unref(pf->close);
1185 g_object_unref(pf->open);
1186 g_object_unref(pf->deny);
1187 g_object_unref(pf->parent);
1188
1189 g_free(pf);
1190 }
1191
1192 /*
1193 *-----------------------------------------------------------------------------
1194 * sidebars
1195 *-----------------------------------------------------------------------------
1196 */
1197
1198 #define SIDEBAR_WIDTH 288
1199
1200 static void layout_bar_info_destroyed(GtkWidget *widget, gpointer data)
1201 {
1202 LayoutWindow *lw = data;
1203
1204 lw->bar_info = NULL;
1205
1206 if (lw->utility_box)
1207 {
1208 /* destroyed from within itself */
1209 lw->bar_info_enabled = FALSE;
1210 layout_util_sync_views(lw);
1211 }
1212 }
1213
1214 static GList *layout_bar_info_list_cb(gpointer data)
1215 {
1216 LayoutWindow *lw = data;
1217
1218 return layout_selection_list(lw);
1219 }
1220
1221 static void layout_bar_info_new(LayoutWindow *lw)
1222 {
1223 if (!lw->utility_box) return;
1224
1225 lw->bar_info = bar_info_new(layout_image_get_path(lw), FALSE, lw->utility_box);
1226 bar_info_set_selection_func(lw->bar_info, layout_bar_info_list_cb, lw);
1227 bar_info_selection(lw->bar_info, layout_selection_count(lw, NULL) - 1);
1228 bar_info_size_request(lw->bar_info, SIDEBAR_WIDTH * 3 / 4);
1229 g_signal_connect(G_OBJECT(lw->bar_info), "destroy",
1230 G_CALLBACK(layout_bar_info_destroyed), lw);
1231 lw->bar_info_enabled = TRUE;
1232
1233 gtk_box_pack_start(GTK_BOX(lw->utility_box), lw->bar_info, FALSE, FALSE, 0);
1234 gtk_widget_show(lw->bar_info);
1235 }
1236
1237 static void layout_bar_info_close(LayoutWindow *lw)
1238 {
1239 if (lw->bar_info)
1240 {
1241 bar_info_close(lw->bar_info);
1242 lw->bar_info = NULL;
1243 }
1244 lw->bar_info_enabled = FALSE;
1245 }
1246
1247 void layout_bar_info_toggle(LayoutWindow *lw)
1248 {
1249 if (lw->bar_info_enabled)
1250 {
1251 layout_bar_info_close(lw);
1252 }
1253 else
1254 {
1255 layout_bar_info_new(lw);
1256 }
1257 }
1258
1259 static void layout_bar_info_new_image(LayoutWindow *lw)
1260 {
1261 if (!lw->bar_info || !lw->bar_info_enabled) return;
1262
1263 bar_info_set(lw->bar_info, layout_image_get_path(lw));
1264 }
1265
1266 static void layout_bar_info_new_selection(LayoutWindow *lw, gint count)
1267 {
1268 if (!lw->bar_info || !lw->bar_info_enabled) return;
1269
1270 bar_info_selection(lw->bar_info, count - 1);
1271 }
1272
1273 static void layout_bar_info_maint_renamed(LayoutWindow *lw)
1274 {
1275 if (!lw->bar_info || !lw->bar_info_enabled) return;
1276
1277 bar_info_maint_renamed(lw->bar_info, layout_image_get_path(lw));
1278 }
1279
1280 static void layout_bar_exif_destroyed(GtkWidget *widget, gpointer data)
1281 {
1282 LayoutWindow *lw = data;
1283
1284 if (lw->bar_exif)
1285 {
1286 lw->bar_exif_advanced = bar_exif_is_advanced(lw->bar_exif);
1287 }
1288
1289 lw->bar_exif = NULL;
1290 if (lw->utility_box)
1291 {
1292 /* destroyed from within itself */
1293 lw->bar_exif_enabled = FALSE;
1294 layout_util_sync_views(lw);
1295 }
1296 }
1297
1298 static void layout_bar_exif_sized(GtkWidget *widget, GtkAllocation *allocation, gpointer data)
1299 {
1300 LayoutWindow *lw = data;
1301
1302 if (lw->bar_exif)
1303 {
1304 lw->bar_exif_size = allocation->width;
1305 }
1306 }
1307
1308 static void layout_bar_exif_new(LayoutWindow *lw)
1309 {
1310 if (!lw->utility_box) return;
1311
1312 lw->bar_exif = bar_exif_new(TRUE, layout_image_get_path(lw),
1313 lw->bar_exif_advanced, lw->utility_box);
1314 g_signal_connect(G_OBJECT(lw->bar_exif), "destroy",
1315 G_CALLBACK(layout_bar_exif_destroyed), lw);
1316 g_signal_connect(G_OBJECT(lw->bar_exif), "size_allocate",
1317 G_CALLBACK(layout_bar_exif_sized), lw);
1318 lw->bar_exif_enabled = TRUE;
1319
1320 if (lw->bar_exif_size < 1) lw->bar_exif_size = SIDEBAR_WIDTH;
1321 gtk_widget_set_size_request(lw->bar_exif, lw->bar_exif_size, -1);
1322 gtk_box_pack_start(GTK_BOX(lw->utility_box), lw->bar_exif, FALSE, FALSE, 0);
1323 if (lw->bar_info) gtk_box_reorder_child(GTK_BOX(lw->utility_box), lw->bar_exif, 1);
1324 gtk_widget_show(lw->bar_exif);
1325 }
1326
1327 static void layout_bar_exif_close(LayoutWindow *lw)
1328 {
1329 if (lw->bar_exif)
1330 {
1331 bar_exif_close(lw->bar_exif);
1332 lw->bar_exif = NULL;
1333 }
1334 lw->bar_exif_enabled = FALSE;
1335 }
1336
1337 void layout_bar_exif_toggle(LayoutWindow *lw)
1338 {
1339 if (lw->bar_exif_enabled)
1340 {
1341 layout_bar_exif_close(lw);
1342 }
1343 else
1344 {
1345 layout_bar_exif_new(lw);
1346 }
1347 }
1348
1349 static void layout_bar_exif_new_image(LayoutWindow *lw)
1350 {
1351 if (!lw->bar_exif || !lw->bar_exif_enabled) return;
1352
1353 bar_exif_set(lw->bar_exif, layout_image_get_path(lw));
1354 }
1355
1356 static void layout_bar_sort_destroyed(GtkWidget *widget, gpointer data)
1357 {
1358 LayoutWindow *lw = data;
1359
1360 lw->bar_sort = NULL;
1361
1362 if (lw->utility_box)
1363 {
1364 /* destroyed from within itself */
1365 lw->bar_sort_enabled = FALSE;
1366
1367 layout_util_sync_views(lw);
1368 }
1369 }
1370
1371 static void layout_bar_sort_new(LayoutWindow *lw)
1372 {
1373 if (!lw->utility_box) return;
1374
1375 lw->bar_sort = bar_sort_new(lw);
1376 g_signal_connect(G_OBJECT(lw->bar_sort), "destroy",
1377 G_CALLBACK(layout_bar_sort_destroyed), lw);
1378 lw->bar_sort_enabled = TRUE;
1379
1380 gtk_box_pack_end(GTK_BOX(lw->utility_box), lw->bar_sort, FALSE, FALSE, 0);
1381 gtk_widget_show(lw->bar_sort);
1382 }
1383
1384 static void layout_bar_sort_close(LayoutWindow *lw)
1385 {
1386 if (lw->bar_sort)
1387 {
1388 bar_sort_close(lw->bar_sort);
1389 lw->bar_sort = NULL;
1390 }
1391 lw->bar_sort_enabled = FALSE;
1392 }
1393
1394 void layout_bar_sort_toggle(LayoutWindow *lw)
1395 {
1396 if (lw->bar_sort_enabled)
1397 {
1398 layout_bar_sort_close(lw);
1399 }
1400 else
1401 {
1402 layout_bar_sort_new(lw);
1403 }
1404 }
1405
1406 void layout_bars_new_image(LayoutWindow *lw)
1407 {
1408 layout_bar_info_new_image(lw);
1409 layout_bar_exif_new_image(lw);
1410 }
1411
1412 void layout_bars_new_selection(LayoutWindow *lw, gint count)
1413 {
1414 layout_bar_info_new_selection(lw, count);
1415 }
1416
1417 GtkWidget *layout_bars_prepare(LayoutWindow *lw, GtkWidget *image)
1418 {
1419 lw->utility_box = gtk_hbox_new(FALSE, PREF_PAD_GAP);
1420 gtk_box_pack_start(GTK_BOX(lw->utility_box), image, TRUE, TRUE, 0);
1421 gtk_widget_show(image);
1422
1423 if (lw->bar_sort_enabled)
1424 {
1425 layout_bar_sort_new(lw);
1426 }
1427
1428 if (lw->bar_info_enabled)
1429 {
1430 layout_bar_info_new(lw);
1431 }
1432
1433 if (lw->bar_exif_enabled)
1434 {
1435 layout_bar_exif_new(lw);
1436 }
1437
1438 return lw->utility_box;
1439 }
1440
1441 void layout_bars_close(LayoutWindow *lw)
1442 {
1443 layout_bar_sort_close(lw);
1444 layout_bar_exif_close(lw);
1445 layout_bar_info_close(lw);
1446 }
1447
1448 void layout_bars_maint_renamed(LayoutWindow *lw)
1449 {
1450 layout_bar_info_maint_renamed(lw);
1451 }
1452