summaryrefslogtreecommitdiff
path: root/mate-dictionary/src/gdict-window.c
diff options
context:
space:
mode:
Diffstat (limited to 'mate-dictionary/src/gdict-window.c')
-rw-r--r--mate-dictionary/src/gdict-window.c2214
1 files changed, 2214 insertions, 0 deletions
diff --git a/mate-dictionary/src/gdict-window.c b/mate-dictionary/src/gdict-window.c
new file mode 100644
index 00000000..1be0256c
--- /dev/null
+++ b/mate-dictionary/src/gdict-window.c
@@ -0,0 +1,2214 @@
+/* gdict-window.c - main application window
+ *
+ * This file is part of MATE Dictionary
+ *
+ * Copyright (C) 2005 Emmanuele Bassi
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include <libgdict/gdict.h>
+
+#include "gdict-sidebar.h"
+#include "gdict-print.h"
+#include "gdict-pref-dialog.h"
+#include "gdict-about.h"
+#include "gdict-window.h"
+#include "gdict-common.h"
+
+#define GDICT_WINDOW_COLUMNS 56
+#define GDICT_WINDOW_ROWS 33
+
+#define GDICT_WINDOW_MIN_WIDTH 400
+#define GDICT_WINDOW_MIN_HEIGHT 330
+
+/* sidebar pages logical ids */
+#define GDICT_SIDEBAR_SPELLER_PAGE "speller"
+#define GDICT_SIDEBAR_DATABASES_PAGE "db-chooser"
+#define GDICT_SIDEBAR_STRATEGIES_PAGE "strat-chooser"
+#define GDICT_SIDEBAR_SOURCES_PAGE "source-chooser"
+
+enum
+{
+ COMPLETION_TEXT_COLUMN,
+
+ COMPLETION_N_COLUMNS
+};
+
+enum
+{
+ PROP_0,
+
+ PROP_ACTION,
+ PROP_SOURCE_LOADER,
+ PROP_SOURCE_NAME,
+ PROP_PRINT_FONT,
+ PROP_DEFBOX_FONT,
+ PROP_WORD,
+ PROP_WINDOW_ID
+};
+
+enum
+{
+ CREATED,
+
+ LAST_SIGNAL
+};
+
+static guint gdict_window_signals[LAST_SIGNAL] = { 0 };
+
+static const GtkTargetEntry drop_types[] =
+{
+ { "text/plain", 0, 0 },
+ { "TEXT", 0, 0 },
+ { "STRING", 0, 0 },
+ { "UTF8_STRING", 0, 0 },
+};
+static const guint n_drop_types = G_N_ELEMENTS (drop_types);
+
+
+
+G_DEFINE_TYPE (GdictWindow, gdict_window, GTK_TYPE_WINDOW);
+
+
+static void
+gdict_window_finalize (GObject *gobject)
+{
+ GdictWindow *window = GDICT_WINDOW (gobject);
+
+ g_free (window->source_name);
+ g_free (window->print_font);
+ g_free (window->defbox_font);
+ g_free (window->word);
+ g_free (window->database);
+ g_free (window->strategy);
+
+ G_OBJECT_CLASS (gdict_window_parent_class)->finalize (gobject);
+}
+
+static void
+gdict_window_dispose (GObject *gobject)
+{
+ GdictWindow *window = GDICT_WINDOW (gobject);
+
+ if (window->notify_id)
+ {
+ mateconf_client_notify_remove (window->mateconf_client, window->notify_id);
+ window->notify_id = 0;
+ }
+
+ if (window->font_notify_id)
+ {
+ mateconf_client_notify_remove (window->mateconf_client,
+ window->font_notify_id);
+ window->font_notify_id = 0;
+ }
+
+ if (window->mateconf_client)
+ {
+ g_object_unref (window->mateconf_client);
+ window->mateconf_client = NULL;
+ }
+
+ if (window->context)
+ {
+ if (window->lookup_start_id)
+ {
+ g_signal_handler_disconnect (window->context,
+ window->lookup_start_id);
+ g_signal_handler_disconnect (window->context,
+ window->definition_id);
+ g_signal_handler_disconnect (window->context,
+ window->lookup_end_id);
+ g_signal_handler_disconnect (window->context,
+ window->error_id);
+
+ window->lookup_start_id = 0;
+ window->definition_id = 0;
+ window->lookup_end_id = 0;
+ window->error_id = 0;
+ }
+
+ g_object_unref (window->context);
+ window->context = NULL;
+ }
+
+ if (window->loader)
+ {
+ g_object_unref (window->loader);
+ window->loader = NULL;
+ }
+
+ if (window->ui_manager)
+ {
+ g_object_unref (window->ui_manager);
+ window->ui_manager = NULL;
+ }
+
+ if (window->action_group)
+ {
+ g_object_unref (window->action_group);
+ window->action_group = NULL;
+ }
+
+ if (window->completion)
+ {
+ g_object_unref (window->completion);
+ window->completion = NULL;
+ }
+
+ if (window->completion_model)
+ {
+ g_object_unref (window->completion_model);
+ window->completion_model = NULL;
+ }
+
+ if (window->busy_cursor)
+ {
+ gdk_cursor_unref (window->busy_cursor);
+ window->busy_cursor = NULL;
+ }
+
+ G_OBJECT_CLASS (gdict_window_parent_class)->dispose (gobject);
+}
+
+static const gchar *toggle_state[] = {
+ "/MainMenu/FileMenu/SaveAsMenu",
+ "/MainMenu/FileMenu/FilePreviewMenu",
+ "/MainMenu/FileMenu/FilePrintMenu",
+ "/MainMenu/GoMenu",
+};
+
+static gint n_toggle_state = G_N_ELEMENTS (toggle_state);
+
+static void
+gdict_window_ensure_menu_state (GdictWindow *window)
+{
+ gint i;
+ gboolean is_sensitive;
+
+ g_assert (GDICT_IS_WINDOW (window));
+
+ if (!window->ui_manager)
+ return;
+
+ is_sensitive = !!(window->word != NULL);
+ for (i = 0; i < n_toggle_state; i++)
+ {
+ GtkWidget *item;
+
+ item = gtk_ui_manager_get_widget (window->ui_manager, toggle_state[i]);
+ if (!item)
+ continue;
+
+ gtk_widget_set_sensitive (item, is_sensitive);
+ }
+}
+
+static void
+gdict_window_set_sidebar_visible (GdictWindow *window,
+ gboolean is_visible)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ if (is_visible != window->sidebar_visible)
+ {
+ GtkAction *action;
+
+ if (is_visible)
+ gtk_widget_show (window->sidebar_frame);
+ else
+ gtk_widget_hide (window->sidebar_frame);
+
+ action = gtk_action_group_get_action (window->action_group,
+ "ViewSidebar");
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), is_visible);
+
+ window->sidebar_visible = is_visible;
+ }
+}
+
+static void
+gdict_window_set_statusbar_visible (GdictWindow *window,
+ gboolean is_visible)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ if (is_visible != window->statusbar_visible)
+ {
+ GtkAction *action;
+
+ if (is_visible)
+ gtk_widget_show (window->status);
+ else
+ gtk_widget_hide (window->status);
+
+ action = gtk_action_group_get_action (window->action_group,
+ "ViewStatusbar");
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), is_visible);
+
+ window->statusbar_visible = is_visible;
+ }
+}
+
+static void
+gdict_window_definition_cb (GdictContext *context,
+ GdictDefinition *definition,
+ GdictWindow *window)
+{
+ gint total, n;
+ gdouble fraction;
+
+ g_assert (GDICT_IS_WINDOW (window));
+
+ total = gdict_definition_get_total (definition);
+ n = window->current_definition + 1;
+
+ fraction = CLAMP (((gdouble) n / (gdouble) total), 0.0, 1.0);
+
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->progress),
+ fraction);
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+
+ window->current_definition = n;
+}
+
+static void
+gdict_window_lookup_start_cb (GdictContext *context,
+ GdictWindow *window)
+{
+ gchar *message;
+
+ if (!window->word)
+ return;
+
+ if (!window->busy_cursor)
+ window->busy_cursor = gdk_cursor_new (GDK_WATCH);
+
+ message = g_strdup_printf (_("Searching for '%s'..."), window->word);
+
+ if (window->status && window->statusbar_visible)
+ gtk_statusbar_push (GTK_STATUSBAR (window->status), 0, message);
+
+ if (window->progress)
+ gtk_widget_show (window->progress);
+
+ window->max_definition = -1;
+ window->last_definition = 0;
+ window->current_definition = 0;
+
+ gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (window)), window->busy_cursor);
+
+ g_free (message);
+}
+
+static void
+gdict_window_lookup_end_cb (GdictContext *context,
+ GdictWindow *window)
+{
+ gchar *message;
+ gint count;
+ GtkTreeIter iter;
+ GdictSource *source;
+ GdictContext *speller_context;
+
+ count = window->current_definition;
+
+ window->max_definition = count - 1;
+
+ if (count == 0)
+ message = g_strdup (_("No definitions found"));
+ else
+ message = g_strdup_printf (ngettext("A definition found",
+ "%d definitions found",
+ count),
+ count);
+
+ if (window->status && window->statusbar_visible)
+ gtk_statusbar_push (GTK_STATUSBAR (window->status), 0, message);
+
+ if (window->progress)
+ gtk_widget_hide (window->progress);
+
+ /* we clone the context, so that the signals that it
+ * fires do not get caught by the signal handlers we
+ * use for getting the definitions.
+ */
+ source = gdict_source_loader_get_source (window->loader, window->source_name);
+ speller_context = gdict_source_get_context (source);
+ gdict_speller_set_context (GDICT_SPELLER (window->speller), speller_context);
+ g_object_unref (speller_context);
+ g_object_unref (source);
+
+ /* search for similar words; if we have a no-match we already started
+ * looking in the error signal handler
+ */
+ if (count != 0 && window->word)
+ {
+ gdict_speller_set_strategy (GDICT_SPELLER (window->speller), window->strategy);
+ gdict_speller_match (GDICT_SPELLER (window->speller), window->word);
+ gtk_list_store_append (window->completion_model, &iter);
+ gtk_list_store_set (window->completion_model, &iter,
+ COMPLETION_TEXT_COLUMN, window->word,
+ -1);
+ }
+
+ gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (window)), NULL);
+ g_free (message);
+
+ if (count == 0)
+ {
+ g_free (window->word);
+ window->word = NULL;
+ }
+
+ gdict_window_ensure_menu_state (window);
+}
+
+static void
+gdict_window_error_cb (GdictContext *context,
+ const GError *error,
+ GdictWindow *window)
+{
+ gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (window)), NULL);
+
+ if (window->status && window->statusbar_visible)
+ gtk_statusbar_push (GTK_STATUSBAR (window->status), 0,
+ _("No definitions found"));
+
+ gtk_widget_hide (window->progress);
+
+ /* launch the speller only on NO_MATCH */
+ if (error->code == GDICT_CONTEXT_ERROR_NO_MATCH)
+ {
+ GdictSource *source;
+ GdictContext *context;
+
+ gdict_window_set_sidebar_visible (window, TRUE);
+ gdict_sidebar_view_page (GDICT_SIDEBAR (window->sidebar),
+ GDICT_SIDEBAR_SPELLER_PAGE);
+
+ /* we clone the context, so that the signals that it
+ * fires do not get caught by the signal handlers we
+ * use for getting the definitions.
+ */
+ source = gdict_source_loader_get_source (window->loader,
+ window->source_name);
+ context = gdict_source_get_context (source);
+
+ gdict_speller_set_context (GDICT_SPELLER (window->speller),
+ context);
+ g_object_unref (context);
+ g_object_unref (source);
+
+ gdict_speller_set_strategy (GDICT_SPELLER (window->speller),
+ window->strategy);
+
+ gdict_speller_match (GDICT_SPELLER (window->speller),
+ window->word);
+ }
+
+ /* unset the word and update the UI */
+ g_free (window->word);
+ window->word = NULL;
+
+ gdict_window_ensure_menu_state (window);
+}
+
+static void
+gdict_window_set_database (GdictWindow *window,
+ const gchar *database)
+{
+ g_free (window->database);
+
+ if (database)
+ window->database = g_strdup (database);
+ else
+ window->database = gdict_mateconf_get_string_with_default (window->mateconf_client,
+ GDICT_MATECONF_DATABASE_KEY,
+ GDICT_DEFAULT_DATABASE);
+
+ if (window->defbox)
+ gdict_defbox_set_database (GDICT_DEFBOX (window->defbox),
+ window->database);
+
+ if (window->db_chooser)
+ gdict_database_chooser_set_current_database (GDICT_DATABASE_CHOOSER (window->db_chooser),
+ window->database);
+}
+
+static void
+gdict_window_set_strategy (GdictWindow *window,
+ const gchar *strategy)
+{
+ g_free (window->strategy);
+
+ if (strategy && strategy[0] != '\0')
+ window->strategy = g_strdup (strategy);
+ else
+ window->strategy = gdict_mateconf_get_string_with_default (window->mateconf_client,
+ GDICT_MATECONF_STRATEGY_KEY,
+ GDICT_DEFAULT_STRATEGY);
+
+ if (window->speller)
+ gdict_speller_set_strategy (GDICT_SPELLER (window->speller),
+ window->strategy);
+
+ if (window->strat_chooser)
+ gdict_strategy_chooser_set_current_strategy (GDICT_STRATEGY_CHOOSER (window->strat_chooser),
+ window->strategy);
+}
+
+static GdictContext *
+get_context_from_loader (GdictWindow *window)
+{
+ GdictSource *source;
+ GdictContext *retval;
+
+ if (!window->source_name)
+ window->source_name = g_strdup (GDICT_DEFAULT_SOURCE_NAME);
+
+ source = gdict_source_loader_get_source (window->loader,
+ window->source_name);
+ if (!source &&
+ strcmp (window->source_name, GDICT_DEFAULT_SOURCE_NAME) != 0)
+ {
+ g_free (window->source_name);
+ window->source_name = g_strdup (GDICT_DEFAULT_SOURCE_NAME);
+
+ source = gdict_source_loader_get_source (window->loader,
+ window->source_name);
+ }
+
+ if (!source)
+ {
+ gchar *detail;
+
+ detail = g_strdup_printf (_("No dictionary source available with name '%s'"),
+ window->source_name);
+
+ gdict_show_error_dialog (GTK_WINDOW (window),
+ _("Unable to find dictionary source"),
+ detail);
+
+ g_free (detail);
+
+ return NULL;
+ }
+
+ gdict_window_set_database (window, gdict_source_get_database (source));
+ gdict_window_set_strategy (window, gdict_source_get_strategy (source));
+
+ retval = gdict_source_get_context (source);
+ if (!retval)
+ {
+ gchar *detail;
+
+ detail = g_strdup_printf (_("No context available for source '%s'"),
+ gdict_source_get_description (source));
+
+ gdict_show_error_dialog (GTK_WINDOW (window),
+ _("Unable to create a context"),
+ detail);
+
+ g_free (detail);
+ g_object_unref (source);
+
+ return NULL;
+ }
+
+ g_object_unref (source);
+
+ return retval;
+}
+
+static void
+gdict_window_set_defbox_font (GdictWindow *window,
+ const gchar *defbox_font)
+{
+ g_free (window->defbox_font);
+
+ if (defbox_font)
+ window->defbox_font = g_strdup (defbox_font);
+ else
+ window->defbox_font = gdict_mateconf_get_string_with_default (window->mateconf_client,
+ DOCUMENT_FONT_KEY,
+ GDICT_DEFAULT_DEFBOX_FONT);
+
+ if (window->defbox)
+ gdict_defbox_set_font_name (GDICT_DEFBOX (window->defbox),
+ window->defbox_font);
+}
+
+static void
+gdict_window_set_print_font (GdictWindow *window,
+ const gchar *print_font)
+{
+ g_free (window->print_font);
+
+ if (print_font)
+ window->print_font = g_strdup (print_font);
+ else
+ window->print_font = gdict_mateconf_get_string_with_default (window->mateconf_client,
+ GDICT_MATECONF_PRINT_FONT_KEY,
+ GDICT_DEFAULT_PRINT_FONT);
+}
+
+static void
+gdict_window_set_word (GdictWindow *window,
+ const gchar *word,
+ const gchar *database)
+{
+ gchar *title;
+
+ g_free (window->word);
+ window->word = NULL;
+
+ if (word && word[0] != '\0')
+ window->word = g_strdup (word);
+ else
+ return;
+
+ if (!database || database[0] == '\0')
+ database = window->database;
+
+ if (window->word)
+ title = g_strdup_printf (_("%s - Dictionary"), window->word);
+ else
+ title = g_strdup (_("Dictionary"));
+
+ gtk_window_set_title (GTK_WINDOW (window), title);
+ g_free (title);
+
+ if (window->defbox)
+ {
+ gdict_defbox_set_database (GDICT_DEFBOX (window->defbox), database);
+ gdict_defbox_lookup (GDICT_DEFBOX (window->defbox), word);
+ }
+}
+
+static void
+gdict_window_set_context (GdictWindow *window,
+ GdictContext *context)
+{
+ if (window->context)
+ {
+ g_signal_handler_disconnect (window->context, window->definition_id);
+ g_signal_handler_disconnect (window->context, window->lookup_start_id);
+ g_signal_handler_disconnect (window->context, window->lookup_end_id);
+ g_signal_handler_disconnect (window->context, window->error_id);
+
+ window->definition_id = 0;
+ window->lookup_start_id = 0;
+ window->lookup_end_id = 0;
+ window->error_id = 0;
+
+ g_object_unref (window->context);
+ window->context = NULL;
+ }
+
+ if (window->defbox)
+ gdict_defbox_set_context (GDICT_DEFBOX (window->defbox), context);
+
+ if (window->db_chooser)
+ gdict_database_chooser_set_context (GDICT_DATABASE_CHOOSER (window->db_chooser), context);
+
+ if (window->strat_chooser)
+ gdict_strategy_chooser_set_context (GDICT_STRATEGY_CHOOSER (window->strat_chooser), context);
+
+ if (!context)
+ return;
+
+ /* attach our callbacks */
+ window->definition_id = g_signal_connect (context, "definition-found",
+ G_CALLBACK (gdict_window_definition_cb),
+ window);
+ window->lookup_start_id = g_signal_connect (context, "lookup-start",
+ G_CALLBACK (gdict_window_lookup_start_cb),
+ window);
+ window->lookup_end_id = g_signal_connect (context, "lookup-end",
+ G_CALLBACK (gdict_window_lookup_end_cb),
+ window);
+ window->error_id = g_signal_connect (context, "error",
+ G_CALLBACK (gdict_window_error_cb),
+ window);
+
+ window->context = context;
+}
+
+static void
+gdict_window_set_source_name (GdictWindow *window,
+ const gchar *source_name)
+{
+ GdictContext *context;
+
+ if (window->source_name && source_name &&
+ strcmp (window->source_name, source_name) == 0)
+ return;
+
+ g_free (window->source_name);
+
+ if (source_name)
+ window->source_name = g_strdup (source_name);
+ else
+ window->source_name = gdict_mateconf_get_string_with_default (window->mateconf_client,
+ GDICT_MATECONF_SOURCE_KEY,
+ GDICT_DEFAULT_SOURCE_NAME);
+
+ context = get_context_from_loader (window);
+ gdict_window_set_context (window, context);
+
+ if (window->source_chooser)
+ gdict_source_chooser_set_current_source (GDICT_SOURCE_CHOOSER (window->source_chooser),
+ window->source_name);
+
+ g_object_notify (G_OBJECT (window), "source-name");
+}
+
+static void
+gdict_window_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GdictWindow *window = GDICT_WINDOW (object);
+
+ switch (prop_id)
+ {
+ case PROP_ACTION:
+ window->action = g_value_get_enum (value);
+ break;
+ case PROP_SOURCE_LOADER:
+ if (window->loader)
+ g_object_unref (window->loader);
+ window->loader = g_value_get_object (value);
+ g_object_ref (window->loader);
+ break;
+ case PROP_SOURCE_NAME:
+ gdict_window_set_source_name (window, g_value_get_string (value));
+ break;
+ case PROP_WORD:
+ gdict_window_set_word (window, g_value_get_string (value), NULL);
+ break;
+ case PROP_PRINT_FONT:
+ gdict_window_set_print_font (window, g_value_get_string (value));
+ break;
+ case PROP_DEFBOX_FONT:
+ gdict_window_set_defbox_font (window, g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gdict_window_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GdictWindow *window = GDICT_WINDOW (object);
+
+ switch (prop_id)
+ {
+ case PROP_ACTION:
+ g_value_set_enum (value, window->action);
+ break;
+ case PROP_SOURCE_LOADER:
+ g_value_set_object (value, window->loader);
+ break;
+ case PROP_SOURCE_NAME:
+ g_value_set_string (value, window->source_name);
+ break;
+ case PROP_WORD:
+ g_value_set_string (value, window->word);
+ break;
+ case PROP_PRINT_FONT:
+ g_value_set_string (value, window->print_font);
+ break;
+ case PROP_DEFBOX_FONT:
+ g_value_set_string (value, window->defbox_font);
+ break;
+ case PROP_WINDOW_ID:
+ g_value_set_uint (value, window->window_id);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gdict_window_cmd_file_new (GtkAction *action,
+ GdictWindow *window)
+{
+ GtkWidget *new_window;
+ gchar *word = NULL;
+
+ /* store the default size of the window and its state, so that
+ * it's picked up by the newly created window
+ */
+ mateconf_client_set_int (window->mateconf_client,
+ GDICT_MATECONF_WINDOW_WIDTH_KEY,
+ window->default_width,
+ NULL);
+ mateconf_client_set_int (window->mateconf_client,
+ GDICT_MATECONF_WINDOW_HEIGHT_KEY,
+ window->default_height,
+ NULL);
+ mateconf_client_set_bool (window->mateconf_client,
+ GDICT_MATECONF_WINDOW_IS_MAXIMIZED_KEY,
+ window->is_maximized,
+ NULL);
+ mateconf_client_set_bool (window->mateconf_client,
+ GDICT_MATECONF_SIDEBAR_VISIBLE_KEY,
+ window->sidebar_visible,
+ NULL);
+ mateconf_client_set_int (window->mateconf_client,
+ GDICT_MATECONF_SIDEBAR_WIDTH_KEY,
+ window->sidebar_width,
+ NULL);
+ mateconf_client_set_string (window->mateconf_client,
+ GDICT_MATECONF_SIDEBAR_PAGE_KEY,
+ gdict_sidebar_current_page (GDICT_SIDEBAR (window->sidebar)),
+ NULL);
+ mateconf_client_set_bool (window->mateconf_client,
+ GDICT_MATECONF_STATUSBAR_VISIBLE_KEY,
+ window->statusbar_visible,
+ NULL);
+
+ word = gdict_defbox_get_selected_word (GDICT_DEFBOX (window->defbox));
+ if (word)
+ {
+ new_window = gdict_window_new (GDICT_WINDOW_ACTION_LOOKUP,
+ window->loader,
+ NULL, word);
+ g_free (word);
+ }
+ else
+ new_window = gdict_window_new (GDICT_WINDOW_ACTION_CLEAR,
+ window->loader,
+ NULL, NULL);
+
+ gtk_widget_show (new_window);
+
+ g_signal_emit (window, gdict_window_signals[CREATED], 0, new_window);
+}
+
+static void
+gdict_window_cmd_save_as (GtkAction *action,
+ GdictWindow *window)
+{
+ GtkWidget *dialog;
+
+ g_assert (GDICT_IS_WINDOW (window));
+
+ dialog = gtk_file_chooser_dialog_new (_("Save a Copy"),
+ GTK_WINDOW (window),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
+
+ /* default to user's home */
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), g_get_home_dir ());
+ gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), _("Untitled document"));
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+ {
+ gchar *filename;
+ gchar *text;
+ gsize len;
+ GError *write_error = NULL;
+
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+
+ text = gdict_defbox_get_text (GDICT_DEFBOX (window->defbox), &len);
+
+ g_file_set_contents (filename,
+ text,
+ len,
+ &write_error);
+ if (write_error)
+ {
+ gchar *message;
+
+ message = g_strdup_printf (_("Error while writing to '%s'"), filename);
+
+ gdict_show_gerror_dialog (GTK_WINDOW (window),
+ message,
+ write_error);
+
+ g_free (message);
+ }
+
+ g_free (text);
+ g_free (filename);
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+gdict_window_cmd_file_preview (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ gdict_show_print_preview (GTK_WINDOW (window),
+ GDICT_DEFBOX (window->defbox));
+}
+
+static void
+gdict_window_cmd_file_print (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ gdict_show_print_dialog (GTK_WINDOW (window),
+ GDICT_DEFBOX (window->defbox));
+}
+
+static void
+gdict_window_cmd_file_close_window (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ /* store the default size of the window and its state */
+ mateconf_client_set_int (window->mateconf_client,
+ GDICT_MATECONF_WINDOW_WIDTH_KEY,
+ window->default_width,
+ NULL);
+ mateconf_client_set_int (window->mateconf_client,
+ GDICT_MATECONF_WINDOW_HEIGHT_KEY,
+ window->default_height,
+ NULL);
+ mateconf_client_set_bool (window->mateconf_client,
+ GDICT_MATECONF_WINDOW_IS_MAXIMIZED_KEY,
+ window->is_maximized,
+ NULL);
+ mateconf_client_set_bool (window->mateconf_client,
+ GDICT_MATECONF_SIDEBAR_VISIBLE_KEY,
+ window->sidebar_visible,
+ NULL);
+ mateconf_client_set_int (window->mateconf_client,
+ GDICT_MATECONF_SIDEBAR_WIDTH_KEY,
+ window->sidebar_width,
+ NULL);
+ mateconf_client_set_string (window->mateconf_client,
+ GDICT_MATECONF_SIDEBAR_PAGE_KEY,
+ gdict_sidebar_current_page (GDICT_SIDEBAR (window->sidebar)),
+ NULL);
+ mateconf_client_set_bool (window->mateconf_client,
+ GDICT_MATECONF_STATUSBAR_VISIBLE_KEY,
+ window->statusbar_visible,
+ NULL);
+
+ /* if this was called from the uimanager, destroy the widget;
+ * otherwise, if it was called from the delete_event, the widget
+ * will destroy itself.
+ */
+ if (action)
+ gtk_widget_destroy (GTK_WIDGET (window));
+}
+
+static void
+gdict_window_cmd_edit_copy (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ gdict_defbox_copy_to_clipboard (GDICT_DEFBOX (window->defbox),
+ gtk_clipboard_get (GDK_SELECTION_CLIPBOARD));
+}
+
+static void
+gdict_window_cmd_edit_select_all (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ gdict_defbox_select_all (GDICT_DEFBOX (window->defbox));
+}
+
+static void
+gdict_window_cmd_edit_find (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ gdict_defbox_set_show_find (GDICT_DEFBOX (window->defbox), TRUE);
+}
+
+static void
+gdict_window_cmd_edit_find_next (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ gdict_defbox_find_next (GDICT_DEFBOX (window->defbox));
+}
+
+static void
+gdict_window_cmd_edit_find_previous (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ gdict_defbox_find_previous (GDICT_DEFBOX (window->defbox));
+}
+
+static void
+gdict_window_cmd_edit_preferences (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ gdict_show_pref_dialog (GTK_WIDGET (window),
+ _("Dictionary Preferences"),
+ window->loader);
+}
+
+static void
+gdict_window_cmd_view_sidebar (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ if (window->sidebar_visible)
+ gdict_window_set_sidebar_visible (window, FALSE);
+ else
+ gdict_window_set_sidebar_visible (window, TRUE);
+}
+
+static void
+gdict_window_cmd_view_statusbar (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ if (window->statusbar_visible)
+ gdict_window_set_statusbar_visible (window, FALSE);
+ else
+ gdict_window_set_statusbar_visible (window, TRUE);
+}
+
+static void
+gdict_window_cmd_view_speller (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ gdict_sidebar_view_page (GDICT_SIDEBAR (window->sidebar),
+ GDICT_SIDEBAR_SPELLER_PAGE);
+ gdict_window_set_sidebar_visible (window, TRUE);
+}
+
+static void
+gdict_window_cmd_view_databases (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ gdict_sidebar_view_page (GDICT_SIDEBAR (window->sidebar),
+ GDICT_SIDEBAR_DATABASES_PAGE);
+ gdict_window_set_sidebar_visible (window, TRUE);
+}
+
+static void
+gdict_window_cmd_view_strategies (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ gdict_sidebar_view_page (GDICT_SIDEBAR (window->sidebar),
+ GDICT_SIDEBAR_STRATEGIES_PAGE);
+ gdict_window_set_sidebar_visible (window, TRUE);
+}
+
+static void
+gdict_window_cmd_view_sources (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ gdict_sidebar_view_page (GDICT_SIDEBAR (window->sidebar),
+ GDICT_SIDEBAR_SOURCES_PAGE);
+ gdict_window_set_sidebar_visible (window, TRUE);
+}
+
+static void
+gdict_window_cmd_go_first_def (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ window->last_definition = 0;
+ gdict_defbox_jump_to_definition (GDICT_DEFBOX (window->defbox),
+ window->last_definition);
+}
+
+static void
+gdict_window_cmd_go_previous_def (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ if (window->last_definition == 0)
+ return;
+
+ window->last_definition -= 1;
+ gdict_defbox_jump_to_definition (GDICT_DEFBOX (window->defbox),
+ window->last_definition);
+}
+
+static void
+gdict_window_cmd_go_next_def (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ if (window->max_definition == -1)
+ window->max_definition = gdict_defbox_count_definitions (GDICT_DEFBOX (window->defbox)) - 1;
+
+ if (window->last_definition == window->max_definition)
+ return;
+
+ window->last_definition += 1;
+ gdict_defbox_jump_to_definition (GDICT_DEFBOX (window->defbox),
+ window->last_definition);
+}
+
+static void
+gdict_window_cmd_go_last_def (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ if (window->max_definition == -1)
+ window->last_definition = gdict_defbox_count_definitions (GDICT_DEFBOX (window->defbox)) - 1;
+
+ window->last_definition = window->max_definition;
+ gdict_defbox_jump_to_definition (GDICT_DEFBOX (window->defbox),
+ window->last_definition);
+}
+
+static void
+gdict_window_cmd_help_contents (GtkAction *action,
+ GdictWindow *window)
+{
+ GError *err = NULL;
+
+ g_return_if_fail (GDICT_IS_WINDOW (window));
+
+ gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (window)),
+ "ghelp:mate-dictionary",
+ gtk_get_current_event_time (), &err);
+ if (err)
+ {
+ gdict_show_gerror_dialog (GTK_WINDOW (window),
+ _("There was an error while displaying help"),
+ err);
+ g_error_free (err);
+ }
+}
+
+static void
+gdict_window_cmd_help_about (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ gdict_show_about_dialog (GTK_WIDGET (window));
+}
+
+static void
+gdict_window_cmd_lookup (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ gtk_widget_grab_focus (window->entry);
+}
+
+static void
+gdict_window_cmd_escape (GtkAction *action,
+ GdictWindow *window)
+{
+ g_assert (GDICT_IS_WINDOW (window));
+
+ gdict_defbox_set_show_find (GDICT_DEFBOX (window->defbox), FALSE);
+}
+
+static const GtkActionEntry entries[] =
+{
+ { "File", NULL, N_("_File") },
+ { "Edit", NULL, N_("_Edit") },
+ { "View", NULL, N_("_View") },
+ { "Go", NULL, N_("_Go") },
+ { "Help", NULL, N_("_Help") },
+
+ /* File menu */
+ { "FileNew", GTK_STOCK_NEW, N_("_New"), "<control>N",
+ N_("New look up"), G_CALLBACK (gdict_window_cmd_file_new) },
+ { "FileSaveAs", GTK_STOCK_SAVE_AS, N_("_Save a Copy..."), NULL, NULL,
+ G_CALLBACK (gdict_window_cmd_save_as) },
+ { "FilePreview", NULL, N_("P_review..."), "<control><shift>P",
+ N_("Preview this document"), G_CALLBACK (gdict_window_cmd_file_preview) },
+ { "FilePrint", GTK_STOCK_PRINT, N_("_Print..."), "<control>P",
+ N_("Print this document"), G_CALLBACK (gdict_window_cmd_file_print) },
+ { "FileCloseWindow", GTK_STOCK_CLOSE, NULL, "<control>W", NULL,
+ G_CALLBACK (gdict_window_cmd_file_close_window) },
+
+ /* Edit menu */
+ { "EditCopy", GTK_STOCK_COPY, NULL, "<control>C", NULL,
+ G_CALLBACK (gdict_window_cmd_edit_copy) },
+ { "EditSelectAll", NULL, N_("Select _All"), "<control>A", NULL,
+ G_CALLBACK (gdict_window_cmd_edit_select_all) },
+ { "EditFind", GTK_STOCK_FIND, NULL, "<control>F",
+ N_("Find a word or phrase in the document"),
+ G_CALLBACK (gdict_window_cmd_edit_find) },
+ { "EditFindNext", NULL, N_("Find Ne_xt"), "<control>G", NULL,
+ G_CALLBACK (gdict_window_cmd_edit_find_next) },
+ { "EditFindPrevious", NULL, N_("Find Pre_vious"), "<control><shift>G", NULL,
+ G_CALLBACK (gdict_window_cmd_edit_find_previous) },
+ { "EditPreferences", GTK_STOCK_PREFERENCES, N_("_Preferences"), NULL, NULL,
+ G_CALLBACK (gdict_window_cmd_edit_preferences) },
+
+ /* Go menu */
+ { "GoPreviousDef", GTK_STOCK_GO_BACK, N_("_Previous Definition"), "<control>Page_Up",
+ N_("Go to the previous definition"), G_CALLBACK (gdict_window_cmd_go_previous_def) },
+ { "GoNextDef", GTK_STOCK_GO_FORWARD, N_("_Next Definition"), "<control>Page_Down",
+ N_("Go to the next definition"), G_CALLBACK (gdict_window_cmd_go_next_def) },
+ { "GoFirstDef", GTK_STOCK_GOTO_FIRST, N_("_First Definition"), "<control>Home",
+ N_("Go to the first definition"), G_CALLBACK (gdict_window_cmd_go_first_def) },
+ { "GoLastDef", GTK_STOCK_GOTO_LAST, N_("_Last Definition"), "<control>End",
+ N_("Go to the last definition"), G_CALLBACK (gdict_window_cmd_go_last_def) },
+
+ /* View menu */
+ { "ViewSpeller", NULL, N_("Similar _Words"), "<control>T", NULL,
+ G_CALLBACK (gdict_window_cmd_view_speller), },
+ { "ViewSource", NULL, N_("Dictionary Sources"), "<control>D", NULL,
+ G_CALLBACK (gdict_window_cmd_view_sources), },
+ { "ViewDB", NULL, N_("Available _Databases"), "<control>B", NULL,
+ G_CALLBACK (gdict_window_cmd_view_databases), },
+ { "ViewStrat", NULL, N_("Available St_rategies"), "<control>R", NULL,
+ G_CALLBACK (gdict_window_cmd_view_strategies), },
+
+ /* Help menu */
+ { "HelpContents", GTK_STOCK_HELP, N_("_Contents"), "F1", NULL,
+ G_CALLBACK (gdict_window_cmd_help_contents) },
+ { "HelpAbout", GTK_STOCK_ABOUT, N_("_About"), NULL, NULL,
+ G_CALLBACK (gdict_window_cmd_help_about) },
+
+ /* Accelerators */
+ { "Lookup", NULL, "", "<control>L", NULL, G_CALLBACK (gdict_window_cmd_lookup) },
+ { "Escape", NULL, "", "Escape", "", G_CALLBACK (gdict_window_cmd_escape) },
+ { "Slash", GTK_STOCK_FIND, NULL, "slash", NULL, G_CALLBACK (gdict_window_cmd_edit_find) },
+};
+
+static const GtkToggleActionEntry toggle_entries[] = {
+ /* View menu */
+ { "ViewSidebar", NULL, N_("_Sidebar"), "F9", NULL,
+ G_CALLBACK (gdict_window_cmd_view_sidebar), FALSE },
+ { "ViewStatusbar", NULL, N_("S_tatusbar"), NULL, NULL,
+ G_CALLBACK (gdict_window_cmd_view_statusbar), FALSE },
+};
+
+static gboolean
+gdict_window_delete_event_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ gdict_window_cmd_file_close_window (NULL, GDICT_WINDOW (widget));
+
+ return FALSE;
+}
+
+static gboolean
+gdict_window_state_event_cb (GtkWidget *widget,
+ GdkEventWindowState *event,
+ gpointer user_data)
+{
+ GdictWindow *window = GDICT_WINDOW (widget);
+
+ if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED)
+ window->is_maximized = TRUE;
+ else
+ window->is_maximized = FALSE;
+
+ return FALSE;
+}
+
+static void
+gdict_window_mateconf_notify_cb (MateConfClient *client,
+ guint cnxn_id,
+ MateConfEntry *entry,
+ gpointer user_data)
+{
+ GdictWindow *window;
+
+ window = GDICT_WINDOW (user_data);
+
+ if (strcmp (entry->key, GDICT_MATECONF_PRINT_FONT_KEY) == 0)
+ {
+ if (entry->value && (entry->value->type == MATECONF_VALUE_STRING))
+ gdict_window_set_print_font (window, mateconf_value_get_string (entry->value));
+ else
+ gdict_window_set_print_font (window, GDICT_DEFAULT_PRINT_FONT);
+ }
+ else if (strcmp (entry->key, GDICT_MATECONF_SOURCE_KEY) == 0)
+ {
+ if (entry->value && (entry->value->type == MATECONF_VALUE_STRING))
+ gdict_window_set_source_name (window, mateconf_value_get_string (entry->value));
+ else
+ gdict_window_set_source_name (window, GDICT_DEFAULT_SOURCE_NAME);
+ }
+ else if (strcmp (entry->key, GDICT_MATECONF_DATABASE_KEY) == 0)
+ {
+ if (entry->value && (entry->value->type == MATECONF_VALUE_STRING))
+ gdict_window_set_database (window, mateconf_value_get_string (entry->value));
+ else
+ gdict_window_set_database (window, GDICT_DEFAULT_DATABASE);
+ }
+ else if (strcmp (entry->key, DOCUMENT_FONT_KEY) == 0)
+ {
+ if (entry->value && (entry->value->type == MATECONF_VALUE_STRING))
+ gdict_window_set_defbox_font (window, mateconf_value_get_string (entry->value));
+ else
+ gdict_window_set_defbox_font (window, GDICT_DEFAULT_DEFBOX_FONT);
+ }
+ else if (strcmp (entry->key, GDICT_MATECONF_SIDEBAR_VISIBLE_KEY) == 0)
+ {
+ if (entry->value && (entry->value->type == MATECONF_VALUE_BOOL))
+ gdict_window_set_sidebar_visible (window,
+ mateconf_value_get_bool (entry->value));
+ else
+ gdict_window_set_sidebar_visible (window, FALSE);
+ }
+ else if (strcmp (entry->key, GDICT_MATECONF_STATUSBAR_VISIBLE_KEY) == 0)
+ {
+ if (entry->value && (entry->value->type == MATECONF_VALUE_BOOL))
+ gdict_window_set_statusbar_visible (window,
+ mateconf_value_get_bool (entry->value));
+ else
+ gdict_window_set_statusbar_visible (window, FALSE);
+ }
+}
+
+static void
+lookup_word (GdictWindow *window,
+ gpointer dummy)
+{
+ const gchar *entry_text;
+ gchar *word;
+
+ g_assert (GDICT_IS_WINDOW (window));
+
+ if (!window->context)
+ return;
+
+ entry_text = gtk_entry_get_text (GTK_ENTRY (window->entry));
+ if (!entry_text || *entry_text == '\0')
+ return;
+
+ word = g_strdup (entry_text);
+ gdict_window_set_word (window, g_strstrip (word), NULL);
+
+ g_free (word);
+}
+
+static void
+source_activated_cb (GdictSourceChooser *chooser,
+ const gchar *source_name,
+ GdictSource *source,
+ GdictWindow *window)
+{
+ g_signal_handlers_block_by_func (chooser, source_activated_cb, window);
+ gdict_window_set_source_name (window, source_name);
+ g_signal_handlers_unblock_by_func (chooser, source_activated_cb, window);
+
+ if (window->status && window->statusbar_visible)
+ {
+ gchar *message;
+
+ message = g_strdup_printf (_("Dictionary source `%s' selected"),
+ gdict_source_get_description (source));
+ gtk_statusbar_push (GTK_STATUSBAR (window->status), 0, message);
+ g_free (message);
+ }
+}
+
+static void
+strategy_activated_cb (GdictStrategyChooser *chooser,
+ const gchar *strat_name,
+ const gchar *strat_desc,
+ GdictWindow *window)
+{
+ g_signal_handlers_block_by_func (chooser, strategy_activated_cb, window);
+ gdict_window_set_strategy (window, strat_name);
+ g_signal_handlers_unblock_by_func (chooser, strategy_activated_cb, window);
+
+ if (window->status && window->statusbar_visible)
+ {
+ gchar *message;
+
+ message = g_strdup_printf (_("Strategy `%s' selected"), strat_desc);
+ gtk_statusbar_push (GTK_STATUSBAR (window->status), 0, message);
+ g_free (message);
+ }
+}
+
+static void
+database_activated_cb (GdictDatabaseChooser *chooser,
+ const gchar *db_name,
+ const gchar *db_desc,
+ GdictWindow *window)
+{
+ g_signal_handlers_block_by_func (chooser, database_activated_cb, window);
+ gdict_window_set_database (window, db_name);
+ g_signal_handlers_unblock_by_func (chooser, database_activated_cb, window);
+
+ if (window->status && window->statusbar_visible)
+ {
+ gchar *message;
+
+ message = g_strdup_printf (_("Database `%s' selected"), db_desc);
+ gtk_statusbar_push (GTK_STATUSBAR (window->status), 0, message);
+ g_free (message);
+ }
+}
+
+static void
+speller_word_activated_cb (GdictSpeller *speller,
+ const gchar *word,
+ const gchar *db_name,
+ GdictWindow *window)
+{
+ gtk_entry_set_text (GTK_ENTRY (window->entry), word);
+
+ gdict_window_set_word (window, word, db_name);
+
+ if (window->status && window->statusbar_visible)
+ {
+ gchar *message;
+
+ message = g_strdup_printf (_("Word `%s' selected"), word);
+ gtk_statusbar_push (GTK_STATUSBAR (window->status), 0, message);
+ g_free (message);
+ }
+}
+
+static void
+sidebar_page_changed_cb (GdictSidebar *sidebar,
+ GdictWindow *window)
+{
+ const gchar *page_id;
+ const gchar *message;
+
+ page_id = gdict_sidebar_current_page (sidebar);
+
+ switch (page_id[0])
+ {
+ case 's':
+ {
+ switch (page_id[1])
+ {
+ case 'p': /* speller */
+ message = _("Double-click on the word to look up");
+ if (window->word)
+ gdict_speller_match (GDICT_SPELLER (window->speller),
+ window->word);
+ break;
+ case 't': /* strat-chooser */
+ message = _("Double-click on the matching strategy to use");
+
+ gdict_strategy_chooser_refresh (GDICT_STRATEGY_CHOOSER (window->strat_chooser));
+ break;
+ case 'o': /* source-chooser */
+ message = _("Double-click on the source to use");
+ gdict_source_chooser_refresh (GDICT_SOURCE_CHOOSER (window->source_chooser));
+ break;
+ default:
+ message = NULL;
+ }
+ }
+ break;
+ case 'd': /* db-chooser */
+ message = _("Double-click on the database to use");
+
+ gdict_database_chooser_refresh (GDICT_DATABASE_CHOOSER (window->db_chooser));
+ break;
+ default:
+ message = NULL;
+ break;
+ }
+
+ if (message && window->status && window->statusbar_visible)
+ gtk_statusbar_push (GTK_STATUSBAR (window->status), 0, message);
+}
+
+static void
+sidebar_closed_cb (GdictSidebar *sidebar,
+ GdictWindow *window)
+{
+ gdict_window_set_sidebar_visible (window, FALSE);
+}
+
+static void
+gdict_window_link_clicked (GdictDefbox *defbox,
+ const gchar *link_text,
+ GdictWindow *window)
+{
+ GtkWidget *new_window;
+
+ /* store the default size of the window and its state, so that
+ * it's picked up by the newly created window
+ */
+ mateconf_client_set_int (window->mateconf_client,
+ GDICT_MATECONF_WINDOW_WIDTH_KEY,
+ window->default_width,
+ NULL);
+ mateconf_client_set_int (window->mateconf_client,
+ GDICT_MATECONF_WINDOW_HEIGHT_KEY,
+ window->default_height,
+ NULL);
+ mateconf_client_set_bool (window->mateconf_client,
+ GDICT_MATECONF_WINDOW_IS_MAXIMIZED_KEY,
+ window->is_maximized,
+ NULL);
+ mateconf_client_set_bool (window->mateconf_client,
+ GDICT_MATECONF_SIDEBAR_VISIBLE_KEY,
+ window->sidebar_visible,
+ NULL);
+ mateconf_client_set_int (window->mateconf_client,
+ GDICT_MATECONF_SIDEBAR_WIDTH_KEY,
+ window->sidebar_width,
+ NULL);
+ mateconf_client_set_string (window->mateconf_client,
+ GDICT_MATECONF_SIDEBAR_PAGE_KEY,
+ gdict_sidebar_current_page (GDICT_SIDEBAR (window->sidebar)),
+ NULL);
+ mateconf_client_set_bool (window->mateconf_client,
+ GDICT_MATECONF_STATUSBAR_VISIBLE_KEY,
+ window->statusbar_visible,
+ NULL);
+
+ new_window = gdict_window_new (GDICT_WINDOW_ACTION_LOOKUP,
+ window->loader,
+ NULL, link_text);
+ gtk_widget_show (new_window);
+
+ g_signal_emit (window, gdict_window_signals[CREATED], 0, new_window);
+}
+
+static void
+gdict_window_drag_data_received_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *data,
+ guint info,
+ guint time_,
+ gpointer user_data)
+{
+ GdictWindow *window = GDICT_WINDOW (user_data);
+ gchar *text;
+
+ text = (gchar *) gtk_selection_data_get_text (data);
+ if (text)
+ {
+ gtk_entry_set_text (GTK_ENTRY (window->entry), text);
+
+ gdict_window_set_word (window, text, NULL);
+ g_free (text);
+
+ gtk_drag_finish (context, TRUE, FALSE, time_);
+ }
+ else
+ gtk_drag_finish (context, FALSE, FALSE, time_);
+}
+
+static void
+gdict_window_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GdictWindow *window = GDICT_WINDOW (widget);
+
+ if (!window->is_maximized)
+ {
+ window->default_width = allocation->width;
+ window->default_height = allocation->height;
+ }
+
+ if (GTK_WIDGET_CLASS (gdict_window_parent_class)->size_allocate)
+ GTK_WIDGET_CLASS (gdict_window_parent_class)->size_allocate (widget,
+ allocation);
+}
+
+static void
+set_window_default_size (GdictWindow *window)
+{
+ GtkWidget *widget;
+ gboolean is_maximized;
+ gint width, height;
+ gint font_size;
+ GdkScreen *screen;
+ gint monitor_num;
+ GtkRequisition req;
+ GdkRectangle monitor;
+
+ g_assert (GDICT_IS_WINDOW (window));
+
+ widget = GTK_WIDGET (window);
+
+ /* make sure that the widget is realized */
+ gtk_widget_realize (widget);
+
+ /* recover the state from MateConf */
+ width = mateconf_client_get_int (window->mateconf_client,
+ GDICT_MATECONF_WINDOW_WIDTH_KEY,
+ NULL);
+ height = mateconf_client_get_int (window->mateconf_client,
+ GDICT_MATECONF_WINDOW_HEIGHT_KEY,
+ NULL);
+ is_maximized = mateconf_client_get_bool (window->mateconf_client,
+ GDICT_MATECONF_WINDOW_IS_MAXIMIZED_KEY,
+ NULL);
+
+ /* XXX - the user wants mate-dictionary to resize itself, so
+ * we compute the minimum safe geometry needed for displaying
+ * the text returned by a dictionary server, which is based
+ * on the font size and the ANSI terminal. this is dumb,
+ * I know, but dictionary servers return pre-formatted text
+ * and we can't reformat it ourselves.
+ */
+ if (width == -1 || height == -1)
+ {
+ /* Size based on the font size */
+ GtkWidget *defbox = window->defbox;
+
+ font_size = pango_font_description_get_size (gtk_widget_get_style (defbox)->font_desc);
+ font_size = PANGO_PIXELS (font_size);
+
+ width = font_size * GDICT_WINDOW_COLUMNS;
+ height = font_size * GDICT_WINDOW_ROWS;
+
+ /* Use at least the requisition size of the window... */
+ gtk_widget_size_request (widget, &req);
+ width = MAX (width, req.width);
+ height = MAX (height, req.height);
+
+ /* ... but make it no larger than the monitor */
+ screen = gtk_widget_get_screen (widget);
+ monitor_num = gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (widget));
+
+ gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+ width = MIN (width, monitor.width * 3 / 4);
+ height = MIN (height, monitor.height * 3 / 4);
+ }
+
+ /* Set default size */
+ gtk_window_set_default_size (GTK_WINDOW (widget),
+ width,
+ height);
+
+ if (is_maximized)
+ gtk_window_maximize (GTK_WINDOW (widget));
+}
+
+static void
+gdict_window_style_set (GtkWidget *widget,
+ GtkStyle *old_style)
+{
+
+ if (GTK_WIDGET_CLASS (gdict_window_parent_class)->style_set)
+ GTK_WIDGET_CLASS (gdict_window_parent_class)->style_set (widget, old_style);
+
+ set_window_default_size (GDICT_WINDOW (widget));
+}
+
+static void
+gdict_window_handle_notify_position_cb (GtkWidget *widget,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ GdictWindow *window = GDICT_WINDOW (user_data);
+ gint window_width, pos;
+ GtkAllocation allocation;
+
+ pos = gtk_paned_get_position (GTK_PANED (widget));
+ gtk_widget_get_allocation (GTK_WIDGET (window), &allocation);
+ window_width = allocation.width;
+
+ window->sidebar_width = window_width - pos;
+}
+
+static GObject *
+gdict_window_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ GdictWindow *window;
+ gint width, height, sidebar_width;
+ gboolean is_maximized;
+ GtkWidget *hbox;
+ GtkWidget *handle;
+ GtkWidget *frame1, *frame2;
+ GtkWidget *vbox;
+ GtkWidget *button;
+ GtkActionGroup *action_group;
+ GtkAccelGroup *accel_group;
+ PangoFontDescription *font_desc;
+ gchar *font_name, *sidebar_page;
+ GError *error;
+ gboolean sidebar_visible;
+ gboolean statusbar_visible;
+ GtkAllocation allocation;
+
+ object = G_OBJECT_CLASS (gdict_window_parent_class)->constructor (type,
+ n_construct_properties,
+ construct_params);
+ window = GDICT_WINDOW (object);
+
+ gtk_widget_push_composite_child ();
+
+ window->main_box = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (window), window->main_box);
+ gtk_widget_show (window->main_box);
+
+ /* build menus */
+ action_group = gtk_action_group_new ("MenuActions");
+ window->action_group = action_group;
+ gtk_action_group_set_translation_domain (action_group, NULL);
+ gtk_action_group_add_actions (action_group, entries,
+ G_N_ELEMENTS (entries),
+ window);
+ gtk_action_group_add_toggle_actions (action_group, toggle_entries,
+ G_N_ELEMENTS (toggle_entries),
+ window);
+
+ window->ui_manager = gtk_ui_manager_new ();
+ gtk_ui_manager_insert_action_group (window->ui_manager, action_group, 0);
+
+ accel_group = gtk_ui_manager_get_accel_group (window->ui_manager);
+ gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
+
+ error = NULL;
+ if (!gtk_ui_manager_add_ui_from_file (window->ui_manager,
+ PKGDATADIR "/mate-dictionary-ui.xml",
+ &error))
+ {
+ g_warning ("Building menus failed: %s", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ window->menubar = gtk_ui_manager_get_widget (window->ui_manager, "/MainMenu");
+
+ gtk_box_pack_start (GTK_BOX (window->main_box), window->menubar, FALSE, FALSE, 0);
+ gtk_widget_show (window->menubar);
+
+ gdict_window_ensure_menu_state (window);
+ }
+
+ vbox = gtk_vbox_new (FALSE, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
+ gtk_container_add (GTK_CONTAINER (window->main_box), vbox);
+ gtk_widget_show (vbox);
+
+ hbox = gtk_hbox_new (FALSE, 12);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+ gtk_widget_show (hbox);
+
+ button = gtk_button_new_with_mnemonic (_("Look _up:"));
+ g_signal_connect_swapped (button, "clicked",
+ G_CALLBACK (lookup_word),
+ window);
+ gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+ gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
+
+ window->completion_model = gtk_list_store_new (COMPLETION_N_COLUMNS,
+ G_TYPE_STRING);
+
+ window->completion = gtk_entry_completion_new ();
+ gtk_entry_completion_set_popup_completion (window->completion, TRUE);
+ gtk_entry_completion_set_model (window->completion,
+ GTK_TREE_MODEL (window->completion_model));
+ gtk_entry_completion_set_text_column (window->completion,
+ COMPLETION_TEXT_COLUMN);
+
+ window->entry = gtk_entry_new ();
+ if (window->word)
+ gtk_entry_set_text (GTK_ENTRY (window->entry), window->word);
+
+ gtk_entry_set_completion (GTK_ENTRY (window->entry),
+ window->completion);
+ g_signal_connect_swapped (window->entry, "activate",
+ G_CALLBACK (lookup_word),
+ window);
+ gtk_box_pack_start (GTK_BOX (hbox), window->entry, TRUE, TRUE, 0);
+ gtk_widget_show (window->entry);
+
+ handle = gtk_hpaned_new ();
+ gtk_box_pack_start (GTK_BOX (vbox), handle, TRUE, TRUE, 0);
+ gtk_widget_show (handle);
+
+ frame1 = gtk_vbox_new (FALSE, 0);
+ frame2 = gtk_vbox_new (FALSE, 0);
+
+ window->defbox = gdict_defbox_new ();
+ if (window->context)
+ gdict_defbox_set_context (GDICT_DEFBOX (window->defbox), window->context);
+
+ g_signal_connect (window->defbox, "link-clicked",
+ G_CALLBACK (gdict_window_link_clicked),
+ window);
+
+ gtk_drag_dest_set (window->defbox,
+ GTK_DEST_DEFAULT_ALL,
+ drop_types, n_drop_types,
+ GDK_ACTION_COPY);
+ g_signal_connect (window->defbox, "drag-data-received",
+ G_CALLBACK (gdict_window_drag_data_received_cb),
+ window);
+ gtk_container_add (GTK_CONTAINER (frame1), window->defbox);
+ gtk_widget_show (window->defbox);
+
+ /* Sidebar */
+ window->sidebar = gdict_sidebar_new ();
+ g_signal_connect (window->sidebar, "page-changed",
+ G_CALLBACK (sidebar_page_changed_cb),
+ window);
+ g_signal_connect (window->sidebar, "closed",
+ G_CALLBACK (sidebar_closed_cb),
+ window);
+
+ /* Speller */
+ window->speller = gdict_speller_new ();
+ if (window->context)
+ gdict_speller_set_context (GDICT_SPELLER (window->speller),
+ window->context);
+ g_signal_connect (window->speller, "word-activated",
+ G_CALLBACK (speller_word_activated_cb),
+ window);
+ gdict_sidebar_add_page (GDICT_SIDEBAR (window->sidebar),
+ GDICT_SIDEBAR_SPELLER_PAGE,
+ _("Similar words"),
+ window->speller);
+ gtk_widget_show (window->speller);
+
+ /* Database chooser */
+ if (window->context)
+ gdict_database_chooser_set_context (GDICT_DATABASE_CHOOSER (window->db_chooser),
+ window->context);
+ g_signal_connect (window->db_chooser, "database-activated",
+ G_CALLBACK (database_activated_cb),
+ window);
+ gdict_sidebar_add_page (GDICT_SIDEBAR (window->sidebar),
+ GDICT_SIDEBAR_DATABASES_PAGE,
+ _("Available dictionaries"),
+ window->db_chooser);
+ gtk_widget_show (window->db_chooser);
+
+ /* Strategy chooser */
+ if (window->context)
+ gdict_strategy_chooser_set_context (GDICT_STRATEGY_CHOOSER (window->strat_chooser),
+ window->context);
+ g_signal_connect (window->strat_chooser, "strategy-activated",
+ G_CALLBACK (strategy_activated_cb),
+ window);
+ gdict_sidebar_add_page (GDICT_SIDEBAR (window->sidebar),
+ GDICT_SIDEBAR_STRATEGIES_PAGE,
+ _("Available strategies"),
+ window->strat_chooser);
+ gtk_widget_show (window->strat_chooser);
+
+ /* Source chooser */
+ window->source_chooser = gdict_source_chooser_new_with_loader (window->loader);
+ g_signal_connect (window->source_chooser, "source-activated",
+ G_CALLBACK (source_activated_cb),
+ window);
+ gdict_sidebar_add_page (GDICT_SIDEBAR (window->sidebar),
+ GDICT_SIDEBAR_SOURCES_PAGE,
+ _("Dictionary sources"),
+ window->source_chooser);
+ gtk_widget_show (window->source_chooser);
+
+ gtk_container_add (GTK_CONTAINER (frame2), window->sidebar);
+ gtk_widget_show (window->sidebar);
+
+ gtk_paned_pack1 (GTK_PANED (handle), frame1, TRUE, FALSE);
+ gtk_paned_pack2 (GTK_PANED (handle), frame2, FALSE, TRUE);
+
+ window->defbox_frame = frame1;
+ window->sidebar_frame = frame2;
+
+ gtk_widget_show (window->defbox_frame);
+
+ window->status = gtk_statusbar_new ();
+ gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (window->status), TRUE);
+ gtk_box_pack_end (GTK_BOX (window->main_box), window->status, FALSE, FALSE, 0);
+ statusbar_visible = mateconf_client_get_bool (window->mateconf_client,
+ GDICT_MATECONF_STATUSBAR_VISIBLE_KEY,
+ NULL);
+ gdict_window_set_statusbar_visible (window, statusbar_visible);
+
+ window->progress = gtk_progress_bar_new ();
+ gtk_box_pack_end (GTK_BOX (window->status), window->progress, FALSE, FALSE, 0);
+
+ /* retrieve the font size from mateconf */
+ font_name = gdict_mateconf_get_string_with_default (window->mateconf_client,
+ DOCUMENT_FONT_KEY,
+ GDICT_DEFAULT_DEFBOX_FONT);
+
+ gdict_window_set_defbox_font (window, font_name);
+ font_desc = pango_font_description_from_string (font_name);
+ g_free (font_name);
+
+ sidebar_visible = mateconf_client_get_bool (window->mateconf_client,
+ GDICT_MATECONF_SIDEBAR_VISIBLE_KEY,
+ NULL);
+ gdict_window_set_sidebar_visible (window, sidebar_visible);
+
+ /* retrieve the window state from mateconf */
+ is_maximized = mateconf_client_get_bool (window->mateconf_client,
+ GDICT_MATECONF_WINDOW_IS_MAXIMIZED_KEY,
+ NULL);
+
+ width = mateconf_client_get_int (window->mateconf_client,
+ GDICT_MATECONF_WINDOW_WIDTH_KEY,
+ NULL);
+ height = mateconf_client_get_int (window->mateconf_client,
+ GDICT_MATECONF_WINDOW_HEIGHT_KEY,
+ NULL);
+ sidebar_width = mateconf_client_get_int (window->mateconf_client,
+ GDICT_MATECONF_SIDEBAR_WIDTH_KEY,
+ NULL);
+ sidebar_page = mateconf_client_get_string (window->mateconf_client,
+ GDICT_MATECONF_SIDEBAR_PAGE_KEY,
+ NULL);
+
+ /* if the (width, height) tuple is not defined, use the font to
+ * calculate the right window geometry
+ */
+ if (width == -1 || height == -1)
+ {
+ gint font_size;
+
+ font_size = pango_font_description_get_size (font_desc);
+ font_size = PANGO_PIXELS (font_size);
+
+ width = MAX (GDICT_WINDOW_COLUMNS * font_size, GDICT_WINDOW_MIN_WIDTH);
+ height = MAX (GDICT_WINDOW_ROWS * font_size, GDICT_WINDOW_MIN_HEIGHT);
+ }
+ else
+ {
+ window->default_width = width;
+ window->default_height = height;
+ }
+
+ pango_font_description_free (font_desc);
+
+ window->is_maximized = is_maximized;
+
+ gtk_window_set_title (GTK_WINDOW (window), _("Dictionary"));
+ gtk_window_set_default_size (GTK_WINDOW (window),
+ width,
+ height);
+ if (is_maximized)
+ gtk_window_maximize (GTK_WINDOW (window));
+
+ gtk_widget_get_allocation (GTK_WIDGET (window), &allocation);
+ gtk_paned_set_position (GTK_PANED (handle), allocation.width - sidebar_width);
+ if (sidebar_page)
+ {
+ gdict_sidebar_view_page (GDICT_SIDEBAR (window->sidebar), sidebar_page);
+ g_free (sidebar_page);
+ }
+
+ g_signal_connect (window, "delete-event",
+ G_CALLBACK (gdict_window_delete_event_cb),
+ NULL);
+ g_signal_connect (window, "window-state-event",
+ G_CALLBACK (gdict_window_state_event_cb),
+ NULL);
+ g_signal_connect (handle, "notify::position",
+ G_CALLBACK (gdict_window_handle_notify_position_cb),
+ window);
+
+ gtk_widget_grab_focus (window->entry);
+
+ gtk_widget_pop_composite_child ();
+
+ return object;
+}
+
+static void
+gdict_window_class_init (GdictWindowClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ gobject_class->finalize = gdict_window_finalize;
+ gobject_class->dispose = gdict_window_dispose;
+ gobject_class->set_property = gdict_window_set_property;
+ gobject_class->get_property = gdict_window_get_property;
+ gobject_class->constructor = gdict_window_constructor;
+
+ widget_class->style_set = gdict_window_style_set;
+ widget_class->size_allocate = gdict_window_size_allocate;
+
+ g_object_class_install_property (gobject_class,
+ PROP_ACTION,
+ g_param_spec_enum ("action",
+ "Action",
+ "The default action performed by the window",
+ GDICT_TYPE_WINDOW_ACTION,
+ GDICT_WINDOW_ACTION_CLEAR,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
+ g_object_class_install_property (gobject_class,
+ PROP_SOURCE_LOADER,
+ g_param_spec_object ("source-loader",
+ "Source Loader",
+ "The GdictSourceLoader to be used to load dictionary sources",
+ GDICT_TYPE_SOURCE_LOADER,
+ (G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)));
+ g_object_class_install_property (gobject_class,
+ PROP_SOURCE_NAME,
+ g_param_spec_string ("source-name",
+ "Source Name",
+ "The name of the GdictSource to be used",
+ GDICT_DEFAULT_SOURCE_NAME,
+ (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+ g_object_class_install_property (gobject_class,
+ PROP_PRINT_FONT,
+ g_param_spec_string ("print-font",
+ "Print Font",
+ "The font name to be used when printing",
+ GDICT_DEFAULT_PRINT_FONT,
+ (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+ g_object_class_install_property (gobject_class,
+ PROP_DEFBOX_FONT,
+ g_param_spec_string ("defbox-font",
+ "Defbox Font",
+ "The font name to be used by the defbox widget",
+ GDICT_DEFAULT_DEFBOX_FONT,
+ (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+ g_object_class_install_property (gobject_class,
+ PROP_WORD,
+ g_param_spec_string ("word",
+ "Word",
+ "The word to search",
+ NULL,
+ (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+ g_object_class_install_property (gobject_class,
+ PROP_WINDOW_ID,
+ g_param_spec_uint ("window-id",
+ "Window ID",
+ "The unique identifier for this window",
+ 0,
+ G_MAXUINT,
+ 0,
+ G_PARAM_READABLE));
+
+ gdict_window_signals[CREATED] =
+ g_signal_new ("created",
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GdictWindowClass, created),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GDICT_TYPE_WINDOW);
+}
+
+static void
+gdict_window_init (GdictWindow *window)
+{
+ GError *mateconf_error;
+
+ window->action = GDICT_WINDOW_ACTION_CLEAR;
+
+ window->loader = NULL;
+ window->context = NULL;
+
+ window->mateconf_client = mateconf_client_get_default ();
+
+ mateconf_error = NULL;
+ mateconf_client_add_dir (window->mateconf_client,
+ GDICT_MATECONF_DIR,
+ MATECONF_CLIENT_PRELOAD_NONE,
+ &mateconf_error);
+ if (mateconf_error)
+ {
+ gdict_show_gerror_dialog (NULL,
+ _("Unable to connect to MateConf"),
+ mateconf_error);
+ }
+
+ window->notify_id = mateconf_client_notify_add (window->mateconf_client,
+ GDICT_MATECONF_DIR,
+ gdict_window_mateconf_notify_cb,
+ window,
+ NULL,
+ &mateconf_error);
+ if (mateconf_error)
+ {
+ gdict_show_gerror_dialog (NULL,
+ _("Unable to get notification for preferences"),
+ mateconf_error);
+ }
+
+ window->font_notify_id = mateconf_client_notify_add (window->mateconf_client,
+ DOCUMENT_FONT_KEY,
+ gdict_window_mateconf_notify_cb,
+ window,
+ NULL,
+ &mateconf_error);
+ if (mateconf_error)
+ {
+ gdict_show_gerror_dialog (NULL,
+ _("Unable to get notification for the document font"),
+ mateconf_error);
+ }
+
+ window->word = NULL;
+ window->source_name = NULL;
+ window->print_font = NULL;
+ window->defbox_font = NULL;
+
+ window->database = NULL;
+ window->strategy = NULL;
+
+ window->default_width = -1;
+ window->default_height = -1;
+ window->is_maximized = FALSE;
+
+ window->window_id = (gulong) time (NULL);
+
+ /* we need to create the chooser widgets for the sidebar before
+ * we set the construction properties
+ */
+ window->db_chooser = gdict_database_chooser_new ();
+ window->strat_chooser = gdict_strategy_chooser_new ();
+}
+
+GtkWidget *
+gdict_window_new (GdictWindowAction action,
+ GdictSourceLoader *loader,
+ const gchar *source_name,
+ const gchar *word)
+{
+ GtkWidget *retval;
+ GdictWindow *window;
+
+ g_return_val_if_fail (GDICT_IS_SOURCE_LOADER (loader), NULL);
+
+ retval = g_object_new (GDICT_TYPE_WINDOW,
+ "action", action,
+ "source-loader", loader,
+ "source-name", source_name,
+ NULL);
+
+ window = GDICT_WINDOW (retval);
+
+ if (word && word[0] != '\0')
+ {
+ switch (action)
+ {
+ case GDICT_WINDOW_ACTION_LOOKUP:
+ gtk_entry_set_text (GTK_ENTRY (window->entry), word);
+ gdict_window_set_word (window, word, NULL);
+ break;
+ case GDICT_WINDOW_ACTION_MATCH:
+ {
+ GdictSource *source;
+ GdictContext *context;
+
+ gtk_entry_set_text (GTK_ENTRY (window->entry), word);
+
+ gdict_window_set_sidebar_visible (window, TRUE);
+ gdict_sidebar_view_page (GDICT_SIDEBAR (window->sidebar),
+ GDICT_SIDEBAR_SPELLER_PAGE);
+
+ /* we clone the context, so that the signals that it
+ * fires do not get caught by the signal handlers we
+ * use for getting the definitions.
+ */
+ source = gdict_source_loader_get_source (window->loader,
+ window->source_name);
+ context = gdict_source_get_context (source);
+
+ gdict_speller_set_context (GDICT_SPELLER (window->speller), context);
+
+ g_object_unref (context);
+ g_object_unref (source);
+
+ gdict_speller_set_strategy (GDICT_SPELLER (window->speller),
+ window->strategy);
+
+ gdict_speller_match (GDICT_SPELLER (window->speller), word);
+ }
+ case GDICT_WINDOW_ACTION_CLEAR:
+ gdict_defbox_clear (GDICT_DEFBOX (window->defbox));
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ }
+
+ return retval;
+}
+
+/* GdictWindowAction */
+static const GEnumValue _gdict_window_action_values[] = {
+ { GDICT_WINDOW_ACTION_LOOKUP, "GDICT_WINDOW_ACTION_LOOKUP", "lookup" },
+ { GDICT_WINDOW_ACTION_MATCH, "GDICT_WINDOW_ACTION_MATCH", "match" },
+ { GDICT_WINDOW_ACTION_CLEAR, "GDICT_WINDOW_ACTION_CLEAR", "clear" },
+ { 0, NULL, NULL }
+};
+
+GType
+gdict_window_action_get_type (void)
+{
+ static GType our_type = 0;
+
+ if (!our_type)
+ our_type = g_enum_register_static ("GdictWindowAction", _gdict_window_action_values);
+
+ return our_type;
+}