1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * pluma-spell-language-dialog.c
4 * This file is part of pluma
5 *
6 * Copyright (C) 2002 Paolo Maggi
7 * Copyright (C) 2012-2021 MATE Developers
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 */
24
25 /*
26 * Modified by the pluma Team, 2002. See the AUTHORS file for a
27 * list of people on the pluma Team.
28 * See the ChangeLog files for a list of changes.
29 */
30
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34
35 #include <glib/gi18n.h>
36 #include <gtk/gtk.h>
37 #include <pluma/pluma-utils.h>
38 #include <pluma/pluma-help.h>
39 #include "pluma-spell-language-dialog.h"
40 #include "pluma-spell-checker-language.h"
41
42
43 enum
44 {
45 COLUMN_LANGUAGE_NAME = 0,
46 COLUMN_LANGUAGE_POINTER,
47 ENCODING_NUM_COLS
48 };
49
50
51 struct _PlumaSpellLanguageDialog
52 {
53 GtkDialog dialog;
54
55 GtkWidget *languages_treeview;
56 GtkTreeModel *model;
57 };
58
G_DEFINE_TYPE(PlumaSpellLanguageDialog,pluma_spell_language_dialog,GTK_TYPE_DIALOG)59 G_DEFINE_TYPE(PlumaSpellLanguageDialog, pluma_spell_language_dialog, GTK_TYPE_DIALOG)
60
61
62 static void
63 pluma_spell_language_dialog_class_init (PlumaSpellLanguageDialogClass *klass)
64 {
65 /* GObjectClass *object_class = G_OBJECT_CLASS (klass); */
66 }
67
68 static void
dialog_response_handler(GtkDialog * dlg,gint res_id)69 dialog_response_handler (GtkDialog *dlg,
70 gint res_id)
71 {
72 if (res_id == GTK_RESPONSE_HELP)
73 {
74 pluma_help_display (GTK_WINDOW (dlg),
75 NULL,
76 "pluma-spell-checker-plugin");
77
78 g_signal_stop_emission_by_name (dlg, "response");
79 }
80 }
81
82 static void
scroll_to_selected(GtkTreeView * tree_view)83 scroll_to_selected (GtkTreeView *tree_view)
84 {
85 GtkTreeModel *model;
86 GtkTreeSelection *selection;
87 GtkTreeIter iter;
88
89 model = gtk_tree_view_get_model (tree_view);
90 g_return_if_fail (model != NULL);
91
92 /* Scroll to selected */
93 selection = gtk_tree_view_get_selection (tree_view);
94 g_return_if_fail (selection != NULL);
95
96 if (gtk_tree_selection_get_selected (selection, NULL, &iter))
97 {
98 GtkTreePath* path;
99
100 path = gtk_tree_model_get_path (model, &iter);
101 g_return_if_fail (path != NULL);
102
103 gtk_tree_view_scroll_to_cell (tree_view,
104 path, NULL, TRUE, 1.0, 0.0);
105 gtk_tree_path_free (path);
106 }
107 }
108
109 static void
language_row_activated(GtkTreeView * tree_view,GtkTreePath * path,GtkTreeViewColumn * column,PlumaSpellLanguageDialog * dialog)110 language_row_activated (GtkTreeView *tree_view,
111 GtkTreePath *path,
112 GtkTreeViewColumn *column,
113 PlumaSpellLanguageDialog *dialog)
114 {
115 gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
116 }
117
118 static void
create_dialog(PlumaSpellLanguageDialog * dlg,const gchar * data_dir)119 create_dialog (PlumaSpellLanguageDialog *dlg,
120 const gchar *data_dir)
121 {
122 GtkWidget *error_widget;
123 GtkWidget *content;
124 gboolean ret;
125 GtkCellRenderer *cell;
126 GtkTreeViewColumn *column;
127 gchar *ui_file;
128 gchar *root_objects[] = {
129 "content",
130 NULL
131 };
132
133 pluma_dialog_add_button (GTK_DIALOG (dlg), _("_Cancel"), "process-stop", GTK_RESPONSE_CANCEL);
134 pluma_dialog_add_button (GTK_DIALOG (dlg), _("_OK"), "gtk-ok", GTK_RESPONSE_OK);
135 pluma_dialog_add_button (GTK_DIALOG (dlg), _("_Help"), "help-browser", GTK_RESPONSE_HELP);
136
137 gtk_window_set_title (GTK_WINDOW (dlg), _("Set language"));
138 gtk_window_set_modal (GTK_WINDOW (dlg), TRUE);
139 gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE);
140
141 /* HIG defaults */
142 gtk_container_set_border_width (GTK_CONTAINER (dlg), 5);
143 gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
144 2); /* 2 * 5 + 2 = 12 */
145
146 g_signal_connect (dlg,
147 "response",
148 G_CALLBACK (dialog_response_handler),
149 NULL);
150
151 ui_file = g_build_filename (data_dir, "languages-dialog.ui", NULL);
152 ret = pluma_utils_get_ui_objects (ui_file,
153 root_objects,
154 &error_widget,
155 "content", &content,
156 "languages_treeview", &dlg->languages_treeview,
157 NULL);
158 g_free (ui_file);
159
160 if (!ret)
161 {
162 gtk_widget_show (error_widget);
163
164 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
165 error_widget,
166 TRUE, TRUE, 0);
167
168 return;
169 }
170
171 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
172 content, TRUE, TRUE, 0);
173 g_object_unref (content);
174 gtk_container_set_border_width (GTK_CONTAINER (content), 5);
175
176 dlg->model = GTK_TREE_MODEL (gtk_list_store_new (ENCODING_NUM_COLS,
177 G_TYPE_STRING,
178 G_TYPE_POINTER));
179
180 gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->languages_treeview),
181 dlg->model);
182
183 g_object_unref (dlg->model);
184
185 /* Add the encoding column */
186 cell = gtk_cell_renderer_text_new ();
187 column = gtk_tree_view_column_new_with_attributes (_("Languages"),
188 cell,
189 "text",
190 COLUMN_LANGUAGE_NAME,
191 NULL);
192
193 gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->languages_treeview),
194 column);
195
196 gtk_tree_view_set_search_column (GTK_TREE_VIEW (dlg->languages_treeview),
197 COLUMN_LANGUAGE_NAME);
198
199 g_signal_connect (dlg->languages_treeview,
200 "realize",
201 G_CALLBACK (scroll_to_selected),
202 dlg);
203 g_signal_connect (dlg->languages_treeview,
204 "row-activated",
205 G_CALLBACK (language_row_activated),
206 dlg);
207 }
208
209 static void
pluma_spell_language_dialog_init(PlumaSpellLanguageDialog * dlg)210 pluma_spell_language_dialog_init (PlumaSpellLanguageDialog *dlg)
211 {
212
213 }
214
215 static void
populate_language_list(PlumaSpellLanguageDialog * dlg,const PlumaSpellCheckerLanguage * cur_lang)216 populate_language_list (PlumaSpellLanguageDialog *dlg,
217 const PlumaSpellCheckerLanguage *cur_lang)
218 {
219 GtkListStore *store;
220 GtkTreeIter iter;
221
222 const GSList* langs;
223
224 /* create list store */
225 store = GTK_LIST_STORE (dlg->model);
226
227 langs = pluma_spell_checker_get_available_languages ();
228
229 while (langs)
230 {
231 const gchar *name;
232
233 name = pluma_spell_checker_language_to_string ((const PlumaSpellCheckerLanguage*)langs->data);
234
235 gtk_list_store_append (store, &iter);
236 gtk_list_store_set (store, &iter,
237 COLUMN_LANGUAGE_NAME, name,
238 COLUMN_LANGUAGE_POINTER, langs->data,
239 -1);
240
241 if (langs->data == cur_lang)
242 {
243 GtkTreeSelection *selection;
244
245 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->languages_treeview));
246 g_return_if_fail (selection != NULL);
247
248 gtk_tree_selection_select_iter (selection, &iter);
249 }
250
251 langs = g_slist_next (langs);
252 }
253 }
254
255 GtkWidget *
pluma_spell_language_dialog_new(GtkWindow * parent,const PlumaSpellCheckerLanguage * cur_lang,const gchar * data_dir)256 pluma_spell_language_dialog_new (GtkWindow *parent,
257 const PlumaSpellCheckerLanguage *cur_lang,
258 const gchar *data_dir)
259 {
260 PlumaSpellLanguageDialog *dlg;
261
262 g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL);
263
264 dlg = g_object_new (PLUMA_TYPE_SPELL_LANGUAGE_DIALOG, NULL);
265
266 create_dialog (dlg, data_dir);
267
268 populate_language_list (dlg, cur_lang);
269
270 gtk_window_set_transient_for (GTK_WINDOW (dlg), parent);
271 gtk_widget_grab_focus (dlg->languages_treeview);
272
273 return GTK_WIDGET (dlg);
274 }
275
276 const PlumaSpellCheckerLanguage *
pluma_spell_language_get_selected_language(PlumaSpellLanguageDialog * dlg)277 pluma_spell_language_get_selected_language (PlumaSpellLanguageDialog *dlg)
278 {
279 GValue value = {0, };
280 const PlumaSpellCheckerLanguage* lang;
281
282 GtkTreeIter iter;
283 GtkTreeSelection *selection;
284
285 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->languages_treeview));
286 g_return_val_if_fail (selection != NULL, NULL);
287
288 if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
289 return NULL;
290
291 gtk_tree_model_get_value (dlg->model,
292 &iter,
293 COLUMN_LANGUAGE_POINTER,
294 &value);
295
296 lang = (const PlumaSpellCheckerLanguage* ) g_value_get_pointer (&value);
297
298 return lang;
299 }
300
301