811 lines
21 KiB
C
811 lines
21 KiB
C
/*
|
|
* gedit-spell-plugin.c
|
|
*
|
|
* Copyright (C) 2002-2005 Paolo Maggi
|
|
* Copyright (C) 2015-2016 Sébastien Wilmet
|
|
*
|
|
* 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, 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, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "gedit-spell-plugin.h"
|
|
|
|
#include <glib/gi18n.h>
|
|
#include <gedit/gedit-debug.h>
|
|
#include <gedit/gedit-app.h>
|
|
#include <gedit/gedit-window.h>
|
|
#include <gedit/gedit-window-activatable.h>
|
|
#include <gspell/gspell.h>
|
|
#include <libpeas-gtk/peas-gtk-configurable.h>
|
|
|
|
#include "gedit-spell-app-activatable.h"
|
|
|
|
#define GEDIT_METADATA_ATTRIBUTE_SPELL_LANGUAGE "gedit-spell-language"
|
|
#define GEDIT_METADATA_ATTRIBUTE_SPELL_ENABLED "gedit-spell-enabled"
|
|
|
|
#define SPELL_ENABLED_STR "1"
|
|
#define SPELL_BASE_SETTINGS "org.gnome.gedit.plugins.spell"
|
|
#define SETTINGS_KEY_HIGHLIGHT_MISSPELLED "highlight-misspelled"
|
|
|
|
static void gedit_window_activatable_iface_init (GeditWindowActivatableInterface *iface);
|
|
static void peas_gtk_configurable_iface_init (PeasGtkConfigurableInterface *iface);
|
|
|
|
struct _GeditSpellPluginPrivate
|
|
{
|
|
GeditWindow *window;
|
|
GSettings *settings;
|
|
};
|
|
|
|
enum
|
|
{
|
|
PROP_0,
|
|
PROP_WINDOW
|
|
};
|
|
|
|
typedef struct _SpellConfigureWidget SpellConfigureWidget;
|
|
|
|
struct _SpellConfigureWidget
|
|
{
|
|
GtkWidget *content;
|
|
GtkWidget *highlight_button;
|
|
|
|
GSettings *settings;
|
|
};
|
|
|
|
G_DEFINE_DYNAMIC_TYPE_EXTENDED (GeditSpellPlugin,
|
|
gedit_spell_plugin,
|
|
PEAS_TYPE_EXTENSION_BASE,
|
|
0,
|
|
G_IMPLEMENT_INTERFACE_DYNAMIC (GEDIT_TYPE_WINDOW_ACTIVATABLE,
|
|
gedit_window_activatable_iface_init)
|
|
G_IMPLEMENT_INTERFACE_DYNAMIC (PEAS_GTK_TYPE_CONFIGURABLE,
|
|
peas_gtk_configurable_iface_init)
|
|
G_ADD_PRIVATE_DYNAMIC (GeditSpellPlugin))
|
|
|
|
static void
|
|
gedit_spell_plugin_set_property (GObject *object,
|
|
guint prop_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GeditSpellPlugin *plugin = GEDIT_SPELL_PLUGIN (object);
|
|
|
|
switch (prop_id)
|
|
{
|
|
case PROP_WINDOW:
|
|
plugin->priv->window = GEDIT_WINDOW (g_value_dup_object (value));
|
|
break;
|
|
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gedit_spell_plugin_get_property (GObject *object,
|
|
guint prop_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GeditSpellPlugin *plugin = GEDIT_SPELL_PLUGIN (object);
|
|
|
|
switch (prop_id)
|
|
{
|
|
case PROP_WINDOW:
|
|
g_value_set_object (value, plugin->priv->window);
|
|
break;
|
|
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gedit_spell_plugin_dispose (GObject *object)
|
|
{
|
|
GeditSpellPlugin *plugin = GEDIT_SPELL_PLUGIN (object);
|
|
|
|
gedit_debug_message (DEBUG_PLUGINS, "GeditSpellPlugin disposing");
|
|
|
|
g_clear_object (&plugin->priv->window);
|
|
g_clear_object (&plugin->priv->settings);
|
|
|
|
G_OBJECT_CLASS (gedit_spell_plugin_parent_class)->dispose (object);
|
|
}
|
|
|
|
static void
|
|
gedit_spell_plugin_class_init (GeditSpellPluginClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
object_class->set_property = gedit_spell_plugin_set_property;
|
|
object_class->get_property = gedit_spell_plugin_get_property;
|
|
object_class->dispose = gedit_spell_plugin_dispose;
|
|
|
|
g_object_class_override_property (object_class, PROP_WINDOW, "window");
|
|
}
|
|
|
|
static void
|
|
gedit_spell_plugin_class_finalize (GeditSpellPluginClass *klass)
|
|
{
|
|
}
|
|
|
|
static void
|
|
gedit_spell_plugin_init (GeditSpellPlugin *plugin)
|
|
{
|
|
gedit_debug_message (DEBUG_PLUGINS, "GeditSpellPlugin initializing");
|
|
|
|
plugin->priv = gedit_spell_plugin_get_instance_private (plugin);
|
|
plugin->priv->settings = g_settings_new (SPELL_BASE_SETTINGS);
|
|
}
|
|
|
|
static GspellChecker *
|
|
get_spell_checker (GeditDocument *doc)
|
|
{
|
|
GspellTextBuffer *gspell_buffer;
|
|
|
|
gspell_buffer = gspell_text_buffer_get_from_gtk_text_buffer (GTK_TEXT_BUFFER (doc));
|
|
return gspell_text_buffer_get_spell_checker (gspell_buffer);
|
|
}
|
|
|
|
static const GspellLanguage *
|
|
get_language_from_metadata (GeditDocument *doc)
|
|
{
|
|
const GspellLanguage *lang = NULL;
|
|
gchar *language_code = NULL;
|
|
|
|
language_code = gedit_document_get_metadata (doc, GEDIT_METADATA_ATTRIBUTE_SPELL_LANGUAGE);
|
|
|
|
if (language_code != NULL)
|
|
{
|
|
lang = gspell_language_lookup (language_code);
|
|
g_free (language_code);
|
|
}
|
|
|
|
return lang;
|
|
}
|
|
|
|
static void
|
|
check_spell_cb (GSimpleAction *action,
|
|
GVariant *parameter,
|
|
gpointer data)
|
|
{
|
|
GeditSpellPlugin *plugin = GEDIT_SPELL_PLUGIN (data);
|
|
GeditSpellPluginPrivate *priv;
|
|
GeditView *view;
|
|
GspellNavigator *navigator;
|
|
GtkWidget *dialog;
|
|
|
|
gedit_debug (DEBUG_PLUGINS);
|
|
|
|
priv = plugin->priv;
|
|
|
|
view = gedit_window_get_active_view (priv->window);
|
|
g_return_if_fail (view != NULL);
|
|
|
|
navigator = gspell_navigator_text_view_new (GTK_TEXT_VIEW (view));
|
|
dialog = gspell_checker_dialog_new (GTK_WINDOW (priv->window), navigator);
|
|
|
|
gtk_widget_show (dialog);
|
|
}
|
|
|
|
static void
|
|
language_dialog_response_cb (GtkDialog *dialog,
|
|
gint response_id,
|
|
gpointer user_data)
|
|
{
|
|
if (response_id == GTK_RESPONSE_HELP)
|
|
{
|
|
gedit_app_show_help (GEDIT_APP (g_application_get_default ()),
|
|
GTK_WINDOW (dialog),
|
|
NULL,
|
|
"gedit-spellcheck");
|
|
return;
|
|
}
|
|
|
|
gtk_widget_destroy (GTK_WIDGET (dialog));
|
|
}
|
|
|
|
static void
|
|
set_language_cb (GSimpleAction *action,
|
|
GVariant *parameter,
|
|
gpointer data)
|
|
{
|
|
GeditSpellPlugin *plugin = GEDIT_SPELL_PLUGIN (data);
|
|
GeditSpellPluginPrivate *priv;
|
|
GeditDocument *doc;
|
|
GspellChecker *checker;
|
|
const GspellLanguage *lang;
|
|
GtkWidget *dialog;
|
|
GtkWindowGroup *window_group;
|
|
|
|
gedit_debug (DEBUG_PLUGINS);
|
|
|
|
priv = plugin->priv;
|
|
|
|
doc = gedit_window_get_active_document (priv->window);
|
|
g_return_if_fail (doc != NULL);
|
|
|
|
checker = get_spell_checker (doc);
|
|
g_return_if_fail (checker != NULL);
|
|
|
|
lang = gspell_checker_get_language (checker);
|
|
|
|
dialog = gspell_language_chooser_dialog_new (GTK_WINDOW (priv->window),
|
|
lang,
|
|
GTK_DIALOG_MODAL |
|
|
GTK_DIALOG_DESTROY_WITH_PARENT);
|
|
|
|
g_object_bind_property (dialog, "language",
|
|
checker, "language",
|
|
G_BINDING_DEFAULT);
|
|
|
|
window_group = gedit_window_get_group (priv->window);
|
|
|
|
gtk_window_group_add_window (window_group, GTK_WINDOW (dialog));
|
|
|
|
gtk_dialog_add_button (GTK_DIALOG (dialog),
|
|
_("_Help"),
|
|
GTK_RESPONSE_HELP);
|
|
|
|
g_signal_connect (dialog,
|
|
"response",
|
|
G_CALLBACK (language_dialog_response_cb),
|
|
NULL);
|
|
|
|
gtk_widget_show (dialog);
|
|
}
|
|
|
|
static void
|
|
inline_checker_activate_cb (GSimpleAction *action,
|
|
GVariant *parameter,
|
|
gpointer data)
|
|
{
|
|
GeditSpellPlugin *plugin = GEDIT_SPELL_PLUGIN (data);
|
|
GeditSpellPluginPrivate *priv = plugin->priv;
|
|
GVariant *state;
|
|
gboolean active;
|
|
GeditView *view;
|
|
|
|
gedit_debug (DEBUG_PLUGINS);
|
|
|
|
state = g_action_get_state (G_ACTION (action));
|
|
g_return_if_fail (state != NULL);
|
|
|
|
active = g_variant_get_boolean (state);
|
|
g_variant_unref (state);
|
|
|
|
/* We must toggle ourself the value. */
|
|
active = !active;
|
|
g_action_change_state (G_ACTION (action), g_variant_new_boolean (active));
|
|
|
|
view = gedit_window_get_active_view (priv->window);
|
|
if (view != NULL)
|
|
{
|
|
GeditDocument *doc;
|
|
|
|
doc = GEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
|
|
|
|
/* Set metadata in the "activate" handler, not in "change-state"
|
|
* because "change-state" is called every time the state
|
|
* changes, not specifically when the user has changed the state
|
|
* herself. For example "change-state" is called to initialize
|
|
* the sate to the default value specified in the GActionEntry.
|
|
*/
|
|
gedit_document_set_metadata (doc,
|
|
GEDIT_METADATA_ATTRIBUTE_SPELL_ENABLED,
|
|
active ? SPELL_ENABLED_STR : NULL,
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
static void
|
|
inline_checker_change_state_cb (GSimpleAction *action,
|
|
GVariant *state,
|
|
gpointer data)
|
|
{
|
|
GeditSpellPlugin *plugin = GEDIT_SPELL_PLUGIN (data);
|
|
GeditSpellPluginPrivate *priv = plugin->priv;
|
|
GeditView *view;
|
|
gboolean active;
|
|
|
|
gedit_debug (DEBUG_PLUGINS);
|
|
|
|
active = g_variant_get_boolean (state);
|
|
|
|
gedit_debug_message (DEBUG_PLUGINS, active ? "Inline Checker activated" : "Inline Checker deactivated");
|
|
|
|
view = gedit_window_get_active_view (priv->window);
|
|
if (view != NULL)
|
|
{
|
|
GspellTextView *gspell_view;
|
|
|
|
gspell_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (view));
|
|
gspell_text_view_set_inline_spell_checking (gspell_view, active);
|
|
|
|
g_simple_action_set_state (action, g_variant_new_boolean (active));
|
|
}
|
|
}
|
|
|
|
static void
|
|
update_ui (GeditSpellPlugin *plugin)
|
|
{
|
|
GeditSpellPluginPrivate *priv;
|
|
GeditTab *tab;
|
|
GeditView *view = NULL;
|
|
gboolean editable_view;
|
|
GAction *check_spell_action;
|
|
GAction *config_spell_action;
|
|
GAction *inline_checker_action;
|
|
|
|
gedit_debug (DEBUG_PLUGINS);
|
|
|
|
priv = plugin->priv;
|
|
|
|
tab = gedit_window_get_active_tab (priv->window);
|
|
if (tab != NULL)
|
|
{
|
|
view = gedit_tab_get_view (tab);
|
|
}
|
|
|
|
editable_view = (view != NULL) && gtk_text_view_get_editable (GTK_TEXT_VIEW (view));
|
|
|
|
check_spell_action = g_action_map_lookup_action (G_ACTION_MAP (priv->window),
|
|
"check-spell");
|
|
g_simple_action_set_enabled (G_SIMPLE_ACTION (check_spell_action),
|
|
editable_view);
|
|
|
|
config_spell_action = g_action_map_lookup_action (G_ACTION_MAP (priv->window),
|
|
"config-spell");
|
|
g_simple_action_set_enabled (G_SIMPLE_ACTION (config_spell_action),
|
|
editable_view);
|
|
|
|
inline_checker_action = g_action_map_lookup_action (G_ACTION_MAP (priv->window),
|
|
"inline-spell-checker");
|
|
g_simple_action_set_enabled (G_SIMPLE_ACTION (inline_checker_action),
|
|
editable_view);
|
|
|
|
/* Update only on normal state to avoid garbage changes during e.g. file
|
|
* loading.
|
|
*/
|
|
if (tab != NULL &&
|
|
gedit_tab_get_state (tab) == GEDIT_TAB_STATE_NORMAL)
|
|
{
|
|
GspellTextView *gspell_view;
|
|
gboolean inline_checking_enabled;
|
|
|
|
gspell_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (view));
|
|
inline_checking_enabled = gspell_text_view_get_inline_spell_checking (gspell_view);
|
|
|
|
g_action_change_state (inline_checker_action,
|
|
g_variant_new_boolean (inline_checking_enabled));
|
|
}
|
|
}
|
|
|
|
static void
|
|
setup_inline_checker_from_metadata (GeditSpellPlugin *plugin,
|
|
GeditView *view)
|
|
{
|
|
GeditDocument *doc;
|
|
gboolean enabled;
|
|
gchar *enabled_str;
|
|
GspellTextView *gspell_view;
|
|
GeditView *active_view;
|
|
|
|
doc = GEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
|
|
|
|
enabled = g_settings_get_boolean(plugin->priv->settings, SETTINGS_KEY_HIGHLIGHT_MISSPELLED);
|
|
enabled_str = gedit_document_get_metadata (doc, GEDIT_METADATA_ATTRIBUTE_SPELL_ENABLED);
|
|
if (enabled_str != NULL)
|
|
{
|
|
enabled = g_str_equal (enabled_str, SPELL_ENABLED_STR);
|
|
g_free (enabled_str);
|
|
}
|
|
|
|
gspell_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (view));
|
|
gspell_text_view_set_inline_spell_checking (gspell_view, enabled);
|
|
|
|
/* In case that the view is the active one we mark the spell action */
|
|
active_view = gedit_window_get_active_view (plugin->priv->window);
|
|
|
|
if (active_view == view)
|
|
{
|
|
GAction *action;
|
|
|
|
action = g_action_map_lookup_action (G_ACTION_MAP (plugin->priv->window),
|
|
"inline-spell-checker");
|
|
g_action_change_state (action, g_variant_new_boolean (enabled));
|
|
}
|
|
}
|
|
|
|
static void
|
|
language_notify_cb (GspellChecker *checker,
|
|
GParamSpec *pspec,
|
|
GeditDocument *doc)
|
|
{
|
|
const GspellLanguage *lang;
|
|
const gchar *language_code;
|
|
|
|
g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
|
|
|
|
lang = gspell_checker_get_language (checker);
|
|
g_return_if_fail (lang != NULL);
|
|
|
|
language_code = gspell_language_get_code (lang);
|
|
g_return_if_fail (language_code != NULL);
|
|
|
|
gedit_document_set_metadata (doc,
|
|
GEDIT_METADATA_ATTRIBUTE_SPELL_LANGUAGE, language_code,
|
|
NULL);
|
|
}
|
|
|
|
static void
|
|
on_document_loaded (GeditDocument *doc,
|
|
GeditSpellPlugin *plugin)
|
|
{
|
|
GspellChecker *checker;
|
|
GeditTab *tab;
|
|
GeditView *view;
|
|
|
|
checker = get_spell_checker (doc);
|
|
|
|
if (checker != NULL)
|
|
{
|
|
const GspellLanguage *lang;
|
|
|
|
lang = get_language_from_metadata (doc);
|
|
|
|
if (lang != NULL)
|
|
{
|
|
g_signal_handlers_block_by_func (checker, language_notify_cb, doc);
|
|
gspell_checker_set_language (checker, lang);
|
|
g_signal_handlers_unblock_by_func (checker, language_notify_cb, doc);
|
|
}
|
|
}
|
|
|
|
tab = gedit_tab_get_from_document (doc);
|
|
view = gedit_tab_get_view (tab);
|
|
setup_inline_checker_from_metadata (plugin, view);
|
|
}
|
|
|
|
static void
|
|
on_document_saved (GeditDocument *doc,
|
|
gpointer user_data)
|
|
{
|
|
GeditTab *tab;
|
|
GeditView *view;
|
|
GspellChecker *checker;
|
|
const gchar *language_code = NULL;
|
|
GspellTextView *gspell_view;
|
|
gboolean inline_checking_enabled;
|
|
|
|
/* Make sure to save the metadata here too */
|
|
|
|
checker = get_spell_checker (doc);
|
|
|
|
if (checker != NULL)
|
|
{
|
|
const GspellLanguage *lang;
|
|
|
|
lang = gspell_checker_get_language (checker);
|
|
if (lang != NULL)
|
|
{
|
|
language_code = gspell_language_get_code (lang);
|
|
}
|
|
}
|
|
|
|
tab = gedit_tab_get_from_document (doc);
|
|
view = gedit_tab_get_view (tab);
|
|
|
|
gspell_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (view));
|
|
inline_checking_enabled = gspell_text_view_get_inline_spell_checking (gspell_view);
|
|
|
|
gedit_document_set_metadata (doc,
|
|
GEDIT_METADATA_ATTRIBUTE_SPELL_ENABLED,
|
|
inline_checking_enabled ? SPELL_ENABLED_STR : NULL,
|
|
GEDIT_METADATA_ATTRIBUTE_SPELL_LANGUAGE,
|
|
language_code,
|
|
NULL);
|
|
}
|
|
|
|
static void
|
|
activate_spell_checking_in_view (GeditSpellPlugin *plugin,
|
|
GeditView *view)
|
|
{
|
|
GeditDocument *doc;
|
|
|
|
doc = GEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
|
|
|
|
/* It is possible that a GspellChecker has already been set, for example
|
|
* if a GeditTab has moved to another window.
|
|
*/
|
|
if (get_spell_checker (doc) == NULL)
|
|
{
|
|
const GspellLanguage *lang;
|
|
GspellChecker *checker;
|
|
GspellTextBuffer *gspell_buffer;
|
|
|
|
lang = get_language_from_metadata (doc);
|
|
checker = gspell_checker_new (lang);
|
|
|
|
g_signal_connect_object (checker,
|
|
"notify::language",
|
|
G_CALLBACK (language_notify_cb),
|
|
doc,
|
|
0);
|
|
|
|
gspell_buffer = gspell_text_buffer_get_from_gtk_text_buffer (GTK_TEXT_BUFFER (doc));
|
|
gspell_text_buffer_set_spell_checker (gspell_buffer, checker);
|
|
g_object_unref (checker);
|
|
|
|
setup_inline_checker_from_metadata (plugin, view);
|
|
}
|
|
|
|
g_signal_connect_object (doc,
|
|
"loaded",
|
|
G_CALLBACK (on_document_loaded),
|
|
plugin,
|
|
0);
|
|
|
|
g_signal_connect_object (doc,
|
|
"saved",
|
|
G_CALLBACK (on_document_saved),
|
|
plugin,
|
|
0);
|
|
}
|
|
|
|
static void
|
|
disconnect_view (GeditSpellPlugin *plugin,
|
|
GeditView *view)
|
|
{
|
|
GtkTextBuffer *buffer;
|
|
|
|
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
|
|
|
/* It should still be the same buffer as the one where the signal
|
|
* handlers were connected. If not, we assume that the old buffer is
|
|
* finalized. And it is anyway safe to call
|
|
* g_signal_handlers_disconnect_by_func() if no signal handlers are
|
|
* found.
|
|
*/
|
|
g_signal_handlers_disconnect_by_func (buffer, on_document_loaded, plugin);
|
|
g_signal_handlers_disconnect_by_func (buffer, on_document_saved, plugin);
|
|
}
|
|
|
|
static void
|
|
deactivate_spell_checking_in_view (GeditSpellPlugin *plugin,
|
|
GeditView *view)
|
|
{
|
|
GtkTextBuffer *gtk_buffer;
|
|
GspellTextBuffer *gspell_buffer;
|
|
GspellTextView *gspell_view;
|
|
|
|
disconnect_view (plugin, view);
|
|
|
|
gtk_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
|
gspell_buffer = gspell_text_buffer_get_from_gtk_text_buffer (gtk_buffer);
|
|
gspell_text_buffer_set_spell_checker (gspell_buffer, NULL);
|
|
|
|
gspell_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (view));
|
|
gspell_text_view_set_inline_spell_checking (gspell_view, FALSE);
|
|
}
|
|
|
|
static void
|
|
tab_added_cb (GeditWindow *window,
|
|
GeditTab *tab,
|
|
GeditSpellPlugin *plugin)
|
|
{
|
|
activate_spell_checking_in_view (plugin, gedit_tab_get_view (tab));
|
|
}
|
|
|
|
static void
|
|
tab_removed_cb (GeditWindow *window,
|
|
GeditTab *tab,
|
|
GeditSpellPlugin *plugin)
|
|
{
|
|
/* Don't deactivate completely the spell checking in @tab, since the tab
|
|
* can be moved to another window and we don't want to loose the spell
|
|
* checking settings (they are not saved in metadata for unsaved
|
|
* documents).
|
|
*/
|
|
disconnect_view (plugin, gedit_tab_get_view (tab));
|
|
}
|
|
|
|
static void
|
|
gedit_spell_plugin_activate (GeditWindowActivatable *activatable)
|
|
{
|
|
GeditSpellPlugin *plugin;
|
|
GeditSpellPluginPrivate *priv;
|
|
GList *views;
|
|
GList *l;
|
|
|
|
const GActionEntry action_entries[] =
|
|
{
|
|
{ "check-spell", check_spell_cb },
|
|
{ "config-spell", set_language_cb },
|
|
{ "inline-spell-checker",
|
|
inline_checker_activate_cb,
|
|
NULL,
|
|
"false",
|
|
inline_checker_change_state_cb }
|
|
};
|
|
|
|
gedit_debug (DEBUG_PLUGINS);
|
|
|
|
plugin = GEDIT_SPELL_PLUGIN (activatable);
|
|
priv = plugin->priv;
|
|
|
|
g_action_map_add_action_entries (G_ACTION_MAP (priv->window),
|
|
action_entries,
|
|
G_N_ELEMENTS (action_entries),
|
|
activatable);
|
|
|
|
update_ui (plugin);
|
|
|
|
views = gedit_window_get_views (priv->window);
|
|
for (l = views; l != NULL; l = l->next)
|
|
{
|
|
activate_spell_checking_in_view (plugin, GEDIT_VIEW (l->data));
|
|
}
|
|
|
|
g_signal_connect (priv->window,
|
|
"tab-added",
|
|
G_CALLBACK (tab_added_cb),
|
|
activatable);
|
|
|
|
g_signal_connect (priv->window,
|
|
"tab-removed",
|
|
G_CALLBACK (tab_removed_cb),
|
|
activatable);
|
|
}
|
|
|
|
static void
|
|
gedit_spell_plugin_deactivate (GeditWindowActivatable *activatable)
|
|
{
|
|
GeditSpellPlugin *plugin;
|
|
GeditSpellPluginPrivate *priv;
|
|
GList *views;
|
|
GList *l;
|
|
|
|
gedit_debug (DEBUG_PLUGINS);
|
|
|
|
plugin = GEDIT_SPELL_PLUGIN (activatable);
|
|
priv = plugin->priv;
|
|
|
|
g_action_map_remove_action (G_ACTION_MAP (priv->window), "check-spell");
|
|
g_action_map_remove_action (G_ACTION_MAP (priv->window), "config-spell");
|
|
g_action_map_remove_action (G_ACTION_MAP (priv->window), "inline-spell-checker");
|
|
|
|
g_signal_handlers_disconnect_by_func (priv->window, tab_added_cb, activatable);
|
|
g_signal_handlers_disconnect_by_func (priv->window, tab_removed_cb, activatable);
|
|
|
|
views = gedit_window_get_views (priv->window);
|
|
for (l = views; l != NULL; l = l->next)
|
|
{
|
|
deactivate_spell_checking_in_view (plugin, GEDIT_VIEW (l->data));
|
|
}
|
|
}
|
|
|
|
static void
|
|
gedit_spell_plugin_update_state (GeditWindowActivatable *activatable)
|
|
{
|
|
gedit_debug (DEBUG_PLUGINS);
|
|
|
|
update_ui (GEDIT_SPELL_PLUGIN (activatable));
|
|
}
|
|
|
|
static void
|
|
gedit_window_activatable_iface_init (GeditWindowActivatableInterface *iface)
|
|
{
|
|
iface->activate = gedit_spell_plugin_activate;
|
|
iface->deactivate = gedit_spell_plugin_deactivate;
|
|
iface->update_state = gedit_spell_plugin_update_state;
|
|
}
|
|
|
|
G_MODULE_EXPORT void
|
|
peas_register_types (PeasObjectModule *module)
|
|
{
|
|
gedit_spell_plugin_register_type (G_TYPE_MODULE (module));
|
|
gedit_spell_app_activatable_register (G_TYPE_MODULE (module));
|
|
|
|
peas_object_module_register_extension_type (module,
|
|
GEDIT_TYPE_WINDOW_ACTIVATABLE,
|
|
GEDIT_TYPE_SPELL_PLUGIN);
|
|
peas_object_module_register_extension_type (module,
|
|
PEAS_GTK_TYPE_CONFIGURABLE,
|
|
GEDIT_TYPE_SPELL_PLUGIN);
|
|
}
|
|
|
|
static void
|
|
highlight_button_toggled (GtkToggleButton *button,
|
|
SpellConfigureWidget *widget)
|
|
{
|
|
gboolean status = gtk_toggle_button_get_active (button);
|
|
g_settings_set_boolean(widget->settings, SETTINGS_KEY_HIGHLIGHT_MISSPELLED, status);
|
|
}
|
|
|
|
static void
|
|
configure_widget_destroyed (GtkWidget *widget,
|
|
gpointer data)
|
|
{
|
|
SpellConfigureWidget *conf_widget = (SpellConfigureWidget *)data;
|
|
|
|
gedit_debug (DEBUG_PLUGINS);
|
|
|
|
g_object_unref (conf_widget->settings);
|
|
g_slice_free (SpellConfigureWidget, data);
|
|
|
|
gedit_debug_message (DEBUG_PLUGINS, "END");
|
|
}
|
|
|
|
static SpellConfigureWidget *
|
|
get_configure_widget (GeditSpellPlugin *plugin)
|
|
{
|
|
SpellConfigureWidget *widget;
|
|
GtkBuilder *builder;
|
|
gboolean status;
|
|
const gchar *root_objects[] = {
|
|
"spell_dialog_content",
|
|
NULL
|
|
};
|
|
|
|
gedit_debug (DEBUG_PLUGINS);
|
|
|
|
widget = g_slice_new (SpellConfigureWidget);
|
|
widget->settings = g_object_ref (plugin->priv->settings);
|
|
|
|
builder = gtk_builder_new ();
|
|
gtk_builder_add_objects_from_resource (builder, "/org/gnome/gedit/plugins/spell/ui/gedit-spell-setup-dialog.ui",
|
|
(gchar **)root_objects, NULL);
|
|
widget->content = GTK_WIDGET (gtk_builder_get_object (builder, "spell_dialog_content"));
|
|
g_object_ref (widget->content);
|
|
|
|
widget->highlight_button = GTK_WIDGET (gtk_builder_get_object (builder, "highlight_button"));
|
|
g_object_unref (builder);
|
|
|
|
status = g_settings_get_boolean (widget->settings, SETTINGS_KEY_HIGHLIGHT_MISSPELLED);
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget->highlight_button), status);
|
|
|
|
g_signal_connect (widget->highlight_button,
|
|
"toggled",
|
|
G_CALLBACK (highlight_button_toggled),
|
|
widget);
|
|
|
|
g_signal_connect (widget->content,
|
|
"destroy",
|
|
G_CALLBACK (configure_widget_destroyed),
|
|
widget);
|
|
|
|
return widget;
|
|
}
|
|
|
|
|
|
static GtkWidget *
|
|
gedit_spell_plugin_create_configure_widget (PeasGtkConfigurable *configurable)
|
|
{
|
|
SpellConfigureWidget *widget;
|
|
|
|
widget = get_configure_widget (GEDIT_SPELL_PLUGIN (configurable));
|
|
|
|
return widget->content;
|
|
}
|
|
|
|
static void
|
|
peas_gtk_configurable_iface_init (PeasGtkConfigurableInterface *iface)
|
|
{
|
|
iface->create_configure_widget = gedit_spell_plugin_create_configure_widget;
|
|
}
|
|
|
|
/* ex:set ts=8 noet: */
|