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