]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-spell-dialog.c
c5914ce9415fa3156872f18c7e775c6b69aeb740
[empathy.git] / libempathy-gtk / empathy-spell-dialog.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2004-2007 Imendio AB
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
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.
14  *
15  * You should have received a copy of the GNU 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.
19  */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include <glib/gi18n-lib.h>
26 #include <gtk/gtkcellrenderertext.h>
27 #include <gtk/gtkdialog.h>
28 #include <gtk/gtklabel.h>
29 #include <gtk/gtkliststore.h>
30 #include <gtk/gtktreeview.h>
31 #include <gtk/gtktreeselection.h>
32 #include <gtk/gtksizegroup.h>
33 #include <glade/glade.h>
34
35 #include <libempathy/empathy-utils.h>
36
37 #include "empathy-chat.h"
38 #include "empathy-spell.h"
39 #include "empathy-spell-dialog.h"
40 #include "empathy-ui-utils.h"
41
42 typedef struct {
43         GtkWidget   *window;
44         GtkWidget   *button_replace;
45         GtkWidget   *label_word;
46         GtkWidget   *treeview_words;
47
48         EmpathyChat  *chat;
49
50         gchar       *word;
51         GtkTextIter  start;
52         GtkTextIter  end;
53 } EmpathySpellDialog;
54
55 enum {
56         COL_SPELL_WORD,
57         COL_SPELL_COUNT
58 };
59
60 static void spell_dialog_model_populate_columns     (EmpathySpellDialog *dialog);
61 static void spell_dialog_model_populate_suggestions (EmpathySpellDialog *dialog);
62 static void spell_dialog_model_row_activated_cb     (GtkTreeView       *tree_view,
63                                                      GtkTreePath       *path,
64                                                      GtkTreeViewColumn *column,
65                                                      EmpathySpellDialog *dialog);
66 static void spell_dialog_model_selection_changed_cb (GtkTreeSelection  *treeselection,
67                                                      EmpathySpellDialog *dialog);
68 static void spell_dialog_model_setup                (EmpathySpellDialog *dialog);
69 static void spell_dialog_response_cb                (GtkWidget         *widget,
70                                                      gint               response,
71                                                      EmpathySpellDialog *dialog);
72 static void spell_dialog_destroy_cb                 (GtkWidget         *widget,
73                                                      EmpathySpellDialog *dialog);
74
75 static void
76 spell_dialog_model_populate_columns (EmpathySpellDialog *dialog)
77 {
78         GtkTreeModel      *model;
79         GtkTreeViewColumn *column;
80         GtkCellRenderer   *renderer;
81         guint              col_offset;
82
83         model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview_words));
84
85         renderer = gtk_cell_renderer_text_new ();
86         col_offset = gtk_tree_view_insert_column_with_attributes (
87                 GTK_TREE_VIEW (dialog->treeview_words),
88                 -1, _("Word"),
89                 renderer,
90                 "text", COL_SPELL_WORD,
91                 NULL);
92
93         g_object_set_data (G_OBJECT (renderer),
94                            "column", GINT_TO_POINTER (COL_SPELL_WORD));
95
96         column = gtk_tree_view_get_column (GTK_TREE_VIEW (dialog->treeview_words), col_offset - 1);
97         gtk_tree_view_column_set_sort_column_id (column, COL_SPELL_WORD);
98         gtk_tree_view_column_set_resizable (column, FALSE);
99         gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE);
100 }
101
102 static void
103 spell_dialog_model_populate_suggestions (EmpathySpellDialog *dialog)
104 {
105         GtkTreeModel *model;
106         GtkListStore *store;
107         GList        *suggestions, *l;
108
109         model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview_words));
110         store = GTK_LIST_STORE (model);
111
112         suggestions = empathy_spell_get_suggestions (dialog->word);
113         for (l = suggestions; l; l=l->next) {
114                 GtkTreeIter  iter;
115                 gchar       *word;
116
117                 word = l->data;
118
119                 gtk_list_store_append (store, &iter);
120                 gtk_list_store_set (store, &iter,
121                                     COL_SPELL_WORD, word,
122                                     -1);
123         }
124
125         empathy_spell_free_suggestions (suggestions);
126 }
127
128 static void
129 spell_dialog_model_row_activated_cb (GtkTreeView       *tree_view,
130                                GtkTreePath       *path,
131                                GtkTreeViewColumn *column,
132                                EmpathySpellDialog *dialog)
133 {
134         spell_dialog_response_cb (dialog->window, GTK_RESPONSE_OK, dialog);
135 }
136
137 static void
138 spell_dialog_model_selection_changed_cb (GtkTreeSelection  *treeselection,
139                                    EmpathySpellDialog *dialog)
140 {
141         gint count;
142
143         count = gtk_tree_selection_count_selected_rows (treeselection);
144         gtk_widget_set_sensitive (dialog->button_replace, (count == 1));
145 }
146
147 static void
148 spell_dialog_model_setup (EmpathySpellDialog *dialog)
149 {
150         GtkTreeView      *view;
151         GtkListStore     *store;
152         GtkTreeSelection *selection;
153
154         view = GTK_TREE_VIEW (dialog->treeview_words);
155
156         g_signal_connect (view, "row-activated",
157                           G_CALLBACK (spell_dialog_model_row_activated_cb),
158                           dialog);
159
160         store = gtk_list_store_new (COL_SPELL_COUNT,
161                                     G_TYPE_STRING);   /* word */
162
163         gtk_tree_view_set_model (view, GTK_TREE_MODEL (store));
164
165         selection = gtk_tree_view_get_selection (view);
166         gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
167
168         g_signal_connect (selection, "changed",
169                           G_CALLBACK (spell_dialog_model_selection_changed_cb),
170                           dialog);
171
172         spell_dialog_model_populate_columns (dialog);
173         spell_dialog_model_populate_suggestions (dialog);
174
175         g_object_unref (store);
176 }
177
178 static void
179 spell_dialog_destroy_cb (GtkWidget         *widget,
180                          EmpathySpellDialog *dialog)
181 {
182         g_object_unref (dialog->chat);
183         g_free (dialog->word);
184
185         g_free (dialog);
186 }
187
188 static void
189 spell_dialog_response_cb (GtkWidget         *widget,
190                           gint               response,
191                           EmpathySpellDialog *dialog)
192 {
193         if (response == GTK_RESPONSE_OK) {
194                 GtkTreeView      *view;
195                 GtkTreeModel     *model;
196                 GtkTreeSelection *selection;
197                 GtkTreeIter       iter;
198
199                 gchar            *new_word;
200
201                 view = GTK_TREE_VIEW (dialog->treeview_words);
202                 selection = gtk_tree_view_get_selection (view);
203
204                 if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
205                         return;
206                 }
207
208                 gtk_tree_model_get (model, &iter, COL_SPELL_WORD, &new_word, -1);
209
210                 empathy_chat_correct_word (dialog->chat,
211                                           &dialog->start,
212                                           &dialog->end,
213                                           new_word);
214
215                 g_free (new_word);
216         }
217
218         gtk_widget_destroy (dialog->window);
219 }
220
221 void
222 empathy_spell_dialog_show (EmpathyChat  *chat,
223                           GtkTextIter *start,
224                           GtkTextIter *end,
225                           const gchar *word)
226 {
227         EmpathySpellDialog *dialog;
228         GladeXML          *gui;
229         gchar             *str;
230         gchar             *filename;
231
232         g_return_if_fail (chat != NULL);
233         g_return_if_fail (word != NULL);
234
235         dialog = g_new0 (EmpathySpellDialog, 1);
236
237         dialog->chat = g_object_ref (chat);
238
239         dialog->word = g_strdup (word);
240
241         dialog->start = *start;
242         dialog->end = *end;
243
244         filename = empathy_file_lookup ("empathy-spell-dialog.glade",
245                                         "libempathy-gtk");
246         gui = empathy_glade_get_file (filename,
247                                      "spell_dialog",
248                                      NULL,
249                                      "spell_dialog", &dialog->window,
250                                      "button_replace", &dialog->button_replace,
251                                      "label_word", &dialog->label_word,
252                                      "treeview_words", &dialog->treeview_words,
253                                      NULL);
254         g_free (filename);
255
256         empathy_glade_connect (gui,
257                               dialog,
258                               "spell_dialog", "response", spell_dialog_response_cb,
259                               "spell_dialog", "destroy", spell_dialog_destroy_cb,
260                               NULL);
261
262         g_object_unref (gui);
263
264         str = g_markup_printf_escaped ("%s:\n<b>%s</b>",
265                                _("Suggestions for the word"),
266                                word);
267
268         gtk_label_set_markup (GTK_LABEL (dialog->label_word), str);
269         g_free (str);
270
271         spell_dialog_model_setup (dialog);
272
273         gtk_widget_show (dialog->window);
274 }