1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* gtkhtml-editor-spell-dialog.c
4 * Copyright (C) 2008 Novell, Inc.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU Lesser General Public
8 * License as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
21 #include "gtkhtml-spell-dialog.h"
23 #include <glib/gi18n-lib.h>
24 #include "gtkhtml-spell-checker.h"
27 COMBO_COLUMN_CHECKER
, /* GTKHTML_TYPE_SPELL_CHECKER */
28 COMBO_COLUMN_TEXT
/* G_TYPE_STRING */
46 struct _GtkhtmlSpellDialogPrivate
{
49 GtkWidget
*add_word_button
;
50 GtkWidget
*back_button
;
51 GtkWidget
*dictionary_combo
;
52 GtkWidget
*ignore_button
;
53 GtkWidget
*replace_button
;
54 GtkWidget
*replace_all_button
;
55 GtkWidget
*skip_button
;
56 GtkWidget
*suggestion_label
;
59 GList
*spell_checkers
;
63 static gpointer parent_class
;
64 static guint signals
[LAST_SIGNAL
];
67 spell_dialog_render_checker (GtkComboBox
*combo_box
,
68 GtkCellRenderer
*renderer
,
72 const GtkhtmlSpellLanguage
*language
;
73 GtkhtmlSpellChecker
*checker
;
76 gtk_tree_model_get (model
, iter
, 0, &checker
, -1);
77 language
= gtkhtml_spell_checker_get_language (checker
);
78 name
= gtkhtml_spell_language_get_name (language
);
80 g_object_set (renderer
, "text", name
, NULL
);
82 g_object_unref (checker
);
86 spell_dialog_update_buttons (GtkhtmlSpellDialog
*dialog
)
90 /* Update "Add Word" and "Ignore" button sensitivity. */
91 sensitive
= (gtkhtml_spell_dialog_get_word (dialog
) != NULL
);
92 gtk_widget_set_sensitive (dialog
->priv
->add_word_button
, sensitive
);
93 gtk_widget_set_sensitive (dialog
->priv
->ignore_button
, sensitive
);
97 spell_dialog_update_suggestion_label (GtkhtmlSpellDialog
*dialog
)
104 label
= GTK_LABEL (dialog
->priv
->suggestion_label
);
105 word
= gtkhtml_spell_dialog_get_word (dialog
);
107 /* Handle the simple case and get out. */
109 gtk_label_set_markup (label
, NULL
);
113 text
= g_strdup_printf (_("Suggestions for \"%s\""), word
);
114 markup
= g_strdup_printf ("<b>%s</b>", text
);
116 gtk_label_set_markup (label
, markup
);
123 spell_dialog_update_tree_view (GtkhtmlSpellDialog
*dialog
)
125 GtkhtmlSpellChecker
*checker
;
126 GtkTreeSelection
*selection
;
127 GtkTreeView
*tree_view
;
133 tree_view
= GTK_TREE_VIEW (dialog
->priv
->tree_view
);
134 selection
= gtk_tree_view_get_selection (tree_view
);
135 checker
= gtkhtml_spell_dialog_get_active_checker (dialog
);
136 word
= gtkhtml_spell_dialog_get_word (dialog
);
138 store
= gtk_list_store_new (1, G_TYPE_STRING
);
140 if (checker
!= NULL
&& word
!= NULL
)
141 list
= gtkhtml_spell_checker_get_suggestions (
144 while (list
!= NULL
) {
145 const gchar
*suggestion
= list
->data
;
148 gtk_list_store_append (store
, &iter
);
149 gtk_list_store_set (store
, &iter
, 0, suggestion
, -1);
152 list
= g_list_delete_link (list
, list
);
155 gtk_tree_view_set_model (tree_view
, GTK_TREE_MODEL (store
));
157 /* Select the first item. */
158 path
= gtk_tree_path_new_first ();
159 gtk_tree_selection_select_path (selection
, path
);
160 gtk_tree_path_free (path
);
162 g_object_unref (checker
);
166 spell_dialog_add_word_cb (GtkhtmlSpellDialog
*dialog
)
168 GtkhtmlSpellChecker
*checker
;
171 checker
= gtkhtml_spell_dialog_get_active_checker (dialog
);
172 word
= gtkhtml_spell_dialog_get_word (dialog
);
174 gtkhtml_spell_checker_add_word (checker
, word
, -1);
175 g_signal_emit (dialog
, signals
[ADDED
], 0);
177 gtkhtml_spell_dialog_next_word (dialog
);
181 spell_dialog_ignore_cb (GtkhtmlSpellDialog
*dialog
)
183 GtkhtmlSpellChecker
*checker
;
186 checker
= gtkhtml_spell_dialog_get_active_checker (dialog
);
187 word
= gtkhtml_spell_dialog_get_word (dialog
);
189 gtkhtml_spell_checker_add_word_to_session (checker
, word
, -1);
190 g_signal_emit (dialog
, signals
[IGNORED
], 0);
192 gtkhtml_spell_dialog_next_word (dialog
);
196 spell_dialog_selection_changed_cb (GtkhtmlSpellDialog
*dialog
)
198 GtkTreeSelection
*selection
;
199 GtkTreeView
*tree_view
;
202 tree_view
= GTK_TREE_VIEW (dialog
->priv
->tree_view
);
203 selection
= gtk_tree_view_get_selection (tree_view
);
205 /* Update "Replace" and "Replace All" button sensitivity. */
206 selected
= gtk_tree_selection_get_selected (selection
, NULL
, NULL
);
207 gtk_widget_set_sensitive (dialog
->priv
->replace_button
, selected
);
208 gtk_widget_set_sensitive (dialog
->priv
->replace_all_button
, selected
);
212 spell_dialog_replace_cb (GtkhtmlSpellDialog
*dialog
)
216 word
= gtkhtml_spell_dialog_get_active_suggestion (dialog
);
217 g_return_if_fail (word
!= NULL
);
219 g_signal_emit (dialog
, signals
[REPLACE
], 0, word
);
225 spell_dialog_replace_all_cb (GtkhtmlSpellDialog
*dialog
)
229 word
= gtkhtml_spell_dialog_get_active_suggestion (dialog
);
230 g_return_if_fail (word
!= NULL
);
232 g_signal_emit (dialog
, signals
[REPLACE_ALL
], 0, word
);
238 spell_dialog_set_property (GObject
*object
,
243 switch (property_id
) {
245 gtkhtml_spell_dialog_set_word (
246 GTKHTML_SPELL_DIALOG (object
),
247 g_value_get_string (value
));
251 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
255 spell_dialog_get_property (GObject
*object
,
260 switch (property_id
) {
263 value
, gtkhtml_spell_dialog_get_word (
264 GTKHTML_SPELL_DIALOG (object
)));
268 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
272 spell_dialog_dispose (GObject
*object
)
274 GtkhtmlSpellDialogPrivate
*priv
;
276 priv
= GTKHTML_SPELL_DIALOG (object
)->priv
;
278 if (priv
->add_word_button
!= NULL
) {
279 g_object_unref (priv
->add_word_button
);
280 priv
->add_word_button
= NULL
;
283 if (priv
->back_button
!= NULL
) {
284 g_object_unref (priv
->back_button
);
285 priv
->back_button
= NULL
;
288 if (priv
->dictionary_combo
!= NULL
) {
289 g_object_unref (priv
->dictionary_combo
);
290 priv
->dictionary_combo
= NULL
;
293 if (priv
->ignore_button
!= NULL
) {
294 g_object_unref (priv
->ignore_button
);
295 priv
->ignore_button
= NULL
;
298 if (priv
->replace_button
!= NULL
) {
299 g_object_unref (priv
->replace_button
);
300 priv
->replace_button
= NULL
;
303 if (priv
->replace_all_button
!= NULL
) {
304 g_object_unref (priv
->replace_all_button
);
305 priv
->replace_all_button
= NULL
;
308 if (priv
->skip_button
!= NULL
) {
309 g_object_unref (priv
->skip_button
);
310 priv
->skip_button
= NULL
;
313 if (priv
->tree_view
!= NULL
) {
314 g_object_unref (priv
->tree_view
);
315 priv
->tree_view
= NULL
;
318 /* Chain up to parent's dispose() method. */
319 G_OBJECT_CLASS (parent_class
)->dispose (object
);
323 spell_dialog_finalize (GObject
*object
)
325 GtkhtmlSpellDialogPrivate
*priv
;
327 priv
= GTKHTML_SPELL_DIALOG (object
)->priv
;
331 /* Chain up to parent's finalize() method. */
332 G_OBJECT_CLASS (parent_class
)->finalize (object
);
336 spell_dialog_class_init (GtkhtmlSpellDialogClass
*class)
338 GObjectClass
*object_class
;
340 parent_class
= g_type_class_peek_parent (class);
341 g_type_class_add_private (class, sizeof (GtkhtmlSpellDialogPrivate
));
343 object_class
= G_OBJECT_CLASS (class);
344 object_class
->set_property
= spell_dialog_set_property
;
345 object_class
->get_property
= spell_dialog_get_property
;
346 object_class
->dispose
= spell_dialog_dispose
;
347 object_class
->finalize
= spell_dialog_finalize
;
349 g_object_class_install_property (
352 g_param_spec_string (
355 "The current misspelled word",
359 signals
[ADDED
] = g_signal_new (
361 G_OBJECT_CLASS_TYPE (object_class
),
364 g_cclosure_marshal_VOID__VOID
,
367 signals
[IGNORED
] = g_signal_new (
369 G_OBJECT_CLASS_TYPE (object_class
),
372 g_cclosure_marshal_VOID__VOID
,
375 signals
[NEXT_WORD
] = g_signal_new (
377 G_OBJECT_CLASS_TYPE (object_class
),
380 g_cclosure_marshal_VOID__VOID
,
383 signals
[PREV_WORD
] = g_signal_new (
385 G_OBJECT_CLASS_TYPE (object_class
),
388 g_cclosure_marshal_VOID__VOID
,
391 signals
[REPLACE
] = g_signal_new (
393 G_OBJECT_CLASS_TYPE (object_class
),
396 g_cclosure_marshal_VOID__STRING
,
400 signals
[REPLACE_ALL
] = g_signal_new (
402 G_OBJECT_CLASS_TYPE (object_class
),
405 g_cclosure_marshal_VOID__STRING
,
411 spell_dialog_init (GtkhtmlSpellDialog
*dialog
)
413 GtkTreeSelection
*selection
;
414 GtkTreeViewColumn
*column
;
415 GtkCellRenderer
*renderer
;
416 GtkWidget
*container
;
417 GtkWidget
*content_area
;
422 dialog
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (
423 dialog
, GTKHTML_TYPE_SPELL_DIALOG
, GtkhtmlSpellDialogPrivate
);
426 dialog
, "notify::word", G_CALLBACK (
427 spell_dialog_update_buttons
), NULL
);
430 dialog
, "notify::word", G_CALLBACK (
431 spell_dialog_update_suggestion_label
), NULL
);
434 dialog
, "notify::word", G_CALLBACK (
435 spell_dialog_update_tree_view
), NULL
);
437 /* Build the widgets. */
439 content_area
= gtk_dialog_get_content_area (GTK_DIALOG (dialog
));
441 gtk_dialog_add_button (
442 GTK_DIALOG (dialog
), GTK_STOCK_CLOSE
, GTK_RESPONSE_CLOSE
);
443 gtk_window_set_title (GTK_WINDOW (dialog
), _("Spell Checker"));
444 gtk_container_set_border_width (GTK_CONTAINER (dialog
), 5);
446 gtk_box_set_spacing (GTK_BOX (content_area
), 2);
449 widget
= gtk_table_new (4, 2, FALSE
);
450 gtk_container_set_border_width (GTK_CONTAINER (widget
), 5);
451 gtk_table_set_row_spacings (GTK_TABLE (widget
), 6);
452 gtk_table_set_col_spacings (GTK_TABLE (widget
), 6);
453 gtk_table_set_row_spacing (GTK_TABLE (widget
), 1, 12);
454 gtk_box_pack_start (GTK_BOX (content_area
), widget
, TRUE
, TRUE
, 0);
455 gtk_widget_show (widget
);
458 /* Suggestion Label */
459 widget
= gtk_label_new (NULL
);
460 gtk_label_set_ellipsize (GTK_LABEL (widget
), PANGO_ELLIPSIZE_END
);
461 gtk_misc_set_alignment (GTK_MISC (widget
), 0.0, 0.5);
463 GTK_TABLE (table
), widget
, 0, 2, 0, 1,
464 GTK_EXPAND
| GTK_FILL
, 0, 0, 0);
465 dialog
->priv
->suggestion_label
= g_object_ref (widget
);
466 gtk_widget_show (widget
);
468 /* Scrolled Window */
469 widget
= gtk_scrolled_window_new (NULL
, NULL
);
470 gtk_scrolled_window_set_policy (
471 GTK_SCROLLED_WINDOW (widget
),
472 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
473 gtk_scrolled_window_set_shadow_type (
474 GTK_SCROLLED_WINDOW (widget
),
475 GTK_SHADOW_ETCHED_IN
);
477 GTK_TABLE (table
), widget
, 0, 1, 1, 2,
478 GTK_EXPAND
| GTK_FILL
, GTK_EXPAND
| GTK_FILL
, 0, 0);
479 gtk_widget_show (widget
);
483 widget
= gtk_tree_view_new ();
484 column
= gtk_tree_view_column_new ();
485 renderer
= gtk_cell_renderer_text_new ();
486 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (widget
));
487 g_object_set (renderer
, "ellipsize", PANGO_ELLIPSIZE_END
, NULL
);
488 gtk_tree_view_column_pack_start (column
, renderer
, TRUE
);
489 gtk_tree_view_column_add_attribute (column
, renderer
, "text", 0);
490 gtk_tree_view_append_column (GTK_TREE_VIEW (widget
), column
);
491 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (widget
), FALSE
);
492 gtk_label_set_mnemonic_widget (
493 GTK_LABEL (dialog
->priv
->suggestion_label
), widget
);
494 g_signal_connect_swapped (
495 widget
, "row-activated",
496 G_CALLBACK (spell_dialog_replace_cb
), dialog
);
497 g_signal_connect_swapped (
498 selection
, "changed",
499 G_CALLBACK (spell_dialog_selection_changed_cb
), dialog
);
500 gtk_container_add (GTK_CONTAINER (container
), widget
);
501 dialog
->priv
->tree_view
= g_object_ref (widget
);
502 gtk_widget_show (widget
);
504 /* Vertical Button Box */
505 widget
= gtk_vbutton_box_new ();
506 gtk_button_box_set_layout (
507 GTK_BUTTON_BOX (widget
), GTK_BUTTONBOX_START
);
508 gtk_box_set_spacing (GTK_BOX (widget
), 6);
510 GTK_TABLE (table
), widget
, 1, 2, 1, 2,
511 0, GTK_EXPAND
| GTK_FILL
, 0, 0);
512 gtk_widget_show (widget
);
516 widget
= gtk_button_new_with_mnemonic (_("_Replace"));
517 gtk_button_set_image (
519 gtk_image_new_from_stock (
520 GTK_STOCK_CONVERT
, GTK_ICON_SIZE_BUTTON
));
521 g_signal_connect_swapped (
523 G_CALLBACK (spell_dialog_replace_cb
), dialog
);
524 gtk_box_pack_start (GTK_BOX (container
), widget
, TRUE
, TRUE
, 0);
525 dialog
->priv
->replace_button
= g_object_ref (widget
);
526 gtk_widget_set_sensitive (widget
, FALSE
);
527 gtk_widget_show (widget
);
529 /* Replace All Button */
530 widget
= gtk_button_new_with_mnemonic (_("R_eplace All"));
531 gtk_button_set_image (
533 gtk_image_new_from_stock (
534 GTK_STOCK_APPLY
, GTK_ICON_SIZE_BUTTON
));
535 g_signal_connect_swapped (
537 G_CALLBACK (spell_dialog_replace_all_cb
), dialog
);
538 gtk_box_pack_start (GTK_BOX (container
), widget
, TRUE
, TRUE
, 0);
539 dialog
->priv
->replace_all_button
= g_object_ref (widget
);
540 gtk_widget_set_sensitive (widget
, FALSE
);
541 gtk_widget_show (widget
);
544 widget
= gtk_button_new_with_mnemonic (_("_Ignore"));
545 gtk_button_set_image (
547 gtk_image_new_from_stock (
548 GTK_STOCK_CLEAR
, GTK_ICON_SIZE_BUTTON
));
549 g_signal_connect_swapped (
551 G_CALLBACK (spell_dialog_ignore_cb
), dialog
);
552 gtk_box_pack_start (GTK_BOX (container
), widget
, TRUE
, TRUE
, 0);
553 dialog
->priv
->ignore_button
= g_object_ref (widget
);
554 gtk_widget_set_sensitive (widget
, FALSE
);
555 gtk_widget_show (widget
);
558 widget
= gtk_button_new_with_mnemonic (_("_Skip"));
559 gtk_button_set_image (
561 gtk_image_new_from_stock (
562 GTK_STOCK_GO_FORWARD
, GTK_ICON_SIZE_BUTTON
));
563 g_signal_connect_swapped (
565 G_CALLBACK (gtkhtml_spell_dialog_next_word
), dialog
);
566 gtk_box_pack_start (GTK_BOX (container
), widget
, TRUE
, TRUE
, 0);
567 dialog
->priv
->skip_button
= g_object_ref (widget
);
568 gtk_widget_show (widget
);
571 widget
= gtk_button_new_with_mnemonic (_("_Back"));
572 gtk_button_set_image (
574 gtk_image_new_from_stock (
575 GTK_STOCK_GO_BACK
, GTK_ICON_SIZE_BUTTON
));
576 g_signal_connect_swapped (
578 G_CALLBACK (gtkhtml_spell_dialog_prev_word
), dialog
);
579 gtk_box_pack_start (GTK_BOX (container
), widget
, TRUE
, TRUE
, 0);
580 dialog
->priv
->back_button
= g_object_ref (widget
);
581 gtk_widget_show (widget
);
583 /* Dictionary Label */
584 markup
= g_markup_printf_escaped ("<b>%s</b>", _("Dictionary"));
585 widget
= gtk_label_new (markup
);
586 gtk_label_set_use_markup (GTK_LABEL (widget
), TRUE
);
587 gtk_misc_set_alignment (GTK_MISC (widget
), 0.0, 0.5);
589 GTK_TABLE (table
), widget
, 0, 2, 2, 3,
590 GTK_EXPAND
| GTK_FILL
, 0, 0, 0);
591 gtk_widget_show (widget
);
594 /* Dictionary Combo Box */
595 widget
= gtk_combo_box_new ();
596 renderer
= gtk_cell_renderer_text_new ();
597 gtk_cell_layout_pack_start (
598 GTK_CELL_LAYOUT (widget
), renderer
, TRUE
);
599 gtk_cell_layout_set_cell_data_func (
600 GTK_CELL_LAYOUT (widget
), renderer
,
601 (GtkCellLayoutDataFunc
) spell_dialog_render_checker
,
603 g_signal_connect_swapped (
605 G_CALLBACK (spell_dialog_update_tree_view
), dialog
);
607 GTK_TABLE (table
), widget
, 0, 1, 3, 4,
608 GTK_EXPAND
| GTK_FILL
, 0, 0, 0);
609 dialog
->priv
->dictionary_combo
= g_object_ref (widget
);
610 gtk_widget_show (widget
);
612 /* Add Word Button */
613 widget
= gtk_button_new_with_mnemonic (_("_Add Word"));
614 g_signal_connect_swapped (
616 G_CALLBACK (spell_dialog_add_word_cb
), dialog
);
617 gtk_button_set_image (
619 gtk_image_new_from_stock (
620 GTK_STOCK_ADD
, GTK_ICON_SIZE_BUTTON
));
622 GTK_TABLE (table
), widget
, 1, 2, 3, 4,
624 dialog
->priv
->add_word_button
= g_object_ref (widget
);
625 gtk_widget_show (widget
);
629 gtkhtml_spell_dialog_get_type (void)
631 static GType type
= 0;
633 if (G_UNLIKELY (type
== 0)) {
634 static const GTypeInfo type_info
= {
635 sizeof (GtkhtmlSpellDialogClass
),
636 (GBaseInitFunc
) NULL
,
637 (GBaseFinalizeFunc
) NULL
,
638 (GClassInitFunc
) spell_dialog_class_init
,
639 (GClassFinalizeFunc
) NULL
,
640 NULL
, /* class_data */
641 sizeof (GtkhtmlSpellDialog
),
643 (GInstanceInitFunc
) spell_dialog_init
,
644 NULL
/* value_table */
647 type
= g_type_register_static (
648 GTK_TYPE_DIALOG
, "GtkhtmlSpellDialog", &type_info
, 0);
655 gtkhtml_spell_dialog_new (GtkWindow
*parent
)
657 return g_object_new (
658 GTKHTML_TYPE_SPELL_DIALOG
, "transient-for", parent
, NULL
);
662 gtkhtml_spell_dialog_close (GtkhtmlSpellDialog
*dialog
)
664 g_return_if_fail (GTKHTML_IS_SPELL_DIALOG (dialog
));
666 gtk_dialog_response (GTK_DIALOG (dialog
), GTK_RESPONSE_CLOSE
);
670 gtkhtml_spell_dialog_get_word (GtkhtmlSpellDialog
*dialog
)
672 g_return_val_if_fail (GTKHTML_IS_SPELL_DIALOG (dialog
), NULL
);
674 return dialog
->priv
->word
;
678 gtkhtml_spell_dialog_set_word (GtkhtmlSpellDialog
*dialog
,
681 g_return_if_fail (GTKHTML_IS_SPELL_DIALOG (dialog
));
683 /* Do not emit signals if the word is unchanged. */
684 if (word
!= NULL
&& dialog
->priv
->word
!= NULL
)
685 if (g_str_equal (word
, dialog
->priv
->word
))
688 g_free (dialog
->priv
->word
);
689 dialog
->priv
->word
= g_strdup (word
);
691 g_object_notify (G_OBJECT (dialog
), "word");
695 gtkhtml_spell_dialog_next_word (GtkhtmlSpellDialog
*dialog
)
697 g_signal_emit (dialog
, signals
[NEXT_WORD
], 0);
701 gtkhtml_spell_dialog_prev_word (GtkhtmlSpellDialog
*dialog
)
703 g_signal_emit (dialog
, signals
[PREV_WORD
], 0);
707 gtkhtml_spell_dialog_get_spell_checkers (GtkhtmlSpellDialog
*dialog
)
709 g_return_val_if_fail (GTKHTML_IS_SPELL_DIALOG (dialog
), NULL
);
711 return g_list_copy (dialog
->priv
->spell_checkers
);
715 gtkhtml_spell_dialog_set_spell_checkers (GtkhtmlSpellDialog
*dialog
,
716 GList
*spell_checkers
)
718 GtkComboBox
*combo_box
;
722 g_return_if_fail (GTKHTML_IS_SPELL_DIALOG (dialog
));
724 combo_box
= GTK_COMBO_BOX (dialog
->priv
->dictionary_combo
);
726 /* Free the old list of spell checkers. */
727 list
= dialog
->priv
->spell_checkers
;
728 g_list_foreach (list
, (GFunc
) g_object_unref
, NULL
);
731 /* Copy and sort the new list of spell checkers. */
733 g_list_copy (spell_checkers
),
734 (GCompareFunc
) gtkhtml_spell_checker_compare
);
735 g_list_foreach (list
, (GFunc
) g_object_ref
, NULL
);
736 dialog
->priv
->spell_checkers
= list
;
738 /* Populate a list store for the combo box. */
740 store
= gtk_list_store_new (1, GTKHTML_TYPE_SPELL_CHECKER
);
742 while (list
!= NULL
) {
743 GtkhtmlSpellChecker
*checker
= list
->data
;
746 gtk_list_store_append (store
, &iter
);
747 gtk_list_store_set (store
, &iter
, 0, checker
, -1);
749 list
= g_list_next (list
);
752 /* FIXME Try to preserve the previously selected language. */
753 gtk_combo_box_set_model (combo_box
, GTK_TREE_MODEL (store
));
754 gtk_combo_box_set_active (combo_box
, 0);
756 g_object_unref (store
);
758 /* XXX notify property? */
761 GtkhtmlSpellChecker
*
762 gtkhtml_spell_dialog_get_active_checker (GtkhtmlSpellDialog
*dialog
)
764 GtkhtmlSpellChecker
*checker
;
765 GtkComboBox
*combo_box
;
769 g_return_val_if_fail (GTKHTML_IS_SPELL_DIALOG (dialog
), NULL
);
771 combo_box
= GTK_COMBO_BOX (dialog
->priv
->dictionary_combo
);
772 model
= gtk_combo_box_get_model (combo_box
);
774 if (!gtk_combo_box_get_active_iter (combo_box
, &iter
))
777 gtk_tree_model_get (model
, &iter
, COMBO_COLUMN_CHECKER
, &checker
, -1);
783 gtkhtml_spell_dialog_get_active_suggestion (GtkhtmlSpellDialog
*dialog
)
785 GtkTreeSelection
*selection
;
786 GtkTreeView
*tree_view
;
791 g_return_val_if_fail (GTKHTML_IS_SPELL_DIALOG (dialog
), NULL
);
793 tree_view
= GTK_TREE_VIEW (dialog
->priv
->tree_view
);
794 selection
= gtk_tree_view_get_selection (tree_view
);
796 /* If nothing is selected, return NULL. */
797 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
800 gtk_tree_model_get (model
, &iter
, 0, &word
, -1);
801 g_return_val_if_fail (word
!= NULL
, NULL
);