Merge pull request #146 from sleeveroller/issue90

Add a new Configure dialog for the Spell Check plugin.
This commit is contained in:
monsta 2015-12-03 10:33:57 +03:00
commit 38427b5d6d
7 changed files with 483 additions and 16 deletions

View File

@ -424,6 +424,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,6 +1264,12 @@ 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,
@ -1023,6 +1277,14 @@ on_document_saved (PlumaDocument *doc,
key,
NULL);
}
else
{
pluma_document_set_metadata (doc,
PLUMA_METADATA_ATTRIBUTE_SPELL_LANGUAGE,
key,
NULL);
}
}
static void
tab_added_cb (PlumaWindow *window,
@ -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