[gnome-builder/wip/slaf/spellcheck: 32/34] spellchecking: inital commit
- From: Sébastien Lafargue <slafargue src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/slaf/spellcheck: 32/34] spellchecking: inital commit
- Date: Wed, 14 Dec 2016 23:01:15 +0000 (UTC)
commit 8ddc1ee0b8bf409300e9d6c113cd993a75ef71b0
Author: Sebastien Lafargue <slafargue gnome org>
Date: Wed Dec 7 21:31:32 2016 +0100
spellchecking: inital commit
contextual menu: Highlighting->spellchecking
Then incorrect words are underlined,
contextual menu on them to show proposals and
options (standard Gspell contextual menu)
configure.ac | 2 +
data/gtk/menus.ui | 4 ++
libide/buffers/ide-buffer.c | 45 ++++++++++++++++++
libide/buffers/ide-buffer.h | 3 +
libide/editor/ide-editor-view-actions.c | 77 +++++++++++++++++++++++++++++++
libide/editor/ide-editor-view.c | 24 ++++++++++
libide/sourceview/ide-source-view.c | 53 +++++++++++++++++++++
libide/sourceview/ide-source-view.h | 3 +
8 files changed, 211 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index a2b2d5a..640409c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -185,6 +185,7 @@ m4_define([libxml_required_version], [2.9.0])
m4_define([pangoft2_required_version], [1.38.0])
m4_define([peas_required_version], [1.18.0])
m4_define([json_glib_required_version], [1.2.0])
+m4_define([gspell_required_version], [1.2.0])
PKG_CHECK_MODULES(EGG, [glib-2.0 >= glib_required_version
gmodule-2.0 >= glib_required_version
@@ -201,6 +202,7 @@ PKG_CHECK_MODULES(LIBIDE, [gio-2.0 >= glib_required_version
gio-unix-2.0 >= glib_required_version
gtk+-3.0 >= gtk_required_version
gtksourceview-3.0 >= gtksourceview_required_version
+ gspell-1 >= gspell_required_version
json-glib-1.0 >= json_glib_required_version
libpeas-1.0 >= peas_required_version
libxml-2.0 >= libxml_required_version
diff --git a/data/gtk/menus.ui b/data/gtk/menus.ui
index 6eefece..f23afd3 100644
--- a/data/gtk/menus.ui
+++ b/data/gtk/menus.ui
@@ -149,6 +149,10 @@
<section id="ide-source-view-popup-menu-highlighting-section">
<submenu id="ide-source-view-popup-menu-highlighting-submenu">
<attribute name="label" translatable="yes">Highlighting</attribute>
+ <item>
+ <attribute name="label" translatable="yes">Spellchecking</attribute>
+ <attribute name="action">view.spellchecking</attribute>
+ </item>
</submenu>
</section>
<section id="ide-source-view-popup-menu-selection-section">
diff --git a/libide/buffers/ide-buffer.c b/libide/buffers/ide-buffer.c
index 15dfd97..bb246d2 100644
--- a/libide/buffers/ide-buffer.c
+++ b/libide/buffers/ide-buffer.c
@@ -21,6 +21,7 @@
#include <egg-counter.h>
#include <egg-signal-group.h>
#include <glib/gi18n.h>
+#include <gspell/gspell.h>
#include "ide-context.h"
#include "ide-debug.h"
@@ -77,6 +78,7 @@ typedef struct
IdeHighlightEngine *highlight_engine;
IdeExtensionAdapter *rename_provider_adapter;
IdeExtensionAdapter *symbol_resolver_adapter;
+ GspellChecker *spellchecker;
gchar *title;
EggSignalGroup *file_signals;
@@ -133,6 +135,48 @@ enum {
static GParamSpec *properties [LAST_PROP];
static guint signals [LAST_SIGNAL];
+void
+ide_buffer_set_spell_checking (IdeBuffer *self,
+ gboolean enable)
+{
+ IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
+ GspellTextBuffer *spell_text_buffer;
+
+ g_return_if_fail (IDE_IS_BUFFER (self));
+
+ if (enable)
+ {
+ if (!GSPELL_IS_CHECKER (priv->spellchecker))
+ {
+ priv->spellchecker = gspell_checker_new (NULL);
+ spell_text_buffer = gspell_text_buffer_get_from_gtk_text_buffer (GTK_TEXT_BUFFER (self));
+ gspell_text_buffer_set_spell_checker (spell_text_buffer, priv->spellchecker);
+ }
+ }
+ else
+ {
+ if (GSPELL_IS_CHECKER (priv->spellchecker))
+ {
+ spell_text_buffer = gspell_text_buffer_get_from_gtk_text_buffer (GTK_TEXT_BUFFER (self));
+ gspell_text_buffer_set_spell_checker (spell_text_buffer, NULL);
+ g_clear_object (&priv->spellchecker);
+ }
+ }
+}
+
+gboolean
+ide_buffer_get_spell_checking (IdeBuffer *self)
+{
+ IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
+
+ g_return_val_if_fail (IDE_IS_BUFFER (self), FALSE);
+
+ /* We keep a ref on the spellchecker because using gspell_text_buffer_get_from_gtk_text_buffer
+ * and gspell_text_buffer_get_spell_checker always return a valid spellchecker
+ */
+ return GSPELL_IS_CHECKER (priv->spellchecker);
+}
+
/**
* ide_buffer_get_has_diagnostics:
* @self: A #IdeBuffer.
@@ -1227,6 +1271,7 @@ ide_buffer_dispose (GObject *object)
g_clear_object (&priv->highlight_engine);
g_clear_object (&priv->rename_provider_adapter);
g_clear_object (&priv->symbol_resolver_adapter);
+ g_clear_object (&priv->spellchecker);
if (priv->context != NULL)
{
diff --git a/libide/buffers/ide-buffer.h b/libide/buffers/ide-buffer.h
index d2c6e07..b596b08 100644
--- a/libide/buffers/ide-buffer.h
+++ b/libide/buffers/ide-buffer.h
@@ -71,6 +71,7 @@ IdeFile *ide_buffer_get_file (IdeBuffer
IdeBufferLineFlags ide_buffer_get_line_flags (IdeBuffer *self,
guint line);
gboolean ide_buffer_get_read_only (IdeBuffer *self);
+gboolean ide_buffer_get_spell_checking (IdeBuffer *self);
gboolean ide_buffer_get_highlight_diagnostics (IdeBuffer *self);
const gchar *ide_buffer_get_style_scheme_name (IdeBuffer *self);
const gchar *ide_buffer_get_title (IdeBuffer *self);
@@ -79,6 +80,8 @@ void ide_buffer_set_file (IdeBuffer
IdeFile *file);
void ide_buffer_set_highlight_diagnostics (IdeBuffer *self,
gboolean highlight_diagnostics);
+void ide_buffer_set_spell_checking (IdeBuffer *self,
+ gboolean enable);
void ide_buffer_set_style_scheme_name (IdeBuffer *self,
const gchar *style_scheme_name);
void ide_buffer_trim_trailing_whitespace (IdeBuffer *self);
diff --git a/libide/editor/ide-editor-view-actions.c b/libide/editor/ide-editor-view-actions.c
index f3de1c9..403f308 100644
--- a/libide/editor/ide-editor-view-actions.c
+++ b/libide/editor/ide-editor-view-actions.c
@@ -31,6 +31,7 @@
#include "editor/ide-editor-view-private.h"
#include "editor/ide-editor-view.h"
#include "projects/ide-project.h"
+#include "sourceview/ide-source-view.h"
#include "util/ide-gtk.h"
#include "util/ide-progress.h"
#include "vcs/ide-vcs.h"
@@ -663,6 +664,80 @@ ide_editor_view_actions_print (GSimpleAction *action,
handle_print_result (self, GTK_PRINT_OPERATION (operation), result);
}
+static void
+activate_spellcheck_cb (GtkWidget *widget,
+ IdeEditorView *self)
+{
+ IdeEditorView *editor_view = (IdeEditorView *)widget;
+ IdeSourceView *original_view;
+ IdeSourceView *dst_view;
+ GtkTextBuffer *original_buffer;
+ GtkTextBuffer *dst_buffer;
+ GActionGroup *group;
+ GAction *action;
+ GVariant *state;
+ gboolean spellcheck_state;
+
+ if (editor_view == self)
+ return;
+
+ original_view = self->frame1->source_view;
+ original_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (original_view));
+ dst_view = editor_view->frame1->source_view;
+ dst_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dst_view));
+
+ if (original_buffer == dst_buffer)
+ {
+ spellcheck_state = ide_source_view_get_spell_checking (original_view);
+ state = g_variant_new_boolean (spellcheck_state);
+
+ if (NULL != (group = gtk_widget_get_action_group (GTK_WIDGET (editor_view), "view")) &&
+ NULL != (action = g_action_map_lookup_action (G_ACTION_MAP (group), "spellchecking")))
+ {
+ g_simple_action_set_state (G_SIMPLE_ACTION (action), state);
+ ide_source_view_set_spell_checking (dst_view, spellcheck_state);
+
+ if (editor_view->frame2)
+ {
+ dst_view = ide_editor_frame_get_source_view (editor_view->frame2);
+ ide_source_view_set_spell_checking (dst_view, spellcheck_state);
+ }
+ }
+ }
+}
+
+static void
+ide_editor_view_actions_spellchecking (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ IdeEditorView *self = user_data;
+ IdeWorkbench *workbench;
+ IdePerspective *editor;
+ IdeSourceView *source_view;
+ gboolean action_state;
+
+ g_assert (IDE_IS_EDITOR_VIEW (self));
+ g_assert (state != NULL);
+ g_assert (g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN));
+
+ g_simple_action_set_state (action, state);
+ action_state = g_variant_get_boolean (state);
+
+ source_view = ide_editor_frame_get_source_view (self->frame1);
+ ide_source_view_set_spell_checking (source_view, action_state);
+
+ if (self->frame2)
+ {
+ source_view = ide_editor_frame_get_source_view (self->frame2);
+ ide_source_view_set_spell_checking (source_view, action_state);
+ }
+
+ workbench = ide_widget_get_workbench (GTK_WIDGET (self));
+ editor = ide_workbench_get_perspective_by_name (workbench, "editor");
+ ide_perspective_views_foreach (IDE_PERSPECTIVE (editor), (GtkCallback)activate_spellcheck_cb, self);
+}
+
static GActionEntry IdeEditorViewActions[] = {
{ "auto-indent", NULL, NULL, "false", ide_editor_view_actions_auto_indent },
{ "close", ide_editor_view_actions_close },
@@ -676,6 +751,7 @@ static GActionEntry IdeEditorViewActions[] = {
{ "show-line-numbers", NULL, NULL, "false", ide_editor_view_actions_show_line_numbers },
{ "show-right-margin", NULL, NULL, "false", ide_editor_view_actions_show_right_margin },
{ "smart-backspace", NULL, NULL, "false", ide_editor_view_actions_smart_backspace },
+ { "spellchecking", NULL, NULL, "false", ide_editor_view_actions_spellchecking },
{ "tab-width", NULL, "i", "8", ide_editor_view_actions_tab_width },
{ "toggle-split", ide_editor_view_actions_toggle_split },
{ "use-spaces", NULL, "b", "false", ide_editor_view_actions_use_spaces },
@@ -689,6 +765,7 @@ ide_editor_view_actions_init (IdeEditorView *self)
group = g_simple_action_group_new ();
g_action_map_add_action_entries (G_ACTION_MAP (group), IdeEditorViewActions,
G_N_ELEMENTS (IdeEditorViewActions), self);
+
gtk_widget_insert_action_group (GTK_WIDGET (self), "view", G_ACTION_GROUP (group));
#define WATCH_PROPERTY(name) \
diff --git a/libide/editor/ide-editor-view.c b/libide/editor/ide-editor-view.c
index 3bf80b2..ebd5a5f 100644
--- a/libide/editor/ide-editor-view.c
+++ b/libide/editor/ide-editor-view.c
@@ -335,6 +335,12 @@ ide_editor_view_create_split (IdeLayoutView *view,
IdeBuffer *buffer;
IdeContext *context;
IdeBufferManager *buf_mgr;
+ IdeSourceView *source_view;
+ IdeSourceView *split_source_view;
+ GActionGroup *group;
+ GAction *action;
+ GVariant *state = NULL;
+ gboolean spellcheck_state;
g_assert (IDE_IS_EDITOR_VIEW (self));
@@ -359,6 +365,19 @@ ide_editor_view_create_split (IdeLayoutView *view,
"visible", TRUE,
NULL);
+ source_view = self->frame1->source_view;
+ spellcheck_state = ide_source_view_get_spell_checking (source_view);
+
+ split_source_view = ((IdeEditorView *)ret)->frame1->source_view;
+ ide_source_view_set_spell_checking (split_source_view, spellcheck_state);
+
+ if (NULL != (group = gtk_widget_get_action_group (GTK_WIDGET (ret), "view")) &&
+ NULL != (action = g_action_map_lookup_action (G_ACTION_MAP (group), "spellchecking")))
+ {
+ state = g_variant_new_boolean (spellcheck_state);
+ g_simple_action_set_state (G_SIMPLE_ACTION (action), state);
+ }
+
return ret;
}
@@ -467,6 +486,7 @@ ide_editor_view_set_split_view (IdeLayoutView *view,
gboolean split_view)
{
IdeEditorView *self = (IdeEditorView *)view;
+ gboolean spellcheck_state;
g_assert (IDE_IS_EDITOR_VIEW (self));
@@ -483,6 +503,10 @@ ide_editor_view_set_split_view (IdeLayoutView *view,
"document", self->document,
"visible", TRUE,
NULL);
+
+ spellcheck_state = ide_source_view_get_spell_checking (self->frame1->source_view);
+ ide_source_view_set_spell_checking (self->frame2->source_view, spellcheck_state);
+
g_signal_connect_object (self->frame2->source_view,
"request-documentation",
G_CALLBACK (ide_editor_view_request_documentation),
diff --git a/libide/sourceview/ide-source-view.c b/libide/sourceview/ide-source-view.c
index 9087f91..695c3a5 100644
--- a/libide/sourceview/ide-source-view.c
+++ b/libide/sourceview/ide-source-view.c
@@ -20,6 +20,7 @@
#include <glib/gi18n.h>
#include <stdlib.h>
+#include <gspell/gspell.h>
#include <egg-animation.h>
#include <egg-binding-group.h>
@@ -185,6 +186,7 @@ typedef struct
guint show_search_shadow : 1;
guint snippet_completion : 1;
guint waiting_for_capture : 1;
+ guint spell_checking : 1;
} IdeSourceViewPrivate;
typedef struct
@@ -231,6 +233,7 @@ enum {
PROP_SHOW_SEARCH_BUBBLES,
PROP_SHOW_SEARCH_SHADOW,
PROP_SNIPPET_COMPLETION,
+ PROP_SPELL_CHECKING,
PROP_OVERSCROLL,
LAST_PROP,
@@ -5787,6 +5790,41 @@ ide_source_view_real_begin_rename (IdeSourceView *self)
IDE_EXIT;
}
+void
+ide_source_view_set_spell_checking (IdeSourceView *self,
+ gboolean enable)
+{
+ IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
+ GspellTextView *spell_text_view;
+
+ g_return_if_fail (IDE_IS_SOURCE_VIEW (self));
+
+ if (priv->spell_checking != enable)
+ {
+ if (IDE_IS_BUFFER (priv->buffer))
+ {
+ spell_text_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (self));
+ gspell_text_view_set_inline_spell_checking (spell_text_view, enable);
+ gspell_text_view_set_enable_language_menu (spell_text_view, enable);
+
+ ide_buffer_set_spell_checking (priv->buffer, enable);
+
+ priv->spell_checking = enable;
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SPELL_CHECKING]);
+ }
+ }
+}
+
+gboolean
+ide_source_view_get_spell_checking (IdeSourceView *self)
+{
+ IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
+
+ g_return_val_if_fail (IDE_IS_SOURCE_VIEW (self), FALSE);
+
+ return priv->spell_checking;
+}
+
static void
ide_source_view_dispose (GObject *object)
{
@@ -5950,6 +5988,10 @@ ide_source_view_get_property (GObject *object,
g_value_set_boolean (value, ide_source_view_get_snippet_completion (self));
break;
+ case PROP_SPELL_CHECKING:
+ g_value_set_boolean (value, ide_source_view_get_spell_checking (self));
+ break;
+
case PROP_OVERSCROLL:
g_value_set_int (value, priv->overscroll_num_lines);
break;
@@ -6051,6 +6093,10 @@ ide_source_view_set_property (GObject *object,
ide_source_view_set_snippet_completion (self, g_value_get_boolean (value));
break;
+ case PROP_SPELL_CHECKING:
+ ide_source_view_set_spell_checking (self, g_value_get_boolean (value));
+ break;
+
case PROP_OVERSCROLL:
ide_source_view_set_overscroll_num_lines (self, g_value_get_int (value));
break;
@@ -6302,6 +6348,13 @@ ide_source_view_class_init (IdeSourceViewClass *klass)
FALSE,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ properties [PROP_SPELL_CHECKING] =
+ g_param_spec_boolean ("spell-checking",
+ "spell-checking",
+ "If spell checking is activated",
+ FALSE,
+ (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
properties [PROP_OVERSCROLL] =
g_param_spec_int ("overscroll",
"Overscroll",
diff --git a/libide/sourceview/ide-source-view.h b/libide/sourceview/ide-source-view.h
index 08e78b8..7ea83c4 100644
--- a/libide/sourceview/ide-source-view.h
+++ b/libide/sourceview/ide-source-view.h
@@ -351,6 +351,7 @@ gboolean ide_source_view_get_show_line_diagnostics (IdeSource
gboolean ide_source_view_get_show_search_bubbles (IdeSourceView *self);
gboolean ide_source_view_get_show_search_shadow (IdeSourceView *self);
gboolean ide_source_view_get_snippet_completion (IdeSourceView *self);
+gboolean ide_source_view_get_spell_checking (IdeSourceView *self);
void ide_source_view_get_visible_rect (IdeSourceView *self,
GdkRectangle
*visible_rect);
void ide_source_view_jump (IdeSourceView *self,
@@ -392,6 +393,8 @@ void ide_source_view_set_show_search_shadow (IdeSource
gboolean
show_search_bubbles);
void ide_source_view_set_snippet_completion (IdeSourceView *self,
gboolean
snippet_completion);
+void ide_source_view_set_spell_checking (IdeSourceView *self,
+ gboolean enable);
void ide_source_view_set_back_forward_list (IdeSourceView *self,
IdeBackForwardList
*back_forward_list);
gboolean ide_source_view_move_mark_onscreen (IdeSourceView *self,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]