1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * gimplanguageentry.c
5 * Copyright (C) 2008 Sven Neumann <sven@gimp.org>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21 /* GimpLanguageEntry is an entry widget that provides completion on
22 * translated language names. It is suited for specifying the language
23 * a text is written in.
24 */
25
26 #include "config.h"
27
28 #include <string.h>
29
30 #include <gtk/gtk.h>
31
32 #include "widgets-types.h"
33
34 #include "gimplanguageentry.h"
35 #include "gimplanguagestore.h"
36
37
38 enum
39 {
40 PROP_0,
41 PROP_MODEL
42 };
43
44 struct _GimpLanguageEntry
45 {
46 GtkEntry parent_instance;
47
48 GtkListStore *store;
49 gchar *code; /* ISO 639-1 language code */
50 };
51
52
53 static void gimp_language_entry_constructed (GObject *object);
54 static void gimp_language_entry_finalize (GObject *object);
55 static void gimp_language_entry_set_property (GObject *object,
56 guint property_id,
57 const GValue *value,
58 GParamSpec *pspec);
59 static void gimp_language_entry_get_property (GObject *object,
60 guint property_id,
61 GValue *value,
62 GParamSpec *pspec);
63
64 static gboolean gimp_language_entry_language_selected (GtkEntryCompletion *completion,
65 GtkTreeModel *model,
66 GtkTreeIter *iter,
67 GimpLanguageEntry *entry);
68
69
G_DEFINE_TYPE(GimpLanguageEntry,gimp_language_entry,GTK_TYPE_ENTRY)70 G_DEFINE_TYPE (GimpLanguageEntry, gimp_language_entry, GTK_TYPE_ENTRY)
71
72 #define parent_class gimp_language_entry_parent_class
73
74
75 static void
76 gimp_language_entry_class_init (GimpLanguageEntryClass *klass)
77 {
78 GObjectClass *object_class = G_OBJECT_CLASS (klass);
79
80 object_class->constructed = gimp_language_entry_constructed;
81 object_class->finalize = gimp_language_entry_finalize;
82 object_class->set_property = gimp_language_entry_set_property;
83 object_class->get_property = gimp_language_entry_get_property;
84
85 g_object_class_install_property (object_class, PROP_MODEL,
86 g_param_spec_object ("model", NULL, NULL,
87 GIMP_TYPE_LANGUAGE_STORE,
88 G_PARAM_CONSTRUCT_ONLY |
89 GIMP_PARAM_READWRITE));
90 }
91
92 static void
gimp_language_entry_init(GimpLanguageEntry * entry)93 gimp_language_entry_init (GimpLanguageEntry *entry)
94 {
95 }
96
97 static void
gimp_language_entry_constructed(GObject * object)98 gimp_language_entry_constructed (GObject *object)
99 {
100 GimpLanguageEntry *entry = GIMP_LANGUAGE_ENTRY (object);
101
102 G_OBJECT_CLASS (parent_class)->constructed (object);
103
104 if (entry->store)
105 {
106 GtkEntryCompletion *completion;
107
108 completion = g_object_new (GTK_TYPE_ENTRY_COMPLETION,
109 "model", entry->store,
110 "inline-selection", TRUE,
111 NULL);
112
113 /* Note that we must use this function to set the text column,
114 * otherwise we won't get a cell renderer for free.
115 */
116 gtk_entry_completion_set_text_column (completion,
117 GIMP_LANGUAGE_STORE_LABEL);
118
119 gtk_entry_set_completion (GTK_ENTRY (entry), completion);
120 g_object_unref (completion);
121
122 g_signal_connect (completion, "match-selected",
123 G_CALLBACK (gimp_language_entry_language_selected),
124 entry);
125 }
126 }
127
128 static void
gimp_language_entry_finalize(GObject * object)129 gimp_language_entry_finalize (GObject *object)
130 {
131 GimpLanguageEntry *entry = GIMP_LANGUAGE_ENTRY (object);
132
133 g_clear_object (&entry->store);
134
135 g_clear_pointer (&entry->code, g_free);
136
137 G_OBJECT_CLASS (parent_class)->finalize (object);
138 }
139
140 static void
gimp_language_entry_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)141 gimp_language_entry_set_property (GObject *object,
142 guint property_id,
143 const GValue *value,
144 GParamSpec *pspec)
145 {
146 GimpLanguageEntry *entry = GIMP_LANGUAGE_ENTRY (object);
147
148 switch (property_id)
149 {
150 case PROP_MODEL:
151 g_return_if_fail (entry->store == NULL);
152 entry->store = g_value_dup_object (value);
153 break;
154
155 default:
156 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
157 break;
158 }
159 }
160
161 static void
gimp_language_entry_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)162 gimp_language_entry_get_property (GObject *object,
163 guint property_id,
164 GValue *value,
165 GParamSpec *pspec)
166 {
167 GimpLanguageEntry *entry = GIMP_LANGUAGE_ENTRY (object);
168
169 switch (property_id)
170 {
171 case PROP_MODEL:
172 g_value_set_object (value, entry->store);
173 break;
174
175 default:
176 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
177 break;
178 }
179 }
180
181 static gboolean
gimp_language_entry_language_selected(GtkEntryCompletion * completion,GtkTreeModel * model,GtkTreeIter * iter,GimpLanguageEntry * entry)182 gimp_language_entry_language_selected (GtkEntryCompletion *completion,
183 GtkTreeModel *model,
184 GtkTreeIter *iter,
185 GimpLanguageEntry *entry)
186 {
187 g_free (entry->code);
188
189 gtk_tree_model_get (model, iter,
190 GIMP_LANGUAGE_STORE_CODE, &entry->code,
191 -1);
192
193 return FALSE;
194 }
195
196 GtkWidget *
gimp_language_entry_new(void)197 gimp_language_entry_new (void)
198 {
199 GtkWidget *entry;
200 GtkListStore *store;
201
202 store = gimp_language_store_new ();
203
204 entry = g_object_new (GIMP_TYPE_LANGUAGE_ENTRY,
205 "model", store,
206 NULL);
207
208 g_object_unref (store);
209
210 return entry;
211 }
212
213 const gchar *
gimp_language_entry_get_code(GimpLanguageEntry * entry)214 gimp_language_entry_get_code (GimpLanguageEntry *entry)
215 {
216 g_return_val_if_fail (GIMP_IS_LANGUAGE_ENTRY (entry), NULL);
217
218 return entry->code;
219 }
220
221 gboolean
gimp_language_entry_set_code(GimpLanguageEntry * entry,const gchar * code)222 gimp_language_entry_set_code (GimpLanguageEntry *entry,
223 const gchar *code)
224 {
225 GtkTreeIter iter;
226
227 g_return_val_if_fail (GIMP_IS_LANGUAGE_ENTRY (entry), FALSE);
228
229 g_clear_pointer (&entry->code, g_free);
230
231 if (! code || ! strlen (code))
232 {
233 gtk_entry_set_text (GTK_ENTRY (entry), "");
234
235 return TRUE;
236 }
237
238 if (gimp_language_store_lookup (GIMP_LANGUAGE_STORE (entry->store),
239 code, &iter))
240 {
241 gchar *label;
242
243 gtk_tree_model_get (GTK_TREE_MODEL (entry->store), &iter,
244 GIMP_LANGUAGE_STORE_LABEL, &label,
245 GIMP_LANGUAGE_STORE_CODE, &entry->code,
246 -1);
247
248 gtk_entry_set_text (GTK_ENTRY (entry), label);
249 g_free (label);
250
251 return TRUE;
252 }
253
254 return FALSE;
255 }
256