1 /*
2 * e-mail-config-service-notebook.c
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18 #include "e-mail-config-service-notebook.h"
19
20 #define E_MAIL_CONFIG_SERVICE_NOTEBOOK_GET_PRIVATE(obj) \
21 (G_TYPE_INSTANCE_GET_PRIVATE \
22 ((obj), E_TYPE_MAIL_CONFIG_SERVICE_NOTEBOOK, EMailConfigServiceNotebookPrivate))
23
24 #define CHILD_BACKEND_KEY_FORMAT \
25 "__e_mail_config_service_notebook_%p_child_backend__"
26
27 struct _EMailConfigServiceNotebookPrivate {
28 EMailConfigServiceBackend *active_backend;
29 gchar *child_backend_key;
30 };
31
32 enum {
33 PROP_0,
34 PROP_ACTIVE_BACKEND
35 };
36
37 enum {
38 PROP_CHILD_0,
39 PROP_CHILD_BACKEND
40 };
41
G_DEFINE_TYPE(EMailConfigServiceNotebook,e_mail_config_service_notebook,GTK_TYPE_NOTEBOOK)42 G_DEFINE_TYPE (
43 EMailConfigServiceNotebook,
44 e_mail_config_service_notebook,
45 GTK_TYPE_NOTEBOOK)
46
47 static void
48 mail_config_service_notebook_set_child_backend (EMailConfigServiceNotebook *notebook,
49 GtkWidget *child,
50 EMailConfigServiceBackend *backend)
51 {
52 const gchar *key;
53
54 key = notebook->priv->child_backend_key;
55
56 if (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend))
57 g_object_set_data_full (
58 G_OBJECT (child), key,
59 g_object_ref (backend),
60 (GDestroyNotify) g_object_unref);
61 }
62
63 static EMailConfigServiceBackend *
mail_config_service_notebook_get_child_backend(EMailConfigServiceNotebook * notebook,GtkWidget * child)64 mail_config_service_notebook_get_child_backend (EMailConfigServiceNotebook *notebook,
65 GtkWidget *child)
66 {
67 const gchar *key;
68
69 key = notebook->priv->child_backend_key;
70
71 return g_object_get_data (G_OBJECT (child), key);
72 }
73
74 static gboolean
mail_config_service_notebook_page_num_to_backend(GBinding * binding,const GValue * source_value,GValue * target_value,gpointer user_data)75 mail_config_service_notebook_page_num_to_backend (GBinding *binding,
76 const GValue *source_value,
77 GValue *target_value,
78 gpointer user_data)
79 {
80 EMailConfigServiceBackend *backend;
81 GtkNotebook *notebook;
82 GtkWidget *child;
83 gint page_num;
84
85 /* The binding's source and target are the same instance. */
86 notebook = GTK_NOTEBOOK (g_binding_get_source (binding));
87
88 page_num = g_value_get_int (source_value);
89 child = gtk_notebook_get_nth_page (notebook, page_num);
90
91 if (child != NULL)
92 backend = mail_config_service_notebook_get_child_backend (
93 E_MAIL_CONFIG_SERVICE_NOTEBOOK (notebook), child);
94 else
95 backend = NULL;
96
97 g_value_set_object (target_value, backend);
98
99 return TRUE;
100 }
101
102 static gboolean
mail_config_service_notebook_backend_to_page_num(GBinding * binding,const GValue * source_value,GValue * target_value,gpointer user_data)103 mail_config_service_notebook_backend_to_page_num (GBinding *binding,
104 const GValue *source_value,
105 GValue *target_value,
106 gpointer user_data)
107 {
108 EMailConfigServiceBackend *backend;
109 GtkNotebook *notebook;
110 gint n_pages, ii;
111
112 /* The binding's source and target are the same instance. */
113 notebook = GTK_NOTEBOOK (g_binding_get_source (binding));
114
115 backend = g_value_get_object (source_value);
116 n_pages = gtk_notebook_get_n_pages (notebook);
117
118 for (ii = 0; ii < n_pages; ii++) {
119 GtkWidget *child;
120 EMailConfigServiceBackend *candidate;
121
122 child = gtk_notebook_get_nth_page (notebook, ii);
123 candidate = mail_config_service_notebook_get_child_backend (
124 E_MAIL_CONFIG_SERVICE_NOTEBOOK (notebook), child);
125
126 if (backend == candidate) {
127 g_value_set_int (target_value, ii);
128 return TRUE;
129 }
130 }
131
132 return FALSE;
133 }
134
135 static void
mail_config_service_notebook_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)136 mail_config_service_notebook_set_property (GObject *object,
137 guint property_id,
138 const GValue *value,
139 GParamSpec *pspec)
140 {
141 switch (property_id) {
142 case PROP_ACTIVE_BACKEND:
143 e_mail_config_service_notebook_set_active_backend (
144 E_MAIL_CONFIG_SERVICE_NOTEBOOK (object),
145 g_value_get_object (value));
146 return;
147 }
148
149 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
150 }
151
152 static void
mail_config_service_notebook_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)153 mail_config_service_notebook_get_property (GObject *object,
154 guint property_id,
155 GValue *value,
156 GParamSpec *pspec)
157 {
158 switch (property_id) {
159 case PROP_ACTIVE_BACKEND:
160 g_value_set_object (
161 value,
162 e_mail_config_service_notebook_get_active_backend (
163 E_MAIL_CONFIG_SERVICE_NOTEBOOK (object)));
164 return;
165 }
166
167 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
168 }
169
170 static void
mail_config_service_notebook_dispose(GObject * object)171 mail_config_service_notebook_dispose (GObject *object)
172 {
173 EMailConfigServiceNotebookPrivate *priv;
174
175 priv = E_MAIL_CONFIG_SERVICE_NOTEBOOK_GET_PRIVATE (object);
176 g_clear_object (&priv->active_backend);
177
178 /* Chain up to parent's dispose() method. */
179 G_OBJECT_CLASS (e_mail_config_service_notebook_parent_class)->
180 dispose (object);
181 }
182
183 static void
mail_config_service_notebook_finalize(GObject * object)184 mail_config_service_notebook_finalize (GObject *object)
185 {
186 EMailConfigServiceNotebookPrivate *priv;
187
188 priv = E_MAIL_CONFIG_SERVICE_NOTEBOOK_GET_PRIVATE (object);
189
190 g_free (priv->child_backend_key);
191
192 /* Chain up to parent's finalize() method. */
193 G_OBJECT_CLASS (e_mail_config_service_notebook_parent_class)->
194 finalize (object);
195 }
196
197 static void
mail_config_service_notebook_constructed(GObject * object)198 mail_config_service_notebook_constructed (GObject *object)
199 {
200 /* Chain up to parent's constructed() method. */
201 G_OBJECT_CLASS (e_mail_config_service_notebook_parent_class)->constructed (object);
202
203 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (object), FALSE);
204 gtk_notebook_set_show_border (GTK_NOTEBOOK (object), FALSE);
205
206 /* Current page is still -1 so skip G_BINDING_SYNC_CREATE. */
207 e_binding_bind_property_full (
208 object, "page",
209 object, "active-backend",
210 G_BINDING_BIDIRECTIONAL,
211 mail_config_service_notebook_page_num_to_backend,
212 mail_config_service_notebook_backend_to_page_num,
213 NULL, (GDestroyNotify) NULL);
214 }
215
216 static void
mail_config_service_notebook_set_child_property(GtkContainer * container,GtkWidget * child,guint property_id,const GValue * value,GParamSpec * pspec)217 mail_config_service_notebook_set_child_property (GtkContainer *container,
218 GtkWidget *child,
219 guint property_id,
220 const GValue *value,
221 GParamSpec *pspec)
222 {
223 switch (property_id) {
224 case PROP_CHILD_BACKEND:
225 mail_config_service_notebook_set_child_backend (
226 E_MAIL_CONFIG_SERVICE_NOTEBOOK (container),
227 child, g_value_get_object (value));
228 return;
229 }
230
231 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (
232 container, property_id, pspec);
233 }
234
235 static void
mail_config_service_notebook_get_child_property(GtkContainer * container,GtkWidget * child,guint property_id,GValue * value,GParamSpec * pspec)236 mail_config_service_notebook_get_child_property (GtkContainer *container,
237 GtkWidget *child,
238 guint property_id,
239 GValue *value,
240 GParamSpec *pspec)
241 {
242 switch (property_id) {
243 case PROP_CHILD_BACKEND:
244 g_value_set_object (
245 value,
246 mail_config_service_notebook_get_child_backend (
247 E_MAIL_CONFIG_SERVICE_NOTEBOOK (container), child));
248 return;
249 }
250
251 GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (
252 container, property_id, pspec);
253 }
254
255 static void
e_mail_config_service_notebook_class_init(EMailConfigServiceNotebookClass * class)256 e_mail_config_service_notebook_class_init (EMailConfigServiceNotebookClass *class)
257 {
258 GObjectClass *object_class;
259 GtkContainerClass *container_class;
260
261 g_type_class_add_private (
262 class, sizeof (EMailConfigServiceNotebookPrivate));
263
264 object_class = G_OBJECT_CLASS (class);
265 object_class->set_property = mail_config_service_notebook_set_property;
266 object_class->get_property = mail_config_service_notebook_get_property;
267 object_class->dispose = mail_config_service_notebook_dispose;
268 object_class->finalize = mail_config_service_notebook_finalize;
269 object_class->constructed = mail_config_service_notebook_constructed;
270
271 container_class = GTK_CONTAINER_CLASS (class);
272 container_class->set_child_property = mail_config_service_notebook_set_child_property;
273 container_class->get_child_property = mail_config_service_notebook_get_child_property;
274
275 g_object_class_install_property (
276 object_class,
277 PROP_ACTIVE_BACKEND,
278 g_param_spec_object (
279 "active-backend",
280 "Active Backend",
281 "The service backend for the current page",
282 E_TYPE_MAIL_CONFIG_SERVICE_BACKEND,
283 G_PARAM_READWRITE |
284 G_PARAM_STATIC_STRINGS));
285
286 /* Child property for notebook pages. */
287 gtk_container_class_install_child_property (
288 container_class,
289 PROP_CHILD_BACKEND,
290 g_param_spec_object (
291 "backend",
292 "Backend",
293 "The service backend for this page",
294 E_TYPE_MAIL_CONFIG_SERVICE_BACKEND,
295 G_PARAM_READWRITE |
296 G_PARAM_STATIC_STRINGS));
297 }
298
299 static void
e_mail_config_service_notebook_init(EMailConfigServiceNotebook * notebook)300 e_mail_config_service_notebook_init (EMailConfigServiceNotebook *notebook)
301 {
302 gchar *key;
303
304 notebook->priv = E_MAIL_CONFIG_SERVICE_NOTEBOOK_GET_PRIVATE (notebook);
305
306 key = g_strdup_printf (CHILD_BACKEND_KEY_FORMAT, notebook);
307 notebook->priv->child_backend_key = key;
308 }
309
310 GtkWidget *
e_mail_config_service_notebook_new(void)311 e_mail_config_service_notebook_new (void)
312 {
313 return g_object_new (E_TYPE_MAIL_CONFIG_SERVICE_NOTEBOOK, NULL);
314 }
315
316 gint
e_mail_config_service_notebook_add_page(EMailConfigServiceNotebook * notebook,EMailConfigServiceBackend * backend,GtkWidget * child)317 e_mail_config_service_notebook_add_page (EMailConfigServiceNotebook *notebook,
318 EMailConfigServiceBackend *backend,
319 GtkWidget *child)
320 {
321 g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_NOTEBOOK (notebook), -1);
322 g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend), -1);
323 g_return_val_if_fail (GTK_IS_WIDGET (child), -1);
324
325 gtk_widget_show (child);
326
327 mail_config_service_notebook_set_child_backend (
328 notebook, child, backend);
329
330 return gtk_notebook_append_page (GTK_NOTEBOOK (notebook), child, NULL);
331 }
332
333 EMailConfigServiceBackend *
e_mail_config_service_notebook_get_active_backend(EMailConfigServiceNotebook * notebook)334 e_mail_config_service_notebook_get_active_backend (EMailConfigServiceNotebook *notebook)
335 {
336 g_return_val_if_fail (
337 E_IS_MAIL_CONFIG_SERVICE_NOTEBOOK (notebook), NULL);
338
339 return notebook->priv->active_backend;
340 }
341
342 void
e_mail_config_service_notebook_set_active_backend(EMailConfigServiceNotebook * notebook,EMailConfigServiceBackend * backend)343 e_mail_config_service_notebook_set_active_backend (EMailConfigServiceNotebook *notebook,
344 EMailConfigServiceBackend *backend)
345 {
346 g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_NOTEBOOK (notebook));
347
348 if (notebook->priv->active_backend == backend)
349 return;
350
351 if (backend != NULL) {
352 g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend));
353 g_object_ref (backend);
354 }
355
356 if (notebook->priv->active_backend != NULL)
357 g_object_unref (notebook->priv->active_backend);
358
359 notebook->priv->active_backend = backend;
360
361 g_object_notify (G_OBJECT (notebook), "active-backend");
362 }
363
364