gspell-checker-dialog.c 19.3 KB
Newer Older
1
/*
2
 * This file is part of gspell, a spell-checking library.
3
 *
4 5
 * Copyright 2002 - Paolo Maggi
 * Copyright 2015 - Sébastien Wilmet
6
 *
7 8 9 10
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
16
 *
17 18
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, see <http://www.gnu.org/licenses/>.
19 20
 */

21
#ifdef HAVE_CONFIG_H
22 23 24
#include <config.h>
#endif

25
#include "gspell-checker-dialog.h"
26
#include <glib/gi18n-lib.h>
27
#include "gspell-checker.h"
28 29

/**
30
 * SECTION:checker-dialog
31
 * @Short_description: Spell checker dialog
32 33
 * @Title: GspellCheckerDialog
 * @See_also: #GspellNavigator
34
 *
35 36
 * #GspellCheckerDialog is a #GtkDialog to spell check a document one word
 * at a time. It uses a #GspellNavigator.
37 38
 */

39
typedef struct _GspellCheckerDialogPrivate GspellCheckerDialogPrivate;
40

41
struct _GspellCheckerDialogPrivate
42
{
43 44
	GspellNavigator *navigator;
	GspellChecker *checker;
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

	gchar *misspelled_word;

	GtkLabel *misspelled_word_label;
	GtkEntry *word_entry;
	GtkWidget *check_word_button;
	GtkWidget *ignore_button;
	GtkWidget *ignore_all_button;
	GtkWidget *change_button;
	GtkWidget *change_all_button;
	GtkWidget *add_word_button;
	GtkTreeView *suggestions_view;

	guint initialized : 1;
};

enum
{
	PROP_0,
	PROP_SPELL_NAVIGATOR,
};

enum
{
	COLUMN_SUGGESTION,
	N_COLUMNS
};

73
G_DEFINE_TYPE_WITH_PRIVATE (GspellCheckerDialog, gspell_checker_dialog, GTK_TYPE_DIALOG)
74 75

static void
76 77
set_spell_checker (GspellCheckerDialog *dialog,
		   GspellChecker       *checker)
78
{
79
	GspellCheckerDialogPrivate *priv;
80

81
	priv = gspell_checker_dialog_get_instance_private (dialog);
82 83 84 85

	if (g_set_object (&priv->checker, checker))
	{
		GtkHeaderBar *header_bar;
86
		const GspellLanguage *lang;
87 88 89

		header_bar = GTK_HEADER_BAR (gtk_dialog_get_header_bar (GTK_DIALOG (dialog)));

90
		lang = gspell_checker_get_language (checker);
91 92

		gtk_header_bar_set_subtitle (header_bar,
93
					     gspell_language_get_name (lang));
94 95 96 97
	}
}

static void
98 99
set_navigator (GspellCheckerDialog *dialog,
	       GspellNavigator     *navigator)
100
{
101
	GspellCheckerDialogPrivate *priv;
102

103
	priv = gspell_checker_dialog_get_instance_private (dialog);
104 105

	g_return_if_fail (priv->navigator == NULL);
106
	priv->navigator = g_object_ref_sink (navigator);
107 108 109 110 111

	g_object_notify (G_OBJECT (dialog), "spell-navigator");
}

static void
112
clear_suggestions (GspellCheckerDialog *dialog)
113
{
114
	GspellCheckerDialogPrivate *priv;
115 116
	GtkListStore *store;

117
	priv = gspell_checker_dialog_get_instance_private (dialog);
118 119 120 121 122 123 124 125

	store = GTK_LIST_STORE (gtk_tree_view_get_model (priv->suggestions_view));
	gtk_list_store_clear (store);

	gtk_tree_view_columns_autosize (priv->suggestions_view);
}

static void
126
set_suggestions (GspellCheckerDialog *dialog,
127
		 GSList              *suggestions)
128
{
129
	GspellCheckerDialogPrivate *priv;
130 131 132 133 134 135
	GtkListStore *store;
	GtkTreeIter iter;
	GtkTreeSelection *selection;
	const gchar *first_suggestion;
	GSList *l;

136
	priv = gspell_checker_dialog_get_instance_private (dialog);
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178

	clear_suggestions (dialog);

	store = GTK_LIST_STORE (gtk_tree_view_get_model (priv->suggestions_view));

	if (suggestions == NULL)
	{
		gtk_list_store_append (store, &iter);
		gtk_list_store_set (store, &iter,
				    /* Translators: Displayed in the "Check Spelling"
				     * dialog if there are no suggestions for the current
				     * misspelled word.
				     */
				    COLUMN_SUGGESTION, _("(no suggested words)"),
				    -1);

		gtk_entry_set_text (priv->word_entry, "");
		gtk_widget_set_sensitive (GTK_WIDGET (priv->suggestions_view), FALSE);
		return;
	}

	gtk_widget_set_sensitive (GTK_WIDGET (priv->suggestions_view), TRUE);

	first_suggestion = suggestions->data;
	gtk_entry_set_text (priv->word_entry, first_suggestion);

	for (l = suggestions; l != NULL; l = l->next)
	{
		const gchar *suggestion = l->data;

		gtk_list_store_append (store, &iter);
		gtk_list_store_set (store, &iter,
				    COLUMN_SUGGESTION, suggestion,
				    -1);
	}

	selection = gtk_tree_view_get_selection (priv->suggestions_view);
	gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
	gtk_tree_selection_select_iter (selection, &iter);
}

static void
179
set_misspelled_word (GspellCheckerDialog *dialog,
180
		     const gchar         *word)
181
{
182
	GspellCheckerDialogPrivate *priv;
183 184 185 186 187
	gchar *label;
	GSList *suggestions;

	g_assert (word != NULL);

188
	priv = gspell_checker_dialog_get_instance_private (dialog);
189

190
	g_return_if_fail (!gspell_checker_check_word (priv->checker, word, -1, NULL));
191 192 193 194 195 196 197 198

	g_free (priv->misspelled_word);
	priv->misspelled_word = g_strdup (word);

	label = g_strdup_printf("<b>%s</b>", word);
	gtk_label_set_markup (priv->misspelled_word_label, label);
	g_free (label);

199
	suggestions = gspell_checker_get_suggestions (priv->checker, priv->misspelled_word, -1);
200 201 202 203 204 205 206

	set_suggestions (dialog, suggestions);

	g_slist_free_full (suggestions, g_free);
}

static void
207
set_completed (GspellCheckerDialog *dialog)
208
{
209
	GspellCheckerDialogPrivate *priv;
210

211
	priv = gspell_checker_dialog_get_instance_private (dialog);
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226

	clear_suggestions (dialog);
	gtk_entry_set_text (priv->word_entry, "");

	gtk_widget_set_sensitive (GTK_WIDGET (priv->word_entry), FALSE);
	gtk_widget_set_sensitive (priv->check_word_button, FALSE);
	gtk_widget_set_sensitive (priv->ignore_button, FALSE);
	gtk_widget_set_sensitive (priv->ignore_all_button, FALSE);
	gtk_widget_set_sensitive (priv->change_button, FALSE);
	gtk_widget_set_sensitive (priv->change_all_button, FALSE);
	gtk_widget_set_sensitive (priv->add_word_button, FALSE);
	gtk_widget_set_sensitive (GTK_WIDGET (priv->suggestions_view), FALSE);
}

static void
227
show_error (GspellCheckerDialog *dialog,
228
	    GError              *error)
229
{
230
	GspellCheckerDialogPrivate *priv;
231 232
	gchar *label;

233
	priv = gspell_checker_dialog_get_instance_private (dialog);
234 235 236 237 238 239 240 241 242

	label = g_strdup_printf ("<b>%s</b> %s", _("Error:"), error->message);
	gtk_label_set_markup (priv->misspelled_word_label, label);
	g_free (label);

	set_completed (dialog);
}

static void
243
goto_next (GspellCheckerDialog *dialog)
244
{
245
	GspellCheckerDialogPrivate *priv;
246
	gchar *word = NULL;
247
	GspellChecker *checker = NULL;
248 249 250
	GError *error = NULL;
	gboolean found;

251
	priv = gspell_checker_dialog_get_instance_private (dialog);
252

253
	found = gspell_navigator_goto_next (priv->navigator, &word, &checker, &error);
254 255 256 257

	if (error != NULL)
	{
		show_error (dialog, error);
Sébastien Wilmet's avatar
Sébastien Wilmet committed
258
		g_clear_error (&error);
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
	}
	else if (found)
	{
		set_spell_checker (dialog, checker);
		set_misspelled_word (dialog, word);
	}
	else
	{
		gchar *label;

		if (priv->initialized)
		{
			label = g_strdup_printf ("<b>%s</b>", _("Completed spell checking"));
		}
		else
		{
			label = g_strdup_printf ("<b>%s</b>", _("No misspelled words"));
		}

		gtk_label_set_markup (priv->misspelled_word_label, label);
		g_free (label);

		set_completed (dialog);
	}

	priv->initialized = TRUE;

	g_free (word);
	g_clear_object (&checker);
}

static void
291 292 293 294
gspell_checker_dialog_get_property (GObject    *object,
				    guint       prop_id,
				    GValue     *value,
				    GParamSpec *pspec)
295
{
296
	GspellCheckerDialog *dialog = GSPELL_CHECKER_DIALOG (object);
297 298 299 300

	switch (prop_id)
	{
		case PROP_SPELL_NAVIGATOR:
301
			g_value_set_object (value, gspell_checker_dialog_get_spell_navigator (dialog));
302 303 304 305 306 307 308 309 310
			break;

		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
			break;
	}
}

static void
311 312 313 314
gspell_checker_dialog_set_property (GObject      *object,
				    guint         prop_id,
				    const GValue *value,
				    GParamSpec   *pspec)
315
{
316
	GspellCheckerDialog *dialog = GSPELL_CHECKER_DIALOG (object);
317 318 319 320 321 322 323 324 325 326 327 328 329 330

	switch (prop_id)
	{
		case PROP_SPELL_NAVIGATOR:
			set_navigator (dialog, g_value_get_object (value));
			break;

		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
			break;
	}
}

static void
331
gspell_checker_dialog_dispose (GObject *object)
332
{
333
	GspellCheckerDialogPrivate *priv;
334

335
	priv = gspell_checker_dialog_get_instance_private (GSPELL_CHECKER_DIALOG (object));
336 337 338 339

	g_clear_object (&priv->navigator);
	g_clear_object (&priv->checker);

340
	G_OBJECT_CLASS (gspell_checker_dialog_parent_class)->dispose (object);
341 342 343
}

static void
344
gspell_checker_dialog_finalize (GObject *object)
345
{
346
	GspellCheckerDialogPrivate *priv;
347

348
	priv = gspell_checker_dialog_get_instance_private (GSPELL_CHECKER_DIALOG (object));
349 350 351

	g_free (priv->misspelled_word);

352
	G_OBJECT_CLASS (gspell_checker_dialog_parent_class)->finalize (object);
353 354 355
}

static void
356
gspell_checker_dialog_show (GtkWidget *widget)
357
{
358 359
	GspellCheckerDialog *dialog = GSPELL_CHECKER_DIALOG (widget);
	GspellCheckerDialogPrivate *priv;
360

361
	priv = gspell_checker_dialog_get_instance_private (dialog);
362 363

	/* Chain-up */
364
	if (GTK_WIDGET_CLASS (gspell_checker_dialog_parent_class)->show != NULL)
365
	{
366
		GTK_WIDGET_CLASS (gspell_checker_dialog_parent_class)->show (widget);
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
	}

	/* A typical implementation of a SpellNavigator is to select the
	 * misspelled word when goto_next() is called. Showing the dialog makes
	 * a focus change, which can unselect the buffer selection (e.g. in a
	 * GtkTextBuffer). So that's why goto_next() is called after the
	 * chain-up.
	 */
	if (!priv->initialized)
	{
		goto_next (dialog);
	}
}

static void
382
gspell_checker_dialog_class_init (GspellCheckerDialogClass *klass)
383 384 385 386
{
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);

387 388 389 390
	object_class->get_property = gspell_checker_dialog_get_property;
	object_class->set_property = gspell_checker_dialog_set_property;
	object_class->dispose = gspell_checker_dialog_dispose;
	object_class->finalize = gspell_checker_dialog_finalize;
391

392
	widget_class->show = gspell_checker_dialog_show;
393 394

	/**
395
	 * GspellCheckerDialog:spell-navigator:
396
	 *
397
	 * The #GspellNavigator to use.
398 399 400 401 402 403
	 */
	g_object_class_install_property (object_class,
					 PROP_SPELL_NAVIGATOR,
					 g_param_spec_object ("spell-navigator",
							      "Spell Navigator",
							      "",
404
							      GSPELL_TYPE_NAVIGATOR,
405 406 407 408 409 410
							      G_PARAM_READWRITE |
							      G_PARAM_CONSTRUCT_ONLY |
							      G_PARAM_STATIC_STRINGS));

	/* Bind class to template */
	gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/gspell/checker-dialog.ui");
411 412 413 414 415 416 417 418 419
	gtk_widget_class_bind_template_child_private (widget_class, GspellCheckerDialog, misspelled_word_label);
	gtk_widget_class_bind_template_child_private (widget_class, GspellCheckerDialog, word_entry);
	gtk_widget_class_bind_template_child_private (widget_class, GspellCheckerDialog, check_word_button);
	gtk_widget_class_bind_template_child_private (widget_class, GspellCheckerDialog, ignore_button);
	gtk_widget_class_bind_template_child_private (widget_class, GspellCheckerDialog, ignore_all_button);
	gtk_widget_class_bind_template_child_private (widget_class, GspellCheckerDialog, change_button);
	gtk_widget_class_bind_template_child_private (widget_class, GspellCheckerDialog, change_all_button);
	gtk_widget_class_bind_template_child_private (widget_class, GspellCheckerDialog, add_word_button);
	gtk_widget_class_bind_template_child_private (widget_class, GspellCheckerDialog, suggestions_view);
420 421 422
}

static void
423
word_entry_changed_handler (GtkEntry            *word_entry,
424
			    GspellCheckerDialog *dialog)
425
{
426
	GspellCheckerDialogPrivate *priv;
427 428
	gboolean sensitive;

429
	priv = gspell_checker_dialog_get_instance_private (dialog);
430 431 432 433 434 435 436 437 438

	sensitive = gtk_entry_get_text_length (word_entry) > 0;

	gtk_widget_set_sensitive (priv->check_word_button, sensitive);
	gtk_widget_set_sensitive (priv->change_button, sensitive);
	gtk_widget_set_sensitive (priv->change_all_button, sensitive);
}

static void
439
suggestions_selection_changed_handler (GtkTreeSelection    *selection,
440
				       GspellCheckerDialog *dialog)
441
{
442
	GspellCheckerDialogPrivate *priv;
443 444 445 446
	GtkTreeModel *model;
	GtkTreeIter iter;
	gchar *text;

447
	priv = gspell_checker_dialog_get_instance_private (dialog);
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463

	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
	{
		return;
	}

	gtk_tree_model_get (model, &iter,
			    COLUMN_SUGGESTION, &text,
			    -1);

	gtk_entry_set_text (priv->word_entry, text);

	g_free (text);
}

static void
464
check_word_button_clicked_handler (GtkButton           *button,
465
				   GspellCheckerDialog *dialog)
466
{
467
	GspellCheckerDialogPrivate *priv;
468 469 470 471
	const gchar *word;
	gboolean correctly_spelled;
	GError *error = NULL;

472
	priv = gspell_checker_dialog_get_instance_private (dialog);
473 474 475 476 477

	g_return_if_fail (gtk_entry_get_text_length (priv->word_entry) > 0);

	word = gtk_entry_get_text (priv->word_entry);

478
	correctly_spelled = gspell_checker_check_word (priv->checker, word, -1, &error);
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510

	if (error != NULL)
	{
		show_error (dialog, error);
		g_error_free (error);
		return;
	}

	if (correctly_spelled)
	{
		GtkListStore *store;
		GtkTreeIter iter;

		clear_suggestions (dialog);

		store = GTK_LIST_STORE (gtk_tree_view_get_model (priv->suggestions_view));

		gtk_list_store_append (store, &iter);
		gtk_list_store_set (store, &iter,
		                    /* Translators: Displayed in the "Check
				     * Spelling" dialog if the current word
				     * isn't misspelled.
				     */
				    COLUMN_SUGGESTION, _("(correct spelling)"),
				    -1);

		gtk_widget_set_sensitive (GTK_WIDGET (priv->suggestions_view), FALSE);
	}
	else
	{
		GSList *suggestions;

511
		suggestions = gspell_checker_get_suggestions (priv->checker, word, -1);
512 513 514 515 516 517 518 519

		set_suggestions (dialog, suggestions);

		g_slist_free_full (suggestions, g_free);
	}
}

static void
520
add_word_button_clicked_handler (GtkButton           *button,
521
				 GspellCheckerDialog *dialog)
522
{
523
	GspellCheckerDialogPrivate *priv;
524

525
	priv = gspell_checker_dialog_get_instance_private (dialog);
526 527 528

	g_return_if_fail (priv->misspelled_word != NULL);

529
	gspell_checker_add_word_to_personal (priv->checker, priv->misspelled_word, -1);
530 531 532 533 534

	goto_next (dialog);
}

static void
535
ignore_button_clicked_handler (GtkButton           *button,
536
			       GspellCheckerDialog *dialog)
537 538 539 540 541
{
	goto_next (dialog);
}

static void
542
ignore_all_button_clicked_handler (GtkButton           *button,
543
				   GspellCheckerDialog *dialog)
544
{
545
	GspellCheckerDialogPrivate *priv;
546

547
	priv = gspell_checker_dialog_get_instance_private (dialog);
548 549 550

	g_return_if_fail (priv->misspelled_word != NULL);

551
	gspell_checker_add_word_to_session (priv->checker, priv->misspelled_word, -1);
552 553 554 555 556

	goto_next (dialog);
}

static void
557
change_button_clicked_handler (GtkButton           *button,
558
			       GspellCheckerDialog *dialog)
559
{
560
	GspellCheckerDialogPrivate *priv;
561
	const gchar *entry_text;
562 563
	gchar *change_to;

564
	priv = gspell_checker_dialog_get_instance_private (dialog);
565 566 567

	g_return_if_fail (priv->misspelled_word != NULL);

568 569 570
	entry_text = gtk_entry_get_text (priv->word_entry);
	g_return_if_fail (entry_text != NULL);
	g_return_if_fail (entry_text[0] != '\0');
571

572
	change_to = g_strdup (entry_text);
573
	gspell_checker_set_correction (priv->checker,
574 575
				       priv->misspelled_word, -1,
				       change_to, -1);
576

577
	gspell_navigator_change (priv->navigator, priv->misspelled_word, change_to);
578 579 580 581 582 583 584
	g_free (change_to);

	goto_next (dialog);
}

/* double click on one of the suggestions is like clicking on "change" */
static void
585 586 587
suggestions_row_activated_handler (GtkTreeView         *view,
				   GtkTreePath         *path,
				   GtkTreeViewColumn   *column,
588
				   GspellCheckerDialog *dialog)
589
{
590
	GspellCheckerDialogPrivate *priv;
591

592
	priv = gspell_checker_dialog_get_instance_private (dialog);
593 594 595 596 597

	change_button_clicked_handler (GTK_BUTTON (priv->change_button), dialog);
}

static void
598
change_all_button_clicked_handler (GtkButton           *button,
599
				   GspellCheckerDialog *dialog)
600
{
601
	GspellCheckerDialogPrivate *priv;
602
	const gchar *entry_text;
603 604
	gchar *change_to;

605
	priv = gspell_checker_dialog_get_instance_private (dialog);
606 607 608

	g_return_if_fail (priv->misspelled_word != NULL);

609 610 611
	entry_text = gtk_entry_get_text (priv->word_entry);
	g_return_if_fail (entry_text != NULL);
	g_return_if_fail (entry_text[0] != '\0');
612

613
	change_to = g_strdup (entry_text);
614
	gspell_checker_set_correction (priv->checker,
615 616
				       priv->misspelled_word, -1,
				       change_to, -1);
617

618
	gspell_navigator_change_all (priv->navigator, priv->misspelled_word, change_to);
619 620 621 622 623 624
	g_free (change_to);

	goto_next (dialog);
}

static void
625
gspell_checker_dialog_init (GspellCheckerDialog *dialog)
626
{
627
	GspellCheckerDialogPrivate *priv;
628 629 630 631 632
	GtkListStore *store;
	GtkTreeViewColumn *column;
	GtkCellRenderer *cell;
	GtkTreeSelection *selection;

633
	priv = gspell_checker_dialog_get_instance_private (dialog);
634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706

	gtk_widget_init_template (GTK_WIDGET (dialog));

	/* Suggestion list */
	store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING);
	gtk_tree_view_set_model (priv->suggestions_view, GTK_TREE_MODEL (store));
	g_object_unref (store);

	/* Add the suggestions column */
	cell = gtk_cell_renderer_text_new ();
	column = gtk_tree_view_column_new_with_attributes (_("Suggestions"), cell,
							   "text", COLUMN_SUGGESTION,
							   NULL);

	gtk_tree_view_append_column (priv->suggestions_view, column);

	gtk_tree_view_set_search_column (priv->suggestions_view, COLUMN_SUGGESTION);

	selection = gtk_tree_view_get_selection (priv->suggestions_view);

	gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);

	/* Connect signals */
	g_signal_connect (priv->word_entry,
			  "changed",
			  G_CALLBACK (word_entry_changed_handler),
			  dialog);

	g_signal_connect_object (selection,
				 "changed",
				 G_CALLBACK (suggestions_selection_changed_handler),
				 dialog,
				 0);

	g_signal_connect (priv->check_word_button,
			  "clicked",
			  G_CALLBACK (check_word_button_clicked_handler),
			  dialog);

	g_signal_connect (priv->add_word_button,
			  "clicked",
			  G_CALLBACK (add_word_button_clicked_handler),
			  dialog);

	g_signal_connect (priv->ignore_button,
			  "clicked",
			  G_CALLBACK (ignore_button_clicked_handler),
			  dialog);

	g_signal_connect (priv->ignore_all_button,
			  "clicked",
			  G_CALLBACK (ignore_all_button_clicked_handler),
			  dialog);

	g_signal_connect (priv->change_button,
			  "clicked",
			  G_CALLBACK (change_button_clicked_handler),
			  dialog);

	g_signal_connect (priv->change_all_button,
			  "clicked",
			  G_CALLBACK (change_all_button_clicked_handler),
			  dialog);

	g_signal_connect (priv->suggestions_view,
			  "row-activated",
			  G_CALLBACK (suggestions_row_activated_handler),
			  dialog);

	gtk_widget_grab_default (priv->change_button);
}

/**
707
 * gspell_checker_dialog_new:
708
 * @parent: transient parent of the dialog.
709
 * @navigator: the #GspellNavigator to use.
710
 *
711
 * Returns: a new #GspellCheckerDialog widget.
712 713
 */
GtkWidget *
714
gspell_checker_dialog_new (GtkWindow       *parent,
715
			   GspellNavigator *navigator)
716 717
{
	g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL);
718
	g_return_val_if_fail (GSPELL_IS_NAVIGATOR (navigator), NULL);
719

720
	return g_object_new (GSPELL_TYPE_CHECKER_DIALOG,
721 722 723 724 725 726
			     "transient-for", parent,
			     "use-header-bar", TRUE,
			     "spell-navigator", navigator,
			     NULL);
}

727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743
/**
 * gspell_checker_dialog_get_spell_navigator:
 * @dialog: a #GspellCheckerDialog.
 *
 * Returns: (transfer none): the #GspellNavigator used.
 */
GspellNavigator *
gspell_checker_dialog_get_spell_navigator (GspellCheckerDialog *dialog)
{
	GspellCheckerDialogPrivate *priv;

	g_return_val_if_fail (GSPELL_IS_CHECKER_DIALOG (dialog), NULL);

	priv = gspell_checker_dialog_get_instance_private (dialog);
	return priv->navigator;
}

744
/* ex:set ts=8 noet: */