diff options
Diffstat (limited to 'plugins/spell')
-rwxr-xr-x | plugins/spell/Makefile.am | 13 | ||||
-rw-r--r-- | plugins/spell/org.mate.pluma.plugins.spell.gschema.xml.in | 14 | ||||
-rwxr-xr-x | plugins/spell/pluma-spell-plugin.c | 306 | ||||
-rwxr-xr-x | plugins/spell/pluma-spell-plugin.h | 2 | ||||
-rw-r--r-- | plugins/spell/pluma-spell-setup-dialog.ui | 161 |
5 files changed, 480 insertions, 16 deletions
diff --git a/plugins/spell/Makefile.am b/plugins/spell/Makefile.am index 7c08bf99..001b25ae 100755 --- a/plugins/spell/Makefile.am +++ b/plugins/spell/Makefile.am @@ -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) diff --git a/plugins/spell/org.mate.pluma.plugins.spell.gschema.xml.in b/plugins/spell/org.mate.pluma.plugins.spell.gschema.xml.in new file mode 100644 index 00000000..d78d58fa --- /dev/null +++ b/plugins/spell/org.mate.pluma.plugins.spell.gschema.xml.in @@ -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> diff --git a/plugins/spell/pluma-spell-plugin.c b/plugins/spell/pluma-spell-plugin.c index 6018621c..b3079bcc 100755 --- a/plugins/spell/pluma-spell-plugin.c +++ b/plugins/spell/pluma-spell-plugin.c @@ -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; - pluma_document_set_metadata (doc, + 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); - active_str = pluma_document_get_metadata (doc, + 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; } - pluma_document_set_metadata (doc, - PLUMA_METADATA_ATTRIBUTE_SPELL_ENABLED, - autospell != NULL ? "1" : NULL, - PLUMA_METADATA_ATTRIBUTE_SPELL_LANGUAGE, - 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)); } diff --git a/plugins/spell/pluma-spell-plugin.h b/plugins/spell/pluma-spell-plugin.h index e78a924e..d2c06252 100755 --- a/plugins/spell/pluma-spell-plugin.h +++ b/plugins/spell/pluma-spell-plugin.h @@ -50,6 +50,8 @@ typedef struct _PlumaSpellPlugin PlumaSpellPlugin; struct _PlumaSpellPlugin { PlumaPlugin parent_instance; + + PlumaSpellPluginPrivate *priv; }; /* diff --git a/plugins/spell/pluma-spell-setup-dialog.ui b/plugins/spell/pluma-spell-setup-dialog.ui new file mode 100644 index 00000000..abc878d4 --- /dev/null +++ b/plugins/spell/pluma-spell-setup-dialog.ui @@ -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> |