1 /* gdict-speller.c - display widget for dictionary matches
2 *
3 * Copyright (C) 2006 Emmanuele Bassi <ebassi@gmail.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library 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 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /**
20 * SECTION:gdict-speller
21 * @short_description: Display matching words
22 *
23 * #GdictSpeller is a widget showing a list of words returned by a
24 * #GdictContext query, using a specific database and a matching strategy.
25 */
26
27 #include "config.h"
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdarg.h>
33
34 #include <gdk/gdkkeysyms.h>
35 #include <gtk/gtk.h>
36 #include <glib/gi18n-lib.h>
37
38 #include "gdict-speller.h"
39 #include "gdict-utils.h"
40 #include "gdict-enum-types.h"
41 #include "gdict-marshal.h"
42 #include "gdict-debug.h"
43 #include "gdict-private.h"
44
45 struct _GdictSpellerPrivate
46 {
47 GdictContext *context;
48 gchar *database;
49 gchar *strategy;
50
51 gchar *word;
52
53 GtkWidget *treeview;
54 GtkWidget *clear_button;
55
56 GdkCursor *busy_cursor;
57
58 GtkListStore *store;
59 gint results;
60
61 guint start_id;
62 guint end_id;
63 guint match_id;
64 guint error_id;
65
66 guint is_searching : 1;
67 };
68
69 typedef enum
70 {
71 MATCH_DB,
72 MATCH_WORD,
73 MATCH_ERROR
74 } MatchType;
75
76 enum
77 {
78 MATCH_COLUMN_TYPE,
79 MATCH_COLUMN_DB_NAME,
80 MATCH_COLUMN_WORD,
81
82 MATCH_N_COLUMNS
83 };
84
85 enum
86 {
87 PROP_0,
88
89 PROP_CONTEXT,
90 PROP_WORD,
91 PROP_DATABASE,
92 PROP_STRATEGY,
93 PROP_COUNT
94 };
95
96 enum
97 {
98 WORD_ACTIVATED,
99
100 LAST_SIGNAL
101 };
102
103 static guint speller_signals[LAST_SIGNAL] = { 0 };
104
G_DEFINE_TYPE_WITH_PRIVATE(GdictSpeller,gdict_speller,GTK_TYPE_BOX)105 G_DEFINE_TYPE_WITH_PRIVATE (GdictSpeller, gdict_speller, GTK_TYPE_BOX)
106
107 static void
108 set_gdict_context (GdictSpeller *speller,
109 GdictContext *context)
110 {
111 GdictSpellerPrivate *priv;
112
113 g_assert (GDICT_IS_SPELLER (speller));
114
115 priv = speller->priv;
116 if (priv->context)
117 {
118 if (priv->start_id)
119 {
120 GDICT_NOTE (SPELLER, "Removing old context handlers");
121
122 g_signal_handler_disconnect (priv->context, priv->start_id);
123 g_signal_handler_disconnect (priv->context, priv->match_id);
124 g_signal_handler_disconnect (priv->context, priv->end_id);
125
126 priv->start_id = 0;
127 priv->end_id = 0;
128 priv->match_id = 0;
129 }
130
131 if (priv->error_id)
132 {
133 g_signal_handler_disconnect (priv->context, priv->error_id);
134
135 priv->error_id = 0;
136 }
137
138 GDICT_NOTE (SPELLER, "Removing old context");
139
140 g_object_unref (G_OBJECT (priv->context));
141 }
142
143 if (!context)
144 return;
145
146 if (!GDICT_IS_CONTEXT (context))
147 {
148 g_warning ("Object of type `%s' instead of a GdictContext\n",
149 g_type_name (G_OBJECT_TYPE (context)));
150 return;
151 }
152
153 GDICT_NOTE (SPELLER, "Setting new context\n");
154
155 priv->context = context;
156 g_object_ref (G_OBJECT (priv->context));
157 }
158
159 static void
gdict_speller_finalize(GObject * gobject)160 gdict_speller_finalize (GObject *gobject)
161 {
162 GdictSpeller *speller = GDICT_SPELLER (gobject);
163 GdictSpellerPrivate *priv = speller->priv;
164
165 if (priv->context)
166 set_gdict_context (speller, NULL);
167
168 g_clear_object (&priv->busy_cursor);
169
170 g_free (priv->strategy);
171 g_free (priv->database);
172 g_free (priv->word);
173
174 if (priv->store)
175 g_object_unref (priv->store);
176
177 G_OBJECT_CLASS (gdict_speller_parent_class)->finalize (gobject);
178 }
179
180
181 static void
gdict_speller_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * pspec)182 gdict_speller_set_property (GObject *gobject,
183 guint prop_id,
184 const GValue *value,
185 GParamSpec *pspec)
186 {
187 GdictSpeller *speller = GDICT_SPELLER (gobject);
188 GdictSpellerPrivate *priv = speller->priv;
189
190 switch (prop_id)
191 {
192 case PROP_CONTEXT:
193 set_gdict_context (speller, g_value_get_object (value));
194 break;
195 case PROP_DATABASE:
196 g_free (priv->database);
197 priv->database = g_strdup (g_value_get_string (value));
198 break;
199 case PROP_STRATEGY:
200 g_free (priv->strategy);
201 priv->strategy = g_strdup (g_value_get_string (value));
202 break;
203 default:
204 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
205 break;
206 }
207 }
208
209 static void
gdict_speller_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * pspec)210 gdict_speller_get_property (GObject *gobject,
211 guint prop_id,
212 GValue *value,
213 GParamSpec *pspec)
214 {
215 GdictSpeller *speller = GDICT_SPELLER (gobject);
216
217 switch (prop_id)
218 {
219 case PROP_DATABASE:
220 g_value_set_string (value, speller->priv->database);
221 break;
222 case PROP_STRATEGY:
223 g_value_set_string (value, speller->priv->strategy);
224 break;
225 case PROP_CONTEXT:
226 g_value_set_object (value, speller->priv->context);
227 break;
228 case PROP_COUNT:
229 g_value_set_int (value, speller->priv->results);
230 break;
231 default:
232 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
233 break;
234 }
235 }
236
237 static void
row_activated_cb(GtkTreeView * treeview,GtkTreePath * path,GtkTreeViewColumn * column,gpointer user_data)238 row_activated_cb (GtkTreeView *treeview,
239 GtkTreePath *path,
240 GtkTreeViewColumn *column,
241 gpointer user_data)
242 {
243 GdictSpeller *speller = GDICT_SPELLER (user_data);
244 GdictSpellerPrivate *priv = speller->priv;
245 GtkTreeIter iter;
246 gchar *word, *db_name;
247 gboolean valid;
248
249 valid = gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->store),
250 &iter,
251 path);
252 if (!valid)
253 {
254 g_warning ("Invalid iterator found");
255
256 return;
257 }
258
259 gtk_tree_model_get (GTK_TREE_MODEL (priv->store), &iter,
260 MATCH_COLUMN_WORD, &word,
261 MATCH_COLUMN_DB_NAME, &db_name,
262 -1);
263 if (word)
264 g_signal_emit (speller, speller_signals[WORD_ACTIVATED], 0,
265 word, db_name);
266 else
267 {
268 gchar *row = gtk_tree_path_to_string (path);
269
270 g_warning ("Row %s activated, but no word attached", row);
271 g_free (row);
272 }
273
274 g_free (word);
275 g_free (db_name);
276 }
277
278 static void
clear_button_clicked_cb(GtkWidget * widget,gpointer user_data)279 clear_button_clicked_cb (GtkWidget *widget,
280 gpointer user_data)
281 {
282 GdictSpeller *speller = GDICT_SPELLER (user_data);
283
284 gdict_speller_clear (speller);
285 }
286
287 static GObject *
gdict_speller_constructor(GType type,guint n_params,GObjectConstructParam * params)288 gdict_speller_constructor (GType type,
289 guint n_params,
290 GObjectConstructParam *params)
291 {
292 GObject *object;
293 GdictSpeller *speller;
294 GdictSpellerPrivate *priv;
295 GtkWidget *sw;
296 GtkCellRenderer *renderer;
297 GtkTreeViewColumn *column;
298 GtkWidget *hbox;
299
300 object = G_OBJECT_CLASS (gdict_speller_parent_class)->constructor (type,
301 n_params,
302 params);
303 speller = GDICT_SPELLER (object);
304 priv = speller->priv;
305
306 sw = gtk_scrolled_window_new (NULL, NULL);
307 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
308 GTK_POLICY_AUTOMATIC,
309 GTK_POLICY_AUTOMATIC);
310 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
311 GTK_SHADOW_IN);
312 gtk_box_pack_start (GTK_BOX (speller), sw, TRUE, TRUE, 0);
313 gtk_widget_show (sw);
314
315 renderer = gtk_cell_renderer_text_new ();
316 column = gtk_tree_view_column_new_with_attributes ("matches",
317 renderer,
318 "text", MATCH_COLUMN_WORD,
319 NULL);
320
321 priv->treeview = gtk_tree_view_new ();
322 gtk_tree_view_set_model (GTK_TREE_VIEW (priv->treeview),
323 GTK_TREE_MODEL (priv->store));
324 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->treeview), FALSE);
325 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->treeview), column);
326 g_signal_connect (priv->treeview, "row-activated",
327 G_CALLBACK (row_activated_cb), speller);
328 gtk_container_add (GTK_CONTAINER (sw), priv->treeview);
329 gtk_widget_show (priv->treeview);
330
331 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
332
333 priv->clear_button = gtk_button_new_from_icon_name ("edit-clear-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
334 gtk_button_set_always_show_image (GTK_BUTTON (priv->clear_button), TRUE);
335 g_signal_connect (priv->clear_button, "clicked",
336 G_CALLBACK (clear_button_clicked_cb),
337 speller);
338 gtk_box_pack_start (GTK_BOX (hbox), priv->clear_button, FALSE, FALSE, 0);
339 gtk_widget_show (priv->clear_button);
340 gtk_widget_set_tooltip_text (priv->clear_button, _("Clear the list of similar words"));
341
342 gtk_box_pack_end (GTK_BOX (speller), hbox, FALSE, FALSE, 0);
343 gtk_widget_show (hbox);
344
345 return object;
346 }
347
348 static void
gdict_speller_class_init(GdictSpellerClass * klass)349 gdict_speller_class_init (GdictSpellerClass *klass)
350 {
351 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
352
353 gobject_class->finalize = gdict_speller_finalize;
354 gobject_class->set_property = gdict_speller_set_property;
355 gobject_class->get_property = gdict_speller_get_property;
356 gobject_class->constructor = gdict_speller_constructor;
357
358 g_object_class_install_property (gobject_class,
359 PROP_CONTEXT,
360 g_param_spec_object ("context",
361 "Context",
362 "The GdictContext object used to get the word definition",
363 GDICT_TYPE_CONTEXT,
364 (G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)));
365 g_object_class_install_property (gobject_class,
366 PROP_DATABASE,
367 g_param_spec_string ("database",
368 "Database",
369 "The database used to query the GdictContext",
370 GDICT_DEFAULT_DATABASE,
371 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
372 g_object_class_install_property (gobject_class,
373 PROP_DATABASE,
374 g_param_spec_string ("strategy",
375 "Strategy",
376 "The strategy used to query the GdictContext",
377 GDICT_DEFAULT_STRATEGY,
378 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
379
380 speller_signals[WORD_ACTIVATED] =
381 g_signal_new ("word-activated",
382 G_OBJECT_CLASS_TYPE (gobject_class),
383 G_SIGNAL_RUN_LAST,
384 G_STRUCT_OFFSET (GdictSpellerClass, word_activated),
385 NULL, NULL,
386 gdict_marshal_VOID__STRING_STRING,
387 G_TYPE_NONE, 2,
388 G_TYPE_STRING,
389 G_TYPE_STRING);
390 }
391
392 static void
gdict_speller_init(GdictSpeller * speller)393 gdict_speller_init (GdictSpeller *speller)
394 {
395 GdictSpellerPrivate *priv;
396
397 speller->priv = priv = gdict_speller_get_instance_private (speller);
398
399 gtk_orientable_set_orientation (GTK_ORIENTABLE (speller), GTK_ORIENTATION_VERTICAL);
400
401 priv->database = NULL;
402 priv->strategy = NULL;
403 priv->word = NULL;
404
405 priv->results = -1;
406 priv->context = NULL;
407
408 priv->store = gtk_list_store_new (MATCH_N_COLUMNS,
409 G_TYPE_INT, /* MatchType */
410 G_TYPE_STRING, /* db_name */
411 G_TYPE_STRING /* word */);
412
413 priv->start_id = 0;
414 priv->end_id = 0;
415 priv->match_id = 0;
416 priv->error_id = 0;
417 }
418
419 /**
420 * gdict_speller_new:
421 *
422 * FIXME
423 *
424 * Return value: FIXME
425 *
426 * Since:
427 */
428 GtkWidget *
gdict_speller_new(void)429 gdict_speller_new (void)
430 {
431 return g_object_new (GDICT_TYPE_SPELLER, NULL);
432 }
433
434 /**
435 * gdict_speller_new_with_context:
436 * @context: a #GdictContext
437 *
438 * FIXME
439 *
440 * Return value: FIXME
441 *
442 * Since:
443 */
444 GtkWidget *
gdict_speller_new_with_context(GdictContext * context)445 gdict_speller_new_with_context (GdictContext *context)
446 {
447 g_return_val_if_fail (GDICT_IS_CONTEXT (context), NULL);
448
449 return g_object_new (GDICT_TYPE_SPELLER,
450 "context", context,
451 NULL);
452 }
453
454 /**
455 * gdict_speller_set_context:
456 * @speller: a #GdictSpeller
457 * @context: a #GdictContext
458 *
459 * FIXME
460 *
461 * Since:
462 */
463 void
gdict_speller_set_context(GdictSpeller * speller,GdictContext * context)464 gdict_speller_set_context (GdictSpeller *speller,
465 GdictContext *context)
466 {
467 g_return_if_fail (GDICT_IS_SPELLER (speller));
468 g_return_if_fail (context == NULL || GDICT_IS_CONTEXT (context));
469
470 set_gdict_context (speller, context);
471
472 g_object_notify (G_OBJECT (speller), "context");
473 }
474
475 /**
476 * gdict_speller_get_context:
477 * @speller: a #GdictSpeller
478 *
479 * FIXME
480 *
481 * Return value: (transfer none): a #GdictContext
482 *
483 * Since:
484 */
485 GdictContext *
gdict_speller_get_context(GdictSpeller * speller)486 gdict_speller_get_context (GdictSpeller *speller)
487 {
488 g_return_val_if_fail (GDICT_IS_SPELLER (speller), NULL);
489
490 return speller->priv->context;
491 }
492
493 /**
494 * gdict_speller_set_database:
495 * @speller: a #GdictSpeller
496 * @database: FIXME
497 *
498 * FIXME
499 *
500 * Since:
501 */
502 void
gdict_speller_set_database(GdictSpeller * speller,const gchar * database)503 gdict_speller_set_database (GdictSpeller *speller,
504 const gchar *database)
505 {
506 GdictSpellerPrivate *priv;
507
508 g_return_if_fail (GDICT_IS_SPELLER (speller));
509
510 priv = speller->priv;
511
512 if (!database || database[0] == '\0')
513 database = GDICT_DEFAULT_DATABASE;
514
515 g_free (priv->database);
516 priv->database = g_strdup (database);
517
518 g_object_notify (G_OBJECT (speller), "database");
519 }
520
521 /**
522 * gdict_speller_get_database:
523 * @speller: a #GdictSpeller
524 *
525 * FIXME
526 *
527 * Return value: FIXME
528 *
529 * Since: FIXME
530 */
531 const gchar *
gdict_speller_get_database(GdictSpeller * speller)532 gdict_speller_get_database (GdictSpeller *speller)
533 {
534 g_return_val_if_fail (GDICT_IS_SPELLER (speller), NULL);
535
536 return speller->priv->database;
537 }
538
539 /**
540 * gdict_speller_set_strategy:
541 * @speller: a #GdictSpeller
542 * @strategy: FIXME
543 *
544 * FIXME
545 *
546 * Since: FIXME
547 */
548 void
gdict_speller_set_strategy(GdictSpeller * speller,const gchar * strategy)549 gdict_speller_set_strategy (GdictSpeller *speller,
550 const gchar *strategy)
551 {
552 GdictSpellerPrivate *priv;
553
554 g_return_if_fail (GDICT_IS_SPELLER (speller));
555
556 priv = speller->priv;
557
558 if (!strategy || strategy[0] == '\0')
559 strategy = GDICT_DEFAULT_STRATEGY;
560
561 g_free (priv->strategy);
562 priv->strategy = g_strdup (strategy);
563
564 g_object_notify (G_OBJECT (speller), "strategy");
565 }
566
567 /**
568 * gdict_speller_get_strategy:
569 * @speller: a #GdictSpeller
570 *
571 * FIXME
572 *
573 * Return value: FIXME
574 *
575 * Since: FIXME
576 */
577 const gchar *
gdict_speller_get_strategy(GdictSpeller * speller)578 gdict_speller_get_strategy (GdictSpeller *speller)
579 {
580 g_return_val_if_fail (GDICT_IS_SPELLER (speller), NULL);
581
582 return speller->priv->strategy;
583 }
584
585 /**
586 * gdict_speller_clear:
587 * @speller: a #GdictSpeller
588 *
589 * FIXME
590 *
591 * Since: FIXME
592 */
593 void
gdict_speller_clear(GdictSpeller * speller)594 gdict_speller_clear (GdictSpeller *speller)
595 {
596 GdictSpellerPrivate *priv;
597
598 g_return_if_fail (GDICT_IS_SPELLER (speller));
599 priv = speller->priv;
600
601 gtk_tree_view_set_model (GTK_TREE_VIEW (priv->treeview), NULL);
602
603 gtk_list_store_clear (priv->store);
604 priv->results = -1;
605
606 gtk_tree_view_set_model (GTK_TREE_VIEW (priv->treeview),
607 GTK_TREE_MODEL (priv->store));
608 }
609
610 static void
lookup_start_cb(GdictContext * context,gpointer user_data)611 lookup_start_cb (GdictContext *context,
612 gpointer user_data)
613 {
614 GdictSpeller *speller = GDICT_SPELLER (user_data);
615 GdictSpellerPrivate *priv = speller->priv;
616
617 if (!priv->busy_cursor)
618 {
619 GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (speller));
620 priv->busy_cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
621 }
622
623 if (gtk_widget_get_window (GTK_WIDGET (speller)))
624 gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (speller)), priv->busy_cursor);
625
626 priv->is_searching = TRUE;
627 }
628
629 static void
lookup_end_cb(GdictContext * context,gpointer user_data)630 lookup_end_cb (GdictContext *context,
631 gpointer user_data)
632 {
633 GdictSpeller *speller = GDICT_SPELLER (user_data);
634 GdictSpellerPrivate *priv = speller->priv;
635
636 if (gtk_widget_get_window (GTK_WIDGET (speller)))
637 gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (speller)), NULL);
638
639 g_free (priv->word);
640 priv->word = NULL;
641
642 priv->is_searching = FALSE;
643 }
644
645 static void
match_found_cb(GdictContext * context,GdictMatch * match,gpointer user_data)646 match_found_cb (GdictContext *context,
647 GdictMatch *match,
648 gpointer user_data)
649 {
650 GdictSpeller *speller = GDICT_SPELLER (user_data);
651 GdictSpellerPrivate *priv = speller->priv;
652 GtkTreeIter iter;
653
654 GDICT_NOTE (SPELLER, "MATCH: `%s' (from `%s')",
655 gdict_match_get_word (match),
656 gdict_match_get_database (match));
657
658 gtk_list_store_append (priv->store, &iter);
659 gtk_list_store_set (priv->store, &iter,
660 MATCH_COLUMN_TYPE, MATCH_WORD,
661 MATCH_COLUMN_DB_NAME, gdict_match_get_database (match),
662 MATCH_COLUMN_WORD, gdict_match_get_word (match),
663 -1);
664
665 if (priv->results == -1)
666 priv->results = 1;
667 else
668 priv->results += 1;
669 }
670
671 static void
error_cb(GdictContext * context,const GError * error,gpointer user_data)672 error_cb (GdictContext *context,
673 const GError *error,
674 gpointer user_data)
675 {
676 GdictSpeller *speller = GDICT_SPELLER (user_data);
677 GdictSpellerPrivate *priv = speller->priv;
678
679 gdict_speller_clear (speller);
680
681 if (gtk_widget_get_window (GTK_WIDGET (speller)))
682 gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (speller)), NULL);
683
684 g_free (priv->word);
685 priv->word = NULL;
686
687 priv->is_searching = FALSE;
688 }
689
690 /**
691 * gdict_speller_match:
692 * @speller: a #GdictSpeller
693 * @word: FIXME
694 *
695 * FIXME
696 *
697 * Since: FIXME
698 */
699 void
gdict_speller_match(GdictSpeller * speller,const gchar * word)700 gdict_speller_match (GdictSpeller *speller,
701 const gchar *word)
702 {
703 GdictSpellerPrivate *priv;
704 GError *match_error;
705
706 g_return_if_fail (GDICT_IS_SPELLER (speller));
707 g_return_if_fail (word != NULL);
708
709 priv = speller->priv;
710
711 if (!priv->context)
712 {
713 g_warning ("Attempting to match `%s', but no GdictContext "
714 "has been set. Use gdict_speller_set_context() "
715 "before invoking gdict_speller_match().",
716 word);
717
718 return;
719 }
720
721 if (priv->is_searching)
722 {
723 _gdict_show_error_dialog (NULL,
724 _("Another search is in progress"),
725 _("Please wait until the current search ends."));
726
727 return;
728 }
729
730 gdict_speller_clear (speller);
731
732 if (!priv->start_id)
733 {
734 priv->start_id = g_signal_connect (priv->context, "lookup-start",
735 G_CALLBACK (lookup_start_cb),
736 speller);
737 priv->match_id = g_signal_connect (priv->context, "match-found",
738 G_CALLBACK (match_found_cb),
739 speller);
740 priv->end_id = g_signal_connect (priv->context, "lookup-end",
741 G_CALLBACK (lookup_end_cb),
742 speller);
743 }
744
745 if (!priv->error_id)
746 priv->error_id = g_signal_connect (priv->context, "error",
747 G_CALLBACK (error_cb),
748 speller);
749
750 g_free (priv->word);
751 priv->word = g_strdup (word);
752
753 match_error = NULL;
754 gdict_context_match_word (priv->context,
755 priv->database,
756 priv->strategy,
757 priv->word,
758 &match_error);
759 if (match_error)
760 {
761 GtkTreeIter iter;
762
763 gtk_list_store_append (priv->store, &iter);
764 gtk_list_store_set (priv->store, &iter,
765 MATCH_COLUMN_TYPE, MATCH_ERROR,
766 MATCH_COLUMN_DB_NAME, _("Error while matching"),
767 MATCH_COLUMN_WORD, NULL,
768 -1);
769
770 g_warning ("Error while matching `%s': %s",
771 priv->word,
772 match_error->message);
773
774 g_error_free (match_error);
775 }
776 }
777
778 /**
779 * gdict_speller_count_match:
780 * @speller: a #GdictSpeller
781 *
782 * FIXME
783 *
784 * Return value: FIXME
785 *
786 * Since: FIXME
787 */
788 gint
gdict_speller_count_matches(GdictSpeller * speller)789 gdict_speller_count_matches (GdictSpeller *speller)
790 {
791 g_return_val_if_fail (GDICT_IS_SPELLER (speller), -1);
792
793 return speller->priv->results;
794 }
795
796 /**
797 * gdict_speller_get_matches:
798 * @speller: a #GdictSpeller
799 * @length: FIXME
800 *
801 * FIXME
802 *
803 * Return value: (transfer full): FIXME
804 *
805 * Since: FIXME
806 */
807 gchar **
gdict_speller_get_matches(GdictSpeller * speller,gsize length)808 gdict_speller_get_matches (GdictSpeller *speller,
809 gsize length)
810 {
811 g_return_val_if_fail (GDICT_IS_SPELLER (speller), NULL);
812
813 return NULL;
814 }
815