[eog] Provide an app menu



commit 232292e570192ff41a6509f381953803cf39e188
Author: Felix Riemann <friemann gnome org>
Date:   Thu Jun 7 15:47:30 2012 +0200

    Provide an app menu
    
    Heavily based on nautilus' app menu implementation.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=674938

 data/Makefile.am      |    1 +
 data/eog-app-menu.xml |   47 +++++++++++++
 src/eog-application.c |  184 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/eog-application.h |    2 +
 src/eog-window.c      |  144 +++++++++++++++++++++------------------
 src/eog-window.h      |    6 ++
 6 files changed, 318 insertions(+), 66 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index b63d4a1..ab41e1b 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -23,6 +23,7 @@ uidir = $(pkgdatadir)
 ui_DATA = eog-image-properties-dialog.ui \
 	eog-multiple-save-as-dialog.ui \
 	eog-preferences-dialog.ui \
+	eog-app-menu.xml \
 	eog-ui.xml \
 	eog-toolbar.xml
 
diff --git a/data/eog-app-menu.xml b/data/eog-app-menu.xml
new file mode 100644
index 0000000..e3cb519
--- /dev/null
+++ b/data/eog-app-menu.xml
@@ -0,0 +1,47 @@
+<interface>
+  <menu id="app-menu">
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_View</attribute>
+        <link name="submenu">
+          <item>
+            <attribute name="action">app.toolbar</attribute>
+            <attribute name="label" translatable="yes">_Toolbar</attribute>
+          </item>
+          <item>
+            <attribute name="action">app.view-statusbar</attribute>
+            <attribute name="label" translatable="yes">_Statusbar</attribute>
+          </item>
+          <item>
+            <attribute name="action">app.view-gallery</attribute>
+            <attribute name="label" translatable="yes">_Image Gallery</attribute>
+          </item>
+          <item>
+            <attribute name="action">app.view-sidebar</attribute>
+            <attribute name="label" translatable="yes">Side _Pane</attribute>
+          </item>
+        </link>
+      </item>
+    </section>
+    <section>
+      <item>
+	<attribute name="action">app.preferences</attribute>
+	<attribute name="label" translatable="yes">Prefere_nces</attribute>
+      </item>
+    </section>
+    <section>
+      <item>
+	<attribute name="action">app.help</attribute>
+	<attribute name="label" translatable="yes">_Help</attribute>
+      </item>
+      <item>
+	<attribute name="action">app.about</attribute>
+	<attribute name="label" translatable="yes">_About Image Viewer</attribute>
+      </item>
+      <item>
+	<attribute name="action">app.quit</attribute>
+	<attribute name="label" translatable="yes">_Quit</attribute>
+      </item>
+    </section>
+  </menu>
+</interface>
diff --git a/src/eog-application.c b/src/eog-application.c
index df57436..a97658a 100644
--- a/src/eog-application.c
+++ b/src/eog-application.c
@@ -26,6 +26,7 @@
 #include "config.h"
 #endif
 
+#include "eog-config-keys.h"
 #include "eog-image.h"
 #include "eog-session.h"
 #include "eog-window.h"
@@ -51,6 +52,183 @@ static void eog_application_save_accelerators (void);
 
 G_DEFINE_TYPE (EogApplication, eog_application, GTK_TYPE_APPLICATION);
 
+static EogWindow*
+get_focus_window (GtkApplication *application)
+{
+	GList *windows;
+	GtkWindow *window = NULL;
+
+	/* the windows are ordered with the last focused first */
+	windows = gtk_application_get_windows (application);
+
+	if (windows != NULL) {
+		window = g_list_nth_data (windows, 0);
+	}
+
+	return EOG_WINDOW (window);
+}
+
+static void
+action_about (GSimpleAction *action,
+	      GVariant      *parameter,
+	      gpointer       user_data)
+{
+	GtkApplication *application = GTK_APPLICATION (user_data);
+
+	eog_window_show_about_dialog (get_focus_window (application));
+}
+
+static void
+action_help (GSimpleAction *action,
+	     GVariant      *parameter,
+	     gpointer       user_data)
+{
+	GtkApplication *application = GTK_APPLICATION (user_data);
+
+	eog_util_show_help ("preferences",
+	                    GTK_WINDOW (get_focus_window (application)));
+}
+
+static void
+action_preferences (GSimpleAction *action,
+	            GVariant      *parameter,
+	            gpointer       user_data)
+{
+	GtkApplication *application = GTK_APPLICATION (user_data);
+
+	eog_window_show_preferences_dialog (get_focus_window (application));
+}
+
+static void
+action_toggle_state (GSimpleAction *action,
+                     GVariant *parameter,
+                     gpointer user_data)
+{
+	GVariant *state;
+	gboolean new_state;
+
+	state = g_action_get_state (G_ACTION (action));
+	new_state = !g_variant_get_boolean (state);
+	g_action_change_state (G_ACTION (action),
+	                       g_variant_new_boolean (new_state));
+	g_variant_unref (state);
+}
+
+static void
+action_quit (GSimpleAction *action,
+             GVariant      *parameter,
+             gpointer       user_data)
+{
+	GList *windows;
+
+	windows = gtk_application_get_windows (GTK_APPLICATION (user_data));
+
+	g_list_foreach (windows, (GFunc) eog_window_close, NULL);
+}
+
+static GActionEntry app_entries[] = {
+	{ "toolbar", action_toggle_state, NULL, "true", NULL },
+	{ "view-statusbar", action_toggle_state, NULL, "true", NULL },
+	{ "view-gallery", action_toggle_state, NULL, "true",  NULL },
+	{ "view-sidebar", action_toggle_state, NULL, "true",  NULL },
+	{ "preferences", action_preferences, NULL, NULL, NULL },
+	{ "about", action_about, NULL, NULL, NULL },
+	{ "help", action_help, NULL, NULL, NULL },
+	{ "quit", action_quit, NULL, NULL, NULL },
+};
+
+static gboolean
+_settings_map_get_bool_variant (GValue   *value,
+                               GVariant *variant,
+                               gpointer  user_data)
+{
+	g_return_val_if_fail (g_variant_is_of_type (variant,
+	                                            G_VARIANT_TYPE_BOOLEAN),
+	                      FALSE);
+
+	g_value_set_variant (value, variant);
+
+	return TRUE;
+}
+
+static GVariant*
+_settings_map_set_variant (const GValue       *value,
+                           const GVariantType *expected_type,
+                           gpointer            user_data)
+{
+	g_return_val_if_fail (g_variant_is_of_type (g_value_get_variant (value), expected_type), NULL);
+
+	return g_value_dup_variant (value);
+}
+
+static void
+eog_application_init_app_menu (EogApplication *application)
+{
+	GtkBuilder *builder;
+	GError *error = NULL;
+	GAction *action;
+
+	g_action_map_add_action_entries (G_ACTION_MAP (application),
+					 app_entries, G_N_ELEMENTS (app_entries),
+					 application);
+
+	builder = gtk_builder_new ();
+	gtk_builder_add_from_file (builder, EOG_DATA_DIR"/eog-app-menu.xml", &error);
+
+	if (error == NULL) {
+		gtk_application_set_app_menu (GTK_APPLICATION (application),
+					      G_MENU_MODEL (gtk_builder_get_object (builder,
+		                                                                    "app-menu")));
+	} else {
+		g_critical ("Unable to add the application menu: %s\n", error->message);
+		g_error_free (error);
+	}
+
+	action = g_action_map_lookup_action (G_ACTION_MAP (application),
+	                                     "view-gallery");
+	g_settings_bind_with_mapping (application->ui_settings,
+	                              EOG_CONF_UI_IMAGE_GALLERY, action,
+	                              "state", G_SETTINGS_BIND_DEFAULT,
+	                              _settings_map_get_bool_variant,
+	                              _settings_map_set_variant,
+	                              NULL, NULL);
+
+	action = g_action_map_lookup_action (G_ACTION_MAP (application),
+	                                     "toolbar");
+	g_settings_bind_with_mapping (application->ui_settings,
+	                              EOG_CONF_UI_TOOLBAR, action, "state",
+                                      G_SETTINGS_BIND_DEFAULT,
+	                              _settings_map_get_bool_variant,
+	                              _settings_map_set_variant,
+	                              NULL, NULL);
+	action = g_action_map_lookup_action (G_ACTION_MAP (application),
+	                                     "view-sidebar");
+	g_settings_bind_with_mapping (application->ui_settings,
+	                              EOG_CONF_UI_SIDEBAR, action, "state",
+                                      G_SETTINGS_BIND_DEFAULT,
+	                              _settings_map_get_bool_variant,
+	                              _settings_map_set_variant,
+	                              NULL, NULL);
+	action = g_action_map_lookup_action (G_ACTION_MAP (application),
+	                                     "view-statusbar");
+	g_settings_bind_with_mapping (application->ui_settings,
+	                              EOG_CONF_UI_STATUSBAR, action, "state",
+                                      G_SETTINGS_BIND_DEFAULT,
+	                              _settings_map_get_bool_variant,
+	                              _settings_map_set_variant,
+	                              NULL, NULL);
+
+	g_object_unref (builder);
+}
+
+static void
+eog_application_startup (GApplication *application)
+{
+	G_APPLICATION_CLASS (eog_application_parent_class)->startup (application);
+
+	eog_application_init_app_menu (EOG_APPLICATION (application));
+}
+
 static void
 eog_application_activate (GApplication *application)
 {
@@ -92,6 +270,9 @@ eog_application_finalize (GObject *object)
 		g_object_unref (application->plugin_engine);
 		application->plugin_engine = NULL;
 	}
+
+	g_clear_object (&application->ui_settings);
+
 	eog_application_save_accelerators ();
 }
 
@@ -142,6 +323,7 @@ eog_application_class_init (EogApplicationClass *eog_application_class)
 
 	object_class->finalize = eog_application_finalize;
 
+	application_class->startup = eog_application_startup;
 	application_class->activate = eog_application_activate;
 	application_class->open = eog_application_open;
 	application_class->add_platform_data = eog_application_add_platform_data;
@@ -159,6 +341,8 @@ eog_application_init (EogApplication *eog_application)
 	eog_application->plugin_engine = eog_plugin_engine_new ();
 	eog_application->flags = 0;
 
+	eog_application->ui_settings = g_settings_new (EOG_CONF_UI);
+
 	egg_toolbars_model_load_names (eog_application->toolbars_model,
 				       EOG_DATA_DIR "/eog-toolbar.xml");
 
diff --git a/src/eog-application.h b/src/eog-application.h
index 22c32cd..b93688c 100644
--- a/src/eog-application.h
+++ b/src/eog-application.h
@@ -58,6 +58,8 @@ struct _EogApplication {
 
 	TotemScrsaver    *scr_saver;
 	EogStartupFlags   flags;
+
+	GSettings        *ui_settings;
 };
 
 struct _EogApplicationClass {
diff --git a/src/eog-window.c b/src/eog-window.c
index c5203d1..064fda3 100644
--- a/src/eog-window.c
+++ b/src/eog-window.c
@@ -2442,36 +2442,17 @@ eog_window_unsaved_images_confirm (EogWindow *window)
 static void
 eog_window_cmd_close_window (GtkAction *action, gpointer user_data)
 {
-	EogWindow *window;
-	EogWindowPrivate *priv;
-
 	g_return_if_fail (EOG_IS_WINDOW (user_data));
 
-	window = EOG_WINDOW (user_data);
-	priv = window->priv;
-
-	if (priv->save_job != NULL) {
-		eog_window_finish_saving (window);
-	}
-
-	if (!eog_window_unsaved_images_confirm (window)) {
-		gtk_widget_destroy (GTK_WIDGET (user_data));
-	}
+	eog_window_close (EOG_WINDOW (user_data));
 }
 
 static void
 eog_window_cmd_preferences (GtkAction *action, gpointer user_data)
 {
-	EogWindow *window;
-	GObject *pref_dlg;
-
 	g_return_if_fail (EOG_IS_WINDOW (user_data));
 
-	window = EOG_WINDOW (user_data);
-
-	pref_dlg = eog_preferences_dialog_get_instance (GTK_WINDOW (window));
-
-	eog_dialog_show (EOG_DIALOG (pref_dlg));
+	eog_window_show_preferences_dialog (EOG_WINDOW (user_data));
 }
 
 #define EOG_TB_EDITOR_DLG_RESET_RESPONSE 128
@@ -2605,54 +2586,10 @@ eog_window_cmd_help (GtkAction *action, gpointer user_data)
 static void
 eog_window_cmd_about (GtkAction *action, gpointer user_data)
 {
-	EogWindow *window;
-
 	g_return_if_fail (EOG_IS_WINDOW (user_data));
 
-	static const char *authors[] = {
-		"Claudio Saavedra <csaavedra igalia com> (maintainer)",
-		"Felix Riemann <friemann gnome org> (maintainer)",
-		"",
-		"Lucas Rocha <lucasr gnome org>",
-		"Tim Gerla <tim+gnomebugs gerla net>",
-		"Philip Van Hoof <pvanhoof gnome org>",
-                "Paolo Borelli <pborelli katamail com>",
-		"Jens Finke <jens triq net>",
-		"Martin Baulig <martin home-of-linux org>",
-		"Arik Devens <arik gnome org>",
-		"Michael Meeks <mmeeks gnu org>",
-		"Federico Mena-Quintero <federico gnu org>",
-		"Lutz M\xc3\xbcller <urc8 rz uni-karlsruhe de>",
-		NULL
-	};
-
-	static const char *documenters[] = {
-		"Eliot Landrum <eliot landrum cx>",
-		"Federico Mena-Quintero <federico gnu org>",
-		"Sun GNOME Documentation Team <gdocteam sun com>",
-		"Tiffany Antopolski <tiffany antopolski com>",
-		NULL
-	};
-
-	const char *translators;
-
-	translators = _("translator-credits");
-
-	window = EOG_WINDOW (user_data);
+	eog_window_show_about_dialog (EOG_WINDOW (user_data));
 
-	gtk_show_about_dialog (GTK_WINDOW (window),
-			       "program-name", _("Image Viewer"),
-			       "version", VERSION,
-			       "copyright", "Copyright \xc2\xa9 2000-2010 Free Software Foundation, Inc.",
-			       "comments",_("The GNOME image viewer."),
-			       "authors", authors,
-			       "documenters", documenters,
-			       "translator-credits", translators,
-			       "website", "http://projects.gnome.org/eog/";,
-			       "logo-icon-name", "eog",
-			       "wrap-license", TRUE,
-			       "license-type", GTK_LICENSE_GPL_2_0,
-			       NULL);
 }
 
 static void
@@ -5737,3 +5674,78 @@ eog_window_is_not_initializing (const EogWindow *window)
 
 	return window->priv->status != EOG_WINDOW_STATUS_INIT;
 }
+
+void
+eog_window_show_about_dialog (EogWindow *window)
+{
+	g_return_if_fail (EOG_IS_WINDOW (window));
+
+	static const char *authors[] = {
+		"Claudio Saavedra <csaavedra igalia com> (maintainer)",
+		"Felix Riemann <friemann gnome org> (maintainer)",
+		"",
+		"Lucas Rocha <lucasr gnome org>",
+		"Tim Gerla <tim+gnomebugs gerla net>",
+		"Philip Van Hoof <pvanhoof gnome org>",
+                "Paolo Borelli <pborelli katamail com>",
+		"Jens Finke <jens triq net>",
+		"Martin Baulig <martin home-of-linux org>",
+		"Arik Devens <arik gnome org>",
+		"Michael Meeks <mmeeks gnu org>",
+		"Federico Mena-Quintero <federico gnu org>",
+		"Lutz M\xc3\xbcller <urc8 rz uni-karlsruhe de>",
+		NULL
+	};
+
+	static const char *documenters[] = {
+		"Eliot Landrum <eliot landrum cx>",
+		"Federico Mena-Quintero <federico gnu org>",
+		"Sun GNOME Documentation Team <gdocteam sun com>",
+		"Tiffany Antopolski <tiffany antopolski com>",
+		NULL
+	};
+
+	gtk_show_about_dialog (GTK_WINDOW (window),
+			       "program-name", _("Image Viewer"),
+			       "version", VERSION,
+			       "copyright", "Copyright \xc2\xa9 2000-2010 Free Software Foundation, Inc.",
+			       "comments",_("The GNOME image viewer."),
+			       "authors", authors,
+			       "documenters", documenters,
+			       "translator-credits", _("translator-credits"),
+			       "website", "http://projects.gnome.org/eog/";,
+			       "logo-icon-name", "eog",
+			       "wrap-license", TRUE,
+			       "license-type", GTK_LICENSE_GPL_2_0,
+			       NULL);
+}
+
+void
+eog_window_show_preferences_dialog (EogWindow *window)
+{
+	GObject *pref_dlg;
+
+	g_return_if_fail (window != NULL);
+
+	pref_dlg = eog_preferences_dialog_get_instance (GTK_WINDOW (window));
+
+	eog_dialog_show (EOG_DIALOG (pref_dlg));
+}
+
+void
+eog_window_close (EogWindow *window)
+{
+	EogWindowPrivate *priv;
+
+	g_return_if_fail (EOG_IS_WINDOW (window));
+
+	priv = window->priv;
+
+	if (priv->save_job != NULL) {
+		eog_window_finish_saving (window);
+	}
+
+	if (!eog_window_unsaved_images_confirm (window)) {
+		gtk_widget_destroy (GTK_WIDGET (window));
+	}
+}
diff --git a/src/eog-window.h b/src/eog-window.h
index e19bcfe..a5c1e58 100644
--- a/src/eog-window.h
+++ b/src/eog-window.h
@@ -128,6 +128,12 @@ gboolean      eog_window_is_not_initializing (const EogWindow *window);
 
 void          eog_window_reload_image (EogWindow *window);
 EogDialog    *eog_window_get_properties_dialog (EogWindow *window);
+
+void          eog_window_show_about_dialog (EogWindow    *window);
+void          eog_window_show_preferences_dialog (EogWindow *window);
+
+void          eog_window_close          (EogWindow *window);
+
 G_END_DECLS
 
 #endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]