]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-spell-dialog.c
Merge call branch from Elliot Fairweather with cleanups from Xavier Claessens.
[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.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 "empathy-chat.h"
36 #include "empathy-spell-dialog.h"
37 #include "empathy-ui-utils.h"
38
39 typedef struct {
40         GtkWidget   *window;
41         GtkWidget   *button_replace;
42         GtkWidget   *label_word;
43         GtkWidget   *treeview_words;
44
45         EmpathyChat  *chat;
46
47         gchar       *word;
48         GtkTextIter  start;
49         GtkTextIter  end;
50 } EmpathySpellDialog;
51
52 enum {
53         COL_SPELL_WORD,
54         COL_SPELL_COUNT
55 };
56
57 static void spell_dialog_model_populate_columns     (EmpathySpellDialog *dialog);
58 static void spell_dialog_model_populate_suggestions (EmpathySpellDialog *dialog);
59 static void spell_dialog_model_row_activated_cb     (GtkTreeView       *tree_view,
60                                                      GtkTreePath       *path,
61                                                      GtkTreeViewColumn *column,
62                                                      EmpathySpellDialog *dialog);
63 static void spell_dialog_model_selection_changed_cb (GtkTreeSelection  *treeselection,
64                                                      EmpathySpellDialog *dialog);
65 static void spell_dialog_model_setup                (EmpathySpellDialog *dialog);
66 static void spell_dialog_response_cb                (GtkWidget         *widget,
67                                                      gint               response,
68                                                      EmpathySpellDialog *dialog);
69 static void spell_dialog_destroy_cb                 (GtkWidget         *widget,
70                                                      EmpathySpellDialog *dialog);
71
72 static void
73 spell_dialog_model_populate_columns (EmpathySpellDialog *dialog)
74 {
75         GtkTreeModel      *model;
76         GtkTreeViewColumn *column;
77         GtkCellRenderer   *renderer;
78         guint              col_offset;
79
80         model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview_words));
81
82         renderer = gtk_cell_renderer_text_new ();
83         col_offset = gtk_tree_view_insert_column_with_attributes (
84                 GTK_TREE_VIEW (dialog->treeview_words),
85                 -1, _("Word"),
86                 renderer,
87                 "text", COL_SPELL_WORD,
88                 NULL);
89
90         g_object_set_data (G_OBJECT (renderer),
91                            "column", GINT_TO_POINTER (COL_SPELL_WORD));
92
93         column = gtk_tree_view_get_column (GTK_TREE_VIEW (dialog->treeview_words), col_offset - 1);
94         gtk_tree_view_column_set_sort_column_id (column, COL_SPELL_WORD);
95         gtk_tree_view_column_set_resizable (column, FALSE);
96         gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE);
97 }
98
99 static void
100 spell_dialog_model_populate_suggestions (EmpathySpellDialog *dialog)
101 {
102         GtkTreeModel *model;
103         GtkListStore *store;
104         GList        *suggestions, *l;
105
106         model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview_words));
107         store = GTK_LIST_STORE (model);
108
109         suggestions = empathy_spell_get_suggestions (dialog->word);
110         for (l = suggestions; l; l=l->next) {
111                 GtkTreeIter  iter;
112                 gchar       *word;
113
114                 word = l->data;
115
116                 gtk_list_store_append (store, &iter);
117                 gtk_list_store_set (store, &iter,
118                                     COL_SPELL_WORD, word,
119                                     -1);
120         }
121
122         empathy_spell_free_suggestions (suggestions);
123 }
124
125 static void
126 spell_dialog_model_row_activated_cb (GtkTreeView       *tree_view,
127                                GtkTreePath       *path,
128                                GtkTreeViewColumn *column,
129                                EmpathySpellDialog *dialog)
130 {
131         spell_dialog_response_cb (dialog->window, GTK_RESPONSE_OK, dialog);
132 }
133
134 static void
135 spell_dialog_model_selection_changed_cb (GtkTreeSelection  *treeselection,
136                                    EmpathySpellDialog *dialog)
137 {
138         gint count;
139
140         count = gtk_tree_selection_count_selected_rows (treeselection);
141         gtk_widget_set_sensitive (dialog->button_replace, (count == 1));
142 }
143
144 static void
145 spell_dialog_model_setup (EmpathySpellDialog *dialog)
146 {
147         GtkTreeView      *view;
148         GtkListStore     *store;
149         GtkTreeSelection *selection;
150
151         view = GTK_TREE_VIEW (dialog->treeview_words);
152
153         g_signal_connect (view, "row-activated",
154                           G_CALLBACK (spell_dialog_model_row_activated_cb),
155                           dialog);
156
157         store = gtk_list_store_new (COL_SPELL_COUNT,
158                                     G_TYPE_STRING);   /* word */
159
160         gtk_tree_view_set_model (view, GTK_TREE_MODEL (store));
161
162         selection = gtk_tree_view_get_selection (view);
163         gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
164
165         g_signal_connect (selection, "changed",
166                           G_CALLBACK (spell_dialog_model_selection_changed_cb),
167                           dialog);
168
169         spell_dialog_model_populate_columns (dialog);
170         spell_dialog_model_populate_suggestions (dialog);
171
172         g_object_unref (store);
173 }
174
175 static void
176 spell_dialog_destroy_cb (GtkWidget         *widget,
177                          EmpathySpellDialog *dialog)
178 {
179         g_object_unref (dialog->chat);
180         g_free (dialog->word);
181
182         g_free (dialog);
183 }
184
185 static void
186 spell_dialog_response_cb (GtkWidget         *widget,
187                           gint               response,
188                           EmpathySpellDialog *dialog)
189 {
190         if (response == GTK_RESPONSE_OK) {
191                 GtkTreeView      *view;
192                 GtkTreeModel     *model;
193                 GtkTreeSelection *selection;
194                 GtkTreeIter       iter;
195
196                 gchar            *new_word;
197
198                 view = GTK_TREE_VIEW (dialog->treeview_words);
199                 selection = gtk_tree_view_get_selection (view);
200
201                 if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
202                         return;
203                 }
204
205                 gtk_tree_model_get (model, &iter, COL_SPELL_WORD, &new_word, -1);
206
207                 empathy_chat_correct_word (dialog->chat,
208                                           dialog->start,
209                                           dialog->end,
210                                           new_word);
211
212                 g_free (new_word);
213         }
214
215         gtk_widget_destroy (dialog->window);
216 }
217
218 void
219 empathy_spell_dialog_show (EmpathyChat  *chat,
220                           GtkTextIter  start,
221                           GtkTextIter  end,
222                           const gchar *word)
223 {
224         EmpathySpellDialog *dialog;
225         GladeXML          *gui;
226         gchar             *str;
227
228         g_return_if_fail (chat != NULL);
229         g_return_if_fail (word != NULL);
230
231         dialog = g_new0 (EmpathySpellDialog, 1);
232
233         dialog->chat = g_object_ref (chat);
234
235         dialog->word = g_strdup (word);
236
237         dialog->start = start;
238         dialog->end = end;
239
240         gui = empathy_glade_get_file ("empathy-spell-dialog.glade",
241                                      "spell_dialog",
242                                      NULL,
243                                      "spell_dialog", &dialog->window,
244                                      "button_replace", &dialog->button_replace,
245                                      "label_word", &dialog->label_word,
246                                      "treeview_words", &dialog->treeview_words,
247                                      NULL);
248
249         empathy_glade_connect (gui,
250                               dialog,
251                               "spell_dialog", "response", spell_dialog_response_cb,
252                               "spell_dialog", "destroy", spell_dialog_destroy_cb,
253                               NULL);
254
255         g_object_unref (gui);
256
257         str = g_strdup_printf ("%s:\n<b>%s</b>",
258                                _("Suggestions for the word"),
259                                word);
260
261         gtk_label_set_markup (GTK_LABEL (dialog->label_word), str);
262         g_free (str);
263
264         spell_dialog_model_setup (dialog);
265
266         gtk_widget_show (dialog->window);
267 }