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 "e-composer-post-header.h"
23
24 #include <string.h>
25 #include <glib/gi18n.h>
26 #include <camel/camel.h>
27
28 #define E_COMPOSER_POST_HEADER_GET_PRIVATE(obj) \
29 (G_TYPE_INSTANCE_GET_PRIVATE \
30 ((obj), E_TYPE_COMPOSER_POST_HEADER, EComposerPostHeaderPrivate))
31
32 enum {
33 PROP_0,
34 PROP_MAIL_ACCOUNT
35 };
36
37 struct _EComposerPostHeaderPrivate {
38 ESource *mail_account;
39 gchar *base_url; /* derived from account */
40 gboolean custom;
41 };
42
G_DEFINE_TYPE(EComposerPostHeader,e_composer_post_header,E_TYPE_COMPOSER_TEXT_HEADER)43 G_DEFINE_TYPE (
44 EComposerPostHeader,
45 e_composer_post_header,
46 E_TYPE_COMPOSER_TEXT_HEADER)
47
48 static gchar *
49 composer_post_header_folder_name_to_string (EComposerPostHeader *header,
50 const gchar *url)
51 {
52 gchar *res = NULL;
53 const gchar *base_url = header->priv->base_url;
54
55 if (base_url != NULL) {
56 gsize length = strlen (base_url);
57
58 if (g_ascii_strncasecmp (url, base_url, length) == 0) {
59 res = g_uri_unescape_string (url + length, NULL);
60 if (!res)
61 res = g_strdup (url + length);
62 }
63 }
64
65 if (!res) {
66 res = g_uri_unescape_string (url, NULL);
67 if (!res)
68 res = g_strdup (url);
69 }
70
71 return res;
72 }
73
74 static void
composer_post_header_set_base_url(EComposerPostHeader * header)75 composer_post_header_set_base_url (EComposerPostHeader *header)
76 {
77 ESource *source;
78 const gchar *uid;
79
80 source = header->priv->mail_account;
81 if (source == NULL)
82 return;
83
84 uid = e_source_get_uid (source);
85 g_free (header->priv->base_url);
86 header->priv->base_url = g_strdup_printf ("folder://%s", uid);
87 }
88
89 static GList *
composer_post_header_split_csv(const gchar * csv)90 composer_post_header_split_csv (const gchar *csv)
91 {
92 GList *list = NULL;
93 gchar **strv;
94 guint length, ii;
95
96 strv = g_strsplit (csv, ",", 0);
97 length = g_strv_length (strv);
98
99 for (ii = 0; ii < length; ii++)
100 if (*g_strstrip (strv[ii]) != '\0')
101 list = g_list_prepend (list, g_strdup (strv[ii]));
102
103 g_strfreev (strv);
104
105 return g_list_reverse (list);
106 }
107
108 static void
composer_post_header_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)109 composer_post_header_set_property (GObject *object,
110 guint property_id,
111 const GValue *value,
112 GParamSpec *pspec)
113 {
114 switch (property_id) {
115 case PROP_MAIL_ACCOUNT:
116 e_composer_post_header_set_mail_account (
117 E_COMPOSER_POST_HEADER (object),
118 g_value_get_object (value));
119 return;
120 }
121
122 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
123 }
124
125 static void
composer_post_header_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)126 composer_post_header_get_property (GObject *object,
127 guint property_id,
128 GValue *value,
129 GParamSpec *pspec)
130 {
131 switch (property_id) {
132 case PROP_MAIL_ACCOUNT:
133 g_value_set_object (
134 value,
135 e_composer_post_header_get_mail_account (
136 E_COMPOSER_POST_HEADER (object)));
137 return;
138 }
139
140 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
141 }
142
143 static void
composer_post_header_dispose(GObject * object)144 composer_post_header_dispose (GObject *object)
145 {
146 EComposerPostHeaderPrivate *priv;
147
148 priv = E_COMPOSER_POST_HEADER_GET_PRIVATE (object);
149 g_clear_object (&priv->mail_account);
150
151 /* Chain up to parent's dispose() method. */
152 G_OBJECT_CLASS (e_composer_post_header_parent_class)->dispose (object);
153 }
154
155 static void
composer_post_header_finalize(GObject * object)156 composer_post_header_finalize (GObject *object)
157 {
158 EComposerPostHeaderPrivate *priv;
159
160 priv = E_COMPOSER_POST_HEADER_GET_PRIVATE (object);
161
162 g_free (priv->base_url);
163
164 /* Chain up to parent's finalize() method. */
165 G_OBJECT_CLASS (e_composer_post_header_parent_class)->finalize (object);
166 }
167
168 static void
composer_post_header_constructed(GObject * object)169 composer_post_header_constructed (GObject *object)
170 {
171 /* Chain up to parent's constructed() method. */
172 G_OBJECT_CLASS (e_composer_post_header_parent_class)->constructed (object);
173
174 e_composer_header_set_title_tooltip (
175 E_COMPOSER_HEADER (object),
176 _("Click here to select folders to post to"));
177 }
178
179 static void
composer_post_header_changed(EComposerHeader * header)180 composer_post_header_changed (EComposerHeader *header)
181 {
182 EComposerPostHeaderPrivate *priv;
183
184 priv = E_COMPOSER_POST_HEADER_GET_PRIVATE (header);
185
186 priv->custom = TRUE;
187 }
188
189 static void
composer_post_header_clicked(EComposerHeader * header)190 composer_post_header_clicked (EComposerHeader *header)
191 {
192 EComposerPostHeaderPrivate *priv;
193
194 priv = E_COMPOSER_POST_HEADER_GET_PRIVATE (header);
195
196 priv->custom = FALSE;
197 }
198
199 static void
e_composer_post_header_class_init(EComposerPostHeaderClass * class)200 e_composer_post_header_class_init (EComposerPostHeaderClass *class)
201 {
202 GObjectClass *object_class;
203 EComposerHeaderClass *header_class;
204
205 g_type_class_add_private (class, sizeof (EComposerPostHeaderPrivate));
206
207 object_class = G_OBJECT_CLASS (class);
208 object_class->set_property = composer_post_header_set_property;
209 object_class->get_property = composer_post_header_get_property;
210 object_class->dispose = composer_post_header_dispose;
211 object_class->finalize = composer_post_header_finalize;
212 object_class->constructed = composer_post_header_constructed;
213
214 header_class = E_COMPOSER_HEADER_CLASS (class);
215 header_class->changed = composer_post_header_changed;
216 header_class->clicked = composer_post_header_clicked;
217
218 g_object_class_install_property (
219 object_class,
220 PROP_MAIL_ACCOUNT,
221 g_param_spec_object (
222 "mail-account",
223 NULL,
224 NULL,
225 E_TYPE_SOURCE,
226 G_PARAM_READWRITE));
227 }
228
229 static void
e_composer_post_header_init(EComposerPostHeader * header)230 e_composer_post_header_init (EComposerPostHeader *header)
231 {
232 header->priv = E_COMPOSER_POST_HEADER_GET_PRIVATE (header);
233 }
234
235 EComposerHeader *
e_composer_post_header_new(ESourceRegistry * registry,const gchar * label)236 e_composer_post_header_new (ESourceRegistry *registry,
237 const gchar *label)
238 {
239 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
240
241 return g_object_new (
242 E_TYPE_COMPOSER_POST_HEADER,
243 "label", label, "button", TRUE,
244 "registry", registry, NULL);
245 }
246
247 GList *
e_composer_post_header_get_folders(EComposerPostHeader * header)248 e_composer_post_header_get_folders (EComposerPostHeader *header)
249 {
250 GList *folders, *iter;
251 gchar *base_url;
252
253 g_return_val_if_fail (E_IS_COMPOSER_POST_HEADER (header), NULL);
254
255 folders = composer_post_header_split_csv (
256 e_composer_text_header_get_text (
257 E_COMPOSER_TEXT_HEADER (header)));
258
259 base_url = header->priv->base_url;
260 if (base_url == NULL)
261 return folders;
262
263 for (iter = folders; iter != NULL; iter = iter->next) {
264 /* Convert relative folder names to absolute. */
265 /* XXX Should use CamelURL for this. */
266 if (strstr (iter->data, ":/") == NULL) {
267 gchar *abs_url;
268
269 abs_url = g_strconcat (base_url, iter->data, NULL);
270 g_free (iter->data);
271 iter->data = abs_url;
272 }
273 }
274
275 return folders;
276 }
277
278 void
e_composer_post_header_set_folders(EComposerPostHeader * header,GList * folders)279 e_composer_post_header_set_folders (EComposerPostHeader *header,
280 GList *folders)
281 {
282 GList *iter;
283 gint ii = 0;
284 gchar **strv;
285 gchar *text;
286 gboolean custom_save;
287
288 g_return_if_fail (E_IS_COMPOSER_POST_HEADER (header));
289
290 strv = g_new0 (gchar *, g_list_length (folders) + 1);
291
292 for (iter = folders; iter != NULL; iter = iter->next)
293 strv[ii++] = composer_post_header_folder_name_to_string (
294 header, iter->data);
295
296 text = g_strjoinv (", ", strv);
297 custom_save = header->priv->custom;
298 e_composer_text_header_set_text (
299 E_COMPOSER_TEXT_HEADER (header), text);
300 header->priv->custom = custom_save;
301 g_free (text);
302
303 g_strfreev (strv);
304 }
305
306 void
e_composer_post_header_set_folders_base(EComposerPostHeader * header,const gchar * base_url,const gchar * folders)307 e_composer_post_header_set_folders_base (EComposerPostHeader *header,
308 const gchar *base_url,
309 const gchar *folders)
310 {
311 GList *list, *iter;
312
313 list = composer_post_header_split_csv (folders);
314 for (iter = list; iter != NULL; iter = iter->next) {
315 gchar *abs_url;
316
317 /* FIXME This doesn't handle all folder names properly. */
318 abs_url = g_strdup_printf (
319 "%s/%s", base_url, (gchar *) iter->data);
320 g_free (iter->data);
321 iter->data = abs_url;
322 }
323
324 e_composer_post_header_set_folders (header, list);
325 g_list_foreach (list, (GFunc) g_free, NULL);
326 g_list_free (list);
327 }
328
329 ESource *
e_composer_post_header_get_mail_account(EComposerPostHeader * header)330 e_composer_post_header_get_mail_account (EComposerPostHeader *header)
331 {
332 g_return_val_if_fail (E_IS_COMPOSER_POST_HEADER (header), NULL);
333
334 return header->priv->mail_account;
335 }
336
337 void
e_composer_post_header_set_mail_account(EComposerPostHeader * header,ESource * mail_account)338 e_composer_post_header_set_mail_account (EComposerPostHeader *header,
339 ESource *mail_account)
340 {
341 GList *folders = NULL;
342
343 g_return_if_fail (E_IS_COMPOSER_POST_HEADER (header));
344
345 if (header->priv->mail_account == mail_account)
346 return;
347
348 if (mail_account != NULL) {
349 g_return_if_fail (E_IS_SOURCE (mail_account));
350 g_object_ref (mail_account);
351 }
352
353 if (!header->priv->custom)
354 folders = e_composer_post_header_get_folders (header);
355
356 if (header->priv->mail_account != NULL)
357 g_object_unref (header->priv->mail_account);
358
359 header->priv->mail_account = mail_account;
360 composer_post_header_set_base_url (header);
361
362 /* Make folders relative to the new account. */
363 if (!header->priv->custom) {
364 e_composer_post_header_set_folders (header, folders);
365 g_list_foreach (folders, (GFunc) g_free, NULL);
366 g_list_free (folders);
367 }
368
369 g_object_notify (G_OBJECT (header), "mail-account");
370 }
371