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!
14 #include "layout_util.h"
19 #include "cache_maint.h"
21 #include "collect-dlg.h"
25 #include "layout_image.h"
26 #include "pixbuf_util.h"
27 #include "preferences.h"
31 #include "ui_bookmark.h"
32 #include "ui_fileops.h"
35 #include "ui_tabcomp.h"
37 #include <gdk/gdkkeysyms.h> /* for keyboard values */
39 #include "icons/icon_thumb.xpm"
40 #include "icons/icon_float.xpm"
43 #define MENU_EDIT_ACTION_OFFSET 16
47 *-----------------------------------------------------------------------------
49 *-----------------------------------------------------------------------------
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,
59 static gint layout_key_match(guint keyval)
63 for (i = 0; i < sizeof(tree_key_overrides) / sizeof(guint); i++)
65 if (keyval == tree_key_overrides[i]) return TRUE;
71 static gint layout_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer data)
73 LayoutWindow *lw = data;
74 gint stop_signal = FALSE;
78 if (lw->path_entry && GTK_WIDGET_HAS_FOCUS(lw->path_entry))
80 if (event->keyval == GDK_Escape && lw->path)
82 gtk_entry_set_text(GTK_ENTRY(lw->path_entry), lw->path);
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)
88 if (gtk_widget_event(lw->path_entry, (GdkEvent *)event))
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))
100 bar_info_event(lw->bar_info, (GdkEvent *)event))
106 (GTK_WIDGET_HAS_FOCUS(lw->image->widget) || (lw->tools && widget == lw->window)) )
108 switch (event->keyval)
110 case GDK_Left: case GDK_KP_Left:
114 case GDK_Right: case GDK_KP_Right:
118 case GDK_Up: case GDK_KP_Up:
122 case GDK_Down: case GDK_KP_Down:
128 layout_image_prev(lw);
133 layout_image_next(lw);
137 layout_image_menu_popup(lw);
143 if (!stop_signal && !(event->state & GDK_CONTROL_MASK) )
144 switch (event->keyval)
146 case '+': case GDK_KP_Add:
147 layout_image_zoom_adjust(lw, get_zoom_increment());
150 case GDK_KP_Subtract:
151 layout_image_zoom_adjust(lw, -get_zoom_increment());
154 case GDK_KP_Multiply:
155 layout_image_zoom_set(lw, 0.0);
160 layout_image_zoom_set(lw, 1.0);
164 layout_image_zoom_set(lw, 2.0);
168 layout_image_zoom_set(lw, 3.0);
172 layout_image_zoom_set(lw, 4.0);
176 layout_image_zoom_set(lw, -4.0);
180 layout_image_zoom_set(lw, -3.0);
184 layout_image_zoom_set(lw, -2.0);
188 layout_image_zoom_set_fill_geometry(lw, FALSE);
191 layout_image_zoom_set_fill_geometry(lw, TRUE);
193 case GDK_Page_Up: case GDK_KP_Page_Up:
194 layout_image_prev(lw);
197 case GDK_Page_Down: case GDK_KP_Page_Down:
198 layout_image_next(lw);
201 case GDK_Home: case GDK_KP_Home:
202 layout_image_first(lw);
205 case GDK_End: case GDK_KP_End:
206 layout_image_last(lw);
209 case GDK_Delete: case GDK_KP_Delete:
210 if (enable_delete_key)
212 file_util_delete(NULL, layout_selection_list(lw), widget);
217 /* FIXME:interrupting thumbs no longer allowed */
224 layout_image_slideshow_pause_toggle(lw);
227 if (!(event->state & GDK_MOD1_MASK)) layout_image_full_screen_toggle(lw);
231 if (event->state & GDK_SHIFT_MASK)
239 keyboard_scroll_calc(&x, &y, event);
240 layout_image_scroll(lw, x, y);
243 if (stop_signal) g_signal_stop_emission_by_name(G_OBJECT(widget), "key_press_event");
248 void layout_keyboard_init(LayoutWindow *lw, GtkWidget *window)
250 g_signal_connect(G_OBJECT(window), "key_press_event",
251 G_CALLBACK(layout_key_press_cb), lw);
255 *-----------------------------------------------------------------------------
257 *-----------------------------------------------------------------------------
260 static void layout_menu_new_window_cb(GtkAction *action, gpointer data)
262 LayoutWindow *lw = data;
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));
270 static void layout_menu_new_cb(GtkAction *action, gpointer data)
272 collection_window_new(NULL);
275 static void layout_menu_open_cb(GtkAction *action, gpointer data)
277 collection_dialog_load(NULL);
280 static void layout_menu_search_cb(GtkAction *action, gpointer data)
282 LayoutWindow *lw = data;
284 search_new(lw->path, layout_image_get_path(lw));
287 static void layout_menu_dupes_cb(GtkAction *action, gpointer data)
289 dupe_window_new(DUPE_MATCH_NAME);
292 static void layout_menu_print_cb(GtkAction *action, gpointer data)
294 LayoutWindow *lw = data;
296 print_window_new(layout_image_get_path(lw), layout_selection_list(lw), layout_list(lw), lw->window);
299 static void layout_menu_dir_cb(GtkAction *action, gpointer data)
301 LayoutWindow *lw = data;
303 file_util_create_dir(lw->path, lw->window);
306 static void layout_menu_copy_cb(GtkAction *action, gpointer data)
308 LayoutWindow *lw = data;
310 file_util_copy(NULL, layout_selection_list(lw), NULL, lw->window);
313 static void layout_menu_move_cb(GtkAction *action, gpointer data)
315 LayoutWindow *lw = data;
317 file_util_move(NULL, layout_selection_list(lw), NULL, lw->window);
320 static void layout_menu_rename_cb(GtkAction *action, gpointer data)
322 LayoutWindow *lw = data;
324 file_util_rename(NULL, layout_selection_list(lw), lw->window);
327 static void layout_menu_delete_cb(GtkAction *action, gpointer data)
329 LayoutWindow *lw = data;
331 file_util_delete(NULL, layout_selection_list(lw), lw->window);
334 static void layout_menu_close_cb(GtkAction *action, gpointer data)
336 LayoutWindow *lw = data;
341 static void layout_menu_exit_cb(GtkAction *action, gpointer data)
346 static void layout_menu_alter_90_cb(GtkAction *action, gpointer data)
348 LayoutWindow *lw = data;
350 layout_image_alter(lw, ALTER_ROTATE_90);
353 static void layout_menu_alter_90cc_cb(GtkAction *action, gpointer data)
355 LayoutWindow *lw = data;
357 layout_image_alter(lw, ALTER_ROTATE_90_CC);
360 static void layout_menu_alter_180_cb(GtkAction *action, gpointer data)
362 LayoutWindow *lw = data;
364 layout_image_alter(lw, ALTER_ROTATE_180);
367 static void layout_menu_alter_mirror_cb(GtkAction *action, gpointer data)
369 LayoutWindow *lw = data;
371 layout_image_alter(lw, ALTER_MIRROR);
374 static void layout_menu_alter_flip_cb(GtkAction *action, gpointer data)
376 LayoutWindow *lw = data;
378 layout_image_alter(lw, ALTER_FLIP);
381 static void layout_menu_info_cb(GtkAction *action, gpointer data)
383 LayoutWindow *lw = data;
385 const gchar *path = NULL;
387 list = layout_selection_list(lw);
388 if (!list) path = layout_image_get_path(lw);
390 info_window_new(path, list);
393 static void layout_menu_select_all_cb(GtkAction *action, gpointer data)
395 LayoutWindow *lw = data;
397 layout_select_all(lw);
400 static void layout_menu_unselect_all_cb(GtkAction *action, gpointer data)
402 LayoutWindow *lw = data;
404 layout_select_none(lw);
407 static void layout_menu_config_cb(GtkAction *action, gpointer data)
409 show_config_window();
412 static void layout_menu_remove_thumb_cb(GtkAction *action, gpointer data)
414 cache_manager_show();
417 static void layout_menu_wallpaper_cb(GtkAction *action, gpointer data)
419 LayoutWindow *lw = data;
421 layout_image_to_root(lw);
424 static void layout_menu_zoom_in_cb(GtkAction *action, gpointer data)
426 LayoutWindow *lw = data;
428 layout_image_zoom_adjust(lw, get_zoom_increment());
431 static void layout_menu_zoom_out_cb(GtkAction *action, gpointer data)
433 LayoutWindow *lw = data;
435 layout_image_zoom_adjust(lw, -get_zoom_increment());
438 static void layout_menu_zoom_1_1_cb(GtkAction *action, gpointer data)
440 LayoutWindow *lw = data;
442 layout_image_zoom_set(lw, 1.0);
445 static void layout_menu_zoom_fit_cb(GtkAction *action, gpointer data)
447 LayoutWindow *lw = data;
449 layout_image_zoom_set(lw, 0.0);
452 static void layout_menu_thumb_cb(GtkToggleAction *action, gpointer data)
454 LayoutWindow *lw = data;
456 layout_thumb_set(lw, gtk_toggle_action_get_active(action));
459 static void layout_menu_list_cb(GtkRadioAction *action, GtkRadioAction *current, gpointer data)
461 LayoutWindow *lw = data;
463 layout_views_set(lw, lw->tree_view, (gtk_radio_action_get_current_value(action) == 1));
467 static void layout_menu_icon_cb(gpointer data, guint action, GtkWidget *widget)
469 LayoutWindow *lw = data;
471 if (!GTK_CHECK_MENU_ITEM(widget)->active) return;
473 layout_views_set(lw, lw->tree_view, TRUE);
477 static void layout_menu_tree_cb(GtkToggleAction *action, gpointer data)
479 LayoutWindow *lw = data;
481 layout_views_set(lw, gtk_toggle_action_get_active(action), lw->icon_view);
484 static void layout_menu_fullscreen_cb(GtkAction *action, gpointer data)
486 LayoutWindow *lw = data;
488 layout_image_full_screen_toggle(lw);
491 static void layout_menu_refresh_cb(GtkAction *action, gpointer data)
493 LayoutWindow *lw = data;
498 static void layout_menu_float_cb(GtkToggleAction *action, gpointer data)
500 LayoutWindow *lw = data;
502 if (lw->tools_float != gtk_toggle_action_get_active(action))
504 layout_tools_float_toggle(lw);
508 static void layout_menu_hide_cb(GtkAction *action, gpointer data)
510 LayoutWindow *lw = data;
512 layout_tools_hide_toggle(lw);
515 static void layout_menu_toolbar_cb(GtkToggleAction *action, gpointer data)
517 LayoutWindow *lw = data;
519 if (lw->toolbar_hidden != gtk_toggle_action_get_active(action))
521 layout_toolbar_toggle(lw);
525 static void layout_menu_bar_info_cb(GtkToggleAction *action, gpointer data)
527 LayoutWindow *lw = data;
529 if (lw->bar_info_enabled != gtk_toggle_action_get_active(action))
531 layout_bar_info_toggle(lw);
535 static void layout_menu_bar_exif_cb(GtkToggleAction *action, gpointer data)
537 LayoutWindow *lw = data;
539 if (lw->bar_exif_enabled != gtk_toggle_action_get_active(action))
541 layout_bar_exif_toggle(lw);
545 static void layout_menu_bar_sort_cb(GtkToggleAction *action, gpointer data)
547 LayoutWindow *lw = data;
549 if (lw->bar_sort_enabled != gtk_toggle_action_get_active(action))
551 layout_bar_sort_toggle(lw);
555 static void layout_menu_slideshow_cb(GtkAction *action, gpointer data)
557 LayoutWindow *lw = data;
559 layout_image_slideshow_toggle(lw);
562 static void layout_menu_help_cb(GtkAction *action, gpointer data)
564 help_window_show("html_contents");
567 static void layout_menu_help_keys_cb(GtkAction *action, gpointer data)
569 help_window_show("documentation");
572 static void layout_menu_notes_cb(GtkAction *action, gpointer data)
574 help_window_show("release_notes");
577 static void layout_menu_about_cb(GtkAction *action, gpointer data)
583 *-----------------------------------------------------------------------------
585 *-----------------------------------------------------------------------------
588 static void layout_menu_edit_cb(GtkAction *action, gpointer data)
590 LayoutWindow *lw = data;
594 n = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(action), "edit_index"));
596 list = layout_selection_list(lw);
597 start_editor_from_path_list(n, list);
598 path_list_free(list);
601 static void layout_menu_edit_update(LayoutWindow *lw)
607 if (!lw->action_group) return;
609 for (i = 0; i < 10; i++)
614 key = g_strdup_printf("Editor%d", i);
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));
619 if (editor_command[i] && strlen(editor_command[i]) > 0)
623 if (editor_name[i] && strlen(editor_name[i]) > 0)
625 text = g_strdup_printf(_("in %s..."), editor_name[i]);
629 text = g_strdup(_("in (unknown)..."));
631 g_object_set(action, "label", text,
632 "sensitive", TRUE, NULL);
637 g_object_set(action, "label", _("empty"),
638 "sensitive", FALSE, NULL);
645 void layout_edit_update_all(void)
649 work = layout_window_list;
652 LayoutWindow *lw = work->data;
655 layout_menu_edit_update(lw);
660 *-----------------------------------------------------------------------------
662 *-----------------------------------------------------------------------------
665 static void layout_menu_recent_cb(GtkWidget *widget, gpointer data)
670 n = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "recent_index"));
672 path = g_list_nth_data(history_list_get_by_key("recent"), n);
676 /* make a copy of it */
677 path = g_strdup(path);
678 collection_window_new(path);
682 static void layout_menu_recent_update(LayoutWindow *lw)
690 if (!lw->ui_manager) return;
692 list = history_list_get_by_key("recent");
695 menu = gtk_menu_new();
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));
708 menu_item_add(menu, _("Empty"), NULL, NULL);
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));
716 void layout_recent_update_all(void)
720 work = layout_window_list;
723 LayoutWindow *lw = work->data;
726 layout_menu_recent_update(lw);
730 void layout_recent_add_path(const gchar *path)
734 history_list_add_to_key("recent", path, recent_list_max);
736 layout_recent_update_all();
740 *-----------------------------------------------------------------------------
742 *-----------------------------------------------------------------------------
745 #define CB G_CALLBACK
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") },
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) },
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) },
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) },
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) }
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) }
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 }
823 static const char *menu_ui_description =
825 " <menubar name='MainMenu'>"
826 " <menu action='FileMenu'>"
827 " <menuitem action='NewWindow'/>"
828 " <menuitem action='NewCollection'/>"
829 " <menuitem action='OpenCollection'/>"
830 " <menuitem action='OpenRecent'/>"
832 " <menuitem action='Search'/>"
833 " <menuitem action='FindDupes'/>"
835 " <menuitem action='Print'/>"
836 " <menuitem action='NewFolder'/>"
838 " <menuitem action='Copy'/>"
839 " <menuitem action='Move'/>"
840 " <menuitem action='Rename'/>"
841 " <menuitem action='Delete'/>"
843 " <menuitem action='CloseWindow'/>"
844 " <menuitem action='Quit'/>"
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'/>"
858 " <menu action='AdjustMenu'>"
859 " <menuitem action='RotateCW'/>"
860 " <menuitem action='RotateCCW'/>"
861 " <menuitem action='Rotate180'/>"
862 " <menuitem action='Mirror'/>"
863 " <menuitem action='Flip'/>"
865 " <menuitem action='Properties'/>"
867 " <menuitem action='SelectAll'/>"
868 " <menuitem action='SelectNone'/>"
870 " <menuitem action='Preferences'/>"
871 " <menuitem action='Maintenance'/>"
873 " <menuitem action='Wallpaper'/>"
875 " <menu action='ViewMenu'>"
877 " <menuitem action='ZoomIn'/>"
878 " <menuitem action='ZoomOut'/>"
879 " <menuitem action='Zoom100'/>"
880 " <menuitem action='ZoomFit'/>"
882 " <menuitem action='Thumbnails'/>"
883 " <menuitem action='ViewList'/>"
884 " <menuitem action='ViewIcons'/>"
886 " <menuitem action='FolderTree'/>"
887 " <menuitem action='FullScreen'/>"
889 " <menuitem action='FloatTools'/>"
890 " <menuitem action='HideTools'/>"
891 " <menuitem action='HideToolbar'/>"
893 " <menuitem action='SBarKeywords'/>"
894 " <menuitem action='SBarExif'/>"
895 " <menuitem action='SBarSort'/>"
897 " <menuitem action='SlideShow'/>"
898 " <menuitem action='Refresh'/>"
900 " <menu action='HelpMenu'>"
902 " <menuitem action='HelpContents'/>"
903 " <menuitem action='HelpShortcuts'/>"
904 " <menuitem action='HelpNotes'/>"
906 " <menuitem action='About'/>"
912 static gchar *menu_translate(const gchar *path, gpointer data)
917 void layout_actions_setup(LayoutWindow *lw)
921 if (lw->ui_manager) return;
923 lw->action_group = gtk_action_group_new ("MenuActions");
924 gtk_action_group_set_translate_func(lw->action_group, menu_translate, NULL, NULL);
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);
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);
939 if (!gtk_ui_manager_add_ui_from_string(lw->ui_manager, menu_ui_description, -1, &error))
941 g_message ("building menus failed: %s", error->message);
942 g_error_free (error);
947 void layout_actions_add_window(LayoutWindow *lw, GtkWidget *window)
949 GtkAccelGroup *group;
951 if (!lw->ui_manager) return;
953 group = gtk_ui_manager_get_accel_group(lw->ui_manager);
954 gtk_window_add_accel_group(GTK_WINDOW(window), group);
957 GtkWidget *layout_actions_menu_bar(LayoutWindow *lw)
959 return gtk_ui_manager_get_widget(lw->ui_manager, "/MainMenu");
964 *-----------------------------------------------------------------------------
966 *-----------------------------------------------------------------------------
969 static void layout_button_thumb_cb(GtkWidget *widget, gpointer data)
971 LayoutWindow *lw = data;
973 layout_thumb_set(lw, GTK_TOGGLE_BUTTON(widget)->active);
976 static void layout_button_home_cb(GtkWidget *widget, gpointer data)
978 LayoutWindow *lw = data;
979 const gchar *path = homedir();
981 if (path) layout_set_path(lw, path);
984 static void layout_button_refresh_cb(GtkWidget *widget, gpointer data)
986 LayoutWindow *lw = data;
991 static void layout_button_zoom_in_cb(GtkWidget *widget, gpointer data)
993 LayoutWindow *lw = data;
995 layout_image_zoom_adjust(lw, get_zoom_increment());
998 static void layout_button_zoom_out_cb(GtkWidget *widget, gpointer data)
1000 LayoutWindow *lw = data;
1002 layout_image_zoom_adjust(lw, -get_zoom_increment());
1005 static void layout_button_zoom_fit_cb(GtkWidget *widget, gpointer data)
1007 LayoutWindow *lw = data;
1009 layout_image_zoom_set(lw, 0.0);
1012 static void layout_button_zoom_1_1_cb(GtkWidget *widget, gpointer data)
1014 LayoutWindow *lw = data;
1016 layout_image_zoom_set(lw, 1.0);
1019 static void layout_button_config_cb(GtkWidget *widget, gpointer data)
1021 show_config_window();
1024 static void layout_button_float_cb(GtkWidget *widget, gpointer data)
1026 LayoutWindow *lw = data;
1028 layout_tools_float_toggle(lw);
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)
1040 button = gtk_toggle_button_new();
1044 button = gtk_button_new();
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);
1054 icon = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_BUTTON);
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);
1065 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
1067 gtk_container_add(GTK_CONTAINER(button), icon);
1068 gtk_widget_show(icon);
1073 GtkWidget *layout_button_bar(LayoutWindow *lw)
1076 GtkTooltips *tooltips;
1078 tooltips = lw->tooltips;
1080 box = gtk_hbox_new(FALSE, 0);
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);
1105 *-----------------------------------------------------------------------------
1107 *-----------------------------------------------------------------------------
1110 static void layout_util_sync_views(LayoutWindow *lw)
1114 if (!lw->action_group) return;
1116 action = gtk_action_group_get_action(lw->action_group, "FolderTree");
1117 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->tree_view);
1119 action = gtk_action_group_get_action(lw->action_group, "ViewIcons");
1120 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->icon_view);
1122 action = gtk_action_group_get_action(lw->action_group, "FloatTools");
1123 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->tools_float);
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);
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);
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);
1134 action = gtk_action_group_get_action(lw->action_group, "HideToolbar");
1135 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->toolbar_hidden);
1138 void layout_util_sync_thumb(LayoutWindow *lw)
1142 if (!lw->action_group) return;
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);
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);
1152 void layout_util_sync(LayoutWindow *lw)
1154 layout_util_sync_views(lw);
1155 layout_util_sync_thumb(lw);
1156 layout_menu_recent_update(lw);
1157 layout_menu_edit_update(lw);
1161 *-----------------------------------------------------------------------------
1162 * icons (since all the toolbar icons are included here, best place as any)
1163 *-----------------------------------------------------------------------------
1166 PixmapFolders *folder_icons_new(void)
1170 pf = g_new0(PixmapFolders, 1);
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);
1180 void folder_icons_free(PixmapFolders *pf)
1184 g_object_unref(pf->close);
1185 g_object_unref(pf->open);
1186 g_object_unref(pf->deny);
1187 g_object_unref(pf->parent);
1193 *-----------------------------------------------------------------------------
1195 *-----------------------------------------------------------------------------
1198 #define SIDEBAR_WIDTH 288
1200 static void layout_bar_info_destroyed(GtkWidget *widget, gpointer data)
1202 LayoutWindow *lw = data;
1204 lw->bar_info = NULL;
1206 if (lw->utility_box)
1208 /* destroyed from within itself */
1209 lw->bar_info_enabled = FALSE;
1210 layout_util_sync_views(lw);
1214 static GList *layout_bar_info_list_cb(gpointer data)
1216 LayoutWindow *lw = data;
1218 return layout_selection_list(lw);
1221 static void layout_bar_info_new(LayoutWindow *lw)
1223 if (!lw->utility_box) return;
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;
1233 gtk_box_pack_start(GTK_BOX(lw->utility_box), lw->bar_info, FALSE, FALSE, 0);
1234 gtk_widget_show(lw->bar_info);
1237 static void layout_bar_info_close(LayoutWindow *lw)
1241 bar_info_close(lw->bar_info);
1242 lw->bar_info = NULL;
1244 lw->bar_info_enabled = FALSE;
1247 void layout_bar_info_toggle(LayoutWindow *lw)
1249 if (lw->bar_info_enabled)
1251 layout_bar_info_close(lw);
1255 layout_bar_info_new(lw);
1259 static void layout_bar_info_new_image(LayoutWindow *lw)
1261 if (!lw->bar_info || !lw->bar_info_enabled) return;
1263 bar_info_set(lw->bar_info, layout_image_get_path(lw));
1266 static void layout_bar_info_new_selection(LayoutWindow *lw, gint count)
1268 if (!lw->bar_info || !lw->bar_info_enabled) return;
1270 bar_info_selection(lw->bar_info, count - 1);
1273 static void layout_bar_info_maint_renamed(LayoutWindow *lw)
1275 if (!lw->bar_info || !lw->bar_info_enabled) return;
1277 bar_info_maint_renamed(lw->bar_info, layout_image_get_path(lw));
1280 static void layout_bar_exif_destroyed(GtkWidget *widget, gpointer data)
1282 LayoutWindow *lw = data;
1286 lw->bar_exif_advanced = bar_exif_is_advanced(lw->bar_exif);
1289 lw->bar_exif = NULL;
1290 if (lw->utility_box)
1292 /* destroyed from within itself */
1293 lw->bar_exif_enabled = FALSE;
1294 layout_util_sync_views(lw);
1298 static void layout_bar_exif_sized(GtkWidget *widget, GtkAllocation *allocation, gpointer data)
1300 LayoutWindow *lw = data;
1304 lw->bar_exif_size = allocation->width;
1308 static void layout_bar_exif_new(LayoutWindow *lw)
1310 if (!lw->utility_box) return;
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;
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);
1327 static void layout_bar_exif_close(LayoutWindow *lw)
1331 bar_exif_close(lw->bar_exif);
1332 lw->bar_exif = NULL;
1334 lw->bar_exif_enabled = FALSE;
1337 void layout_bar_exif_toggle(LayoutWindow *lw)
1339 if (lw->bar_exif_enabled)
1341 layout_bar_exif_close(lw);
1345 layout_bar_exif_new(lw);
1349 static void layout_bar_exif_new_image(LayoutWindow *lw)
1351 if (!lw->bar_exif || !lw->bar_exif_enabled) return;
1353 bar_exif_set(lw->bar_exif, layout_image_get_path(lw));
1356 static void layout_bar_sort_destroyed(GtkWidget *widget, gpointer data)
1358 LayoutWindow *lw = data;
1360 lw->bar_sort = NULL;
1362 if (lw->utility_box)
1364 /* destroyed from within itself */
1365 lw->bar_sort_enabled = FALSE;
1367 layout_util_sync_views(lw);
1371 static void layout_bar_sort_new(LayoutWindow *lw)
1373 if (!lw->utility_box) return;
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;
1380 gtk_box_pack_end(GTK_BOX(lw->utility_box), lw->bar_sort, FALSE, FALSE, 0);
1381 gtk_widget_show(lw->bar_sort);
1384 static void layout_bar_sort_close(LayoutWindow *lw)
1388 bar_sort_close(lw->bar_sort);
1389 lw->bar_sort = NULL;
1391 lw->bar_sort_enabled = FALSE;
1394 void layout_bar_sort_toggle(LayoutWindow *lw)
1396 if (lw->bar_sort_enabled)
1398 layout_bar_sort_close(lw);
1402 layout_bar_sort_new(lw);
1406 void layout_bars_new_image(LayoutWindow *lw)
1408 layout_bar_info_new_image(lw);
1409 layout_bar_exif_new_image(lw);
1412 void layout_bars_new_selection(LayoutWindow *lw, gint count)
1414 layout_bar_info_new_selection(lw, count);
1417 GtkWidget *layout_bars_prepare(LayoutWindow *lw, GtkWidget *image)
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);
1423 if (lw->bar_sort_enabled)
1425 layout_bar_sort_new(lw);
1428 if (lw->bar_info_enabled)
1430 layout_bar_info_new(lw);
1433 if (lw->bar_exif_enabled)
1435 layout_bar_exif_new(lw);
1438 return lw->utility_box;
1441 void layout_bars_close(LayoutWindow *lw)
1443 layout_bar_sort_close(lw);
1444 layout_bar_exif_close(lw);
1445 layout_bar_info_close(lw);
1448 void layout_bars_maint_renamed(LayoutWindow *lw)
1450 layout_bar_info_maint_renamed(lw);