From 20bb11bcb74131a26d0c4fcdaef33007e726eea7 Mon Sep 17 00:00:00 2001 From: "Gergely POLONKAI (W00d5t0ck)" Date: Sun, 8 Sep 2013 13:39:44 +0200 Subject: [PATCH] Created the wrapper application AgApp AgApp is a subclass of GtkApplication, and is used to wrap around the whole Astrognome application --- src/ag-app.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++ src/ag-app.h | 41 ++++++++++ src/astrognome.c | 63 +++++++++++++++- 3 files changed, 290 insertions(+), 4 deletions(-) create mode 100644 src/ag-app.c create mode 100644 src/ag-app.h diff --git a/src/ag-app.c b/src/ag-app.c new file mode 100644 index 0000000..97bad11 --- /dev/null +++ b/src/ag-app.c @@ -0,0 +1,190 @@ +#include + +#include "ag-app.h" +#include "config.h" + +struct _AgAppPrivate { +}; + +G_DEFINE_TYPE(AgApp, ag_app, GTK_TYPE_APPLICATION); + +GtkWindow * +ag_app_peek_first_window(AgApp *self) +{ + GList *l; + + for (l = gtk_application_get_windows(GTK_APPLICATION(self)); l; l = g_list_next(l)) { + if (GTK_IS_WINDOW(l->data)) { + return (GTK_WINDOW(l->data)); + } + } + + ag_app_new_window(self); + + return ag_app_peek_first_window(self); +} + +void +ag_app_new_window(AgApp *self) +{ + g_action_group_activate_action(G_ACTION_GROUP(self), "new-window", NULL); +} + +void +ag_app_quit(AgApp *self) +{ + g_action_group_activate_action(G_ACTION_GROUP(self), "quit", NULL); +} + +void +ag_app_raise(AgApp *self) +{ + g_action_group_activate_action(G_ACTION_GROUP(self), "raise", NULL); +} + +static void +new_window_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data) +{ + AgApp *self = AG_APP(user_data); + GtkWidget *window; + + window = gtk_application_window_new(GTK_APPLICATION(self)); + gtk_application_add_window(GTK_APPLICATION(self), GTK_WINDOW(window)); + gtk_widget_show_all(window); +} + +static void +preferences_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data) +{ + //ag_preferences_show_dialog(); +} + +static void +about_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data) +{ + const gchar *authors[] = { + "Gergely Polonkai ", + "Jean-André Santoni ", + NULL + }; + + const gchar **documentors = NULL; + const gchar *translator_credits = _("translator_credits"); + + /* i18n: Please don't translate "Astrognome" (it's marked as translatable for transliteration only */ + gtk_show_about_dialog(NULL, + "name", _("Astrognome"), + "version", PACKAGE_VERSION, + "comments", _("Astrologers' software for GNOME"), + "authors", authors, + "documentors", documentors, + "translator_credits", ((strcmp(translator_credits, "translator_credits") != 0) ? translator_credits : NULL), + "website", PACKAGE_URL, + "website-label", _("Astrognome Website"), + "logo-icon-name", PACKAGE_TARNAME, + NULL); +} + +static void +quit_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data) +{ + AgApp *self = AG_APP(user_data); + GList *l; + + while ((l = gtk_application_get_windows(GTK_APPLICATION(self)))) { + gtk_application_remove_window(GTK_APPLICATION(self), GTK_WINDOW(l->data)); + } +} + +static void +raise_cb(GSimpleAction *action, GVariant *parameter, gpointer user_data) +{ + AgApp *self = AG_APP(user_data); + GtkWindow *window; + + window = ag_app_peek_first_window(self); + gtk_window_present(window); +} + +static GActionEntry app_entries[] = { + { "new-window", new_window_cb, NULL, NULL, NULL }, + { "preferences", preferences_cb, NULL, NULL, NULL }, + { "about", about_cb, NULL, NULL, NULL }, + { "quit", quit_cb, NULL, NULL, NULL }, + { "raise", raise_cb, NULL, NULL, NULL }, +}; + +static void +setup_actions(AgApp *self) +{ + g_action_map_add_action_entries(G_ACTION_MAP(self), app_entries, G_N_ELEMENTS(app_entries), self); +} + +static void +setup_accelerators(AgApp *self) +{ + gtk_application_add_accelerator(GTK_APPLICATION(self), "w", "win.close", NULL); + gtk_application_add_accelerator(GTK_APPLICATION(self), "F10", "win.gear-menu", NULL); +} + +static void +setup_menu(AgApp *self) +{ + GtkBuilder *builder; + GMenuModel *model; + GError *err = NULL; + + builder = gtk_builder_new(); + + if (!gtk_builder_add_from_resource(builder, "/eu/polonkai/gergely/astrognome/astrognome.ui", &err)) { + g_error("%s", (err) ? err->message : "unknown error"); + } + + model = G_MENU_MODEL(gtk_builder_get_object(builder, "app-menu")); + gtk_application_set_app_menu(GTK_APPLICATION(self), model); + + g_object_unref(builder); +} + +static void +startup(GApplication *app) +{ + AgApp *self = AG_APP(app); + + G_APPLICATION_CLASS(ag_app_parent_class)->startup(app); + + setup_actions(self); + setup_menu(self); + setup_accelerators(self); +} + +AgApp * +ag_app_new(void) +{ + AgApp *app; + + /* i18n: Please don't translate "Astrognome" (it's marked as translatable for transliteration only */ + g_set_application_name(_("Astrognome")); + + app = g_object_new(AG_TYPE_APP, + "application-id", "eu.polonkai.gergely.Astrognome", + "flags", G_APPLICATION_FLAGS_NONE, + "register-session", TRUE, + NULL); + + return app; +} + +static void +ag_app_init(AgApp *self) +{ +} + +static void +ag_app_class_init(AgAppClass *klass) +{ + GApplicationClass *application_class = G_APPLICATION_CLASS(klass); + + application_class->startup = startup; +} + diff --git a/src/ag-app.h b/src/ag-app.h new file mode 100644 index 0000000..bc79b88 --- /dev/null +++ b/src/ag-app.h @@ -0,0 +1,41 @@ +#ifndef __AG_APP_H__ +#define __AG_APP_H__ + +#include + +G_BEGIN_DECLS + +#define AG_TYPE_APP (ag_app_get_type()) +#define AG_APP(o) (G_TYPE_CHECK_INSTANCE_CAST((o), AG_TYPE_APP, AgApp)) +#define AG_APP_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), AG_TYPE_APP, AgAppClass)) +#define AG_IS_APP(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), AG_TYPE_APP)) +#define AG_IS_APP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), AG_TYPE_APP)) +#define AG_APP_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), AG_TYPE_APP, AgAppClass)) + +typedef struct _AgApp AgApp; +typedef struct _AgAppClass AgAppClass; +typedef struct _AgAppPrivate AgAppPrivate; + +struct _AgApp { + GtkApplication parent_instance; + AgAppPrivate *priv; +}; + +struct _AgAppClass { + GtkApplicationClass parent_class; +}; + +GType ag_app_get_type(void) G_GNUC_CONST; + +AgApp *ag_app_new(void); + +GtkWindow *ag_app_peek_first_window(AgApp *self); + +void ag_app_new_window(AgApp *self); +void ag_app_quit(AgApp *self); +void ag_app_raise(AgApp *self); + +G_END_DECLS + +#endif /* __AG_APP_H__ */ + diff --git a/src/astrognome.c b/src/astrognome.c index 3201f32..cc6b75c 100644 --- a/src/astrognome.c +++ b/src/astrognome.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -6,9 +7,19 @@ #include +#include "ag-app.h" + #define UI_FILE PKGDATADIR "/astrognome.ui" GtkBuilder *builder; +static gboolean option_quit; +static gboolean option_version; + +static GOptionEntry options[] = { + { "version", 'v', 0, G_OPTION_ARG_NONE, &option_version, N_("Display version and exit"), NULL }, + { "quit", 'q', 0, G_OPTION_ARG_NONE, &option_quit, N_("Quit any running Astrognome"), NULL }, + { NULL } +}; const char *moonStateName[] = { "New Moon", @@ -483,12 +494,24 @@ action_new_activate_cb(GtkAction *action, gpointer user_data) gtk_widget_hide(GTK_WIDGET(dialog_new)); } +static void +run_action(AgApp *app, gboolean is_remote) +{ + if (option_quit) { + ag_app_quit(app); + } else if (is_remote) { + ag_app_raise(app); + } +} + static void application_activate_cb(GtkApplication *app, gpointer user_data) { GError *err = NULL; GtkWidget *window, - *grid; + *grid, + *header_bar, + *menu_button; builder = gtk_builder_new(); @@ -532,17 +555,49 @@ int main(int argc, char *argv[]) { gint status; - GtkApplication *app; + AgApp *app; + GError *err = NULL; + + setlocale(LC_ALL, ""); + bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR); + bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); + textdomain(GETTEXT_PACKAGE); gswe_init(); - app = gtk_application_new("eu.polonkai.gergely.astrognome", G_APPLICATION_FLAGS_NONE); + if (!gtk_init_with_args(&argc, &argv, NULL, options, GETTEXT_PACKAGE, &err)) { + g_printerr("%s\n", err->message); + + return EXIT_FAILURE; + } + + if (option_version) { + g_print("%s\n", PACKAGE_STRING); + + return EXIT_SUCCESS; + } + + app = ag_app_new(); g_signal_connect(app, "activate", G_CALLBACK(application_activate_cb), NULL); + g_application_set_default(G_APPLICATION(app)); + + if (!g_application_register(G_APPLICATION(app), NULL, &err)) { + g_printerr("Couldn't register Astrognome instance: '%s'\n", (err) ? err->message : ""); + g_object_unref(app); + + return EXIT_FAILURE; + } + + if (g_application_get_is_remote(G_APPLICATION(app))) { + run_action(app, TRUE); + g_object_unref(app); + + return EXIT_SUCCESS; + } status = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); - g_object_unref(G_OBJECT(builder)); return status; }