No issues found
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2
3 /*
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) version 3.
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 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with the program; if not, see <http://www.gnu.org/licenses/>
17 *
18 *
19 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
20 *
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include "e-composer-header.h"
28
29 #include <config.h>
30 #include <glib/gi18n-lib.h>
31
32 #define E_COMPOSER_HEADER_GET_PRIVATE(obj) \
33 (G_TYPE_INSTANCE_GET_PRIVATE \
34 ((obj), E_TYPE_COMPOSER_HEADER, EComposerHeaderPrivate))
35
36 struct _EComposerHeaderPrivate {
37 gchar *label;
38 gboolean button;
39
40 ESourceRegistry *registry;
41
42 guint sensitive : 1;
43 guint visible : 1;
44 };
45
46 #define E_COMPOSER_HEADER_GET_PRIVATE(obj) \
47 (G_TYPE_INSTANCE_GET_PRIVATE \
48 ((obj), E_TYPE_COMPOSER_HEADER, EComposerHeaderPrivate))
49
50 enum {
51 PROP_0,
52 PROP_BUTTON,
53 PROP_LABEL,
54 PROP_REGISTRY,
55 PROP_SENSITIVE,
56 PROP_VISIBLE
57 };
58
59 enum {
60 CHANGED,
61 CLICKED,
62 LAST_SIGNAL
63 };
64
65 static guint signal_ids[LAST_SIGNAL];
66
67 G_DEFINE_ABSTRACT_TYPE (
68 EComposerHeader,
69 e_composer_header,
70 G_TYPE_OBJECT)
71
72 static void
73 composer_header_button_clicked_cb (GtkButton *button,
74 EComposerHeader *header)
75 {
76 gtk_widget_grab_focus (header->input_widget);
77 g_signal_emit (header, signal_ids[CLICKED], 0);
78 }
79
80 static void
81 composer_header_set_registry (EComposerHeader *header,
82 ESourceRegistry *registry)
83 {
84 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
85 g_return_if_fail (header->priv->registry == NULL);
86
87 header->priv->registry = g_object_ref (registry);
88 }
89
90 static void
91 composer_header_set_property (GObject *object,
92 guint property_id,
93 const GValue *value,
94 GParamSpec *pspec)
95 {
96 EComposerHeaderPrivate *priv;
97
98 priv = E_COMPOSER_HEADER_GET_PRIVATE (object);
99
100 switch (property_id) {
101 case PROP_BUTTON: /* construct only */
102 priv->button = g_value_get_boolean (value);
103 return;
104
105 case PROP_LABEL: /* construct only */
106 priv->label = g_value_dup_string (value);
107 return;
108
109 case PROP_REGISTRY:
110 composer_header_set_registry (
111 E_COMPOSER_HEADER (object),
112 g_value_get_object (value));
113 return;
114
115 case PROP_SENSITIVE:
116 e_composer_header_set_sensitive (
117 E_COMPOSER_HEADER (object),
118 g_value_get_boolean (value));
119 return;
120
121 case PROP_VISIBLE:
122 e_composer_header_set_visible (
123 E_COMPOSER_HEADER (object),
124 g_value_get_boolean (value));
125 return;
126 }
127
128 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
129 }
130
131 static void
132 composer_header_get_property (GObject *object,
133 guint property_id,
134 GValue *value,
135 GParamSpec *pspec)
136 {
137 EComposerHeaderPrivate *priv;
138
139 priv = E_COMPOSER_HEADER_GET_PRIVATE (object);
140
141 switch (property_id) {
142 case PROP_BUTTON: /* construct only */
143 g_value_set_boolean (value, priv->button);
144 return;
145
146 case PROP_LABEL: /* construct only */
147 g_value_set_string (value, priv->label);
148 return;
149
150 case PROP_REGISTRY:
151 g_value_set_object (
152 value, e_composer_header_get_registry (
153 E_COMPOSER_HEADER (object)));
154 return;
155
156 case PROP_SENSITIVE:
157 g_value_set_boolean (
158 value, e_composer_header_get_sensitive (
159 E_COMPOSER_HEADER (object)));
160 return;
161
162 case PROP_VISIBLE:
163 g_value_set_boolean (
164 value, e_composer_header_get_visible (
165 E_COMPOSER_HEADER (object)));
166 return;
167 }
168
169 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
170 }
171
172 static void
173 composer_header_dispose (GObject *object)
174 {
175 EComposerHeader *header = E_COMPOSER_HEADER (object);
176
177 if (header->title_widget != NULL) {
178 g_object_unref (header->title_widget);
179 header->title_widget = NULL;
180 }
181
182 if (header->input_widget != NULL) {
183 g_object_unref (header->input_widget);
184 header->input_widget = NULL;
185 }
186
187 if (header->priv->registry != NULL) {
188 g_object_unref (header->priv->registry);
189 header->priv->registry = NULL;
190 }
191
192 /* Chain up to parent's dispose() method. */
193 G_OBJECT_CLASS (e_composer_header_parent_class)->dispose (object);
194 }
195
196 static void
197 composer_header_finalize (GObject *object)
198 {
199 EComposerHeaderPrivate *priv;
200
201 priv = E_COMPOSER_HEADER_GET_PRIVATE (object);
202
203 g_free (priv->label);
204
205 /* Chain up to parent's finalize() method. */
206 G_OBJECT_CLASS (e_composer_header_parent_class)->finalize (object);
207 }
208
209 static void
210 composer_header_constructed (GObject *object)
211 {
212 EComposerHeader *header;
213 GtkWidget *widget;
214 GtkWidget *label;
215
216 header = E_COMPOSER_HEADER (object);
217
218 if (header->input_widget == NULL) {
219 g_critical (
220 "EComposerHeader's input_widget "
221 "must be set before chaining up");
222 return;
223 }
224
225 if (header->priv->button) {
226 widget = gtk_button_new_with_mnemonic (header->priv->label);
227 gtk_widget_set_can_focus (widget, FALSE);
228 g_signal_connect (
229 widget, "clicked",
230 G_CALLBACK (composer_header_button_clicked_cb),
231 header);
232 label = gtk_bin_get_child (GTK_BIN (widget));
233 } else {
234 widget = gtk_label_new_with_mnemonic (header->priv->label);
235 gtk_label_set_mnemonic_widget (
236 GTK_LABEL (widget), header->input_widget);
237 label = widget;
238 }
239
240 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
241
242 header->title_widget = g_object_ref_sink (widget);
243
244 g_object_bind_property (
245 header, "visible",
246 header->title_widget, "visible",
247 G_BINDING_SYNC_CREATE);
248
249 g_object_bind_property (
250 header, "visible",
251 header->input_widget, "visible",
252 G_BINDING_SYNC_CREATE);
253 }
254
255 static void
256 e_composer_header_class_init (EComposerHeaderClass *class)
257 {
258 GObjectClass *object_class;
259
260 g_type_class_add_private (class, sizeof (EComposerHeaderPrivate));
261
262 object_class = G_OBJECT_CLASS (class);
263 object_class->set_property = composer_header_set_property;
264 object_class->get_property = composer_header_get_property;
265 object_class->dispose = composer_header_dispose;
266 object_class->finalize = composer_header_finalize;
267 object_class->constructed = composer_header_constructed;
268
269 g_object_class_install_property (
270 object_class,
271 PROP_BUTTON,
272 g_param_spec_boolean (
273 "button",
274 NULL,
275 NULL,
276 FALSE,
277 G_PARAM_READWRITE |
278 G_PARAM_CONSTRUCT_ONLY |
279 G_PARAM_STATIC_STRINGS));
280
281 g_object_class_install_property (
282 object_class,
283 PROP_LABEL,
284 g_param_spec_string (
285 "label",
286 NULL,
287 NULL,
288 NULL,
289 G_PARAM_READWRITE |
290 G_PARAM_CONSTRUCT_ONLY |
291 G_PARAM_STATIC_STRINGS));
292
293 g_object_class_install_property (
294 object_class,
295 PROP_REGISTRY,
296 g_param_spec_object (
297 "registry",
298 NULL,
299 NULL,
300 E_TYPE_SOURCE_REGISTRY,
301 G_PARAM_READWRITE |
302 G_PARAM_CONSTRUCT_ONLY |
303 G_PARAM_STATIC_STRINGS));
304
305 g_object_class_install_property (
306 object_class,
307 PROP_SENSITIVE,
308 g_param_spec_boolean (
309 "sensitive",
310 NULL,
311 NULL,
312 FALSE,
313 G_PARAM_READWRITE |
314 G_PARAM_STATIC_STRINGS));
315
316 g_object_class_install_property (
317 object_class,
318 PROP_VISIBLE,
319 g_param_spec_boolean (
320 "visible",
321 NULL,
322 NULL,
323 FALSE,
324 G_PARAM_READWRITE |
325 G_PARAM_STATIC_STRINGS));
326
327 signal_ids[CHANGED] = g_signal_new (
328 "changed",
329 G_TYPE_FROM_CLASS (class),
330 G_SIGNAL_RUN_LAST,
331 G_STRUCT_OFFSET (EComposerHeaderClass, changed),
332 NULL, NULL,
333 g_cclosure_marshal_VOID__VOID,
334 G_TYPE_NONE, 0);
335
336 signal_ids[CLICKED] = g_signal_new (
337 "clicked",
338 G_TYPE_FROM_CLASS (class),
339 G_SIGNAL_RUN_LAST,
340 G_STRUCT_OFFSET (EComposerHeaderClass, clicked),
341 NULL, NULL,
342 g_cclosure_marshal_VOID__VOID,
343 G_TYPE_NONE, 0);
344 }
345
346 static void
347 e_composer_header_init (EComposerHeader *header)
348 {
349 header->priv = E_COMPOSER_HEADER_GET_PRIVATE (header);
350 }
351
352 const gchar *
353 e_composer_header_get_label (EComposerHeader *header)
354 {
355 g_return_val_if_fail (E_IS_COMPOSER_HEADER (header), NULL);
356
357 return header->priv->label;
358 }
359
360 ESourceRegistry *
361 e_composer_header_get_registry (EComposerHeader *header)
362 {
363 g_return_val_if_fail (E_IS_COMPOSER_HEADER (header), NULL);
364
365 return header->priv->registry;
366 }
367
368 gboolean
369 e_composer_header_get_sensitive (EComposerHeader *header)
370 {
371 g_return_val_if_fail (E_IS_COMPOSER_HEADER (header), FALSE);
372
373 return header->priv->sensitive;
374 }
375
376 void
377 e_composer_header_set_sensitive (EComposerHeader *header,
378 gboolean sensitive)
379 {
380 g_return_if_fail (E_IS_COMPOSER_HEADER (header));
381
382 if (header->priv->sensitive == sensitive)
383 return;
384
385 header->priv->sensitive = sensitive;
386
387 g_object_notify (G_OBJECT (header), "sensitive");
388 }
389
390 gboolean
391 e_composer_header_get_visible (EComposerHeader *header)
392 {
393 g_return_val_if_fail (E_IS_COMPOSER_HEADER (header), FALSE);
394
395 return header->priv->visible;
396 }
397
398 void
399 e_composer_header_set_visible (EComposerHeader *header,
400 gboolean visible)
401 {
402 g_return_if_fail (E_IS_COMPOSER_HEADER (header));
403
404 if (header->priv->visible == visible)
405 return;
406
407 header->priv->visible = visible;
408
409 g_object_notify (G_OBJECT (header), "visible");
410 }
411
412 void
413 e_composer_header_set_title_tooltip (EComposerHeader *header,
414 const gchar *tooltip)
415 {
416 g_return_if_fail (E_IS_COMPOSER_HEADER (header));
417
418 gtk_widget_set_tooltip_text (header->title_widget, tooltip);
419 }
420
421 void
422 e_composer_header_set_input_tooltip (EComposerHeader *header,
423 const gchar *tooltip)
424 {
425 g_return_if_fail (E_IS_COMPOSER_HEADER (header));
426
427 gtk_widget_set_tooltip_text (header->input_widget, tooltip);
428 }