changes: Bump to 3.8.1
[platform/upstream/evolution-data-server.git] / libedataserver / e-source-mail-composition.c
1 /*
2  * e-source-mail-composition.c
3  *
4  * This library 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 library 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 library; if not, see <http://www.gnu.org/licenses/>.
15  *
16  */
17
18 /**
19  * SECTION: e-source-mail-composition
20  * @include: libedataserver/libedataserver.h
21  * @short_description: #ESource extension for mail composition settings
22  *
23  * The #ESourceMailComposition extension tracks settings to be applied
24  * when composing a new mail message.
25  *
26  * Access the extension as follows:
27  *
28  * |[
29  *   #include <libedataserver/libedataserver.h>
30  *
31  *   ESourceMailComposition *extension;
32  *
33  *   extension = e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_COMPOSITION);
34  * ]|
35  **/
36
37 #include "e-source-mail-composition.h"
38
39 #include <libedataserver/e-data-server-util.h>
40
41 #define E_SOURCE_MAIL_COMPOSITION_GET_PRIVATE(obj) \
42         (G_TYPE_INSTANCE_GET_PRIVATE \
43         ((obj), E_TYPE_SOURCE_MAIL_COMPOSITION, ESourceMailCompositionPrivate))
44
45 struct _ESourceMailCompositionPrivate {
46         GMutex property_lock;
47         gchar **bcc;
48         gchar **cc;
49         gchar *drafts_folder;
50         gchar *templates_folder;
51         gboolean sign_imip;
52 };
53
54 enum {
55         PROP_0,
56         PROP_BCC,
57         PROP_CC,
58         PROP_DRAFTS_FOLDER,
59         PROP_SIGN_IMIP,
60         PROP_TEMPLATES_FOLDER
61 };
62
63 G_DEFINE_TYPE (
64         ESourceMailComposition,
65         e_source_mail_composition,
66         E_TYPE_SOURCE_EXTENSION)
67
68 static void
69 source_mail_composition_set_property (GObject *object,
70                                       guint property_id,
71                                       const GValue *value,
72                                       GParamSpec *pspec)
73 {
74         switch (property_id) {
75                 case PROP_BCC:
76                         e_source_mail_composition_set_bcc (
77                                 E_SOURCE_MAIL_COMPOSITION (object),
78                                 g_value_get_boxed (value));
79                         return;
80
81                 case PROP_CC:
82                         e_source_mail_composition_set_cc (
83                                 E_SOURCE_MAIL_COMPOSITION (object),
84                                 g_value_get_boxed (value));
85                         return;
86
87                 case PROP_DRAFTS_FOLDER:
88                         e_source_mail_composition_set_drafts_folder (
89                                 E_SOURCE_MAIL_COMPOSITION (object),
90                                 g_value_get_string (value));
91                         return;
92
93                 case PROP_SIGN_IMIP:
94                         e_source_mail_composition_set_sign_imip (
95                                 E_SOURCE_MAIL_COMPOSITION (object),
96                                 g_value_get_boolean (value));
97                         return;
98
99                 case PROP_TEMPLATES_FOLDER:
100                         e_source_mail_composition_set_templates_folder (
101                                 E_SOURCE_MAIL_COMPOSITION (object),
102                                 g_value_get_string (value));
103                         return;
104         }
105
106         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
107 }
108
109 static void
110 source_mail_composition_get_property (GObject *object,
111                                       guint property_id,
112                                       GValue *value,
113                                       GParamSpec *pspec)
114 {
115         switch (property_id) {
116                 case PROP_BCC:
117                         g_value_take_boxed (
118                                 value,
119                                 e_source_mail_composition_dup_bcc (
120                                 E_SOURCE_MAIL_COMPOSITION (object)));
121                         return;
122
123                 case PROP_CC:
124                         g_value_take_boxed (
125                                 value,
126                                 e_source_mail_composition_dup_cc (
127                                 E_SOURCE_MAIL_COMPOSITION (object)));
128                         return;
129
130                 case PROP_DRAFTS_FOLDER:
131                         g_value_take_string (
132                                 value,
133                                 e_source_mail_composition_dup_drafts_folder (
134                                 E_SOURCE_MAIL_COMPOSITION (object)));
135                         return;
136
137                 case PROP_SIGN_IMIP:
138                         g_value_set_boolean (
139                                 value,
140                                 e_source_mail_composition_get_sign_imip (
141                                 E_SOURCE_MAIL_COMPOSITION (object)));
142                         return;
143
144                 case PROP_TEMPLATES_FOLDER:
145                         g_value_take_string (
146                                 value,
147                                 e_source_mail_composition_dup_templates_folder (
148                                 E_SOURCE_MAIL_COMPOSITION (object)));
149                         return;
150         }
151
152         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
153 }
154
155 static void
156 source_mail_composition_finalize (GObject *object)
157 {
158         ESourceMailCompositionPrivate *priv;
159
160         priv = E_SOURCE_MAIL_COMPOSITION_GET_PRIVATE (object);
161
162         g_mutex_clear (&priv->property_lock);
163
164         g_strfreev (priv->bcc);
165         g_strfreev (priv->cc);
166         g_free (priv->drafts_folder);
167         g_free (priv->templates_folder);
168
169         /* Chain up to parent's finalize() method. */
170         G_OBJECT_CLASS (e_source_mail_composition_parent_class)->
171                 finalize (object);
172 }
173
174 static void
175 e_source_mail_composition_class_init (ESourceMailCompositionClass *class)
176 {
177         GObjectClass *object_class;
178         ESourceExtensionClass *extension_class;
179
180         g_type_class_add_private (
181                 class, sizeof (ESourceMailCompositionPrivate));
182
183         object_class = G_OBJECT_CLASS (class);
184         object_class->set_property = source_mail_composition_set_property;
185         object_class->get_property = source_mail_composition_get_property;
186         object_class->finalize = source_mail_composition_finalize;
187
188         extension_class = E_SOURCE_EXTENSION_CLASS (class);
189         extension_class->name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
190
191         g_object_class_install_property (
192                 object_class,
193                 PROP_BCC,
194                 g_param_spec_boxed (
195                         "bcc",
196                         "Bcc",
197                         "Recipients to blind carbon-copy",
198                         G_TYPE_STRV,
199                         G_PARAM_READWRITE |
200                         G_PARAM_CONSTRUCT |
201                         G_PARAM_STATIC_STRINGS |
202                         E_SOURCE_PARAM_SETTING));
203
204         g_object_class_install_property (
205                 object_class,
206                 PROP_CC,
207                 g_param_spec_boxed (
208                         "cc",
209                         "Cc",
210                         "Recipients to carbon-copy",
211                         G_TYPE_STRV,
212                         G_PARAM_READWRITE |
213                         G_PARAM_CONSTRUCT |
214                         G_PARAM_STATIC_STRINGS |
215                         E_SOURCE_PARAM_SETTING));
216
217         g_object_class_install_property (
218                 object_class,
219                 PROP_DRAFTS_FOLDER,
220                 g_param_spec_string (
221                         "drafts-folder",
222                         "Drafts Folder",
223                         "Preferred folder for draft messages",
224                         NULL,
225                         G_PARAM_READWRITE |
226                         G_PARAM_CONSTRUCT |
227                         G_PARAM_STATIC_STRINGS |
228                         E_SOURCE_PARAM_SETTING));
229
230         g_object_class_install_property (
231                 object_class,
232                 PROP_SIGN_IMIP,
233                 g_param_spec_boolean (
234                         "sign-imip",
235                         "Sign iMIP",
236                         "Include iMIP messages when signing",
237                         TRUE,
238                         G_PARAM_READWRITE |
239                         G_PARAM_CONSTRUCT |
240                         G_PARAM_STATIC_STRINGS |
241                         E_SOURCE_PARAM_SETTING));
242
243         g_object_class_install_property (
244                 object_class,
245                 PROP_TEMPLATES_FOLDER,
246                 g_param_spec_string (
247                         "templates-folder",
248                         "Templates Folder",
249                         "Preferred folder for message templates",
250                         NULL,
251                         G_PARAM_READWRITE |
252                         G_PARAM_CONSTRUCT |
253                         G_PARAM_STATIC_STRINGS |
254                         E_SOURCE_PARAM_SETTING));
255 }
256
257 static void
258 e_source_mail_composition_init (ESourceMailComposition *extension)
259 {
260         extension->priv = E_SOURCE_MAIL_COMPOSITION_GET_PRIVATE (extension);
261         g_mutex_init (&extension->priv->property_lock);
262 }
263
264 /**
265  * e_source_mail_composition_get_bcc:
266  * @extension: an #ESourceMailComposition
267  *
268  * Returns a %NULL-terminated string array of recipients which should
269  * automatically be added to the blind carbon-copy (Bcc) list when
270  * composing a new mail message.  The recipient strings should be of
271  * the form "Full Name &lt;email-address&gt;".  The returned array is
272  * owned by @extension and should not be modified or freed.
273  *
274  * Returns: (transfer none): a %NULL-terminated string array of Bcc recipients
275  *
276  * Since: 3.6
277  **/
278 const gchar * const *
279 e_source_mail_composition_get_bcc (ESourceMailComposition *extension)
280 {
281         g_return_val_if_fail (E_IS_SOURCE_MAIL_COMPOSITION (extension), NULL);
282
283         return (const gchar * const *) extension->priv->bcc;
284 }
285
286 /**
287  * e_source_mail_composition_dup_bcc:
288  * @extension: an #ESourceMailComposition
289  *
290  * Thread-safe variation of e_source_mail_composition_get_bcc().
291  * Use this function when accessing @extension from multiple threads.
292  *
293  * The returned string array should be freed with g_strfreev() when no
294  * longer needed.
295  *
296  * Returns: (transfer full): a newly-allocated copy of
297  * #ESourceMailComposition:bcc
298  *
299  * Since: 3.6
300  **/
301 gchar **
302 e_source_mail_composition_dup_bcc (ESourceMailComposition *extension)
303 {
304         const gchar * const *protected;
305         gchar **duplicate;
306
307         g_return_val_if_fail (E_IS_SOURCE_MAIL_COMPOSITION (extension), NULL);
308
309         g_mutex_lock (&extension->priv->property_lock);
310
311         protected = e_source_mail_composition_get_bcc (extension);
312         duplicate = g_strdupv ((gchar **) protected);
313
314         g_mutex_unlock (&extension->priv->property_lock);
315
316         return duplicate;
317 }
318
319 /**
320  * e_source_mail_composition_set_bcc:
321  * @extension: an #ESource
322  * @bcc: (allow-none): a %NULL-terminated string array of Bcc recipients
323  *
324  * Sets the recipients which should automatically be added to the blind
325  * carbon-copy (Bcc) list when composing a new mail message.  The recipient
326  * strings should be of the form "Full Name &lt;email-address&gt;".
327  *
328  * Since: 3.6
329  **/
330 void
331 e_source_mail_composition_set_bcc (ESourceMailComposition *extension,
332                                    const gchar * const *bcc)
333 {
334         g_return_if_fail (E_IS_SOURCE_MAIL_COMPOSITION (extension));
335
336         g_mutex_lock (&extension->priv->property_lock);
337
338         if (e_util_strv_equal (bcc, extension->priv->bcc)) {
339                 g_mutex_unlock (&extension->priv->property_lock);
340                 return;
341         }
342
343         g_strfreev (extension->priv->bcc);
344         extension->priv->bcc = g_strdupv ((gchar **) bcc);
345
346         g_mutex_unlock (&extension->priv->property_lock);
347
348         g_object_notify (G_OBJECT (extension), "bcc");
349 }
350
351 /**
352  * e_source_mail_composition_get_cc:
353  * @extension: an #ESourceMailComposition
354  *
355  * Returns a %NULL-terminated string array of recipients which should
356  * automatically be added to the carbon-copy (Cc) list when composing a
357  * new mail message.  The recipient strings should be of the form "Full
358  * Name <email-address>".  The returned array is owned by @extension and
359  * should not be modified or freed.
360  *
361  * Returns: (transfer none): a %NULL-terminated string array of Cc recipients
362  *
363  * Since: 3.6
364  **/
365 const gchar * const *
366 e_source_mail_composition_get_cc (ESourceMailComposition *extension)
367 {
368         g_return_val_if_fail (E_IS_SOURCE_MAIL_COMPOSITION (extension), NULL);
369
370         return (const gchar * const *) extension->priv->cc;
371 }
372
373 /**
374  * e_source_mail_composition_dup_cc:
375  * @extension: an #ESourceMailComposition
376  *
377  * Thread-safe variation of e_source_mail_composition_get_cc().
378  * Use this function when accessing @extension from multiple threads.
379  *
380  * The returned string array should be freed with g_strfreev() when no
381  * longer needed.
382  *
383  * Returns: (transfer full): a newly-allocated copy of
384  * #ESourceMailComposition:cc
385  *
386  * Since: 3.6
387  **/
388 gchar **
389 e_source_mail_composition_dup_cc (ESourceMailComposition *extension)
390 {
391         const gchar * const *protected;
392         gchar **duplicate;
393
394         g_return_val_if_fail (E_IS_SOURCE_MAIL_COMPOSITION (extension), NULL);
395
396         g_mutex_lock (&extension->priv->property_lock);
397
398         protected = e_source_mail_composition_get_cc (extension);
399         duplicate = g_strdupv ((gchar **) protected);
400
401         g_mutex_unlock (&extension->priv->property_lock);
402
403         return duplicate;
404 }
405
406 /**
407  * e_source_mail_composition_set_cc:
408  * @extension: an #ESourceMailComposition
409  * @cc: (allow-none): a %NULL-terminated string array of Cc recipients
410  *
411  * Sets the recipients which should automatically be added to the carbon
412  * copy (Cc) list when composing a new mail message.  The recipient strings
413  * should be of the form "Full Name &lt;email-address&gt;".
414  *
415  * Since: 3.6
416  **/
417 void
418 e_source_mail_composition_set_cc (ESourceMailComposition *extension,
419                                   const gchar * const *cc)
420 {
421         g_return_if_fail (E_IS_SOURCE_MAIL_COMPOSITION (extension));
422
423         g_mutex_lock (&extension->priv->property_lock);
424
425         if (e_util_strv_equal (cc, extension->priv->cc)) {
426                 g_mutex_unlock (&extension->priv->property_lock);
427                 return;
428         }
429
430         g_strfreev (extension->priv->cc);
431         extension->priv->cc = g_strdupv ((gchar **) cc);
432
433         g_mutex_unlock (&extension->priv->property_lock);
434
435         g_object_notify (G_OBJECT (extension), "cc");
436 }
437
438 /**
439  * e_source_mail_composition_get_drafts_folder:
440  * @extension: an #ESourceMailComposition
441  * 
442  * Returns a string identifying the preferred folder for draft messages.
443  * The format of the identifier string is defined by the client application.
444  *
445  * Returns: an identifier for the preferred drafts folder
446  *
447  * Since: 3.6
448  **/
449 const gchar *
450 e_source_mail_composition_get_drafts_folder (ESourceMailComposition *extension)
451 {
452         g_return_val_if_fail (E_IS_SOURCE_MAIL_COMPOSITION (extension), NULL);
453
454         return extension->priv->drafts_folder;
455 }
456
457 /**
458  * e_source_mail_composition_dup_drafts_folder:
459  * @extension: an #ESourceMailComposition
460  *
461  * Thread-safe variation of e_source_mail_composition_get_drafts_folder().
462  * Use this function when accessing @extension from multiple threads.
463  *
464  * The returned string should be freed with g_free() when no longer needed.
465  *
466  * Returns: a newly-allocated copy of #ESourceMailComposition:drafts-folder
467  *
468  * Since: 3.6
469  **/
470 gchar *
471 e_source_mail_composition_dup_drafts_folder (ESourceMailComposition *extension)
472 {
473         const gchar *protected;
474         gchar *duplicate;
475
476         g_return_val_if_fail (E_IS_SOURCE_MAIL_COMPOSITION (extension), NULL);
477
478         g_mutex_lock (&extension->priv->property_lock);
479
480         protected = e_source_mail_composition_get_drafts_folder (extension);
481         duplicate = g_strdup (protected);
482
483         g_mutex_unlock (&extension->priv->property_lock);
484
485         return duplicate;
486 }
487
488 /**
489  * e_source_mail_composition_set_drafts_folder:
490  * @extension: an #ESourceMailComposition
491  * @drafts_folder: (allow-none): an identifier for the preferred drafts
492  *                 folder, or %NULL
493  *
494  * Sets the preferred folder for draft messages by an identifier string.
495  * The format of the identifier string is defined by the client application.
496  *
497  * The internal copy of @drafts_folder is automatically stripped of
498  * leading and trailing whitespace.  If the resulting string is empty,
499  * %NULL is set instead.
500  *
501  * Since: 3.6
502  **/
503 void
504 e_source_mail_composition_set_drafts_folder (ESourceMailComposition *extension,
505                                              const gchar *drafts_folder)
506 {
507         g_return_if_fail (E_IS_SOURCE_MAIL_COMPOSITION (extension));
508
509         g_mutex_lock (&extension->priv->property_lock);
510
511         if (g_strcmp0 (extension->priv->drafts_folder, drafts_folder) == 0) {
512                 g_mutex_unlock (&extension->priv->property_lock);
513                 return;
514         }
515
516         g_free (extension->priv->drafts_folder);
517         extension->priv->drafts_folder = e_util_strdup_strip (drafts_folder);
518
519         g_mutex_unlock (&extension->priv->property_lock);
520
521         g_object_notify (G_OBJECT (extension), "drafts-folder");
522 }
523
524 /**
525  * e_source_mail_composition_get_sign_imip:
526  * @extension: an #ESourceMailComposition
527  *
528  * Returns whether outgoing iMIP messages such as meeting requests should
529  * also be signed.  This is primarily intended as a workaround for certain
530  * versions of Microsoft Outlook which can't handle signed iMIP messages.
531  *
532  * Returns: whether outgoing iMIP messages should be signed
533  *
534  * Since: 3.6
535  **/
536 gboolean
537 e_source_mail_composition_get_sign_imip (ESourceMailComposition *extension)
538 {
539         g_return_val_if_fail (E_IS_SOURCE_MAIL_COMPOSITION (extension), FALSE);
540
541         return extension->priv->sign_imip;
542 }
543
544 /**
545  * e_source_mail_composition_set_sign_imip:
546  * @extension: an #ESourceMailComposition
547  * @sign_imip: whether outgoing iMIP messages should be signed
548  *
549  * Sets whether outgoing iMIP messages such as meeting requests should
550  * also be signed.  This is primarily intended as a workaround for certain
551  * versions of Microsoft Outlook which can't handle signed iMIP messages.
552  *
553  * Since: 3.6
554  **/
555 void
556 e_source_mail_composition_set_sign_imip (ESourceMailComposition *extension,
557                                          gboolean sign_imip)
558 {
559         g_return_if_fail (E_IS_SOURCE_MAIL_COMPOSITION (extension));
560
561         if (extension->priv->sign_imip == sign_imip)
562                 return;
563
564         extension->priv->sign_imip = sign_imip;
565
566         g_object_notify (G_OBJECT (extension), "sign-imip");
567 }
568
569 /**
570  * e_source_mail_composition_get_templates_folder:
571  * @extension: an #ESourceMailComposition
572  *
573  * Returns a string identifying the preferred folder for message templates.
574  * The format of the identifier string is defined by the client application.
575  *
576  * Returns: an identifier for the preferred templates folder
577  *
578  * Since: 3.6
579  **/
580 const gchar *
581 e_source_mail_composition_get_templates_folder (ESourceMailComposition *extension)
582 {
583         g_return_val_if_fail (E_IS_SOURCE_MAIL_COMPOSITION (extension), NULL);
584
585         return extension->priv->templates_folder;
586 }
587
588 /**
589  * e_source_mail_composition_dup_templates_folder:
590  * @extension: an #ESourceMailComposition
591  *
592  * Thread-safe variation of e_source_mail_composition_get_templates_folder().
593  * Use this function when accessing @extension from multiple threads.
594  *
595  * The returned string should be freed with g_free() when no longer needed.
596  *
597  * Returns: a newly-allocated copy of #ESourceMailComposition:templates-folder
598  *
599  * Since: 3.6
600  **/
601 gchar *
602 e_source_mail_composition_dup_templates_folder (ESourceMailComposition *extension)
603 {
604         const gchar *protected;
605         gchar *duplicate;
606
607         g_return_val_if_fail (E_IS_SOURCE_MAIL_COMPOSITION (extension), NULL);
608
609         g_mutex_lock (&extension->priv->property_lock);
610
611         protected = e_source_mail_composition_get_templates_folder (extension);
612         duplicate = g_strdup (protected);
613
614         g_mutex_unlock (&extension->priv->property_lock);
615
616         return duplicate;
617 }
618
619 /**
620  * e_source_mail_composition_set_templates_folder:
621  * @extension: an #ESourceMailComposition
622  * @templates_folder: (allow-none): an identifier for the preferred templates
623  *                    folder, or %NULL
624  *
625  * Sets the preferred folder for message templates by an identifier string.
626  * The format of the identifier string is defined by the client application.
627  *
628  * The internal copy of @templates_folder is automatically stripped of
629  * leading and trailing whitespace.  If the resulting string is empty,
630  * %NULL is set instead.
631  *
632  * Since: 3.6
633  **/
634 void
635 e_source_mail_composition_set_templates_folder (ESourceMailComposition *extension,
636                                                 const gchar *templates_folder)
637 {
638         g_return_if_fail (E_IS_SOURCE_MAIL_COMPOSITION (extension));
639
640         g_mutex_lock (&extension->priv->property_lock);
641
642         if (g_strcmp0 (extension->priv->templates_folder, templates_folder) == 0) {
643                 g_mutex_unlock (&extension->priv->property_lock);
644                 return;
645         }
646
647         g_free (extension->priv->templates_folder);
648         extension->priv->templates_folder = e_util_strdup_strip (templates_folder);
649
650         g_mutex_unlock (&extension->priv->property_lock);
651
652         g_object_notify (G_OBJECT (extension), "templates-folder");
653 }
654