Add a new Configure dialog for the Spell Check plugin.

There are three options for autocheck when a doc is loaded:

Always autocheck, Never autocheck and Remember the autocheck setting for each document

The chosen option is stored in the gsettings schema.
The default setting is to remember by document as this is what Pluma did previously.
This commit is contained in:
John Church 2015-11-12 10:45:00 +00:00
parent e357519c94
commit efc6229fce
7 changed files with 483 additions and 16 deletions

View File

@ -403,6 +403,7 @@ plugins/snippets/Makefile
plugins/snippets/snippets/Makefile
plugins/sort/Makefile
plugins/spell/Makefile
plugins/spell/org.mate.pluma.plugins.spell.gschema.xml
plugins/taglist/Makefile
plugins/time/Makefile
plugins/time/org.mate.pluma.plugins.time.gschema.xml

View File

@ -35,7 +35,7 @@ libspell_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
libspell_la_LIBADD = $(PLUMA_LIBS) $(ENCHANT_LIBS)
uidir = $(PLUMA_PLUGINS_DATA_DIR)/spell
ui_DATA = spell-checker.ui languages-dialog.ui
ui_DATA = spell-checker.ui languages-dialog.ui pluma-spell-setup-dialog.ui
pluma-spell-marshal.h: pluma-spell-marshal.list $(GLIB_GENMARSHAL)
$(AM_V_GEN) $(GLIB_GENMARSHAL) $< --header --prefix=pluma_marshal > $@
@ -50,12 +50,19 @@ plugin_in_files = spell.pluma-plugin.desktop.in
plugin_DATA = $(plugin_in_files:.pluma-plugin.desktop.in=.pluma-plugin)
@INTLTOOL_XML_NOMERGE_RULE@
spell_gschema_in = org.mate.pluma.plugins.spell.gschema.xml.in
gsettings_SCHEMAS = $(spell_gschema_in:.xml.in=.xml)
@GSETTINGS_RULES@
EXTRA_DIST = \
$(ui_DATA) \
$(plugin_in_files) \
pluma-spell-marshal.list
pluma-spell-marshal.list \
$(spell_gschema_in)
CLEANFILES = $(BUILT_SOURCES) $(plugin_DATA)
CLEANFILES = $(BUILT_SOURCES) $(plugin_DATA) $(gsettings_SCHEMAS)
dist-hook:
cd $(distdir); rm -f $(BUILT_SOURCES)

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<schemalist gettext-domain="@GETTEXT_PACKAGE@">
<enum id="org.mate.pluma.plugins.spell.AutocheckType">
<value value="0" nick="never"/>
<value value="1" nick="document"/>
<value value="2" nick="always"/>
</enum>
<schema path="/org/mate/pluma/plugins/spell/" id="org.mate.pluma.plugins.spell">
<key name="autocheck-type" enum="org.mate.pluma.plugins.spell.AutocheckType">
<default>'document'</default>
<summary>Autocheck Type</summary>
</key>
</schema>
</schemalist>

View File

@ -33,8 +33,10 @@
#include <gmodule.h>
#include <pluma/pluma-debug.h>
#include <pluma/pluma-help.h>
#include <pluma/pluma-prefs-manager.h>
#include <pluma/pluma-statusbar.h>
#include <pluma/pluma-utils.h>
#include "pluma-spell-checker.h"
#include "pluma-spell-checker-dialog.h"
@ -51,6 +53,10 @@
PLUMA_TYPE_SPELL_PLUGIN, \
PlumaSpellPluginPrivate))
/* GSettings keys */
#define SPELL_SCHEMA "org.mate.pluma.plugins.spell"
#define AUTOCHECK_TYPE_KEY "autocheck-type"
PLUMA_PLUGIN_REGISTER_TYPE(PlumaSpellPlugin, pluma_spell_plugin)
typedef struct
@ -60,6 +66,7 @@ typedef struct
guint message_cid;
gulong tab_added_id;
gulong tab_removed_id;
PlumaSpellPlugin *plugin;
} WindowData;
typedef struct
@ -68,6 +75,11 @@ typedef struct
PlumaWindow *window;
} ActionData;
struct _PlumaSpellPluginPrivate
{
GSettings *settings;
};
static void spell_cb (GtkAction *action, ActionData *action_data);
static void set_language_cb (GtkAction *action, ActionData *action_data);
static void auto_spell_cb (GtkAction *action, PlumaWindow *window);
@ -104,6 +116,26 @@ static const GtkToggleActionEntry toggle_action_entries[] =
}
};
typedef struct _SpellConfigureDialog SpellConfigureDialog;
struct _SpellConfigureDialog
{
GtkWidget *dialog;
GtkWidget *never;
GtkWidget *always;
GtkWidget *document;
PlumaSpellPlugin *plugin;
};
typedef enum
{
AUTOCHECK_NEVER = 0,
AUTOCHECK_DOCUMENT,
AUTOCHECK_ALWAYS
} PlumaSpellPluginAutocheckType;
typedef struct _CheckRange CheckRange;
struct _CheckRange
@ -124,13 +156,21 @@ static void
pluma_spell_plugin_init (PlumaSpellPlugin *plugin)
{
pluma_debug_message (DEBUG_PLUGINS, "PlumaSpellPlugin initializing");
plugin->priv = PLUMA_SPELL_PLUGIN_GET_PRIVATE (plugin);
plugin->priv->settings = g_settings_new (SPELL_SCHEMA);
}
static void
pluma_spell_plugin_finalize (GObject *object)
{
PlumaSpellPlugin *plugin = PLUMA_SPELL_PLUGIN (object);
pluma_debug_message (DEBUG_PLUGINS, "PlumaSpellPlugin finalizing");
g_object_unref (G_OBJECT (plugin->priv->settings));
G_OBJECT_CLASS (pluma_spell_plugin_parent_class)->finalize (object);
}
@ -174,6 +214,32 @@ set_language_from_metadata (PlumaSpellChecker *spell,
}
}
static PlumaSpellPluginAutocheckType
get_autocheck_type (PlumaSpellPlugin *plugin)
{
PlumaSpellPluginAutocheckType autocheck_type;
autocheck_type = g_settings_get_enum (plugin->priv->settings,
AUTOCHECK_TYPE_KEY);
return autocheck_type;
}
static void
set_autocheck_type (PlumaSpellPlugin *plugin,
PlumaSpellPluginAutocheckType autocheck_type)
{
if (!g_settings_is_writable (plugin->priv->settings,
AUTOCHECK_TYPE_KEY))
{
return;
}
g_settings_set_enum (plugin->priv->settings,
AUTOCHECK_TYPE_KEY,
autocheck_type);
}
static PlumaSpellChecker *
get_spell_checker_from_document (PlumaDocument *doc)
{
@ -667,6 +733,156 @@ language_dialog_response (GtkDialog *dlg,
gtk_widget_destroy (GTK_WIDGET (dlg));
}
static SpellConfigureDialog *
get_configure_dialog (PlumaSpellPlugin *plugin)
{
SpellConfigureDialog *dialog = NULL;
gchar *data_dir;
gchar *ui_file;
GtkWidget *content;
PlumaSpellPluginAutocheckType autocheck_type;
GtkWidget *error_widget;
gboolean ret;
gchar *root_objects[] = {
"spell_dialog_content",
NULL
};
pluma_debug (DEBUG_PLUGINS);
GtkWidget *dlg = gtk_dialog_new_with_buttons (_("Configure Spell Checker plugin..."),
NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL,
GTK_STOCK_OK,
GTK_RESPONSE_OK,
GTK_STOCK_HELP,
GTK_RESPONSE_HELP,
NULL);
g_return_val_if_fail (dlg != NULL, NULL);
dialog = g_new0 (SpellConfigureDialog, 1);
dialog->dialog = dlg;
/* HIG defaults */
gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog->dialog)), 5);
gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog->dialog))),
2); /* 2 * 5 + 2 = 12 */
gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_action_area (GTK_DIALOG (dialog->dialog))),
5);
gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dialog->dialog))), 6);
data_dir = pluma_plugin_get_data_dir (PLUMA_PLUGIN (plugin));
ui_file = g_build_filename (data_dir, "pluma-spell-setup-dialog.ui", NULL);
ret = pluma_utils_get_ui_objects (ui_file,
root_objects,
&error_widget,
"spell_dialog_content", &content,
"autocheck_never", &dialog->never,
"autocheck_document", &dialog->document,
"autocheck_always", &dialog->always,
NULL);
g_free (data_dir);
g_free (ui_file);
if (!ret)
{
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog->dialog))),
error_widget, TRUE, TRUE, 0);
gtk_container_set_border_width (GTK_CONTAINER (error_widget), 5);
gtk_widget_show (error_widget);
return dialog;
}
gtk_window_set_resizable (GTK_WINDOW (dialog->dialog), FALSE);
autocheck_type = get_autocheck_type (plugin);
if (autocheck_type == AUTOCHECK_ALWAYS)
{
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->always), TRUE);
}
else if (autocheck_type == AUTOCHECK_DOCUMENT)
{
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->document), TRUE);
}
else
{
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->never), TRUE);
}
gtk_window_set_default_size (GTK_WIDGET (content), 15, 120);
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog->dialog))),
content, FALSE, FALSE, 0);
g_object_unref (content);
gtk_container_set_border_width (GTK_CONTAINER (content), 5);
gtk_dialog_set_default_response (GTK_DIALOG (dialog->dialog),
GTK_RESPONSE_OK);
return dialog;
}
static void
ok_button_pressed (SpellConfigureDialog *dialog)
{
pluma_debug (DEBUG_PLUGINS);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->always)))
{
set_autocheck_type (dialog->plugin, AUTOCHECK_ALWAYS);
}
else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->document)))
{
set_autocheck_type (dialog->plugin, AUTOCHECK_DOCUMENT);
}
else
{
set_autocheck_type (dialog->plugin, AUTOCHECK_NEVER);
}
}
static void
configure_dialog_response_cb (GtkWidget *widget,
gint response,
SpellConfigureDialog *dialog)
{
switch (response)
{
case GTK_RESPONSE_HELP:
{
pluma_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_HELP");
pluma_help_display (GTK_WINDOW (widget),
NULL,
"pluma-spell-checker-plugin");
break;
}
case GTK_RESPONSE_OK:
{
pluma_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_OK");
ok_button_pressed (dialog);
gtk_widget_destroy (dialog->dialog);
break;
}
case GTK_RESPONSE_CANCEL:
{
pluma_debug_message (DEBUG_PLUGINS, "GTK_RESPONSE_CANCEL");
gtk_widget_destroy (dialog->dialog);
}
}
}
static void
set_language_cb (GtkAction *action,
ActionData *action_data)
@ -843,6 +1059,7 @@ auto_spell_cb (GtkAction *action,
PlumaDocument *doc;
gboolean active;
WindowData *data;
pluma_debug (DEBUG_PLUGINS);
@ -854,9 +1071,16 @@ auto_spell_cb (GtkAction *action,
if (doc == NULL)
return;
data = g_object_get_data (G_OBJECT (window),
WINDOW_DATA_KEY);
if (get_autocheck_type(data->plugin) == AUTOCHECK_DOCUMENT)
{
pluma_document_set_metadata (doc,
PLUMA_METADATA_ATTRIBUTE_SPELL_ENABLED,
active ? "1" : NULL, NULL);
}
set_auto_spell (window, doc, active);
}
@ -931,11 +1155,34 @@ set_auto_spell_from_metadata (PlumaWindow *window,
GtkActionGroup *action_group)
{
gboolean active = FALSE;
gchar *active_str;
gchar *active_str = NULL;
PlumaDocument *active_doc;
PlumaSpellPluginAutocheckType autocheck_type;
WindowData *data;
data = g_object_get_data (G_OBJECT (window),
WINDOW_DATA_KEY);
autocheck_type = get_autocheck_type(data->plugin);
switch (autocheck_type)
{
case AUTOCHECK_ALWAYS:
{
active = TRUE;
break;
}
case AUTOCHECK_DOCUMENT:
{
active_str = pluma_document_get_metadata (doc,
PLUMA_METADATA_ATTRIBUTE_SPELL_ENABLED);
break;
}
case AUTOCHECK_NEVER:
default:
active = FALSE;
break;
}
if (active_str)
{
@ -997,6 +1244,7 @@ on_document_saved (PlumaDocument *doc,
PlumaAutomaticSpellChecker *autospell;
PlumaSpellChecker *spell;
const gchar *key;
WindowData *data;
if (error != NULL)
{
@ -1016,12 +1264,26 @@ on_document_saved (PlumaDocument *doc,
key = NULL;
}
data = g_object_get_data (G_OBJECT (window),
WINDOW_DATA_KEY);
if (get_autocheck_type(data->plugin) == AUTOCHECK_DOCUMENT)
{
pluma_document_set_metadata (doc,
PLUMA_METADATA_ATTRIBUTE_SPELL_ENABLED,
autospell != NULL ? "1" : NULL,
PLUMA_METADATA_ATTRIBUTE_SPELL_LANGUAGE,
key,
NULL);
}
else
{
pluma_document_set_metadata (doc,
PLUMA_METADATA_ATTRIBUTE_SPELL_LANGUAGE,
key,
NULL);
}
}
static void
@ -1030,10 +1292,8 @@ tab_added_cb (PlumaWindow *window,
gpointer useless)
{
PlumaDocument *doc;
PlumaView *view;
doc = pluma_tab_get_document (tab);
view = pluma_tab_get_view (tab);
g_signal_connect (doc, "loaded",
G_CALLBACK (on_document_loaded),
@ -1050,10 +1310,8 @@ tab_removed_cb (PlumaWindow *window,
gpointer useless)
{
PlumaDocument *doc;
PlumaView *view;
doc = pluma_tab_get_document (tab);
view = pluma_tab_get_view (tab);
g_signal_handlers_disconnect_by_func (doc, on_document_loaded, window);
g_signal_handlers_disconnect_by_func (doc, on_document_saved, window);
@ -1071,6 +1329,7 @@ impl_activate (PlumaPlugin *plugin,
pluma_debug (DEBUG_PLUGINS);
data = g_slice_new (WindowData);
data->plugin = PLUMA_SPELL_PLUGIN (plugin);
action_data = g_slice_new (ActionData);
action_data->plugin = plugin;
action_data->window = window;
@ -1191,6 +1450,23 @@ impl_update_ui (PlumaPlugin *plugin,
update_ui_real (window, data);
}
static GtkWidget *
impl_create_configure_dialog (PlumaPlugin *plugin)
{
SpellConfigureDialog *dialog;
dialog = get_configure_dialog(PLUMA_SPELL_PLUGIN (plugin));
dialog->plugin = PLUMA_SPELL_PLUGIN (plugin);
g_signal_connect (dialog->dialog,
"response",
G_CALLBACK (configure_dialog_response_cb),
dialog);
return GTK_WIDGET (dialog->dialog);
}
static void
pluma_spell_plugin_class_init (PlumaSpellPluginClass *klass)
{
@ -1203,9 +1479,13 @@ pluma_spell_plugin_class_init (PlumaSpellPluginClass *klass)
plugin_class->deactivate = impl_deactivate;
plugin_class->update_ui = impl_update_ui;
plugin_class->create_configure_dialog = impl_create_configure_dialog;
if (spell_checker_id == 0)
spell_checker_id = g_quark_from_string ("PlumaSpellCheckerID");
if (check_range_id == 0)
check_range_id = g_quark_from_string ("CheckRangeID");
g_type_class_add_private (object_class, sizeof (PlumaSpellPluginPrivate));
}

View File

@ -50,6 +50,8 @@ typedef struct _PlumaSpellPlugin PlumaSpellPlugin;
struct _PlumaSpellPlugin
{
PlumaPlugin parent_instance;
PlumaSpellPluginPrivate *priv;
};
/*

View File

@ -0,0 +1,161 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*- mode: xml -*-->
<interface>
<object class="GtkDialog" id="spell_dialog">
<property name="can_focus">False</property>
<property name="title" translatable="yes">_Configure Spell Checker plugin...</property>
<property name="resizable">False</property>
<property name="type_hint">normal</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">8</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button1">
<property name="label">gtk-help</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button3">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button4">
<property name="label">gtk-ok</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="spell_dialog_content">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Autocheck spelling on document load...</property>
<property name="xalign">0</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="autocheck_never">
<property name="label" translatable="yes">_Never autocheck</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="autocheck_document">
<property name="label" translatable="yes">_Remember autocheck by document</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">autocheck_never</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="autocheck_always">
<property name="label" translatable="yes">_Always autocheck</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">autocheck_never</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="0">button1</action-widget>
<action-widget response="0">button3</action-widget>
<action-widget response="0">button4</action-widget>
</action-widgets>
</object>
</interface>

View File

@ -88,6 +88,7 @@ plugins/snippets/snippets/Placeholder.py
plugins/sort/pluma-sort-plugin.c
plugins/sort/sort.pluma-plugin.desktop.in
[type: gettext/glade]plugins/sort/sort.ui
[type: gettext/gsettings]plugins/spell/org.mate.pluma.plugins.spell.gschema.xml.in
plugins/spell/pluma-automatic-spell-checker.c
plugins/spell/pluma-spell-checker.c
plugins/spell/pluma-spell-checker-dialog.c
@ -96,6 +97,7 @@ plugins/spell/pluma-spell-language-dialog.c
plugins/spell/pluma-spell-plugin.c
[type: gettext/glade]plugins/spell/languages-dialog.ui
[type: gettext/glade]plugins/spell/spell-checker.ui
[type: gettext/glade]plugins/spell/pluma-spell-setup-dialog.ui
plugins/spell/spell.pluma-plugin.desktop.in
plugins/taglist/pluma-taglist-plugin.c
plugins/taglist/pluma-taglist-plugin-panel.c