1 /*
2  *
3  * This program is free software; you can redistribute it and/or modify it
4  * under the terms of the GNU Lesser General Public License as published by
5  * the Free Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful, but
8  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
10  * for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public License
13  * along with this program; if not, see <http://www.gnu.org/licenses/>.
14  *
15  *
16  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
17  *
18  */
19 
20 #include "evolution-config.h"
21 
22 #include <glib/gi18n-lib.h>
23 
24 #include "e-composer-from-header.h"
25 
26 enum {
27 	PROP_0,
28 	PROP_OVERRIDE_VISIBLE
29 };
30 
G_DEFINE_TYPE(EComposerFromHeader,e_composer_from_header,E_TYPE_COMPOSER_HEADER)31 G_DEFINE_TYPE (
32 	EComposerFromHeader,
33 	e_composer_from_header,
34 	E_TYPE_COMPOSER_HEADER)
35 
36 static void
37 composer_from_header_changed_cb (EMailIdentityComboBox *combo_box,
38                                  EComposerFromHeader *header)
39 {
40 	if (e_mail_identity_combo_box_get_refreshing (combo_box))
41 		return;
42 
43 	g_signal_emit_by_name (header, "changed");
44 }
45 
46 static void
composer_from_header_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)47 composer_from_header_set_property (GObject *object,
48 				   guint property_id,
49 				   const GValue *value,
50 				   GParamSpec *pspec)
51 {
52 	switch (property_id) {
53 		case PROP_OVERRIDE_VISIBLE:
54 			e_composer_from_header_set_override_visible (
55 				E_COMPOSER_FROM_HEADER (object),
56 				g_value_get_boolean (value));
57 			return;
58 	}
59 
60 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
61 }
62 
63 static void
composer_from_header_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)64 composer_from_header_get_property (GObject *object,
65 				   guint property_id,
66 				   GValue *value,
67 				   GParamSpec *pspec)
68 {
69 	switch (property_id) {
70 		case PROP_OVERRIDE_VISIBLE:
71 			g_value_set_boolean (
72 				value, e_composer_from_header_get_override_visible (
73 				E_COMPOSER_FROM_HEADER (object)));
74 			return;
75 	}
76 
77 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
78 }
79 
80 static void
composer_from_header_constructed(GObject * object)81 composer_from_header_constructed (GObject *object)
82 {
83 	ESourceRegistry *registry;
84 	EComposerHeader *header;
85 	EComposerFromHeader *from_header;
86 	GtkWidget *widget;
87 	GtkWidget *grid;
88 	GtkWidget *label;
89 	GtkWidget *name;
90 	GtkWidget *address;
91 
92 	header = E_COMPOSER_HEADER (object);
93 	from_header = E_COMPOSER_FROM_HEADER (object);
94 	registry = e_composer_header_get_registry (header);
95 
96 	/* Input widget must be set before chaining up. */
97 
98 	widget = e_mail_identity_combo_box_new (registry);
99 	e_mail_identity_combo_box_set_allow_aliases (E_MAIL_IDENTITY_COMBO_BOX (widget), TRUE);
100 	gtk_widget_show (widget);
101 	g_signal_connect (
102 		widget, "changed",
103 		G_CALLBACK (composer_from_header_changed_cb), header);
104 	header->input_widget = g_object_ref_sink (widget);
105 
106 	grid = gtk_grid_new ();
107 	gtk_grid_set_column_homogeneous (GTK_GRID (grid), FALSE);
108 	label = gtk_label_new_with_mnemonic (_("_Name:"));
109 	gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
110 	name = gtk_entry_new ();
111 	g_object_set (G_OBJECT (name),
112 		"hexpand", TRUE,
113 		"halign", GTK_ALIGN_FILL,
114 		"margin-left", 2,
115 		"margin-right", 2,
116 		NULL);
117 	gtk_grid_attach (GTK_GRID (grid), name, 1, 0, 1, 1);
118 	gtk_label_set_mnemonic_widget (GTK_LABEL (label), name);
119 	gtk_widget_show (label);
120 	gtk_widget_show (name);
121 
122 	label = gtk_label_new_with_mnemonic (_("_Address:"));
123 	gtk_grid_attach (GTK_GRID (grid), label, 2, 0, 1, 1);
124 	address = gtk_entry_new ();
125 	g_object_set (G_OBJECT (address),
126 		"hexpand", TRUE,
127 		"halign", GTK_ALIGN_FILL,
128 		"margin-left", 2,
129 		"margin-right", 0,
130 		NULL);
131 	gtk_grid_attach (GTK_GRID (grid), address, 3, 0, 1, 1);
132 	gtk_label_set_mnemonic_widget (GTK_LABEL (label), address);
133 	gtk_widget_show (label);
134 	gtk_widget_show (address);
135 
136 	if (from_header->override_visible)
137 		gtk_widget_show (grid);
138 	else
139 		gtk_widget_hide (grid);
140 
141 	from_header->override_widget = g_object_ref_sink (grid);
142 
143 	/* Chain up to parent's constructed() method. */
144 	G_OBJECT_CLASS (e_composer_from_header_parent_class)->constructed (object);
145 }
146 
147 static void
composer_from_header_dispose(GObject * object)148 composer_from_header_dispose (GObject *object)
149 {
150 	EComposerFromHeader *from_header;
151 
152 	from_header = E_COMPOSER_FROM_HEADER (object);
153 
154 	g_clear_object (&from_header->override_widget);
155 
156 	/* Chain up to parent's method. */
157 	G_OBJECT_CLASS (e_composer_from_header_parent_class)->dispose (object);
158 }
159 
160 static void
e_composer_from_header_class_init(EComposerFromHeaderClass * class)161 e_composer_from_header_class_init (EComposerFromHeaderClass *class)
162 {
163 	GObjectClass *object_class;
164 
165 	object_class = G_OBJECT_CLASS (class);
166 	object_class->set_property = composer_from_header_set_property;
167 	object_class->get_property = composer_from_header_get_property;
168 	object_class->constructed = composer_from_header_constructed;
169 	object_class->dispose = composer_from_header_dispose;
170 
171 	g_object_class_install_property (
172 		object_class,
173 		PROP_OVERRIDE_VISIBLE,
174 		g_param_spec_boolean (
175 			"override-visible",
176 			NULL,
177 			NULL,
178 			FALSE,
179 			G_PARAM_READWRITE |
180 			G_PARAM_STATIC_STRINGS));
181 }
182 
183 static void
e_composer_from_header_init(EComposerFromHeader * from_header)184 e_composer_from_header_init (EComposerFromHeader *from_header)
185 {
186 }
187 
188 EComposerHeader *
e_composer_from_header_new(ESourceRegistry * registry,const gchar * label)189 e_composer_from_header_new (ESourceRegistry *registry,
190                             const gchar *label)
191 {
192 	g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
193 
194 	return g_object_new (
195 		E_TYPE_COMPOSER_FROM_HEADER,
196 		"label", label, "button", FALSE,
197 		"registry", registry, NULL);
198 }
199 
200 static GtkComboBox *
e_composer_from_header_get_identities_widget(EComposerFromHeader * header)201 e_composer_from_header_get_identities_widget (EComposerFromHeader *header)
202 
203 {
204 	g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), NULL);
205 
206 	return GTK_COMBO_BOX (E_COMPOSER_HEADER (header)->input_widget);
207 }
208 
209 gchar *
e_composer_from_header_dup_active_id(EComposerFromHeader * header,gchar ** alias_name,gchar ** alias_address)210 e_composer_from_header_dup_active_id (EComposerFromHeader *header,
211 				      gchar **alias_name,
212 				      gchar **alias_address)
213 {
214 	GtkComboBox *combo_box;
215 	gchar *identity_uid = NULL;
216 
217 	g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), NULL);
218 
219 	combo_box = e_composer_from_header_get_identities_widget (header);
220 
221 	if (!e_mail_identity_combo_box_get_active_uid (E_MAIL_IDENTITY_COMBO_BOX (combo_box), &identity_uid, alias_name, alias_address))
222 		return NULL;
223 
224 	return identity_uid;
225 }
226 
227 void
e_composer_from_header_set_active_id(EComposerFromHeader * header,const gchar * active_id,const gchar * alias_name,const gchar * alias_address)228 e_composer_from_header_set_active_id (EComposerFromHeader *header,
229 				      const gchar *active_id,
230 				      const gchar *alias_name,
231 				      const gchar *alias_address)
232 {
233 	GtkComboBox *combo_box;
234 
235 	g_return_if_fail (E_IS_COMPOSER_FROM_HEADER (header));
236 
237 	if (!active_id)
238 		return;
239 
240 	combo_box = e_composer_from_header_get_identities_widget (header);
241 
242 	if (!e_mail_identity_combo_box_set_active_uid (E_MAIL_IDENTITY_COMBO_BOX (combo_box),
243 		active_id, alias_name, alias_address) && active_id && *active_id) {
244 		ESourceRegistry *registry;
245 		GtkTreeModel *model;
246 		GtkTreeIter iter;
247 		gint id_column;
248 
249 		registry = e_composer_header_get_registry (E_COMPOSER_HEADER (header));
250 		id_column = gtk_combo_box_get_id_column (combo_box);
251 		model = gtk_combo_box_get_model (combo_box);
252 
253 		if (gtk_tree_model_get_iter_first (model, &iter)) {
254 			do {
255 				gchar *identity_uid = NULL;
256 
257 				gtk_tree_model_get (model, &iter, id_column, &identity_uid, -1);
258 
259 				if (identity_uid) {
260 					ESource *source;
261 
262 					source = e_source_registry_ref_source (registry, identity_uid);
263 					if (source) {
264 						if (g_strcmp0 (e_source_get_parent (source), active_id) == 0) {
265 							g_object_unref (source);
266 							gtk_combo_box_set_active_id (combo_box, identity_uid);
267 							g_free (identity_uid);
268 							break;
269 						}
270 						g_object_unref (source);
271 					}
272 
273 					g_free (identity_uid);
274 				}
275 			} while (gtk_tree_model_iter_next (model, &iter));
276 		}
277 	}
278 }
279 
280 GtkEntry *
e_composer_from_header_get_name_entry(EComposerFromHeader * header)281 e_composer_from_header_get_name_entry (EComposerFromHeader *header)
282 {
283 	g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), NULL);
284 
285 	return GTK_ENTRY (gtk_grid_get_child_at (GTK_GRID (header->override_widget), 1, 0));
286 }
287 
288 const gchar *
e_composer_from_header_get_name(EComposerFromHeader * header)289 e_composer_from_header_get_name (EComposerFromHeader *header)
290 {
291 	const gchar *text;
292 
293 	g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), NULL);
294 
295 	text = gtk_entry_get_text (e_composer_from_header_get_name_entry (header));
296 	if (text && !*text)
297 		text = NULL;
298 
299 	return text;
300 }
301 
302 void
e_composer_from_header_set_name(EComposerFromHeader * header,const gchar * name)303 e_composer_from_header_set_name (EComposerFromHeader *header,
304                                  const gchar *name)
305 {
306 	GtkEntry *widget;
307 
308 	g_return_if_fail (E_IS_COMPOSER_FROM_HEADER (header));
309 
310 	if (!name)
311 		name = "";
312 
313 	widget = e_composer_from_header_get_name_entry (header);
314 
315 	gtk_entry_set_text (widget, name);
316 }
317 
318 GtkEntry *
e_composer_from_header_get_address_entry(EComposerFromHeader * header)319 e_composer_from_header_get_address_entry (EComposerFromHeader *header)
320 {
321 	g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), NULL);
322 
323 	return GTK_ENTRY (gtk_grid_get_child_at (GTK_GRID (header->override_widget), 3, 0));
324 }
325 
326 const gchar *
e_composer_from_header_get_address(EComposerFromHeader * header)327 e_composer_from_header_get_address (EComposerFromHeader *header)
328 {
329 	const gchar *text;
330 
331 	g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), NULL);
332 
333 	text = gtk_entry_get_text (e_composer_from_header_get_address_entry (header));
334 	if (text && !*text)
335 		text = NULL;
336 
337 	return text;
338 }
339 
340 void
e_composer_from_header_set_address(EComposerFromHeader * header,const gchar * address)341 e_composer_from_header_set_address (EComposerFromHeader *header,
342                                     const gchar *address)
343 {
344 	GtkEntry *widget;
345 
346 	g_return_if_fail (E_IS_COMPOSER_FROM_HEADER (header));
347 
348 	if (!address)
349 		address = "";
350 
351 	widget = e_composer_from_header_get_address_entry (header);
352 
353 	gtk_entry_set_text (widget, address);
354 }
355 
356 gboolean
e_composer_from_header_get_override_visible(EComposerFromHeader * header)357 e_composer_from_header_get_override_visible (EComposerFromHeader *header)
358 {
359 	g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), FALSE);
360 
361 	return header->override_visible;
362 }
363 
364 void
e_composer_from_header_set_override_visible(EComposerFromHeader * header,gboolean visible)365 e_composer_from_header_set_override_visible (EComposerFromHeader *header,
366 					     gboolean visible)
367 {
368 	g_return_if_fail (E_IS_COMPOSER_FROM_HEADER (header));
369 
370 	if (header->override_visible == visible)
371 		return;
372 
373 	header->override_visible = visible;
374 
375 	/* Show/hide the override widgets accordingly. */
376 	if (header->override_widget) {
377 		if (visible)
378 			gtk_widget_show (header->override_widget);
379 		else
380 			gtk_widget_hide (header->override_widget);
381 	}
382 
383 	g_object_notify (G_OBJECT (header), "override-visible");
384 }
385