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"
27 #include "pixbuf_util.h"
28 #include "preferences.h"
32 #include "ui_bookmark.h"
33 #include "ui_fileops.h"
36 #include "ui_tabcomp.h"
38 #include <gdk/gdkkeysyms.h> /* for keyboard values */
40 #include "icons/icon_thumb.xpm"
41 #include "icons/icon_float.xpm"
44 #define MENU_EDIT_ACTION_OFFSET 16
48 *-----------------------------------------------------------------------------
50 *-----------------------------------------------------------------------------
53 static guint tree_key_overrides[] = {
54 GDK_Page_Up, GDK_KP_Page_Up,
55 GDK_Page_Down, GDK_KP_Page_Down,
56 GDK_Home, GDK_KP_Home,
60 static gint layout_key_match(guint keyval)
64 for (i = 0; i < sizeof(tree_key_overrides) / sizeof(guint); i++)
66 if (keyval == tree_key_overrides[i]) return TRUE;
72 static gint layout_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer data)
74 LayoutWindow *lw = data;
75 gint stop_signal = FALSE;
79 if (lw->path_entry && GTK_WIDGET_HAS_FOCUS(lw->path_entry))
81 if (event->keyval == GDK_Escape && lw->path)
83 gtk_entry_set_text(GTK_ENTRY(lw->path_entry), lw->path);
86 /* the gtkaccelgroup of the window is stealing presses before they get to the entry (and more),
87 * so when the some widgets have focus, give them priority (HACK)
89 if (gtk_widget_event(lw->path_entry, (GdkEvent *)event))
94 if (lw->vdt && GTK_WIDGET_HAS_FOCUS(lw->vdt->treeview) &&
95 !layout_key_match(event->keyval) &&
96 gtk_widget_event(lw->vdt->treeview, (GdkEvent *)event))
101 bar_info_event(lw->bar_info, (GdkEvent *)event))
107 (GTK_WIDGET_HAS_FOCUS(lw->image->widget) || (lw->tools && widget == lw->window)) )
109 switch (event->keyval)
111 case GDK_Left: case GDK_KP_Left:
115 case GDK_Right: case GDK_KP_Right:
119 case GDK_Up: case GDK_KP_Up:
123 case GDK_Down: case GDK_KP_Down:
129 layout_image_prev(lw);
134 layout_image_next(lw);
138 layout_image_menu_popup(lw);
144 if (!stop_signal && !(event->state & GDK_CONTROL_MASK) )
145 switch (event->keyval)
147 case '+': case GDK_KP_Add:
148 layout_image_zoom_adjust(lw, get_zoom_increment());
151 case GDK_KP_Subtract:
152 layout_image_zoom_adjust(lw, -get_zoom_increment());
155 case GDK_KP_Multiply:
156 layout_image_zoom_set(lw, 0.0);
161 layout_image_zoom_set(lw, 1.0);
165 layout_image_zoom_set(lw, 2.0);
169 layout_image_zoom_set(lw, 3.0);
173 layout_image_zoom_set(lw, 4.0);
177 layout_image_zoom_set(lw, -4.0);
181 layout_image_zoom_set(lw, -3.0);
185 layout_image_zoom_set(lw, -2.0);
189 layout_image_zoom_set_fill_geometry(lw, FALSE);
192 layout_image_zoom_set_fill_geometry(lw, TRUE);
194 case GDK_Page_Up: case GDK_KP_Page_Up:
195 layout_image_prev(lw);
198 case GDK_Page_Down: case GDK_KP_Page_Down:
199 layout_image_next(lw);
202 case GDK_Home: case GDK_KP_Home:
203 layout_image_first(lw);
206 case GDK_End: case GDK_KP_End:
207 layout_image_last(lw);
210 case GDK_Delete: case GDK_KP_Delete:
211 if (enable_delete_key)
213 file_util_delete(NULL, layout_selection_list(lw), widget);
218 /* FIXME:interrupting thumbs no longer allowed */
225 layout_image_slideshow_pause_toggle(lw);
228 if (!(event->state & GDK_MOD1_MASK)) layout_image_full_screen_toggle(lw);
232 if (event->state & GDK_SHIFT_MASK)
240 keyboard_scroll_calc(&x, &y, event);
241 layout_image_scroll(lw, x, y);
244 if (stop_signal) g_signal_stop_emission_by_name(G_OBJECT(widget), "key_press_event");
249 void layout_keyboard_init(LayoutWindow *lw, GtkWidget *window)
251 g_signal_connect(G_OBJECT(window), "key_press_event",
252 G_CALLBACK(layout_key_press_cb), lw);
256 *-----------------------------------------------------------------------------
258 *-----------------------------------------------------------------------------
261 static void layout_menu_new_window_cb(GtkAction *action, gpointer data)
263 LayoutWindow *lw = data;
266 nw = layout_new(NULL, FALSE, FALSE);
267 layout_sort_set(nw, file_sort_method, file_sort_ascending);
268 layout_set_path(nw, layout_get_path(lw));
271 static void layout_menu_new_cb(GtkAction *action, gpointer data)
273 collection_window_new(NULL);
276 static void layout_menu_open_cb(GtkAction *action, gpointer data)
278 collection_dialog_load(NULL);
281 static void layout_menu_search_cb(GtkAction *action, gpointer data)
283 LayoutWindow *lw = data;
285 search_new(lw->path, layout_image_get_path(lw));
288 static void layout_menu_dupes_cb(GtkAction *action, gpointer data)
290 dupe_window_new(DUPE_MATCH_NAME);
293 static void layout_menu_pan_cb(GtkAction *action, gpointer data)
295 LayoutWindow *lw = data;
297 pan_window_new(layout_get_path(lw));
300 static void layout_menu_print_cb(GtkAction *action, gpointer data)
302 LayoutWindow *lw = data;
304 print_window_new(layout_image_get_path(lw), layout_selection_list(lw), layout_list(lw), lw->window);
307 static void layout_menu_dir_cb(GtkAction *action, gpointer data)
309 LayoutWindow *lw = data;
311 file_util_create_dir(lw->path, lw->window);
314 static void layout_menu_copy_cb(GtkAction *action, gpointer data)
316 LayoutWindow *lw = data;
318 file_util_copy(NULL, layout_selection_list(lw), NULL, lw->window);
321 static void layout_menu_move_cb(GtkAction *action, gpointer data)
323 LayoutWindow *lw = data;
325 file_util_move(NULL, layout_selection_list(lw), NULL, lw->window);
328 static void layout_menu_rename_cb(GtkAction *action, gpointer data)
330 LayoutWindow *lw = data;
332 file_util_rename(NULL, layout_selection_list(lw), lw->window);
335 static void layout_menu_delete_cb(GtkAction *action, gpointer data)
337 LayoutWindow *lw = data;
339 file_util_delete(NULL, layout_selection_list(lw), lw->window);
342 static void layout_menu_close_cb(GtkAction *action, gpointer data)
344 LayoutWindow *lw = data;
349 static void layout_menu_exit_cb(GtkAction *action, gpointer data)
354 static void layout_menu_alter_90_cb(GtkAction *action, gpointer data)
356 LayoutWindow *lw = data;
358 layout_image_alter(lw, ALTER_ROTATE_90);
361 static void layout_menu_alter_90cc_cb(GtkAction *action, gpointer data)
363 LayoutWindow *lw = data;
365 layout_image_alter(lw, ALTER_ROTATE_90_CC);
368 static void layout_menu_alter_180_cb(GtkAction *action, gpointer data)
370 LayoutWindow *lw = data;
372 layout_image_alter(lw, ALTER_ROTATE_180);
375 static void layout_menu_alter_mirror_cb(GtkAction *action, gpointer data)
377 LayoutWindow *lw = data;
379 layout_image_alter(lw, ALTER_MIRROR);
382 static void layout_menu_alter_flip_cb(GtkAction *action, gpointer data)
384 LayoutWindow *lw = data;
386 layout_image_alter(lw, ALTER_FLIP);
389 static void layout_menu_info_cb(GtkAction *action, gpointer data)
391 LayoutWindow *lw = data;
393 const gchar *path = NULL;
395 list = layout_selection_list(lw);
396 if (!list) path = layout_image_get_path(lw);
398 info_window_new(path, list);
401 static void layout_menu_select_all_cb(GtkAction *action, gpointer data)
403 LayoutWindow *lw = data;
405 layout_select_all(lw);
408 static void layout_menu_unselect_all_cb(GtkAction *action, gpointer data)
410 LayoutWindow *lw = data;
412 layout_select_none(lw);
415 static void layout_menu_config_cb(GtkAction *action, gpointer data)
417 show_config_window();
420 static void layout_menu_remove_thumb_cb(GtkAction *action, gpointer data)
422 cache_manager_show();
425 static void layout_menu_wallpaper_cb(GtkAction *action, gpointer data)
427 LayoutWindow *lw = data;
429 layout_image_to_root(lw);
432 static void layout_menu_zoom_in_cb(GtkAction *action, gpointer data)
434 LayoutWindow *lw = data;
436 layout_image_zoom_adjust(lw, get_zoom_increment());
439 static void layout_menu_zoom_out_cb(GtkAction *action, gpointer data)
441 LayoutWindow *lw = data;
443 layout_image_zoom_adjust(lw, -get_zoom_increment());
446 static void layout_menu_zoom_1_1_cb(GtkAction *action, gpointer data)
448 LayoutWindow *lw = data;
450 layout_image_zoom_set(lw, 1.0);
453 static void layout_menu_zoom_fit_cb(GtkAction *action, gpointer data)
455 LayoutWindow *lw = data;
457 layout_image_zoom_set(lw, 0.0);
460 static void layout_menu_thumb_cb(GtkToggleAction *action, gpointer data)
462 LayoutWindow *lw = data;
464 layout_thumb_set(lw, gtk_toggle_action_get_active(action));
467 static void layout_menu_list_cb(GtkRadioAction *action, GtkRadioAction *current, gpointer data)
469 LayoutWindow *lw = data;
471 layout_views_set(lw, lw->tree_view, (gtk_radio_action_get_current_value(action) == 1));
475 static void layout_menu_icon_cb(gpointer data, guint action, GtkWidget *widget)
477 LayoutWindow *lw = data;
479 if (!GTK_CHECK_MENU_ITEM(widget)->active) return;
481 layout_views_set(lw, lw->tree_view, TRUE);
485 static void layout_menu_tree_cb(GtkToggleAction *action, gpointer data)
487 LayoutWindow *lw = data;
489 layout_views_set(lw, gtk_toggle_action_get_active(action), lw->icon_view);
492 static void layout_menu_fullscreen_cb(GtkAction *action, gpointer data)
494 LayoutWindow *lw = data;
496 layout_image_full_screen_toggle(lw);
499 static void layout_menu_refresh_cb(GtkAction *action, gpointer data)
501 LayoutWindow *lw = data;
506 static void layout_menu_float_cb(GtkToggleAction *action, gpointer data)
508 LayoutWindow *lw = data;
510 if (lw->tools_float != gtk_toggle_action_get_active(action))
512 layout_tools_float_toggle(lw);
516 static void layout_menu_hide_cb(GtkAction *action, gpointer data)
518 LayoutWindow *lw = data;
520 layout_tools_hide_toggle(lw);
523 static void layout_menu_toolbar_cb(GtkToggleAction *action, gpointer data)
525 LayoutWindow *lw = data;
527 if (lw->toolbar_hidden != gtk_toggle_action_get_active(action))
529 layout_toolbar_toggle(lw);
533 static void layout_menu_bar_info_cb(GtkToggleAction *action, gpointer data)
535 LayoutWindow *lw = data;
537 if (lw->bar_info_enabled != gtk_toggle_action_get_active(action))
539 layout_bar_info_toggle(lw);
543 static void layout_menu_bar_exif_cb(GtkToggleAction *action, gpointer data)
545 LayoutWindow *lw = data;
547 if (lw->bar_exif_enabled != gtk_toggle_action_get_active(action))
549 layout_bar_exif_toggle(lw);
553 static void layout_menu_bar_sort_cb(GtkToggleAction *action, gpointer data)
555 LayoutWindow *lw = data;
557 if (lw->bar_sort_enabled != gtk_toggle_action_get_active(action))
559 layout_bar_sort_toggle(lw);
563 static void layout_menu_slideshow_cb(GtkAction *action, gpointer data)
565 LayoutWindow *lw = data;
567 layout_image_slideshow_toggle(lw);
570 static void layout_menu_help_cb(GtkAction *action, gpointer data)
572 help_window_show("html_contents");
575 static void layout_menu_help_keys_cb(GtkAction *action, gpointer data)
577 help_window_show("documentation");
580 static void layout_menu_notes_cb(GtkAction *action, gpointer data)
582 help_window_show("release_notes");
585 static void layout_menu_about_cb(GtkAction *action, gpointer data)
591 *-----------------------------------------------------------------------------
593 *-----------------------------------------------------------------------------
596 static void layout_menu_edit_cb(GtkAction *action, gpointer data)
598 LayoutWindow *lw = data;
602 n = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(action), "edit_index"));
604 list = layout_selection_list(lw);
605 start_editor_from_path_list(n, list);
606 path_list_free(list);
609 static void layout_menu_edit_update(LayoutWindow *lw)
615 if (!lw->action_group) return;
617 for (i = 0; i < 10; i++)
622 key = g_strdup_printf("Editor%d", i);
624 action = gtk_action_group_get_action(lw->action_group, key);
625 g_object_set_data(G_OBJECT(action), "edit_index", GINT_TO_POINTER(i));
627 if (editor_command[i] && strlen(editor_command[i]) > 0)
631 if (editor_name[i] && strlen(editor_name[i]) > 0)
633 text = g_strdup_printf(_("in %s..."), editor_name[i]);
637 text = g_strdup(_("in (unknown)..."));
639 g_object_set(action, "label", text,
640 "sensitive", TRUE, NULL);
645 g_object_set(action, "label", _("empty"),
646 "sensitive", FALSE, NULL);
653 void layout_edit_update_all(void)
657 work = layout_window_list;
660 LayoutWindow *lw = work->data;
663 layout_menu_edit_update(lw);
668 *-----------------------------------------------------------------------------
670 *-----------------------------------------------------------------------------
673 static void layout_menu_recent_cb(GtkWidget *widget, gpointer data)
678 n = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "recent_index"));
680 path = g_list_nth_data(history_list_get_by_key("recent"), n);
684 /* make a copy of it */
685 path = g_strdup(path);
686 collection_window_new(path);
690 static void layout_menu_recent_update(LayoutWindow *lw)
698 if (!lw->ui_manager) return;
700 list = history_list_get_by_key("recent");
703 menu = gtk_menu_new();
707 item = menu_item_add_simple(menu, filename_from_path((gchar *)list->data),
708 G_CALLBACK(layout_menu_recent_cb), lw);
709 g_object_set_data(G_OBJECT(item), "recent_index", GINT_TO_POINTER(n));
716 menu_item_add(menu, _("Empty"), NULL, NULL);
719 recent = gtk_ui_manager_get_widget(lw->ui_manager, "/MainMenu/FileMenu/OpenRecent");
720 gtk_menu_item_set_submenu(GTK_MENU_ITEM(recent), menu);
721 gtk_widget_set_sensitive(recent, (n != 0));
724 void layout_recent_update_all(void)
728 work = layout_window_list;
731 LayoutWindow *lw = work->data;
734 layout_menu_recent_update(lw);
738 void layout_recent_add_path(const gchar *path)
742 history_list_add_to_key("recent", path, recent_list_max);
744 layout_recent_update_all();
748 *-----------------------------------------------------------------------------
750 *-----------------------------------------------------------------------------
753 #define CB G_CALLBACK
755 static GtkActionEntry menu_entries[] = {
756 { "FileMenu", NULL, N_("_File") },
757 { "EditMenu", NULL, N_("_Edit") },
758 { "AdjustMenu", NULL, N_("_Adjust") },
759 { "ViewMenu", NULL, N_("_View") },
760 { "HelpMenu", NULL, N_("_Help") },
762 { "NewWindow", GTK_STOCK_NEW, N_("New _window"), NULL, NULL, CB(layout_menu_new_window_cb) },
763 { "NewCollection", GTK_STOCK_INDEX,N_("_New collection"), "C", NULL, CB(layout_menu_new_cb) },
764 { "OpenCollection", GTK_STOCK_OPEN, N_("_Open collection..."),"O", NULL, CB(layout_menu_open_cb) },
765 { "OpenRecent", NULL, N_("Open _recent") },
766 { "Search", GTK_STOCK_FIND, N_("_Search..."), "F3", NULL, CB(layout_menu_search_cb) },
767 { "FindDupes", GTK_STOCK_FIND, N_("_Find duplicates..."),"D", NULL, CB(layout_menu_dupes_cb) },
768 { "PanView", NULL, N_("Pan _view"), "<control>J", NULL, CB(layout_menu_pan_cb) },
769 { "Print", GTK_STOCK_PRINT,N_("_Print..."), "<shift>P", NULL, CB(layout_menu_print_cb) },
770 { "NewFolder", NULL, N_("N_ew folder..."), "<control>F", NULL, CB(layout_menu_dir_cb) },
771 { "Copy", NULL, N_("_Copy..."), "<control>C", NULL, CB(layout_menu_copy_cb) },
772 { "Move", NULL, N_("_Move..."), "<control>M", NULL, CB(layout_menu_move_cb) },
773 { "Rename", NULL, N_("_Rename..."), "<control>R", NULL, CB(layout_menu_rename_cb) },
774 { "Delete", GTK_STOCK_DELETE, N_("_Delete..."), "<control>D", NULL, CB(layout_menu_delete_cb) },
775 { "CloseWindow", GTK_STOCK_CLOSE,N_("C_lose window"), "<control>W", NULL, CB(layout_menu_close_cb) },
776 { "Quit", GTK_STOCK_QUIT, N_("_Quit"), "<control>Q", NULL, CB(layout_menu_exit_cb) },
778 { "Editor0", NULL, "editor0", "<control>1", NULL, CB(layout_menu_edit_cb) },
779 { "Editor1", NULL, "editor1", "<control>2", NULL, CB(layout_menu_edit_cb) },
780 { "Editor2", NULL, "editor2", "<control>3", NULL, CB(layout_menu_edit_cb) },
781 { "Editor3", NULL, "editor3", "<control>4", NULL, CB(layout_menu_edit_cb) },
782 { "Editor4", NULL, "editor4", "<control>5", NULL, CB(layout_menu_edit_cb) },
783 { "Editor5", NULL, "editor5", "<control>6", NULL, CB(layout_menu_edit_cb) },
784 { "Editor6", NULL, "editor6", "<control>7", NULL, CB(layout_menu_edit_cb) },
785 { "Editor7", NULL, "editor7", "<control>8", NULL, CB(layout_menu_edit_cb) },
786 { "Editor8", NULL, "editor8", "<control>9", NULL, CB(layout_menu_edit_cb) },
787 { "Editor9", NULL, "editor9", "<control>0", NULL, CB(layout_menu_edit_cb) },
788 { "RotateCW", NULL, N_("_Rotate clockwise"), "bracketright", NULL, CB(layout_menu_alter_90_cb) },
789 { "RotateCCW", NULL, N_("Rotate _counterclockwise"), "bracketleft", NULL, CB(layout_menu_alter_90cc_cb) },
790 { "Rotate180", NULL, N_("Rotate 1_80"), "<shift>R", NULL, CB(layout_menu_alter_180_cb) },
791 { "Mirror", NULL, N_("_Mirror"), "<shift>M", NULL, CB(layout_menu_alter_mirror_cb) },
792 { "Flip", NULL, N_("_Flip"), "<shift>F", NULL, CB(layout_menu_alter_flip_cb) },
793 { "Properties",GTK_STOCK_PROPERTIES, N_("_Properties"), "<control>P", NULL, CB(layout_menu_info_cb) },
794 { "SelectAll", NULL, N_("Select _all"), "<control>A", NULL, CB(layout_menu_select_all_cb) },
795 { "SelectNone", NULL, N_("Select _none"), "<control><shift>A",NULL, CB(layout_menu_unselect_all_cb) },
796 { "Preferences",GTK_STOCK_PREFERENCES,N_("P_references..."), "<control>O", NULL, CB(layout_menu_config_cb) },
797 { "Maintenance", NULL, N_("_Thumbnail maintenance..."),NULL, NULL, CB(layout_menu_remove_thumb_cb) },
798 { "Wallpaper", NULL, N_("Set as _wallpaper"),NULL, NULL, CB(layout_menu_wallpaper_cb) },
800 { "ZoomIn", GTK_STOCK_ZOOM_IN, N_("Zoom _in"), "equal", NULL, CB(layout_menu_zoom_in_cb) },
801 { "ZoomOut", GTK_STOCK_ZOOM_OUT, N_("Zoom _out"), "minus", NULL, CB(layout_menu_zoom_out_cb) },
802 { "Zoom100", GTK_STOCK_ZOOM_100, N_("Zoom _1:1"), "Z", NULL, CB(layout_menu_zoom_1_1_cb) },
803 { "ZoomFit", GTK_STOCK_ZOOM_FIT, N_("_Zoom to fit"), "X", NULL, CB(layout_menu_zoom_fit_cb) },
804 { "FullScreen", NULL, N_("F_ull screen"), "F", NULL, CB(layout_menu_fullscreen_cb) },
805 { "HideTools", NULL, N_("_Hide file list"), "<control>H", NULL, CB(layout_menu_hide_cb) },
806 { "SlideShow", NULL, N_("Toggle _slideshow"),"S", NULL, CB(layout_menu_slideshow_cb) },
807 { "Refresh", GTK_STOCK_REFRESH, N_("_Refresh"), "R", NULL, CB(layout_menu_refresh_cb) },
809 { "HelpContents", GTK_STOCK_HELP, N_("_Contents"), "F1", NULL, CB(layout_menu_help_cb) },
810 { "HelpShortcuts", NULL, N_("_Keyboard shortcuts"),NULL, NULL, CB(layout_menu_help_keys_cb) },
811 { "HelpNotes", NULL, N_("_Release notes"), NULL, NULL, CB(layout_menu_notes_cb) },
812 { "About", NULL, N_("_About"), NULL, NULL, CB(layout_menu_about_cb) }
815 static GtkToggleActionEntry menu_toggle_entries[] = {
816 { "Thumbnails", NULL, N_("_Thumbnails"), "T", NULL, CB(layout_menu_thumb_cb) },
817 { "FolderTree", NULL, N_("Tr_ee"), "<control>T", NULL, CB(layout_menu_tree_cb) },
818 { "FloatTools", NULL, N_("_Float file list"), "L", NULL, CB(layout_menu_float_cb) },
819 { "HideToolbar", NULL, N_("Hide tool_bar"), NULL, NULL, CB(layout_menu_toolbar_cb) },
820 { "SBarKeywords", NULL, N_("_Keywords"), "<control>K", NULL, CB(layout_menu_bar_info_cb) },
821 { "SBarExif", NULL, N_("E_xif data"), "<control>E", NULL, CB(layout_menu_bar_exif_cb) },
822 { "SBarSort", NULL, N_("Sort _manager"), "<control>S", NULL, CB(layout_menu_bar_sort_cb) }
825 static GtkRadioActionEntry menu_radio_entries[] = {
826 { "ViewList", NULL, N_("_List"), "<control>L", NULL, 0 },
827 { "ViewIcons", NULL, N_("I_cons"), "<control>I", NULL, 1 }
832 static const char *menu_ui_description =
834 " <menubar name='MainMenu'>"
835 " <menu action='FileMenu'>"
836 " <menuitem action='NewWindow'/>"
837 " <menuitem action='NewCollection'/>"
838 " <menuitem action='OpenCollection'/>"
839 " <menuitem action='OpenRecent'/>"
841 " <menuitem action='Search'/>"
842 " <menuitem action='FindDupes'/>"
843 " <menuitem action='PanView'/>"
845 " <menuitem action='Print'/>"
846 " <menuitem action='NewFolder'/>"
848 " <menuitem action='Copy'/>"
849 " <menuitem action='Move'/>"
850 " <menuitem action='Rename'/>"
851 " <menuitem action='Delete'/>"
853 " <menuitem action='CloseWindow'/>"
854 " <menuitem action='Quit'/>"
856 " <menu action='EditMenu'>"
857 " <menuitem action='Editor0'/>"
858 " <menuitem action='Editor1'/>"
859 " <menuitem action='Editor2'/>"
860 " <menuitem action='Editor3'/>"
861 " <menuitem action='Editor4'/>"
862 " <menuitem action='Editor5'/>"
863 " <menuitem action='Editor6'/>"
864 " <menuitem action='Editor7'/>"
865 " <menuitem action='Editor8'/>"
866 " <menuitem action='Editor9'/>"
868 " <menu action='AdjustMenu'>"
869 " <menuitem action='RotateCW'/>"
870 " <menuitem action='RotateCCW'/>"
871 " <menuitem action='Rotate180'/>"
872 " <menuitem action='Mirror'/>"
873 " <menuitem action='Flip'/>"
875 " <menuitem action='Properties'/>"
877 " <menuitem action='SelectAll'/>"
878 " <menuitem action='SelectNone'/>"
880 " <menuitem action='Preferences'/>"
881 " <menuitem action='Maintenance'/>"
883 " <menuitem action='Wallpaper'/>"
885 " <menu action='ViewMenu'>"
887 " <menuitem action='ZoomIn'/>"
888 " <menuitem action='ZoomOut'/>"
889 " <menuitem action='Zoom100'/>"
890 " <menuitem action='ZoomFit'/>"
892 " <menuitem action='Thumbnails'/>"
893 " <menuitem action='ViewList'/>"
894 " <menuitem action='ViewIcons'/>"
896 " <menuitem action='FolderTree'/>"
897 " <menuitem action='FullScreen'/>"
899 " <menuitem action='FloatTools'/>"
900 " <menuitem action='HideTools'/>"
901 " <menuitem action='HideToolbar'/>"
903 " <menuitem action='SBarKeywords'/>"
904 " <menuitem action='SBarExif'/>"
905 " <menuitem action='SBarSort'/>"
907 " <menuitem action='SlideShow'/>"
908 " <menuitem action='Refresh'/>"
910 " <menu action='HelpMenu'>"
912 " <menuitem action='HelpContents'/>"
913 " <menuitem action='HelpShortcuts'/>"
914 " <menuitem action='HelpNotes'/>"
916 " <menuitem action='About'/>"
922 static gchar *menu_translate(const gchar *path, gpointer data)
927 void layout_actions_setup(LayoutWindow *lw)
931 if (lw->ui_manager) return;
933 lw->action_group = gtk_action_group_new ("MenuActions");
934 gtk_action_group_set_translate_func(lw->action_group, menu_translate, NULL, NULL);
936 gtk_action_group_add_actions(lw->action_group,
937 menu_entries, G_N_ELEMENTS(menu_entries), lw);
938 gtk_action_group_add_toggle_actions(lw->action_group,
939 menu_toggle_entries, G_N_ELEMENTS(menu_toggle_entries), lw);
940 gtk_action_group_add_radio_actions(lw->action_group,
941 menu_radio_entries, G_N_ELEMENTS(menu_radio_entries),
942 0, G_CALLBACK(layout_menu_list_cb), lw);
944 lw->ui_manager = gtk_ui_manager_new();
945 gtk_ui_manager_set_add_tearoffs(lw->ui_manager, TRUE);
946 gtk_ui_manager_insert_action_group(lw->ui_manager, lw->action_group, 0);
949 if (!gtk_ui_manager_add_ui_from_string(lw->ui_manager, menu_ui_description, -1, &error))
951 g_message ("building menus failed: %s", error->message);
952 g_error_free (error);
957 void layout_actions_add_window(LayoutWindow *lw, GtkWidget *window)
959 GtkAccelGroup *group;
961 if (!lw->ui_manager) return;
963 group = gtk_ui_manager_get_accel_group(lw->ui_manager);
964 gtk_window_add_accel_group(GTK_WINDOW(window), group);
967 GtkWidget *layout_actions_menu_bar(LayoutWindow *lw)
969 return gtk_ui_manager_get_widget(lw->ui_manager, "/MainMenu");
974 *-----------------------------------------------------------------------------
976 *-----------------------------------------------------------------------------
979 static void layout_button_thumb_cb(GtkWidget *widget, gpointer data)
981 LayoutWindow *lw = data;
983 layout_thumb_set(lw, GTK_TOGGLE_BUTTON(widget)->active);
986 static void layout_button_home_cb(GtkWidget *widget, gpointer data)
988 LayoutWindow *lw = data;
989 const gchar *path = homedir();
991 if (path) layout_set_path(lw, path);
994 static void layout_button_refresh_cb(GtkWidget *widget, gpointer data)
996 LayoutWindow *lw = data;
1001 static void layout_button_zoom_in_cb(GtkWidget *widget, gpointer data)
1003 LayoutWindow *lw = data;
1005 layout_image_zoom_adjust(lw, get_zoom_increment());
1008 static void layout_button_zoom_out_cb(GtkWidget *widget, gpointer data)
1010 LayoutWindow *lw = data;
1012 layout_image_zoom_adjust(lw, -get_zoom_increment());
1015 static void layout_button_zoom_fit_cb(GtkWidget *widget, gpointer data)
1017 LayoutWindow *lw = data;
1019 layout_image_zoom_set(lw, 0.0);
1022 static void layout_button_zoom_1_1_cb(GtkWidget *widget, gpointer data)
1024 LayoutWindow *lw = data;
1026 layout_image_zoom_set(lw, 1.0);
1029 static void layout_button_config_cb(GtkWidget *widget, gpointer data)
1031 show_config_window();
1034 static void layout_button_float_cb(GtkWidget *widget, gpointer data)
1036 LayoutWindow *lw = data;
1038 layout_tools_float_toggle(lw);
1041 GtkWidget *layout_button(GtkWidget *box, gchar **pixmap_data, const gchar *stock_id, gint toggle,
1042 GtkTooltips *tooltips, const gchar *tip_text,
1043 GCallback func, gpointer data)
1050 button = gtk_toggle_button_new();
1054 button = gtk_button_new();
1057 g_signal_connect(G_OBJECT(button), "clicked", func, data);
1058 gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
1059 gtk_widget_show(button);
1060 gtk_tooltips_set_tip(tooltips, button, tip_text, NULL);
1064 icon = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_BUTTON);
1070 pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)pixmap_data);
1071 icon = gtk_image_new_from_pixbuf(pixbuf);
1072 gdk_pixbuf_unref(pixbuf);
1075 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
1077 gtk_container_add(GTK_CONTAINER(button), icon);
1078 gtk_widget_show(icon);
1083 GtkWidget *layout_button_bar(LayoutWindow *lw)
1086 GtkTooltips *tooltips;
1088 tooltips = lw->tooltips;
1090 box = gtk_hbox_new(FALSE, 0);
1092 lw->thumb_button = layout_button(box, (gchar **)icon_thumb_xpm, NULL, TRUE,
1093 tooltips, _("Show thumbnails"), G_CALLBACK(layout_button_thumb_cb), lw);
1094 layout_button(box, NULL, GTK_STOCK_HOME, FALSE,
1095 tooltips, _("Change to home folder"), G_CALLBACK(layout_button_home_cb), lw);
1096 layout_button(box, NULL, GTK_STOCK_REFRESH, FALSE,
1097 tooltips, _("Refresh file list"), G_CALLBACK(layout_button_refresh_cb), lw);
1098 layout_button(box, NULL, GTK_STOCK_ZOOM_IN, FALSE,
1099 tooltips, _("Zoom in"), G_CALLBACK(layout_button_zoom_in_cb), lw);
1100 layout_button(box, NULL, GTK_STOCK_ZOOM_OUT, FALSE,
1101 tooltips, _("Zoom out"), G_CALLBACK(layout_button_zoom_out_cb), lw);
1102 layout_button(box, NULL, GTK_STOCK_ZOOM_FIT, FALSE,
1103 tooltips, _("Fit image to window"), G_CALLBACK(layout_button_zoom_fit_cb), lw);
1104 layout_button(box, NULL, GTK_STOCK_ZOOM_100, FALSE,
1105 tooltips, _("Set zoom 1:1"), G_CALLBACK(layout_button_zoom_1_1_cb), lw);
1106 layout_button(box, NULL, GTK_STOCK_PREFERENCES, FALSE,
1107 tooltips, _("Configure options"), G_CALLBACK(layout_button_config_cb), lw);
1108 layout_button(box, (gchar **)icon_float_xpm, NULL, FALSE,
1109 tooltips, _("Float Controls"), G_CALLBACK(layout_button_float_cb), lw);
1115 *-----------------------------------------------------------------------------
1117 *-----------------------------------------------------------------------------
1120 static void layout_util_sync_views(LayoutWindow *lw)
1124 if (!lw->action_group) return;
1126 action = gtk_action_group_get_action(lw->action_group, "FolderTree");
1127 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->tree_view);
1129 action = gtk_action_group_get_action(lw->action_group, "ViewIcons");
1130 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->icon_view);
1132 action = gtk_action_group_get_action(lw->action_group, "FloatTools");
1133 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->tools_float);
1135 action = gtk_action_group_get_action(lw->action_group, "SBarKeywords");
1136 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->bar_info_enabled);
1138 action = gtk_action_group_get_action(lw->action_group, "SBarExif");
1139 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->bar_exif_enabled);
1141 action = gtk_action_group_get_action(lw->action_group, "SBarSort");
1142 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->bar_sort_enabled);
1144 action = gtk_action_group_get_action(lw->action_group, "HideToolbar");
1145 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->toolbar_hidden);
1148 void layout_util_sync_thumb(LayoutWindow *lw)
1152 if (!lw->action_group) return;
1154 action = gtk_action_group_get_action(lw->action_group, "Thumbnails");
1155 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->thumbs_enabled);
1156 g_object_set(action, "sensitive", !lw->icon_view, NULL);
1158 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lw->thumb_button), lw->thumbs_enabled);
1159 gtk_widget_set_sensitive(lw->thumb_button, !lw->icon_view);
1162 void layout_util_sync(LayoutWindow *lw)
1164 layout_util_sync_views(lw);
1165 layout_util_sync_thumb(lw);
1166 layout_menu_recent_update(lw);
1167 layout_menu_edit_update(lw);
1171 *-----------------------------------------------------------------------------
1172 * icons (since all the toolbar icons are included here, best place as any)
1173 *-----------------------------------------------------------------------------
1176 PixmapFolders *folder_icons_new(void)
1180 pf = g_new0(PixmapFolders, 1);
1182 pf->close = pixbuf_inline(PIXBUF_INLINE_FOLDER_CLOSED);
1183 pf->open = pixbuf_inline(PIXBUF_INLINE_FOLDER_OPEN);
1184 pf->deny = pixbuf_inline(PIXBUF_INLINE_FOLDER_LOCKED);
1185 pf->parent = pixbuf_inline(PIXBUF_INLINE_FOLDER_UP);
1190 void folder_icons_free(PixmapFolders *pf)
1194 g_object_unref(pf->close);
1195 g_object_unref(pf->open);
1196 g_object_unref(pf->deny);
1197 g_object_unref(pf->parent);
1203 *-----------------------------------------------------------------------------
1205 *-----------------------------------------------------------------------------
1208 #define SIDEBAR_WIDTH 288
1210 static void layout_bar_info_destroyed(GtkWidget *widget, gpointer data)
1212 LayoutWindow *lw = data;
1214 lw->bar_info = NULL;
1216 if (lw->utility_box)
1218 /* destroyed from within itself */
1219 lw->bar_info_enabled = FALSE;
1220 layout_util_sync_views(lw);
1224 static GList *layout_bar_info_list_cb(gpointer data)
1226 LayoutWindow *lw = data;
1228 return layout_selection_list(lw);
1231 static void layout_bar_info_new(LayoutWindow *lw)
1233 if (!lw->utility_box) return;
1235 lw->bar_info = bar_info_new(layout_image_get_path(lw), FALSE, lw->utility_box);
1236 bar_info_set_selection_func(lw->bar_info, layout_bar_info_list_cb, lw);
1237 bar_info_selection(lw->bar_info, layout_selection_count(lw, NULL) - 1);
1238 bar_info_size_request(lw->bar_info, SIDEBAR_WIDTH * 3 / 4);
1239 g_signal_connect(G_OBJECT(lw->bar_info), "destroy",
1240 G_CALLBACK(layout_bar_info_destroyed), lw);
1241 lw->bar_info_enabled = TRUE;
1243 gtk_box_pack_start(GTK_BOX(lw->utility_box), lw->bar_info, FALSE, FALSE, 0);
1244 gtk_widget_show(lw->bar_info);
1247 static void layout_bar_info_close(LayoutWindow *lw)
1251 bar_info_close(lw->bar_info);
1252 lw->bar_info = NULL;
1254 lw->bar_info_enabled = FALSE;
1257 void layout_bar_info_toggle(LayoutWindow *lw)
1259 if (lw->bar_info_enabled)
1261 layout_bar_info_close(lw);
1265 layout_bar_info_new(lw);
1269 static void layout_bar_info_new_image(LayoutWindow *lw)
1271 if (!lw->bar_info || !lw->bar_info_enabled) return;
1273 bar_info_set(lw->bar_info, layout_image_get_path(lw));
1276 static void layout_bar_info_new_selection(LayoutWindow *lw, gint count)
1278 if (!lw->bar_info || !lw->bar_info_enabled) return;
1280 bar_info_selection(lw->bar_info, count - 1);
1283 static void layout_bar_info_maint_renamed(LayoutWindow *lw)
1285 if (!lw->bar_info || !lw->bar_info_enabled) return;
1287 bar_info_maint_renamed(lw->bar_info, layout_image_get_path(lw));
1290 static void layout_bar_exif_destroyed(GtkWidget *widget, gpointer data)
1292 LayoutWindow *lw = data;
1296 lw->bar_exif_advanced = bar_exif_is_advanced(lw->bar_exif);
1299 lw->bar_exif = NULL;
1300 if (lw->utility_box)
1302 /* destroyed from within itself */
1303 lw->bar_exif_enabled = FALSE;
1304 layout_util_sync_views(lw);
1308 static void layout_bar_exif_sized(GtkWidget *widget, GtkAllocation *allocation, gpointer data)
1310 LayoutWindow *lw = data;
1314 lw->bar_exif_size = allocation->width;
1318 static void layout_bar_exif_new(LayoutWindow *lw)
1320 if (!lw->utility_box) return;
1322 lw->bar_exif = bar_exif_new(TRUE, layout_image_get_path(lw),
1323 lw->bar_exif_advanced, lw->utility_box);
1324 g_signal_connect(G_OBJECT(lw->bar_exif), "destroy",
1325 G_CALLBACK(layout_bar_exif_destroyed), lw);
1326 g_signal_connect(G_OBJECT(lw->bar_exif), "size_allocate",
1327 G_CALLBACK(layout_bar_exif_sized), lw);
1328 lw->bar_exif_enabled = TRUE;
1330 if (lw->bar_exif_size < 1) lw->bar_exif_size = SIDEBAR_WIDTH;
1331 gtk_widget_set_size_request(lw->bar_exif, lw->bar_exif_size, -1);
1332 gtk_box_pack_start(GTK_BOX(lw->utility_box), lw->bar_exif, FALSE, FALSE, 0);
1333 if (lw->bar_info) gtk_box_reorder_child(GTK_BOX(lw->utility_box), lw->bar_exif, 1);
1334 gtk_widget_show(lw->bar_exif);
1337 static void layout_bar_exif_close(LayoutWindow *lw)
1341 bar_exif_close(lw->bar_exif);
1342 lw->bar_exif = NULL;
1344 lw->bar_exif_enabled = FALSE;
1347 void layout_bar_exif_toggle(LayoutWindow *lw)
1349 if (lw->bar_exif_enabled)
1351 layout_bar_exif_close(lw);
1355 layout_bar_exif_new(lw);
1359 static void layout_bar_exif_new_image(LayoutWindow *lw)
1361 if (!lw->bar_exif || !lw->bar_exif_enabled) return;
1363 bar_exif_set(lw->bar_exif, layout_image_get_path(lw));
1366 static void layout_bar_sort_destroyed(GtkWidget *widget, gpointer data)
1368 LayoutWindow *lw = data;
1370 lw->bar_sort = NULL;
1372 if (lw->utility_box)
1374 /* destroyed from within itself */
1375 lw->bar_sort_enabled = FALSE;
1377 layout_util_sync_views(lw);
1381 static void layout_bar_sort_new(LayoutWindow *lw)
1383 if (!lw->utility_box) return;
1385 lw->bar_sort = bar_sort_new(lw);
1386 g_signal_connect(G_OBJECT(lw->bar_sort), "destroy",
1387 G_CALLBACK(layout_bar_sort_destroyed), lw);
1388 lw->bar_sort_enabled = TRUE;
1390 gtk_box_pack_end(GTK_BOX(lw->utility_box), lw->bar_sort, FALSE, FALSE, 0);
1391 gtk_widget_show(lw->bar_sort);
1394 static void layout_bar_sort_close(LayoutWindow *lw)
1398 bar_sort_close(lw->bar_sort);
1399 lw->bar_sort = NULL;
1401 lw->bar_sort_enabled = FALSE;
1404 void layout_bar_sort_toggle(LayoutWindow *lw)
1406 if (lw->bar_sort_enabled)
1408 layout_bar_sort_close(lw);
1412 layout_bar_sort_new(lw);
1416 void layout_bars_new_image(LayoutWindow *lw)
1418 layout_bar_info_new_image(lw);
1419 layout_bar_exif_new_image(lw);
1422 void layout_bars_new_selection(LayoutWindow *lw, gint count)
1424 layout_bar_info_new_selection(lw, count);
1427 GtkWidget *layout_bars_prepare(LayoutWindow *lw, GtkWidget *image)
1429 lw->utility_box = gtk_hbox_new(FALSE, PREF_PAD_GAP);
1430 gtk_box_pack_start(GTK_BOX(lw->utility_box), image, TRUE, TRUE, 0);
1431 gtk_widget_show(image);
1433 if (lw->bar_sort_enabled)
1435 layout_bar_sort_new(lw);
1438 if (lw->bar_info_enabled)
1440 layout_bar_info_new(lw);
1443 if (lw->bar_exif_enabled)
1445 layout_bar_exif_new(lw);
1448 return lw->utility_box;
1451 void layout_bars_close(LayoutWindow *lw)
1453 layout_bar_sort_close(lw);
1454 layout_bar_exif_close(lw);
1455 layout_bar_info_close(lw);
1458 void layout_bars_maint_renamed(LayoutWindow *lw)
1460 layout_bar_info_maint_renamed(lw);