[gnome-utils] dictionary: Port to GtkApplication
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-utils] dictionary: Port to GtkApplication
- Date: Sat, 29 Jan 2011 19:21:59 +0000 (UTC)
commit d84f19ae8cd387d1600ece9c4cc50cfeccd5020e
Author: Emmanuele Bassi <ebassi linux intel com>
Date: Sat Jan 29 18:36:04 2011 +0000
dictionary: Port to GtkApplication
Use the newly added GApplication and GtkApplication classes, provided by
GIO and GTK+ respectively, to handle the lifetime of the Dictionary.
This makes the Dictionary a single instance application; new windows are
created on demand by the running process.
gnome-dictionary/src/gdict-app.c | 451 ++++++++++-------------------------
gnome-dictionary/src/gdict-app.h | 18 +--
gnome-dictionary/src/gdict-window.c | 23 ++-
gnome-dictionary/src/gdict-window.h | 2 +
gnome-dictionary/src/main.c | 5 +-
5 files changed, 150 insertions(+), 349 deletions(-)
---
diff --git a/gnome-dictionary/src/gdict-app.c b/gnome-dictionary/src/gdict-app.c
index 8d41fbc..c744920 100644
--- a/gnome-dictionary/src/gdict-app.c
+++ b/gnome-dictionary/src/gdict-app.c
@@ -40,40 +40,66 @@
static GdictApp *singleton = NULL;
-
struct _GdictAppClass
{
GObjectClass parent_class;
};
+G_DEFINE_TYPE (GdictApp, gdict_app, G_TYPE_OBJECT);
+static gchar **gdict_lookup_words = NULL;
+static gchar **gdict_match_words = NULL;
-G_DEFINE_TYPE (GdictApp, gdict_app, G_TYPE_OBJECT);
+static gchar *gdict_source_name = NULL;
+static gchar *gdict_database_name = NULL;
+static gchar *gdict_strategy_name = NULL;
+static GOptionEntry gdict_app_goptions[] = {
+ {
+ "look-up", 0,
+ 0,
+ G_OPTION_ARG_STRING_ARRAY, &gdict_lookup_words,
+ N_("Words to look up"), N_("WORD")
+ },
+ {
+ "match", 0,
+ 0,
+ G_OPTION_ARG_STRING_ARRAY, &gdict_match_words,
+ N_("Words to match"), N_("WORD")
+ },
+ {
+ "source", 's',
+ 0,
+ G_OPTION_ARG_STRING, &gdict_source_name,
+ N_("Dictionary source to use"), N_("NAME")
+ },
+ {
+ "database", 'D',
+ 0,
+ G_OPTION_ARG_STRING, &gdict_database_name,
+ N_("Database to use"), N_("NAME")
+ },
+ {
+ "strategy", 'S',
+ 0,
+ G_OPTION_ARG_STRING, &gdict_strategy_name,
+ N_("Strategy to use"), N_("NAME")
+ },
+ {
+ G_OPTION_REMAINING, 0, 0,
+ G_OPTION_ARG_STRING_ARRAY, &gdict_lookup_words,
+ N_("Words to look up"), N_("WORDS")
+ },
+ { NULL },
+};
static void
gdict_app_finalize (GObject *object)
{
GdictApp *app = GDICT_APP (object);
-
+
if (app->loader)
g_object_unref (app->loader);
-
- app->current_window = NULL;
-
- g_slist_foreach (app->windows,
- (GFunc) gtk_widget_destroy,
- NULL);
- g_slist_free (app->windows);
-
- g_slist_foreach (app->lookup_words, (GFunc) g_free, NULL);
- g_slist_free (app->lookup_words);
-
- g_slist_foreach (app->match_words, (GFunc) g_free, NULL);
- g_slist_free (app->match_words);
-
- g_free (app->database);
- g_free (app->source_name);
G_OBJECT_CLASS (gdict_app_parent_class)->finalize (object);
}
@@ -89,310 +115,126 @@ gdict_app_class_init (GdictAppClass *klass)
static void
gdict_app_init (GdictApp *app)
{
- app->windows = NULL;
- app->current_window = NULL;
}
static void
-gdict_window_destroy_cb (GtkWidget *widget,
- gpointer user_data)
+gdict_activate (GApplication *application,
+ GdictApp *gdict_app)
{
- GdictWindow *window = GDICT_WINDOW (widget);
- GdictApp *app = GDICT_APP (user_data);
-
- g_assert (GDICT_IS_APP (app));
+ GtkWidget *window;
- app->windows = g_slist_remove (app->windows, window);
-
- if (window == app->current_window)
- app->current_window = app->windows ? app->windows->data : NULL;
-
- if (app->windows == NULL)
- gtk_main_quit ();
}
-static void
-gdict_window_created_cb (GdictWindow *parent,
- GdictWindow *new_window,
- gpointer user_data)
-{
- GdictApp *app = GDICT_APP (user_data);
-
- /* this might seem convoluted - but it's necessary, since I don't want
- * GdictWindow to know about the GdictApp singleton. every time a new
- * window is created by a GdictWindow, it will register its "child window"
- * here; the lifetime handlers will check every child window created and
- * destroyed, and will add/remove it to the windows list accordingly
- */
- g_signal_connect (new_window, "created",
- G_CALLBACK (gdict_window_created_cb), app);
- g_signal_connect (new_window, "destroy",
- G_CALLBACK (gdict_window_destroy_cb), app);
-
- if (gtk_window_get_group (GTK_WINDOW (parent)))
- gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (parent)),
- GTK_WINDOW (new_window));
-
- app->windows = g_slist_prepend (app->windows, new_window);
- app->current_window = new_window;
-}
-
-static void
-gdict_create_window (GdictApp *app)
+static int
+gdict_command_line (GApplication *application,
+ GApplicationCommandLine *cmd_line,
+ GdictApp *gdict_app)
{
+ GOptionContext *context;
+ GError *error;
GSList *l;
+ gsize words_len, i;
+ gint argc;
+ char **argv;
- if (!singleton->lookup_words && !singleton->match_words)
- {
- GtkWidget *window;
+ argv = g_application_command_line_get_arguments (cmd_line, &argc);
- window = gdict_window_new (GDICT_WINDOW_ACTION_CLEAR,
- singleton->loader,
- singleton->source_name,
- NULL);
- g_signal_connect (window, "created",
- G_CALLBACK (gdict_window_created_cb), app);
- g_signal_connect (window, "destroy",
- G_CALLBACK (gdict_window_destroy_cb), app);
-
- app->windows = g_slist_prepend (app->windows, window);
- app->current_window = GDICT_WINDOW (window);
+ /* create the new option context */
+ context = g_option_context_new (N_(" - Look up words in dictionaries"));
+ g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
+ g_option_context_add_main_entries (context, gdict_app_goptions, GETTEXT_PACKAGE);
+ g_option_context_add_group (context, gdict_get_option_group ());
+ g_option_context_add_group (context, gtk_get_option_group (FALSE));
+
+ error = NULL;
+ if (!g_option_context_parse (context, &argc, &argv, &error))
+ {
+ g_critical ("Failed to parse argument: %s", error->message);
+ g_error_free (error);
+ g_option_context_free (context);
+ return 1;
+ }
+
+ g_option_context_free (context);
+
+ if (gdict_lookup_words == NULL &&
+ gdict_match_words == NULL)
+ {
+ GtkWidget *window = gdict_window_new (GDICT_WINDOW_ACTION_CLEAR,
+ singleton->loader,
+ gdict_source_name,
+ gdict_database_name,
+ gdict_strategy_name,
+ NULL);
+ gtk_window_set_application (GTK_WINDOW (window), singleton->app);
gtk_widget_show (window);
- return;
+ return 0;
}
-
- for (l = singleton->lookup_words; l != NULL; l = l->next)
+
+ if (gdict_lookup_words != NULL)
+ words_len = g_strv_length (gdict_lookup_words);
+ else
+ words_len = 0;
+
+ for (i = 0; i < words_len; i++)
{
- gchar *word = l->data;
+ const gchar *word = gdict_lookup_words[i];
GtkWidget *window;
window = gdict_window_new (GDICT_WINDOW_ACTION_LOOKUP,
- singleton->loader,
- singleton->source_name,
- word);
+ singleton->loader,
+ gdict_source_name,
+ gdict_database_name,
+ gdict_strategy_name,
+ word);
- g_signal_connect (window, "created",
- G_CALLBACK (gdict_window_created_cb), app);
- g_signal_connect (window, "destroy",
- G_CALLBACK (gdict_window_destroy_cb), app);
-
- app->windows = g_slist_prepend (app->windows, window);
- app->current_window = GDICT_WINDOW (window);
-
+ gtk_window_set_application (GTK_WINDOW (window), singleton->app);
gtk_widget_show (window);
}
- for (l = singleton->match_words; l != NULL; l = l->next)
+ if (gdict_match_words != NULL)
+ words_len = g_strv_length (gdict_match_words);
+ else
+ words_len = 0;
+
+ for (i = 0; i < words_len; i++)
{
- gchar *word = l->data;
+ const gchar *word = gdict_match_words[i];
GtkWidget *window;
window = gdict_window_new (GDICT_WINDOW_ACTION_MATCH,
singleton->loader,
- singleton->source_name,
+ gdict_source_name,
+ gdict_database_name,
+ gdict_strategy_name,
word);
- g_signal_connect (window, "created",
- G_CALLBACK (gdict_window_created_cb), app);
- g_signal_connect (window, "destroy",
- G_CALLBACK (gdict_window_destroy_cb), app);
-
- app->windows = g_slist_prepend (app->windows, window);
- app->current_window = GDICT_WINDOW (window);
-
+ gtk_window_set_application (GTK_WINDOW (window), singleton->app);
gtk_widget_show (window);
}
-}
-
-static void
-definition_found_cb (GdictContext *context,
- GdictDefinition *definition,
- gpointer user_data)
-{
- /* Translators: the first is the word found, the second is the
- * database name and the last is the definition's text; please
- * keep the new lines. */
- g_print (_("Definition for '%s'\n"
- " From '%s':\n"
- "\n"
- "%s\n"),
- gdict_definition_get_word (definition),
- gdict_definition_get_database (definition),
- gdict_definition_get_text (definition));
-}
-
-static void
-error_cb (GdictContext *context,
- const GError *error,
- gpointer user_data)
-{
- g_print (_("Error: %s\n"), error->message);
-
- gtk_main_quit ();
-}
-
-static void
-lookup_end_cb (GdictContext *context,
- gpointer user_data)
-{
- GdictApp *app = GDICT_APP (user_data);
-
- app->remaining_words -= 1;
- if (app->remaining_words == 0)
- gtk_main_quit ();
-}
-
-static void
-gdict_look_up_word_and_quit (GdictApp *app)
-{
- GdictSource *source;
- GdictContext *context;
- GSList *l;
-
- if ((!app->lookup_words) || (!app->match_words))
- {
- g_print (_("See gnome-dictionary --help for usage\n"));
-
- gdict_cleanup ();
- exit (1);
- }
-
- if (app->source_name)
- source = gdict_source_loader_get_source (app->loader, app->source_name);
- else
- source = gdict_source_loader_get_source (app->loader, GDICT_DEFAULT_SOURCE_NAME);
-
- if (!source)
- {
- g_warning (_("Unable to find a suitable dictionary source"));
-
- gdict_cleanup ();
- exit (1);
- }
-
- /* we'll just use this one context, so we can destroy it along with
- * the source that contains it
- */
- context = gdict_source_peek_context (source);
- g_assert (GDICT_IS_CONTEXT (context));
-
- g_signal_connect (context, "definition-found",
- G_CALLBACK (definition_found_cb), app);
- g_signal_connect (context, "error",
- G_CALLBACK (error_cb), app);
- g_signal_connect (context, "lookup-end",
- G_CALLBACK (lookup_end_cb), app);
-
- app->remaining_words = 0;
- for (l = app->lookup_words; l != NULL; l = l->next)
- {
- gchar *word = l->data;
- GError *err = NULL;
-
- app->remaining_words += 1;
-
- gdict_context_define_word (context,
- app->database,
- word,
- &err);
-
- if (err)
- {
- g_warning (_("Error while looking up the definition of \"%s\":\n%s"),
- word,
- err->message);
-
- g_error_free (err);
- }
- }
-
- gtk_main ();
-
- g_object_unref (source);
-
- gdict_cleanup ();
- exit (0);
+ return 0;
}
void
-gdict_init (int *argc, char ***argv)
+gdict_main (int *argc,
+ char ***argv)
{
- GError *err = NULL;
- GOptionContext *context;
gchar *loader_path;
- gchar **lookup_words = NULL;
- gchar **match_words = NULL;
- gchar *database = NULL;
- gchar *strategy = NULL;
- gchar *source_name = NULL;
- gboolean no_window = FALSE;
- gboolean list_sources = FALSE;
-
- const GOptionEntry gdict_app_goptions[] =
- {
- { "look-up", 0, 0, G_OPTION_ARG_STRING_ARRAY, &lookup_words,
- N_("Words to look up"), N_("word") },
- { "match", 0, 0, G_OPTION_ARG_STRING_ARRAY, &match_words,
- N_("Words to match"), N_("word") },
- { "source", 's', 0, G_OPTION_ARG_STRING, &source_name,
- N_("Dictionary source to use"), N_("source") },
- { "list-sources", 'l', 0, G_OPTION_ARG_NONE, &list_sources,
- N_("Show available dictionary sources"), NULL },
- { "no-window", 'n', 0, G_OPTION_ARG_NONE, &no_window,
- N_("Print result to the console"), NULL },
- { "database", 'D', 0, G_OPTION_ARG_STRING, &database,
- N_("Database to use"), N_("db") },
- { "strategy", 'S', 0, G_OPTION_ARG_STRING, &strategy,
- N_("Strategy to use"), N_("strat") },
- { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &lookup_words,
- N_("Words to look up"), N_("word") },
- { NULL },
- };
-
- /* we must have GLib's type system up and running in order to create the
- * singleton object for gnome-dictionary; thus, we can't rely on
- * gnome_program_init() calling g_type_init() for us.
- */
- g_type_init ();
- g_assert (singleton == NULL);
-
- singleton = GDICT_APP (g_object_new (GDICT_TYPE_APP, NULL));
- g_assert (GDICT_IS_APP (singleton));
-
- /* create the new option context */
- context = g_option_context_new (_(" - Look up words in dictionaries"));
-
- g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
- g_option_context_add_main_entries (context, gdict_app_goptions, GETTEXT_PACKAGE);
- g_option_context_add_group (context, gdict_get_option_group ());
- g_option_context_add_group (context, gtk_get_option_group (TRUE));
+ if (!gdict_create_data_dir ())
+ exit (1);
- g_option_context_parse (context, argc, argv, &err);
- if (err)
- {
- g_critical ("Failed to parse argument: %s", err->message);
- g_error_free (err);
- g_option_context_free (context);
- gdict_cleanup ();
+ g_type_init ();
+ gtk_init (argc, argv);
- exit (1);
- }
-
g_set_application_name (_("Dictionary"));
gtk_window_set_default_icon_name ("accessories-dictionary");
-
- if (!gdict_create_data_dir ())
- {
- gdict_cleanup ();
-
- exit (1);
- }
- singleton->settings = g_settings_new ("org.gnome.dictionary");
+ /* the main application instance */
+ singleton = g_object_new (gdict_app_get_type (), NULL);
/* add user's path for fetching dictionary sources */
singleton->loader = gdict_source_loader_new ();
@@ -400,54 +242,10 @@ gdict_init (int *argc, char ***argv)
gdict_source_loader_add_search_path (singleton->loader, loader_path);
g_free (loader_path);
- if (lookup_words)
- {
- gsize i;
- gsize length = g_strv_length (lookup_words);
-
- for (i = 0; i < length; i++)
- singleton->lookup_words = g_slist_prepend (singleton->lookup_words,
- g_strdup (lookup_words[i]));
- }
-
- if (match_words)
- {
- gsize i;
- gsize length = g_strv_length (match_words);
-
- for (i = 0; i < length; i++)
- singleton->match_words = g_slist_prepend (singleton->match_words,
- g_strdup (match_words[i]));
- }
-
- if (database)
- singleton->database = g_strdup (database);
-
- if (source_name)
- singleton->source_name = g_strdup (source_name);
-
- if (no_window)
- singleton->no_window = TRUE;
+ singleton->app = gtk_application_new ("org.gnome.Dictionary", G_APPLICATION_HANDLES_COMMAND_LINE);
+ g_signal_connect (singleton->app, "command-line", G_CALLBACK (gdict_command_line), singleton);
- if (list_sources)
- singleton->list_sources = TRUE;
-}
-
-void
-gdict_main (void)
-{
- if (!singleton)
- {
- g_warning ("You must initialize GdictApp using gdict_init()\n");
- return;
- }
-
- if (!singleton->no_window)
- gdict_create_window (singleton);
- else
- gdict_look_up_word_and_quit (singleton);
-
- gtk_main ();
+ g_application_run (G_APPLICATION (singleton->app), *argc, *argv);
}
void
@@ -459,5 +257,6 @@ gdict_cleanup (void)
return;
}
+ g_object_unref (singleton->app);
g_object_unref (singleton);
}
diff --git a/gnome-dictionary/src/gdict-app.h b/gnome-dictionary/src/gdict-app.h
index e70d585..5223b0f 100644
--- a/gnome-dictionary/src/gdict-app.h
+++ b/gnome-dictionary/src/gdict-app.h
@@ -23,7 +23,6 @@
#ifndef __GDICT_APP_H__
#define __GDICT_APP_H__
-#include <gio/gio.h>
#include <gtk/gtk.h>
#include <libgdict/gdict.h>
@@ -43,28 +42,15 @@ struct _GdictApp
{
GObject parent_instance;
- GSettings *settings;
+ GtkApplication *app;
- GSList *lookup_words;
- GSList *match_words;
- gint remaining_words;
-
- gchar *database;
- gchar *source_name;
- gboolean no_window;
- gboolean list_sources;
-
GdictSourceLoader *loader;
-
- GdictWindow *current_window;
- GSList *windows;
};
GType gdict_app_get_type (void) G_GNUC_CONST;
-void gdict_init (int *argc, char ***argv);
-void gdict_main (void);
+void gdict_main (int *argc, char ***argv);
void gdict_cleanup (void);
G_END_DECLS
diff --git a/gnome-dictionary/src/gdict-window.c b/gnome-dictionary/src/gdict-window.c
index d84d4a6..a114e7a 100644
--- a/gnome-dictionary/src/gdict-window.c
+++ b/gnome-dictionary/src/gdict-window.c
@@ -925,13 +925,19 @@ gdict_window_cmd_file_new (GtkAction *action,
{
new_window = gdict_window_new (GDICT_WINDOW_ACTION_LOOKUP,
window->loader,
- NULL, word);
+ NULL,
+ NULL,
+ NULL,
+ word);
g_free (word);
}
else
new_window = gdict_window_new (GDICT_WINDOW_ACTION_CLEAR,
window->loader,
- NULL, NULL);
+ NULL,
+ NULL,
+ NULL,
+ NULL);
gtk_widget_show (new_window);
@@ -1530,7 +1536,10 @@ gdict_window_link_clicked (GdictDefbox *defbox,
new_window = gdict_window_new (GDICT_WINDOW_ACTION_LOOKUP,
window->loader,
- NULL, link_text);
+ NULL,
+ NULL,
+ NULL,
+ link_text);
gtk_widget_show (new_window);
g_signal_emit (window, gdict_window_signals[CREATED], 0, new_window);
@@ -2100,6 +2109,8 @@ GtkWidget *
gdict_window_new (GdictWindowAction action,
GdictSourceLoader *loader,
const gchar *source_name,
+ const gchar *database_name,
+ const gchar *strategy_name,
const gchar *word)
{
GtkWidget *retval;
@@ -2111,6 +2122,8 @@ gdict_window_new (GdictWindowAction action,
"action", action,
"source-loader", loader,
"source-name", source_name,
+ "database", database_name,
+ "strategy", strategy_name,
NULL);
window = GDICT_WINDOW (retval);
@@ -2123,6 +2136,7 @@ gdict_window_new (GdictWindowAction action,
gtk_entry_set_text (GTK_ENTRY (window->entry), word);
gdict_window_set_word (window, word, NULL);
break;
+
case GDICT_WINDOW_ACTION_MATCH:
{
GdictSource *source;
@@ -2152,9 +2166,12 @@ gdict_window_new (GdictWindowAction action,
gdict_speller_match (GDICT_SPELLER (window->speller), word);
}
+ break;
+
case GDICT_WINDOW_ACTION_CLEAR:
gdict_defbox_clear (GDICT_DEFBOX (window->defbox));
break;
+
default:
g_assert_not_reached ();
break;
diff --git a/gnome-dictionary/src/gdict-window.h b/gnome-dictionary/src/gdict-window.h
index 8c35670..74b65e6 100644
--- a/gnome-dictionary/src/gdict-window.h
+++ b/gnome-dictionary/src/gdict-window.h
@@ -128,6 +128,8 @@ GType gdict_window_get_type (void) G_GNUC_CONST;
GtkWidget *gdict_window_new (GdictWindowAction action,
GdictSourceLoader *loader,
const gchar *source_name,
+ const gchar *database_name,
+ const gchar *strategy_name,
const gchar *word);
#endif /* __GDICT_WINDOW_H__ */
diff --git a/gnome-dictionary/src/main.c b/gnome-dictionary/src/main.c
index 669f050..5db8abc 100644
--- a/gnome-dictionary/src/main.c
+++ b/gnome-dictionary/src/main.c
@@ -14,10 +14,7 @@ int main (int argc, char *argv[])
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
- gdict_init (&argc, &argv);
-
- gdict_main ();
-
+ gdict_main (&argc, &argv);
gdict_cleanup ();
return EXIT_SUCCESS;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]