[gnome-builder/wip/slaf/spellcheck: 33/34] spellcheck: spell widget



commit 9320c8288bf3ff36c43c72542e0a086109af6064
Author: Sebastien Lafargue <slafargue gnome org>
Date:   Thu Dec 8 19:28:14 2016 +0100

    spellcheck: spell widget

 data/keybindings/default.css             |    1 +
 data/keybindings/emacs.css               |    1 +
 data/keybindings/vim.css                 |    2 +
 data/theme/shared.css                    |   33 +-
 libide/Makefile.am                       |    2 +
 libide/editor/ide-editor-frame-actions.c |   65 +++
 libide/editor/ide-editor-frame-private.h |    7 +
 libide/editor/ide-editor-frame.c         |   21 +
 libide/editor/ide-editor-frame.ui        |  441 ++++++++++----------
 libide/editor/ide-editor-spell-widget.c  |  675 ++++++++++++++++++++++++++++++
 libide/editor/ide-editor-spell-widget.h  |   38 ++
 libide/editor/ide-editor-spell-widget.ui |  310 ++++++++++++++
 libide/ide-types.h                       |    2 +
 libide/resources/libide.gresource.xml    |    1 +
 po/POTFILES.in                           |    1 +
 15 files changed, 1378 insertions(+), 222 deletions(-)
---
diff --git a/data/keybindings/default.css b/data/keybindings/default.css
index 89e2966..d50ad7a 100644
--- a/data/keybindings/default.css
+++ b/data/keybindings/default.css
@@ -8,6 +8,7 @@
                   "clear-count" ()
                   "clear-snippets" ()
                   "hide-completion" () };
+  bind "<shift>F7" { "action" ("frame", "spellcheck", "1") };
   bind "<ctrl>f" { "action" ("frame", "find", "3") };
   bind "<ctrl>o" { "action" ("win", "open-with-dialog", "") };
   bind "<ctrl>s" { "action" ("view", "save", "") };
diff --git a/data/keybindings/emacs.css b/data/keybindings/emacs.css
index 6da5923..7c5cd6f 100644
--- a/data/keybindings/emacs.css
+++ b/data/keybindings/emacs.css
@@ -59,6 +59,7 @@
   bind "<alt>x" { "action" ("win", "show-command-bar", "") };
   bind "<ctrl>r" { "action" ("frame", "find", "2") };
   bind "<ctrl>s" { "action" ("frame", "find", "3") };
+  bind "<alt>dollar" { "action" ("frame", "spellcheck", "1") };
   bind "<alt>period" { "goto-definition" () };
   bind "<alt>n" { "move-error" (down) };
   bind "<alt>p" { "move-error" (up) };
diff --git a/data/keybindings/vim.css b/data/keybindings/vim.css
index 4da8e08..ba433d0 100644
--- a/data/keybindings/vim.css
+++ b/data/keybindings/vim.css
@@ -178,6 +178,8 @@
   /* start search backward */
   bind "question" { "action" ("frame", "find", "2") };
 
+  /* start spell checking */
+  bind "<shift>F7" { "action" ("frame", "spellcheck", "1") };
   /* start search */
   bind "slash" { "action" ("frame", "find", "3") };
   bind "KP_Divide" { "action" ("frame", "find", "3") };
diff --git a/data/theme/shared.css b/data/theme/shared.css
index cbb6d34..64ec952 100644
--- a/data/theme/shared.css
+++ b/data/theme/shared.css
@@ -3,8 +3,8 @@ filechooser actionbar button.combo {
   padding: 0;
 }
 
-/* styling for editor search */
-frame.gb-search-frame {
+/* styling for editor search and spellchecker */
+frame.gb-search-frame, frame.gb-spell-frame {
   background-image: linear-gradient(shade(@theme_bg_color,1.05), @theme_bg_color);
   padding: 6px;
   border-style: solid;
@@ -15,36 +15,51 @@ frame.gb-search-frame {
   border-bottom-left-radius: 5px;
   border-bottom-right-radius: 5px;
 }
-frame.gb-search-frame border {
+frame.gb-search-frame border,
+frame.gb-spell-frame border {
   border: none;
 }
 
-/* styling for the search frame close button */
+frame.gb-spell-frame list {
+  border: 1px solid @borders;
+}
+
+frame.gb-spell-option-frame border {
+  border: 1px solid @borders;
+}
+
+/* styling for the search and spellchecker frame close button */
 frame.gb-search-frame > box > grid:first-child > button.close:disabled,
-frame.gb-search-frame > box > grid:first-child > button.close {
+frame.gb-spell-frame > box > grid:first-child > button.close:disabled,
+frame.gb-search-frame > box > grid:first-child > button.close,
+frame.gb-spell-frame > box > grid:first-child > button.close {
   background: none;
   border: none;
   box-shadow: none;
   padding-left: 4px;
   padding-right: 4px;
 }
-frame.gb-search-frame > box > grid:first-child > button.close image {
+frame.gb-search-frame > box > grid:first-child > button.close image,
+frame.gb-spell-frame > box > grid:first-child > button.close image {
   color: @theme_fg_color;
   opacity: 0.3;
   margin: 2px;
   border: 1px solid transparent;
   border-radius: 3px;
 }
-frame.gb-search-frame > box > grid:first-child > button.close:hover image {
+frame.gb-search-frame > box > grid:first-child > button.close:hover image,
+frame.gb-spell-frame > box > grid:first-child > button.close:hover image {
   opacity: .75;
   transition-duration: 250ms;
   border: 1px solid @borders;
 }
-frame.gb-search-frame > box > grid:first-child > button.close:active image {
+frame.gb-search-frame > box > grid:first-child > button.close:active image,
+frame.gb-spell-frame > box > grid:first-child > button.close:active image {
   opacity: .8;
   background-image: linear-gradient(shade(@theme_bg_color, 0.9), @theme_bg_color);
 }
-frame.gb-search-frame > box > grid:first-child > button.close:backdrop image {
+frame.gb-search-frame > box > grid:first-child > button.close:backdrop image,
+frame.gb-spell-frame > box > grid:first-child > button.close:backdrop image {
   opacity: .1;
 }
 
diff --git a/libide/Makefile.am b/libide/Makefile.am
index 987d890..f841fa7 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -388,6 +388,8 @@ libide_1_0_la_SOURCES =                                   \
        editor/ide-editor-layout-stack-controls.h         \
        editor/ide-editor-print-operation.c               \
        editor/ide-editor-print-operation.h               \
+       editor/ide-editor-spell-widget.c                  \
+       editor/ide-editor-spell-widget.h                  \
        editor/ide-editor-tweak-widget.c                  \
        editor/ide-editor-tweak-widget.h                  \
        editor/ide-editor-view-actions.c                  \
diff --git a/libide/editor/ide-editor-frame-actions.c b/libide/editor/ide-editor-frame-actions.c
index ed0fda8..930862a 100644
--- a/libide/editor/ide-editor-frame-actions.c
+++ b/libide/editor/ide-editor-frame-actions.c
@@ -20,9 +20,61 @@
 
 #include "ide-editor-frame-actions.h"
 #include "ide-editor-frame-private.h"
+#include "ide-editor-spell-widget.h"
 #include "util/ide-gtk.h"
 
 static void
+ide_editor_frame_actions_spellcheck (GSimpleAction *action,
+                                     GVariant      *variant,
+                                     gpointer       user_data)
+{
+  IdeEditorFrame *self = user_data;
+  GtkWidget *spell_widget;
+  GtkWidget *entry;
+
+  g_assert (IDE_IS_EDITOR_FRAME (self));
+
+  if (IDE_IS_SOURCE_VIEW (self->source_view) &&
+      !self->spellchecker_opened)
+    {
+      g_assert (gtk_bin_get_child (GTK_BIN (self->spell_revealer)) == NULL);
+
+      self->spellchecker_opened = TRUE;
+
+      spell_widget = ide_editor_spell_widget_new (self->source_view);
+      gtk_widget_show (spell_widget);
+      gtk_container_add (GTK_CONTAINER (self->spell_revealer), spell_widget);
+
+      gtk_revealer_set_reveal_child (self->spell_revealer, TRUE);
+      entry = ide_editor_spell_widget_get_entry (IDE_EDITOR_SPELL_WIDGET (spell_widget));
+
+      /* We need the widget to be realized before the grab to avoid:
+       * gtk_widget_event: assertion 'WIDGET_REALIZED_FOR_EVENT (widget, event)' failed
+       */
+      gtk_widget_realize (entry);
+      gtk_widget_grab_focus (entry);
+      g_signal_connect_object (spell_widget,
+                               "unmap",
+                               G_CALLBACK (ide_editor_frame_spell_widget_unmapped_cb),
+                               self,
+                               G_CONNECT_SWAPPED | G_CONNECT_AFTER);
+    }
+}
+
+static void
+ide_editor_frame_actions_exit_spell (GSimpleAction *action,
+                                     GVariant      *state,
+                                     gpointer       user_data)
+{
+  IdeEditorFrame *self = user_data;
+
+  g_assert (IDE_IS_EDITOR_FRAME (self));
+
+  printf ("ide_editor_frame_actions_exit_spell\n");
+  gtk_widget_grab_focus (GTK_WIDGET (self->source_view));
+}
+
+static void
 ide_editor_frame_actions_find (GSimpleAction *action,
                               GVariant      *variant,
                               gpointer       user_data)
@@ -204,6 +256,7 @@ ide_editor_frame_actions_toggle_search_options (GSimpleAction *action,
 
   g_assert (IDE_IS_EDITOR_FRAME (self));
 
+  printf ("spellchecking\n");
   visible = !gtk_widget_get_visible (GTK_WIDGET (self->search_options));
 
   gtk_widget_set_visible (GTK_WIDGET (self->search_options), visible);
@@ -389,6 +442,7 @@ static const GActionEntry IdeEditorFrameActions[] = {
   { "next-search-result", ide_editor_frame_actions_next_search_result },
   { "previous-search-result", ide_editor_frame_actions_previous_search_result },
   { "replace-confirm", ide_editor_frame_actions_replace_confirm, "as" },
+  { "spellcheck", ide_editor_frame_actions_spellcheck, "i" },
 };
 
 static const GActionEntry IdeEditorFrameSearchActions[] = {
@@ -404,6 +458,10 @@ static const GActionEntry IdeEditorFrameSearchActions[] = {
   { "replace-all", ide_editor_frame_actions_replace_all },
 };
 
+static const GActionEntry IdeEditorFrameSpellActions[] = {
+  { "exit-spell", ide_editor_frame_actions_exit_spell },
+};
+
 void
 ide_editor_frame_actions_init (IdeEditorFrame *self)
 {
@@ -433,4 +491,11 @@ ide_editor_frame_actions_init (IdeEditorFrame *self)
   gtk_widget_insert_action_group (GTK_WIDGET (self->search_frame), "search-entry", G_ACTION_GROUP (group));
 
   g_object_unref (group);
+
+  group = g_simple_action_group_new ();
+  g_action_map_add_action_entries (G_ACTION_MAP (group), IdeEditorFrameSpellActions,
+                                   G_N_ELEMENTS (IdeEditorFrameSpellActions), self);
+
+  gtk_widget_insert_action_group (GTK_WIDGET (self->spell_revealer), "spell-entry", G_ACTION_GROUP (group));
+  g_object_unref (group);
 }
diff --git a/libide/editor/ide-editor-frame-private.h b/libide/editor/ide-editor-frame-private.h
index 134eb2f..2b07937 100644
--- a/libide/editor/ide-editor-frame-private.h
+++ b/libide/editor/ide-editor-frame-private.h
@@ -23,7 +23,9 @@
 #include <gtk/gtk.h>
 #include <nautilus-floating-bar.h>
 
+#include "ide-types.h"
 #include "editor/ide-editor-map-bin.h"
+#include "ide-editor-spell-widget.h"
 #include "sourceview/ide-source-map.h"
 #include "sourceview/ide-source-view.h"
 
@@ -41,6 +43,7 @@ struct _IdeEditorFrame
   GtkLabel            *overwrite_label;
   GtkScrolledWindow   *scrolled_window;
   GtkRevealer         *search_revealer;
+  GtkRevealer         *spell_revealer;
   GtkFrame            *search_frame;
   GdTaggedEntry       *search_entry;
   GtkSearchEntry      *replace_entry;
@@ -58,8 +61,12 @@ struct _IdeEditorFrame
   guint                pending_replace_confirm;
   guint                auto_hide_map : 1;
   guint                show_ruler : 1;
+  guint                spellchecker_opened : 1;
 };
 
+void      ide_editor_frame_spell_widget_unmapped_cb      (IdeEditorFrame       *self,
+                                                          IdeEditorSpellWidget *spell_widget);
+
 G_END_DECLS
 
 #endif /* IDE_EDITOR_FRAME_PRIVATE_H */
diff --git a/libide/editor/ide-editor-frame.c b/libide/editor/ide-editor-frame.c
index b76a7ad..46d7080 100644
--- a/libide/editor/ide-editor-frame.c
+++ b/libide/editor/ide-editor-frame.c
@@ -29,6 +29,7 @@
 #include "editor/ide-editor-frame.h"
 #include "editor/ide-editor-map-bin.h"
 #include "editor/ide-editor-perspective.h"
+#include "editor/ide-editor-spell-widget.h"
 #include "history/ide-back-forward-list.h"
 #include "util/ide-dnd.h"
 #include "util/ide-gtk.h"
@@ -56,6 +57,24 @@ enum {
 
 static GParamSpec *properties [LAST_PROP];
 
+void
+ide_editor_frame_spell_widget_unmapped_cb (IdeEditorFrame       *self,
+                                           IdeEditorSpellWidget *spell_widget)
+{
+  GtkWidget *child;
+
+  g_assert (IDE_IS_EDITOR_FRAME (self));
+  g_assert (IDE_IS_EDITOR_SPELL_WIDGET (spell_widget));
+
+  printf ("ide_editor_frame_spell_widget_unmapped_cb\n");
+  if (NULL != (child = gtk_bin_get_child (GTK_BIN (self->spell_revealer))))
+    {
+      gtk_container_remove (GTK_CONTAINER (self->spell_revealer), child);
+      self->spellchecker_opened = FALSE;
+      printf ("spellchecker unmapped\n");
+    }
+}
+
 static void
 update_replace_actions_sensitivity (IdeEditorFrame *self)
 {
@@ -845,6 +864,7 @@ ide_editor_frame__source_view_focus_in_event (IdeEditorFrame *self,
   g_assert (IDE_IS_SOURCE_VIEW (source_view));
 
   gtk_revealer_set_reveal_child (self->search_revealer, FALSE);
+  gtk_revealer_set_reveal_child (self->spell_revealer, FALSE);
 
   buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (source_view));
 
@@ -1201,6 +1221,7 @@ ide_editor_frame_class_init (IdeEditorFrameClass *klass)
   gtk_widget_class_bind_template_child (widget_class, IdeEditorFrame, replace_all_button);
   gtk_widget_class_bind_template_child (widget_class, IdeEditorFrame, search_options);
   gtk_widget_class_bind_template_child (widget_class, IdeEditorFrame, search_revealer);
+  gtk_widget_class_bind_template_child (widget_class, IdeEditorFrame, spell_revealer);
   gtk_widget_class_bind_template_child (widget_class, IdeEditorFrame, source_map_container);
   gtk_widget_class_bind_template_child (widget_class, IdeEditorFrame, source_overlay);
   gtk_widget_class_bind_template_child (widget_class, IdeEditorFrame, source_view);
diff --git a/libide/editor/ide-editor-frame.ui b/libide/editor/ide-editor-frame.ui
index 0d14976..07609b8 100644
--- a/libide/editor/ide-editor-frame.ui
+++ b/libide/editor/ide-editor-frame.ui
@@ -45,290 +45,305 @@
                 <property name="expand">true</property>
                 <property name="visible">true</property>
                 <child type="overlay">
-                  <object class="GtkRevealer" id="search_revealer">
+                  <object class="GtkBox" id="revealer_box">
+                    <property name="orientation">vertical</property>
                     <property name="halign">end</property>
                     <property name="valign">start</property>
                     <property name="visible">true</property>
                     <child>
-                      <object class="GtkFrame" id="search_frame">
+                      <object class="GtkRevealer" id="search_revealer">
+                        <property name="halign">end</property>
+                        <property name="valign">start</property>
                         <property name="visible">true</property>
-                        <property name="margin-end">12</property>
-                        <style>
-                          <class name="gb-search-frame"/>
-                        </style>
                         <child>
-                          <object class="GtkBox">
+                          <object class="GtkFrame" id="search_frame">
                             <property name="visible">true</property>
-                            <property name="orientation">vertical</property>
-                            <property name="spacing">7</property>
+                            <property name="margin-end">12</property>
+                            <style>
+                              <class name="gb-search-frame"/>
+                            </style>
                             <child>
-                              <object class="GtkGrid">
+                              <object class="GtkBox">
                                 <property name="visible">true</property>
-                                <property name="can_focus">false</property>
-                                <property name="row_spacing">8</property>
-                                <property name="column_spacing">8</property>
+                                <property name="orientation">vertical</property>
+                                <property name="spacing">7</property>
                                 <child>
-                                  <object class="GdTaggedEntry" id="search_entry">
-                                    <property name="visible">true</property>
-                                    <property name="tag-close-visible">false</property>
-                                    <property name="can_focus">true</property>
-                                    <property name="width-chars">20</property>
-                                    <property name="max-width-chars">30</property>
-                                    <property name="primary_icon_name">edit-find-symbolic</property>
-                                    <property name="primary_icon_activatable">false</property>
-                                    <property name="primary_icon_sensitive">false</property>
-                                  </object>
-                                  <packing>
-                                    <property name="left_attach">0</property>
-                                    <property name="top_attach">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkSearchEntry" id="replace_entry">
-                                    <property name="visible">false</property>
-                                    <property name="can_focus">true</property>
-                                    <property name="width-chars">20</property>
-                                    <property name="max-width-chars">30</property>
-                                    <property name="primary_icon_name">edit-find-replace-symbolic</property>
-                                    <property name="primary_icon_activatable">false</property>
-                                    <property name="primary_icon_sensitive">false</property>
-                                  </object>
-                                  <packing>
-                                    <property name="left_attach">0</property>
-                                    <property name="top_attach">1</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkBox">
-                                    <property name="homogeneous">true</property>
+                                  <object class="GtkGrid">
                                     <property name="visible">true</property>
                                     <property name="can_focus">false</property>
-                                    <property name="valign">center</property>
-                                    <style>
-                                      <class name="linked"/>
-                                    </style>
+                                    <property name="row_spacing">8</property>
+                                    <property name="column_spacing">8</property>
                                     <child>
-                                      <object class="GtkButton">
-                                        <property name="action-name">frame.previous-search-result</property>
+                                      <object class="GdTaggedEntry" id="search_entry">
                                         <property name="visible">true</property>
-                                        <property name="can_focus">false</property>
-                                        <property name="receives_default">true</property>
-                                        <child>
-                                          <object class="GtkImage">
-                                            <property name="visible">true</property>
-                                            <property name="can_focus">false</property>
-                                            <property name="icon_name">go-up-symbolic</property>
-                                            <property name="icon_size">1</property>
-                                          </object>
-                                        </child>
+                                        <property name="tag-close-visible">false</property>
+                                        <property name="can_focus">true</property>
+                                        <property name="width-chars">20</property>
+                                        <property name="max-width-chars">30</property>
+                                        <property name="primary_icon_name">edit-find-symbolic</property>
+                                        <property name="primary_icon_activatable">false</property>
+                                        <property name="primary_icon_sensitive">false</property>
+                                      </object>
+                                      <packing>
+                                        <property name="left_attach">0</property>
+                                        <property name="top_attach">0</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkSearchEntry" id="replace_entry">
+                                        <property name="visible">false</property>
+                                        <property name="can_focus">true</property>
+                                        <property name="width-chars">20</property>
+                                        <property name="max-width-chars">30</property>
+                                        <property 
name="primary_icon_name">edit-find-replace-symbolic</property>
+                                        <property name="primary_icon_activatable">false</property>
+                                        <property name="primary_icon_sensitive">false</property>
                                       </object>
                                       <packing>
-                                        <property name="expand">false</property>
-                                        <property name="fill">true</property>
-                                        <property name="position">0</property>
+                                        <property name="left_attach">0</property>
+                                        <property name="top_attach">1</property>
                                       </packing>
                                     </child>
                                     <child>
-                                      <object class="GtkButton">
-                                        <property name="action-name">frame.next-search-result</property>
+                                      <object class="GtkBox">
+                                        <property name="homogeneous">true</property>
                                         <property name="visible">true</property>
                                         <property name="can_focus">false</property>
-                                        <property name="receives_default">true</property>
+                                        <property name="valign">center</property>
+                                        <style>
+                                          <class name="linked"/>
+                                        </style>
                                         <child>
-                                          <object class="GtkImage">
+                                          <object class="GtkButton">
+                                            <property 
name="action-name">frame.previous-search-result</property>
                                             <property name="visible">true</property>
                                             <property name="can_focus">false</property>
-                                            <property name="icon_name">go-down-symbolic</property>
-                                            <property name="icon_size">1</property>
+                                            <property name="receives_default">true</property>
+                                            <child>
+                                              <object class="GtkImage">
+                                                <property name="visible">true</property>
+                                                <property name="can_focus">false</property>
+                                                <property name="icon_name">go-up-symbolic</property>
+                                                <property name="icon_size">1</property>
+                                              </object>
+                                            </child>
                                           </object>
+                                          <packing>
+                                            <property name="expand">false</property>
+                                            <property name="fill">true</property>
+                                            <property name="position">0</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkButton">
+                                            <property name="action-name">frame.next-search-result</property>
+                                            <property name="visible">true</property>
+                                            <property name="can_focus">false</property>
+                                            <property name="receives_default">true</property>
+                                            <child>
+                                              <object class="GtkImage">
+                                                <property name="visible">true</property>
+                                                <property name="can_focus">false</property>
+                                                <property name="icon_name">go-down-symbolic</property>
+                                                <property name="icon_size">1</property>
+                                              </object>
+                                            </child>
+                                          </object>
+                                          <packing>
+                                            <property name="expand">false</property>
+                                            <property name="fill">true</property>
+                                            <property name="position">1</property>
+                                          </packing>
                                         </child>
                                       </object>
                                       <packing>
-                                        <property name="expand">false</property>
-                                        <property name="fill">true</property>
-                                        <property name="position">1</property>
+                                        <property name="left_attach">1</property>
+                                        <property name="top_attach">0</property>
                                       </packing>
                                     </child>
-                                  </object>
-                                  <packing>
-                                    <property name="left_attach">1</property>
-                                    <property name="top_attach">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkButton" id="replace_button">
-                                    <property name="label" translatable="yes">Replace</property>
-                                    <property name="action-name">search-entry.replace</property>
-                                    <property name="visible">false</property>
-                                    <property name="can_focus">true</property>
-                                    <property name="receives_default">true</property>
-                                  </object>
-                                  <packing>
-                                    <property name="left_attach">1</property>
-                                    <property name="top_attach">1</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkButton" id="replace_all_button">
-                                    <property name="label" translatable="yes">Replace All</property>
-                                    <property name="action-name">search-entry.replace-all</property>
-                                    <property name="visible">false</property>
-                                    <property name="can_focus">true</property>
-                                    <property name="receives_default">true</property>
-                                  </object>
-                                  <packing>
-                                    <property name="left_attach">2</property>
-                                    <property name="top_attach">1</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkBox">
-                                    <property name="homogeneous">true</property>
-                                    <property name="visible">true</property>
-                                    <property name="can_focus">false</property>
-                                    <property name="valign">center</property>
-                                    <property name="spacing">8</property>
                                     <child>
-                                      <object class="GtkToggleButton">
-                                        <property 
name="action-name">search-entry.toggle-search-replace</property>
-                                        <property name="action-target">true</property>
-                                        <property name="tooltip-text" translatable="yes">Switch between 
Search and Search-and-Replace</property>
-                                        <property name="visible">true</property>
+                                      <object class="GtkButton" id="replace_button">
+                                        <property name="label" translatable="yes">Replace</property>
+                                        <property name="action-name">search-entry.replace</property>
+                                        <property name="visible">false</property>
                                         <property name="can_focus">true</property>
                                         <property name="receives_default">true</property>
-                                        <property name="image_position">right</property>
+                                      </object>
+                                      <packing>
+                                        <property name="left_attach">1</property>
+                                        <property name="top_attach">1</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkButton" id="replace_all_button">
+                                        <property name="label" translatable="yes">Replace All</property>
+                                        <property name="action-name">search-entry.replace-all</property>
+                                        <property name="visible">false</property>
+                                        <property name="can_focus">true</property>
+                                        <property name="receives_default">true</property>
+                                      </object>
+                                      <packing>
+                                        <property name="left_attach">2</property>
+                                        <property name="top_attach">1</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkBox">
+                                        <property name="homogeneous">true</property>
+                                        <property name="visible">true</property>
+                                        <property name="can_focus">false</property>
+                                        <property name="valign">center</property>
+                                        <property name="spacing">8</property>
                                         <child>
-                                          <object class="GtkImage">
+                                          <object class="GtkToggleButton">
+                                            <property 
name="action-name">search-entry.toggle-search-replace</property>
+                                            <property name="action-target">true</property>
+                                            <property name="tooltip-text" translatable="yes">Switch between 
Search and Search-and-Replace</property>
                                             <property name="visible">true</property>
-                                            <property name="can_focus">false</property>
-                                            <property name="icon_name">edit-find-replace-symbolic</property>
+                                            <property name="can_focus">true</property>
+                                            <property name="receives_default">true</property>
+                                            <property name="image_position">right</property>
+                                            <child>
+                                              <object class="GtkImage">
+                                                <property name="visible">true</property>
+                                                <property name="can_focus">false</property>
+                                                <property 
name="icon_name">edit-find-replace-symbolic</property>
+                                              </object>
+                                            </child>
+                                          </object>
+                                          <packing>
+                                            <property name="expand">false</property>
+                                            <property name="fill">true</property>
+                                            <property name="position">0</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkToggleButton">
+                                            <property 
name="action-name">search-entry.toggle-search-options</property>
+                                            <property name="action-target">true</property>
+                                            <property name="tooltip-text" translatable="yes">Show or hide 
search options such as case sensitivity</property>
+                                            <property name="visible">true</property>
+                                            <property name="can_focus">true</property>
+                                            <property name="receives_default">true</property>
+                                            <child>
+                                              <object class="GtkImage">
+                                                <property name="visible">true</property>
+                                                <property name="can_focus">false</property>
+                                                <property name="icon_name">emblem-system-symbolic</property>
+                                              </object>
+                                            </child>
                                           </object>
+                                          <packing>
+                                            <property name="expand">false</property>
+                                            <property name="fill">true</property>
+                                            <property name="position">1</property>
+                                          </packing>
                                         </child>
                                       </object>
                                       <packing>
-                                        <property name="expand">false</property>
-                                        <property name="fill">true</property>
-                                        <property name="position">0</property>
+                                        <property name="left_attach">2</property>
+                                        <property name="top_attach">0</property>
                                       </packing>
                                     </child>
                                     <child>
-                                      <object class="GtkToggleButton">
-                                        <property 
name="action-name">search-entry.toggle-search-options</property>
-                                        <property name="action-target">true</property>
-                                        <property name="tooltip-text" translatable="yes">Show or hide search 
options such as case sensitivity</property>
+                                      <object class="GtkButton" id="close_button">
                                         <property name="visible">true</property>
-                                        <property name="can_focus">true</property>
-                                        <property name="receives_default">true</property>
+                                        <property name="action-name">search-entry.exit-search</property>
+                                        <property name="halign">center</property>
+                                        <property name="valign">center</property>
+                                        <property name="focus_on_click">false</property>
+                                        <style>
+                                          <class name="close"/>
+                                        </style>
                                         <child>
                                           <object class="GtkImage">
                                             <property name="visible">true</property>
-                                            <property name="can_focus">false</property>
-                                            <property name="icon_name">emblem-system-symbolic</property>
+                                            <property name="icon_name">window-close-symbolic</property>
                                           </object>
                                         </child>
                                       </object>
                                       <packing>
-                                        <property name="expand">false</property>
-                                        <property name="fill">true</property>
-                                        <property name="position">1</property>
+                                        <property name="left_attach">4</property>
+                                        <property name="top_attach">0</property>
                                       </packing>
                                     </child>
                                   </object>
                                   <packing>
-                                    <property name="left_attach">2</property>
-                                    <property name="top_attach">0</property>
+                                    <property name="expand">false</property>
+                                    <property name="fill">true</property>
+                                    <property name="position">0</property>
                                   </packing>
                                 </child>
                                 <child>
-                                  <object class="GtkButton" id="close_button">
-                                    <property name="visible">true</property>
-                                    <property name="action-name">search-entry.exit-search</property>
-                                    <property name="halign">center</property>
-                                    <property name="valign">center</property>
-                                    <property name="focus_on_click">false</property>
-                                    <style>
-                                      <class name="close"/>
-                                    </style>
+                                  <object class="GtkGrid" id="search_options">
+                                    <property name="visible">false</property>
+                                    <property name="can_focus">false</property>
+                                    <property name="column_spacing">8</property>
                                     <child>
-                                      <object class="GtkImage">
+                                      <object class="GtkCheckButton" id="use_regex">
+                                        <property 
name="action-name">search-entry.change-regex-enabled</property>
+                                        <property name="label" translatable="yes">Regular 
expressions</property>
                                         <property name="visible">true</property>
-                                        <property name="icon_name">window-close-symbolic</property>
+                                        <property name="can_focus">false</property>
+                                        <property name="receives_default">false</property>
+                                        <property name="xalign">0</property>
+                                        <property name="draw_indicator">true</property>
                                       </object>
+                                      <packing>
+                                        <property name="left_attach">0</property>
+                                        <property name="top_attach">0</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkCheckButton" id="case_sensitive">
+                                        <property 
name="action-name">search-entry.change-case-sensitive</property>
+                                        <property name="label" translatable="yes">Case sensitive</property>
+                                        <property name="visible">true</property>
+                                        <property name="can_focus">false</property>
+                                        <property name="receives_default">false</property>
+                                        <property name="xalign">0</property>
+                                        <property name="draw_indicator">true</property>
+                                      </object>
+                                      <packing>
+                                        <property name="left_attach">1</property>
+                                        <property name="top_attach">0</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkCheckButton" id="whole_word">
+                                        <property 
name="action-name">search-entry.change-word-boundaries</property>
+                                        <property name="label" translatable="yes">Match whole word 
only</property>
+                                        <property name="visible">true</property>
+                                        <property name="can_focus">false</property>
+                                        <property name="receives_default">false</property>
+                                        <property name="xalign">0</property>
+                                        <property name="draw_indicator">true</property>
+                                      </object>
+                                      <packing>
+                                        <property name="left_attach">2</property>
+                                        <property name="top_attach">0</property>
+                                      </packing>
                                     </child>
                                   </object>
                                   <packing>
-                                    <property name="left_attach">4</property>
-                                    <property name="top_attach">0</property>
-                                  </packing>
-                                </child>
-                              </object>
-                              <packing>
-                                <property name="expand">false</property>
-                                <property name="fill">true</property>
-                                <property name="position">0</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkGrid" id="search_options">
-                                <property name="visible">false</property>
-                                <property name="can_focus">false</property>
-                                <property name="column_spacing">8</property>
-                                <child>
-                                  <object class="GtkCheckButton" id="use_regex">
-                                    <property name="action-name">search-entry.change-regex-enabled</property>
-                                    <property name="label" translatable="yes">Regular expressions</property>
-                                    <property name="visible">true</property>
-                                    <property name="can_focus">false</property>
-                                    <property name="receives_default">false</property>
-                                    <property name="xalign">0</property>
-                                    <property name="draw_indicator">true</property>
-                                  </object>
-                                  <packing>
-                                    <property name="left_attach">0</property>
-                                    <property name="top_attach">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="case_sensitive">
-                                    <property 
name="action-name">search-entry.change-case-sensitive</property>
-                                    <property name="label" translatable="yes">Case sensitive</property>
-                                    <property name="visible">true</property>
-                                    <property name="can_focus">false</property>
-                                    <property name="receives_default">false</property>
-                                    <property name="xalign">0</property>
-                                    <property name="draw_indicator">true</property>
-                                  </object>
-                                  <packing>
-                                    <property name="left_attach">1</property>
-                                    <property name="top_attach">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="whole_word">
-                                    <property 
name="action-name">search-entry.change-word-boundaries</property>
-                                    <property name="label" translatable="yes">Match whole word 
only</property>
-                                    <property name="visible">true</property>
-                                    <property name="can_focus">false</property>
-                                    <property name="receives_default">false</property>
-                                    <property name="xalign">0</property>
-                                    <property name="draw_indicator">true</property>
-                                  </object>
-                                  <packing>
-                                    <property name="left_attach">2</property>
-                                    <property name="top_attach">0</property>
+                                    <property name="expand">false</property>
+                                    <property name="fill">true</property>
+                                    <property name="position">1</property>
                                   </packing>
                                 </child>
                               </object>
-                              <packing>
-                                <property name="expand">false</property>
-                                <property name="fill">true</property>
-                                <property name="position">1</property>
-                              </packing>
                             </child>
                           </object>
                         </child>
                       </object>
                     </child>
+                    <child>
+                      <object class="GtkRevealer" id="spell_revealer">
+                        <property name="halign">end</property>
+                        <property name="valign">start</property>
+                        <property name="visible">true</property>
+                      </object>
+                    </child>
                   </object>
                 </child>
                 <child>
diff --git a/libide/editor/ide-editor-spell-widget.c b/libide/editor/ide-editor-spell-widget.c
new file mode 100644
index 0000000..2f02f39
--- /dev/null
+++ b/libide/editor/ide-editor-spell-widget.c
@@ -0,0 +1,675 @@
+/* ide-editor-spell-widget.c
+ *
+ * Copyright (C) 2016 Sebastien Lafargue <slafargue gnome org>
+ *
+ * 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 3 of the License, 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 "ide.h"
+
+#include <glib/gi18n.h>
+#include <gspell/gspell.h>
+
+#include "ide-editor-spell-widget.h"
+
+struct _IdeEditorSpellWidget
+{
+  GtkBin                 parent_instance;
+
+  GspellNavigator       *navigator;
+  IdeSourceView         *view;
+  IdeBuffer             *buffer;
+  GspellChecker         *checker;
+  const GspellLanguage  *spellchecker_language;
+
+  GtkLabel              *word_label;
+  GtkEntry              *word_entry;
+  GtkButton             *check_button;
+  GtkButton             *add_dict_button;
+  GtkButton             *ignore_button;
+  GtkButton             *ignore_all_button;
+  GtkButton             *change_button;
+  GtkButton             *change_all_button;
+  GtkButton             *close_button;
+  GtkListBox            *suggestions_box;
+
+  GtkButton             *highlight_checkbutton;
+  GtkButton             *language_chooser_button;
+
+  GtkWidget             *placeholder;
+  GAction               *view_spellchecking_action;
+
+  guint                  view_spellchecker_set : 1;
+};
+
+G_DEFINE_TYPE (IdeEditorSpellWidget, ide_editor_spell_widget, GTK_TYPE_BIN)
+
+enum {
+  PROP_0,
+  PROP_VIEW,
+  N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+clear_suggestions_box (IdeEditorSpellWidget *self)
+{
+  GList *children;
+
+  children = gtk_container_get_children (GTK_CONTAINER (self->suggestions_box));
+
+  for (GList *l = children; l != NULL; l = g_list_next (l))
+    gtk_widget_destroy (GTK_WIDGET (l->data));
+}
+
+static void
+set_sensiblility (IdeEditorSpellWidget *self,
+                  gboolean              sensibility)
+{
+  g_assert (IDE_IS_EDITOR_SPELL_WIDGET (self));
+
+  gtk_entry_set_text (self->word_entry, "");
+  clear_suggestions_box (self);
+
+  gtk_widget_set_sensitive (GTK_WIDGET (self->word_entry), sensibility);
+  gtk_widget_set_sensitive (GTK_WIDGET (self->check_button), sensibility);
+  gtk_widget_set_sensitive (GTK_WIDGET (self->ignore_button), sensibility);
+  gtk_widget_set_sensitive (GTK_WIDGET (self->ignore_all_button), sensibility);
+  gtk_widget_set_sensitive (GTK_WIDGET (self->change_button), sensibility);
+  gtk_widget_set_sensitive (GTK_WIDGET (self->change_all_button), sensibility);
+  gtk_widget_set_sensitive (GTK_WIDGET (self->add_dict_button), sensibility);
+  gtk_widget_set_sensitive (GTK_WIDGET (self->suggestions_box), sensibility);
+}
+
+GtkWidget *
+ide_editor_spell_widget_get_entry (IdeEditorSpellWidget *self)
+{
+  return GTK_WIDGET (self->word_entry);
+}
+
+static GtkWidget *
+create_suggestion_row (IdeEditorSpellWidget *self,
+                       const gchar          *word)
+{
+  GtkWidget *row;
+
+  g_assert (IDE_IS_EDITOR_SPELL_WIDGET (self));
+
+  row = g_object_new (GTK_TYPE_LABEL,
+                      "label", word,
+                      "visible", TRUE,
+                      "halign", GTK_ALIGN_START,
+                      NULL);
+
+  return row;
+}
+
+static void
+fill_suggestions_box (IdeEditorSpellWidget *self,
+                      const gchar          *word,
+                      gchar               **first_result)
+{
+  GSList *suggestions = NULL;
+  GtkWidget *item;
+
+  g_assert (IDE_IS_EDITOR_SPELL_WIDGET (self));
+
+  clear_suggestions_box (self);
+  if (ide_str_empty0 (word))
+    {
+      gtk_widget_set_sensitive (GTK_WIDGET (self->suggestions_box), FALSE);
+      return;
+    }
+
+  if (NULL == (suggestions = gspell_checker_get_suggestions (self->checker, word, -1)))
+    {
+      *first_result = NULL;
+      gtk_widget_set_sensitive (GTK_WIDGET (self->suggestions_box), FALSE);
+    }
+  else
+    {
+      *first_result = g_strdup (suggestions->data);
+      gtk_widget_set_sensitive (GTK_WIDGET (self->suggestions_box), TRUE);
+      for (GSList *l = (GSList *)suggestions; l != NULL; l = l->next)
+        {
+          item = create_suggestion_row (self, l->data);
+          gtk_list_box_insert (self->suggestions_box, item, -1);
+        }
+
+      g_slist_free_full (suggestions, g_free);
+    }
+}
+
+static gboolean
+jump_to_next_misspelled_word (IdeEditorSpellWidget *self)
+{
+  GspellChecker *checker = NULL;
+  g_autofree gchar *word = NULL;
+  g_autofree gchar *first_result = NULL;
+  GtkListBoxRow *row;
+  GError *error = NULL;
+  gboolean ret = FALSE;
+
+  g_assert (IDE_IS_EDITOR_SPELL_WIDGET (self));
+
+  gtk_widget_grab_focus (GTK_WIDGET (self->word_entry));
+  if ((ret = gspell_navigator_goto_next (self->navigator, &word, &checker, &error)))
+    {
+      gtk_label_set_text (self->word_label, word);
+      fill_suggestions_box (self, word, &first_result);
+      if (!ide_str_empty0 (first_result))
+        {
+          row = gtk_list_box_get_row_at_index (self->suggestions_box, 0);
+          gtk_list_box_select_row (self->suggestions_box, row);
+        }
+    }
+  else
+    {
+      if (error != NULL)
+        gtk_label_set_text (GTK_LABEL (self->placeholder), error->message);
+      else
+        {
+          gtk_label_set_text (GTK_LABEL (self->placeholder), _("Completed spell checking"));
+          set_sensiblility (self, FALSE);
+        }
+    }
+
+  return ret;
+}
+
+GtkWidget *
+ide_editor_spell_widget_new (IdeSourceView *source_view)
+{
+  return g_object_new (IDE_TYPE_EDITOR_SPELL_WIDGET,
+                       "view", source_view,
+                       NULL);
+}
+
+static IdeSourceView *
+ide_editor_spell_widget_get_view (IdeEditorSpellWidget *self)
+{
+  g_return_val_if_fail (IDE_IS_EDITOR_SPELL_WIDGET (self), NULL);
+
+  return self->view;
+}
+
+static void
+ide_editor_spell_widget_set_view (IdeEditorSpellWidget *self,
+                                  IdeSourceView        *view)
+{
+  g_return_if_fail (IDE_IS_EDITOR_SPELL_WIDGET (self));
+  g_return_if_fail (IDE_IS_SOURCE_VIEW (view));
+
+  self->view = view;
+  if (GSPELL_IS_NAVIGATOR (self->navigator))
+    g_clear_object (&self->navigator);
+
+  self->navigator = gspell_navigator_text_view_new (GTK_TEXT_VIEW (view));
+}
+
+static void
+ide_editor_spell_widget__word_entry_changed_cb (IdeEditorSpellWidget *self,
+                                                GtkEntry             *entry)
+{
+  gboolean sensitive;
+
+  g_assert (IDE_IS_EDITOR_SPELL_WIDGET (self));
+  g_assert (GTK_IS_ENTRY (entry));
+
+  sensitive = (gtk_entry_get_text_length (entry) > 0);
+
+  gtk_widget_set_sensitive (GTK_WIDGET (self->check_button), sensitive);
+  gtk_widget_set_sensitive (GTK_WIDGET (self->change_button), sensitive);
+  gtk_widget_set_sensitive (GTK_WIDGET (self->change_all_button), sensitive);
+}
+
+static void
+ide_editor_spell_widget__check_button_clicked_cb (IdeEditorSpellWidget *self,
+                                                  GtkButton            *button)
+{
+  const gchar *word;
+  g_autofree gchar *first_result = NULL;
+  GError *error = NULL;
+  gboolean ret = FALSE;
+
+  g_assert (IDE_IS_EDITOR_SPELL_WIDGET (self));
+  g_assert (GTK_IS_BUTTON (button));
+
+  word = gtk_entry_get_text (self->word_entry);
+  g_assert (!ide_str_empty0 (word));
+
+  ret = gspell_checker_check_word (self->checker, word, -1, &error);
+  if (error != NULL)
+    {
+      printf ("check error:%s\n", error->message);
+    }
+
+  if (ret)
+    {
+      gtk_label_set_text (GTK_LABEL (self->placeholder), _("Correct spelling"));
+      fill_suggestions_box (self, NULL, NULL);
+    }
+  else
+    {
+      fill_suggestions_box (self, word, &first_result);
+      if (!ide_str_empty0 (first_result))
+        gtk_entry_set_text (self->word_entry, first_result);
+      else
+        gtk_label_set_text (GTK_LABEL (self->placeholder), _("No suggestioons"));
+    }
+}
+
+static void
+ide_editor_spell_widget__add_dict_button_clicked_cb (IdeEditorSpellWidget *self,
+                                                     GtkButton            *button)
+{
+  const gchar *word;
+
+  g_assert (IDE_IS_EDITOR_SPELL_WIDGET (self));
+  g_assert (GTK_IS_BUTTON (button));
+
+  word = gtk_label_get_text (self->word_label);
+  g_assert (!ide_str_empty0 (word));
+
+  gspell_checker_add_word_to_personal (self->checker, word, -1);
+  jump_to_next_misspelled_word (self);
+}
+
+static void
+ide_editor_spell_widget__ignore_button_clicked_cb (IdeEditorSpellWidget *self,
+                                                   GtkButton            *button)
+{
+  g_assert (IDE_IS_EDITOR_SPELL_WIDGET (self));
+  g_assert (GTK_IS_BUTTON (button));
+
+  jump_to_next_misspelled_word (self);
+}
+
+static void
+ide_editor_spell_widget__ignore_all_button_clicked_cb (IdeEditorSpellWidget *self,
+                                                       GtkButton            *button)
+{
+  const gchar *word;
+
+  g_assert (IDE_IS_EDITOR_SPELL_WIDGET (self));
+  g_assert (GTK_IS_BUTTON (button));
+
+  word = gtk_label_get_text (self->word_label);
+  g_assert (!ide_str_empty0 (word));
+
+  gspell_checker_add_word_to_session (self->checker, word, -1);
+  jump_to_next_misspelled_word (self);
+}
+
+static void
+change_misspelled_word (IdeEditorSpellWidget *self,
+                        gboolean              change_all)
+{
+  const gchar *word;
+  g_autofree gchar *change_to = NULL;
+
+  g_assert (IDE_IS_EDITOR_SPELL_WIDGET (self));
+
+  word = gtk_label_get_text (self->word_label);
+  g_assert (!ide_str_empty0 (word));
+
+  change_to = g_strdup (gtk_entry_get_text (self->word_entry));
+  g_assert (!ide_str_empty0 (change_to));
+
+  gspell_checker_set_correction (self->checker, word, -1, change_to, -1);
+
+  if (change_all)
+    gspell_navigator_change_all (self->navigator, word, change_to);
+  else
+    gspell_navigator_change (self->navigator, word, change_to);
+
+  jump_to_next_misspelled_word (self);
+}
+
+static void
+ide_editor_spell_widget__change_button_clicked_cb (IdeEditorSpellWidget *self,
+                                                   GtkButton            *button)
+{
+  change_misspelled_word (self, FALSE);
+}
+
+static void
+ide_editor_spell_widget__change_all_button_clicked_cb (IdeEditorSpellWidget *self,
+                                                       GtkButton            *button)
+{
+  change_misspelled_word (self, TRUE);
+}
+
+static void
+ide_editor_spell_widget__row_selected_cb (IdeEditorSpellWidget *self,
+                                          GtkListBoxRow        *row,
+                                          GtkListBox           *listbox)
+{
+  const gchar *word;
+  GtkLabel *label;
+
+  if (row != NULL)
+    {
+      label = GTK_LABEL (gtk_bin_get_child (GTK_BIN (row)));
+      word = gtk_label_get_text (label);
+      gtk_entry_set_text (self->word_entry, word);
+      gtk_editable_set_position (GTK_EDITABLE (self->word_entry), -1);
+    }
+}
+
+static void
+ide_editor_spell_widget__row_activated_cb (IdeEditorSpellWidget *self,
+                                           GtkListBoxRow        *row,
+                                           GtkListBox           *listbox)
+{
+  if (row != NULL)
+    change_misspelled_word (self, FALSE);
+}
+
+static gboolean
+ide_editor_spell_widget__key_press_event_cb (IdeEditorSpellWidget *self,
+                                             GdkEventKey          *event)
+{
+  g_assert (IDE_IS_SOURCE_VIEW (self->view));
+
+  switch (event->keyval)
+    {
+    case GDK_KEY_Escape:
+      ide_widget_action (GTK_WIDGET (self), "spell-entry", "exit-spell", NULL);
+      return GDK_EVENT_STOP;
+
+    default:
+      break;
+    }
+
+  return GDK_EVENT_PROPAGATE;
+}
+
+static void
+ide_editor_frame_spell_widget_mapped_cb (IdeEditorSpellWidget *self)
+{
+  GActionGroup *group = NULL;
+  GtkWidget *widget = GTK_WIDGET (self);
+  g_autoptr (GVariant) value = NULL;
+
+  g_assert (IDE_IS_EDITOR_SPELL_WIDGET (self));
+
+  while ((group == NULL) && (widget != NULL))
+    {
+      group = gtk_widget_get_action_group (widget, "view");
+      widget = gtk_widget_get_parent (widget);
+    }
+
+  if (group != NULL &&
+      NULL != (self->view_spellchecking_action = g_action_map_lookup_action (G_ACTION_MAP (group),
+                                                                             "spellchecking")))
+    {
+      value = g_action_get_state (self->view_spellchecking_action);
+      self->view_spellchecker_set = g_variant_get_boolean (value);
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->highlight_checkbutton),
+                                    self->view_spellchecker_set);
+    }
+
+  jump_to_next_misspelled_word (self);
+}
+
+static void
+ide_editor_spell_widget__highlight_checkbutton_toggled_cb (IdeEditorSpellWidget *self,
+                                                           GtkCheckButton       *button)
+{
+  GspellTextView *spell_text_view;
+  gboolean state;
+
+  g_assert (IDE_IS_EDITOR_SPELL_WIDGET (self));
+
+  state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+  spell_text_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (self->view));
+  gspell_text_view_set_inline_spell_checking (spell_text_view, state);
+}
+
+static void
+ide_editor_spell_widget__language_notify_cb (IdeEditorSpellWidget *self,
+                                             GParamSpec           *pspec,
+                                             GtkButton            *language_chooser_button)
+{
+  const GspellLanguage *current_language;
+  const GspellLanguage *spell_language;
+  g_autofree gchar *word = NULL;
+  g_autofree gchar *first_result = NULL;
+  GtkListBoxRow *row;
+
+  g_assert (IDE_IS_EDITOR_SPELL_WIDGET (self));
+
+  current_language = gspell_checker_get_language (self->checker);
+  spell_language = gspell_language_chooser_get_language (GSPELL_LANGUAGE_CHOOSER (language_chooser_button));
+  if (gspell_language_compare (current_language, spell_language) != 0)
+    {
+      gspell_checker_set_language (self->checker, spell_language);
+      fill_suggestions_box (self, word, &first_result);
+      if (!ide_str_empty0 (first_result))
+        {
+          row = gtk_list_box_get_row_at_index (self->suggestions_box, 0);
+          gtk_list_box_select_row (self->suggestions_box, row);
+        }
+    }
+}
+
+static void
+ide_editor_spell_widget_constructed (GObject *object)
+{
+  IdeEditorSpellWidget *self = (IdeEditorSpellWidget *)object;
+  GspellTextBuffer *spell_buffer;
+
+  g_assert (IDE_IS_SOURCE_VIEW (self->view));
+
+  self->buffer = IDE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->view)));
+  ide_buffer_set_spell_checking (self->buffer, TRUE);
+
+  spell_buffer = gspell_text_buffer_get_from_gtk_text_buffer (GTK_TEXT_BUFFER (self->buffer));
+  self->checker = gspell_text_buffer_get_spell_checker (spell_buffer);
+
+  self->spellchecker_language = gspell_checker_get_language (self->checker);
+  gspell_language_chooser_set_language (GSPELL_LANGUAGE_CHOOSER (self->language_chooser_button),
+                                        self->spellchecker_language);
+
+  self->navigator = gspell_navigator_text_view_new (GTK_TEXT_VIEW (self->view));
+
+  g_signal_connect_swapped (self->word_entry,
+                            "changed",
+                            G_CALLBACK (ide_editor_spell_widget__word_entry_changed_cb),
+                            self);
+
+  g_signal_connect_swapped (self->check_button,
+                            "clicked",
+                            G_CALLBACK (ide_editor_spell_widget__check_button_clicked_cb),
+                            self);
+
+  g_signal_connect_swapped (self->add_dict_button,
+                            "clicked",
+                            G_CALLBACK (ide_editor_spell_widget__add_dict_button_clicked_cb),
+                            self);
+
+  g_signal_connect_swapped (self->ignore_button,
+                            "clicked",
+                            G_CALLBACK (ide_editor_spell_widget__ignore_button_clicked_cb),
+                            self);
+
+  g_signal_connect_swapped (self->ignore_all_button,
+                            "clicked",
+                            G_CALLBACK (ide_editor_spell_widget__ignore_all_button_clicked_cb),
+                            self);
+
+  g_signal_connect_swapped (self->change_button,
+                            "clicked",
+                            G_CALLBACK (ide_editor_spell_widget__change_button_clicked_cb),
+                            self);
+
+  g_signal_connect_swapped (self->change_all_button,
+                            "clicked",
+                            G_CALLBACK (ide_editor_spell_widget__change_all_button_clicked_cb),
+                            self);
+
+  g_signal_connect_swapped (self->suggestions_box,
+                            "row-selected",
+                            G_CALLBACK (ide_editor_spell_widget__row_selected_cb),
+                            self);
+
+  g_signal_connect_swapped (self->suggestions_box,
+                            "row-activated",
+                            G_CALLBACK (ide_editor_spell_widget__row_activated_cb),
+                            self);
+
+  g_signal_connect_swapped (self,
+                            "key-press-event",
+                            G_CALLBACK (ide_editor_spell_widget__key_press_event_cb),
+                            self);
+
+  g_signal_connect_swapped (self->highlight_checkbutton,
+                            "toggled",
+                            G_CALLBACK (ide_editor_spell_widget__highlight_checkbutton_toggled_cb),
+                            self);
+
+  g_signal_connect_object (self->language_chooser_button,
+                           "notify::language",
+                           G_CALLBACK (ide_editor_spell_widget__language_notify_cb),
+                           self,
+                           G_CONNECT_SWAPPED);
+
+  self->placeholder = gtk_label_new (NULL);
+  gtk_widget_set_visible (self->placeholder, TRUE);
+  gtk_list_box_set_placeholder (self->suggestions_box, self->placeholder);
+
+  /* Due to the change of focus between the view and the spellchecker widget,
+   * we need to start checking only when the widget is mapped,
+   * so the view can keep the selection on the first word.
+   */
+  g_signal_connect_object (self,
+                           "map",
+                           G_CALLBACK (ide_editor_frame_spell_widget_mapped_cb),
+                           NULL,
+                           G_CONNECT_AFTER);
+}
+
+static void
+ide_editor_spell_widget_finalize (GObject *object)
+{
+  IdeEditorSpellWidget *self = (IdeEditorSpellWidget *)object;
+  GspellTextView *spell_text_view;
+  const GspellLanguage *spell_language;
+  GtkTextBuffer *buffer;
+
+  printf ("ide_editor_spell_widget_finalize\n");
+  g_clear_object (&self->navigator);
+
+  /* Set back the view spellchecking previous state */
+  spell_text_view = gspell_text_view_get_from_gtk_text_view (GTK_TEXT_VIEW (self->view));
+  if (self->view_spellchecker_set)
+    {
+      gspell_text_view_set_inline_spell_checking (spell_text_view, TRUE);
+      spell_language = gspell_checker_get_language (self->checker);
+      if (gspell_language_compare (self->spellchecker_language, spell_language) != 0)
+        gspell_checker_set_language (self->checker, self->spellchecker_language);
+    }
+  else
+    {
+      gspell_text_view_set_inline_spell_checking (spell_text_view, FALSE);
+      gspell_text_view_set_enable_language_menu (spell_text_view, FALSE);
+
+      buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->view));
+      ide_buffer_set_spell_checking (IDE_BUFFER (buffer), FALSE);
+    }
+
+  G_OBJECT_CLASS (ide_editor_spell_widget_parent_class)->finalize (object);
+}
+
+static void
+ide_editor_spell_widget_get_property (GObject    *object,
+                                      guint       prop_id,
+                                      GValue     *value,
+                                      GParamSpec *pspec)
+{
+  IdeEditorSpellWidget *self = IDE_EDITOR_SPELL_WIDGET (object);
+
+  switch (prop_id)
+    {
+    case PROP_VIEW:
+      g_value_set_object (value, ide_editor_spell_widget_get_view (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_editor_spell_widget_set_property (GObject      *object,
+                                      guint         prop_id,
+                                      const GValue *value,
+                                      GParamSpec   *pspec)
+{
+  IdeEditorSpellWidget *self = IDE_EDITOR_SPELL_WIDGET (object);
+
+  switch (prop_id)
+    {
+    case PROP_VIEW:
+      ide_editor_spell_widget_set_view (self, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_editor_spell_widget_class_init (IdeEditorSpellWidgetClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->constructed = ide_editor_spell_widget_constructed;
+  object_class->finalize = ide_editor_spell_widget_finalize;
+  object_class->get_property = ide_editor_spell_widget_get_property;
+  object_class->set_property = ide_editor_spell_widget_set_property;
+
+  properties [PROP_VIEW] =
+    g_param_spec_object ("view",
+                         "View",
+                         "The source view.",
+                         IDE_TYPE_SOURCE_VIEW,
+                         (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+
+  gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/builder/ui/ide-editor-spell-widget.ui");
+  gtk_widget_class_bind_template_child (widget_class, IdeEditorSpellWidget, word_label);
+  gtk_widget_class_bind_template_child (widget_class, IdeEditorSpellWidget, word_entry);
+  gtk_widget_class_bind_template_child (widget_class, IdeEditorSpellWidget, check_button);
+  gtk_widget_class_bind_template_child (widget_class, IdeEditorSpellWidget, add_dict_button);
+  gtk_widget_class_bind_template_child (widget_class, IdeEditorSpellWidget, ignore_button);
+  gtk_widget_class_bind_template_child (widget_class, IdeEditorSpellWidget, ignore_all_button);
+  gtk_widget_class_bind_template_child (widget_class, IdeEditorSpellWidget, change_button);
+  gtk_widget_class_bind_template_child (widget_class, IdeEditorSpellWidget, change_all_button);
+  gtk_widget_class_bind_template_child (widget_class, IdeEditorSpellWidget, close_button);
+  gtk_widget_class_bind_template_child (widget_class, IdeEditorSpellWidget, highlight_checkbutton);
+  gtk_widget_class_bind_template_child (widget_class, IdeEditorSpellWidget, language_chooser_button);
+  gtk_widget_class_bind_template_child (widget_class, IdeEditorSpellWidget, suggestions_box);
+}
+
+static void
+ide_editor_spell_widget_init (IdeEditorSpellWidget *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+
+  self->view_spellchecker_set = FALSE;
+}
diff --git a/libide/editor/ide-editor-spell-widget.h b/libide/editor/ide-editor-spell-widget.h
new file mode 100644
index 0000000..c08bb08
--- /dev/null
+++ b/libide/editor/ide-editor-spell-widget.h
@@ -0,0 +1,38 @@
+/* ide-editor-spell-widget.h
+ *
+ * Copyright (C) 2016 Sebastien Lafargue <slafargue gnome org>
+ *
+ * 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 3 of the License, 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/>.
+ */
+
+#ifndef IDE_EDITOR_SPELL_WIDGET_H
+#define IDE_EDITOR_SPELL_WIDGET_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "sourceview/ide-source-view.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_EDITOR_SPELL_WIDGET (ide_editor_spell_widget_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeEditorSpellWidget, ide_editor_spell_widget, IDE, EDITOR_SPELL_WIDGET, GtkBin)
+
+GtkWidget       *ide_editor_spell_widget_new          (IdeSourceView           *source_view);
+GtkWidget       *ide_editor_spell_widget_get_entry    (IdeEditorSpellWidget    *self);
+
+G_END_DECLS
+
+#endif /* IDE_EDITOR_SPELL_WIDGET_H */
diff --git a/libide/editor/ide-editor-spell-widget.ui b/libide/editor/ide-editor-spell-widget.ui
new file mode 100644
index 0000000..7af36ca
--- /dev/null
+++ b/libide/editor/ide-editor-spell-widget.ui
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.15 -->
+  <template class="IdeEditorSpellWidget" parent="GtkBin">
+    <child>
+      <object class="GtkFrame" id="spell_frame">
+        <property name="visible">true</property>
+        <property name="margin-end">12</property>
+        <style>
+          <class name="gb-spell-frame"/>
+        </style>
+        <child>
+          <object class="GtkBox">
+            <property name="visible">true</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">7</property>
+            <child>
+              <object class="GtkGrid">
+                <property name="visible">true</property>
+                <property name="row_spacing">6</property>
+                <property name="column_spacing">6</property>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">true</property>
+                    <property name="label" translatable="yes">Misspelled</property>
+                    <property name="halign">end</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">true</property>
+                    <property name="label" translatable="yes">Change _to</property>
+                    <property name="halign">end</property>
+                    <property name="use_underline">True</property>
+                    <property name="mnemonic_widget">word_entry</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">true</property>
+                    <property name="label" translatable="yes">_Suggestions</property>
+                    <property name="halign">end</property>
+                    <property name="valign">start</property>
+                    <property name="use_underline">True</property>
+                    <property name="mnemonic_widget">suggestions_box</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox">
+                    <property name="visible">true</property>
+                    <property name="orientation">horizontal</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="word_label">
+                        <property name="visible">true</property>
+                        <property name="halign">start</property>
+                        <property name="margin_left">10</property>
+                        <property name="selectable">True</property>
+                        <property name="use_markup">True</property>
+                        <property name="wrap">True</property>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="count_label">
+                        <property name="visible">true</property>
+                        <property name="halign">end</property>
+                        <property name="expand">true</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkEntry" id="word_entry">
+                    <property name="visible">true</property>
+                    <property name="can_focus">true</property>
+                    <property name="width-chars">20</property>
+                    <property name="max-width-chars">30</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkScrolledWindow">
+                    <property name="visible">true</property>
+                    <property name="expand">true</property>
+                    <property name="shadow_type">in</property>
+                    <property name="min-content-height">110</property>
+                    <property name="max-content-height">110</property>
+                    <property name="propagate-natural-height">true</property>
+                    <child>
+                      <object class="GtkListBox" id="suggestions_box">
+                        <property name="visible">true</property>
+                        <property name="can_focus">true</property>
+                        <property name="activate-on-single-click">false</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="add_dict_button">
+                    <property name="label" translatable="yes">Add w_ord</property>
+                    <property name="visible">true</property>
+                    <property name="can_focus">true</property>
+                    <property name="use_underline">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">2</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="check_button">
+                    <property name="label" translatable="yes">Check _word</property>
+                    <property name="visible">true</property>
+                    <property name="can_focus">true</property>
+                    <property name="use_underline">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">2</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="ignore_button">
+                    <property name="label" translatable="yes">_Ignore</property>
+                    <property name="visible">true</property>
+                    <property name="can_focus">true</property>
+                    <property name="use_underline">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">3</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="change_button">
+                    <property name="label" translatable="yes">Cha_nge</property>
+                    <property name="visible">true</property>
+                    <property name="can_focus">true</property>
+                    <property name="use_underline">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">3</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="ignore_all_button">
+                    <property name="label" translatable="yes">Ignore _All</property>
+                    <property name="visible">true</property>
+                    <property name="can_focus">true</property>
+                    <property name="use_underline">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">4</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="change_all_button">
+                    <property name="label" translatable="yes">Change A_ll</property>
+                    <property name="visible">true</property>
+                    <property name="can_focus">true</property>
+                    <property name="use_underline">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">4</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="close_button">
+                    <property name="visible">true</property>
+                    <property name="halign">center</property>
+                    <property name="valign">center</property>
+                    <property name="focus_on_click">false</property>
+                    <property name="action-name">spell-entry.exit-spell</property>
+                    <style>
+                      <class name="close"/>
+                    </style>
+                    <child>
+                      <object class="GtkImage">
+                        <property name="visible">true</property>
+                        <property name="icon_name">window-close-symbolic</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="left_attach">5</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkFrame" id="option_frame">
+                    <property name="visible">true</property>
+                    <property name="label" translatable="yes">Options</property>
+                    <property name="shadow_type">in</property>
+                    <property name="halign">fill</property>
+                    <property name="valign">fill</property>
+                    <child>
+                      <object class="GtkGrid">
+                        <property name="visible">true</property>
+                        <property name="can_focus">false</property>
+                        <property name="row_spacing">6</property>
+                        <property name="column_spacing">6</property>
+                        <property name="margin">6</property>
+                        <child>
+                          <object class="GtkLabel">
+                            <property name="visible">true</property>
+                            <property name="label" translatable="yes">_Language</property>
+                            <property name="halign">end</property>
+                            <property name="expand">true</property>
+                            <property name="use_underline">True</property>
+                            <property name="mnemonic_widget">language_chooser_button</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkCheckButton" id="highlight_checkbutton">
+                            <property name="visible">true</property>
+                            <property name="can_focus">true</property>
+                            <property name="halign">end</property>
+                            <property name="expand">true</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GspellLanguageChooserButton" id="language_chooser_button">
+                            <property name="visible">true</property>
+                            <property name="can_focus">true</property>
+                            <property name="expand">true</property>
+                            <property name="valign">center</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel">
+                            <property name="visible">true</property>
+                            <property name="label" translatable="yes">_Highlight in the view</property>
+                            <property name="expand">true</property>
+                            <property name="halign">start</property>
+                            <property name="margin-start">6</property>
+                            <property name="use_underline">True</property>
+                            <property name="mnemonic_widget">highlight_checkbutton</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                    <style>
+                      <class name="gb-spell-option-frame"/>
+                    </style>
+                  </object>
+                  <packing>
+                    <property name="left_attach">2</property>
+                    <property name="top_attach">2</property>
+                    <property name="width">3</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/libide/ide-types.h b/libide/ide-types.h
index 230ebaa..80e9a62 100644
--- a/libide/ide-types.h
+++ b/libide/ide-types.h
@@ -57,6 +57,8 @@ typedef struct _IdeDiagnosticProvider          IdeDiagnosticProvider;
 typedef struct _IdeDiagnostics                 IdeDiagnostics;
 typedef struct _IdeDiagnosticsManager          IdeDiagnosticsManager;
 
+typedef struct _IdeEditorFrame                 IdeEditorFrame;
+
 typedef struct _IdeEnvironment                 IdeEnvironment;
 typedef struct _IdeEnvironmentVariable         IdeEnvironmentVariable;
 
diff --git a/libide/resources/libide.gresource.xml b/libide/resources/libide.gresource.xml
index 5f49c8f..1f69cf1 100644
--- a/libide/resources/libide.gresource.xml
+++ b/libide/resources/libide.gresource.xml
@@ -54,6 +54,7 @@
     <file compressed="true" alias="ide-editor-frame.ui">../editor/ide-editor-frame.ui</file>
     <file compressed="true" 
alias="ide-editor-layout-stack-controls.ui">../editor/ide-editor-layout-stack-controls.ui</file>
     <file compressed="true" alias="ide-editor-perspective.ui">../editor/ide-editor-perspective.ui</file>
+    <file compressed="true" alias="ide-editor-spell-widget.ui">../editor/ide-editor-spell-widget.ui</file>
     <file compressed="true" alias="ide-editor-tweak-widget.ui">../editor/ide-editor-tweak-widget.ui</file>
     <file compressed="true" alias="ide-editor-view.ui">../editor/ide-editor-view.ui</file>
     <file compressed="true" alias="ide-greeter-perspective.ui">../greeter/ide-greeter-perspective.ui</file>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 4ce0441..c99feba 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -55,6 +55,7 @@ libide/editor/ide-editor-layout-stack-controls.c
 libide/editor/ide-editor-layout-stack-controls.ui
 libide/editor/ide-editor-perspective.c
 libide/editor/ide-editor-perspective.ui
+libide/editor/ide-editor-spell-widget.ui
 libide/editor/ide-editor-tweak-widget.ui
 libide/editor/ide-editor-view-actions.c
 libide/editor/ide-editor-view.c



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]