1 /*
2  * e-source-mail-submission.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 Lesser 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-submission
20  * @include: libedataserver/libedataserver.h
21  * @short_description: #ESource extension for submitting emails
22  *
23  * The #ESourceMailSubmission extension tracks settings to be applied
24  * when submitting a mail message for delivery.
25  *
26  * Access the extension as follows:
27  *
28  * |[
29  *   #include <libedataserver/libedataserver.h>
30  *
31  *   ESourceMailSubmission *extension;
32  *
33  *   extension = e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_SUBMISSION);
34  * ]|
35  **/
36 
37 #include "e-source-mail-submission.h"
38 
39 #include <libedataserver/e-data-server-util.h>
40 
41 struct _ESourceMailSubmissionPrivate {
42 	gchar *sent_folder;
43 	gchar *transport_uid;
44 	gboolean replies_to_origin_folder;
45 	gboolean use_sent_folder;
46 };
47 
48 enum {
49 	PROP_0,
50 	PROP_SENT_FOLDER,
51 	PROP_TRANSPORT_UID,
52 	PROP_REPLIES_TO_ORIGIN_FOLDER,
53 	PROP_USE_SENT_FOLDER
54 };
55 
G_DEFINE_TYPE_WITH_PRIVATE(ESourceMailSubmission,e_source_mail_submission,E_TYPE_SOURCE_EXTENSION)56 G_DEFINE_TYPE_WITH_PRIVATE (
57 	ESourceMailSubmission,
58 	e_source_mail_submission,
59 	E_TYPE_SOURCE_EXTENSION)
60 
61 static void
62 source_mail_submission_set_property (GObject *object,
63                                      guint property_id,
64                                      const GValue *value,
65                                      GParamSpec *pspec)
66 {
67 	switch (property_id) {
68 		case PROP_SENT_FOLDER:
69 			e_source_mail_submission_set_sent_folder (
70 				E_SOURCE_MAIL_SUBMISSION (object),
71 				g_value_get_string (value));
72 			return;
73 
74 		case PROP_TRANSPORT_UID:
75 			e_source_mail_submission_set_transport_uid (
76 				E_SOURCE_MAIL_SUBMISSION (object),
77 				g_value_get_string (value));
78 			return;
79 
80 		case PROP_REPLIES_TO_ORIGIN_FOLDER:
81 			e_source_mail_submission_set_replies_to_origin_folder (
82 				E_SOURCE_MAIL_SUBMISSION (object),
83 				g_value_get_boolean (value));
84 			return;
85 
86 		case PROP_USE_SENT_FOLDER:
87 			e_source_mail_submission_set_use_sent_folder (
88 				E_SOURCE_MAIL_SUBMISSION (object),
89 				g_value_get_boolean (value));
90 			return;
91 	}
92 
93 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
94 }
95 
96 static void
source_mail_submission_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)97 source_mail_submission_get_property (GObject *object,
98                                      guint property_id,
99                                      GValue *value,
100                                      GParamSpec *pspec)
101 {
102 	switch (property_id) {
103 		case PROP_SENT_FOLDER:
104 			g_value_take_string (
105 				value,
106 				e_source_mail_submission_dup_sent_folder (
107 				E_SOURCE_MAIL_SUBMISSION (object)));
108 			return;
109 
110 		case PROP_TRANSPORT_UID:
111 			g_value_take_string (
112 				value,
113 				e_source_mail_submission_dup_transport_uid (
114 				E_SOURCE_MAIL_SUBMISSION (object)));
115 			return;
116 
117 		case PROP_REPLIES_TO_ORIGIN_FOLDER:
118 			g_value_set_boolean (
119 				value,
120 				e_source_mail_submission_get_replies_to_origin_folder (
121 				E_SOURCE_MAIL_SUBMISSION (object)));
122 			return;
123 
124 		case PROP_USE_SENT_FOLDER:
125 			g_value_set_boolean (
126 				value,
127 				e_source_mail_submission_get_use_sent_folder (
128 				E_SOURCE_MAIL_SUBMISSION (object)));
129 			return;
130 	}
131 
132 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
133 }
134 
135 static void
source_mail_submission_finalize(GObject * object)136 source_mail_submission_finalize (GObject *object)
137 {
138 	ESourceMailSubmissionPrivate *priv;
139 
140 	priv = E_SOURCE_MAIL_SUBMISSION (object)->priv;
141 
142 	g_free (priv->sent_folder);
143 	g_free (priv->transport_uid);
144 
145 	/* Chain up to parent's finalize() method. */
146 	G_OBJECT_CLASS (e_source_mail_submission_parent_class)->
147 		finalize (object);
148 }
149 
150 static void
e_source_mail_submission_class_init(ESourceMailSubmissionClass * class)151 e_source_mail_submission_class_init (ESourceMailSubmissionClass *class)
152 {
153 	GObjectClass *object_class;
154 	ESourceExtensionClass *extension_class;
155 
156 	object_class = G_OBJECT_CLASS (class);
157 	object_class->set_property = source_mail_submission_set_property;
158 	object_class->get_property = source_mail_submission_get_property;
159 	object_class->finalize = source_mail_submission_finalize;
160 
161 	extension_class = E_SOURCE_EXTENSION_CLASS (class);
162 	extension_class->name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
163 
164 	g_object_class_install_property (
165 		object_class,
166 		PROP_SENT_FOLDER,
167 		g_param_spec_string (
168 			"sent-folder",
169 			"Sent Folder",
170 			"Preferred folder for sent messages",
171 			NULL,
172 			G_PARAM_READWRITE |
173 			G_PARAM_CONSTRUCT |
174 			G_PARAM_EXPLICIT_NOTIFY |
175 			G_PARAM_STATIC_STRINGS |
176 			E_SOURCE_PARAM_SETTING));
177 
178 	g_object_class_install_property (
179 		object_class,
180 		PROP_USE_SENT_FOLDER,
181 		g_param_spec_boolean (
182 			"use-sent-folder",
183 			"Use Sent Folder",
184 			"Whether to save sent messages to sent-folder",
185 			TRUE,
186 			G_PARAM_READWRITE |
187 			G_PARAM_CONSTRUCT |
188 			G_PARAM_EXPLICIT_NOTIFY |
189 			G_PARAM_STATIC_STRINGS |
190 			E_SOURCE_PARAM_SETTING));
191 
192 	g_object_class_install_property (
193 		object_class,
194 		PROP_TRANSPORT_UID,
195 		g_param_spec_string (
196 			"transport-uid",
197 			"Transport UID",
198 			"ESource UID of a Mail Transport",
199 			NULL,
200 			G_PARAM_READWRITE |
201 			G_PARAM_CONSTRUCT |
202 			G_PARAM_EXPLICIT_NOTIFY |
203 			G_PARAM_STATIC_STRINGS |
204 			E_SOURCE_PARAM_SETTING));
205 
206 	g_object_class_install_property (
207 		object_class,
208 		PROP_REPLIES_TO_ORIGIN_FOLDER,
209 		g_param_spec_boolean (
210 			"replies-to-origin-folder",
211 			"Replies to origin folder",
212 			"Whether to save replies to folder of the message "
213 			"being replied to, instead of the Sent folder",
214 			FALSE,
215 			G_PARAM_READWRITE |
216 			G_PARAM_CONSTRUCT |
217 			G_PARAM_EXPLICIT_NOTIFY |
218 			G_PARAM_STATIC_STRINGS |
219 			E_SOURCE_PARAM_SETTING));
220 }
221 
222 static void
e_source_mail_submission_init(ESourceMailSubmission * extension)223 e_source_mail_submission_init (ESourceMailSubmission *extension)
224 {
225 	extension->priv = e_source_mail_submission_get_instance_private (extension);
226 }
227 
228 /**
229  * e_source_mail_submission_get_sent_folder:
230  * @extension: an #ESourceMailSubmission
231  *
232  * Returns a string identifying the preferred folder for sent messages.
233  * The format of the identifier string is defined by the client application.
234  *
235  * Returns: (nullable): an identifier for the preferred sent folder
236  *
237  * Since: 3.6
238  **/
239 const gchar *
e_source_mail_submission_get_sent_folder(ESourceMailSubmission * extension)240 e_source_mail_submission_get_sent_folder (ESourceMailSubmission *extension)
241 {
242 	g_return_val_if_fail (E_IS_SOURCE_MAIL_SUBMISSION (extension), NULL);
243 
244 	return extension->priv->sent_folder;
245 }
246 
247 /**
248  * e_source_mail_submission_dup_sent_folder:
249  * @extension: an #ESourceMailSubmission
250  *
251  * Thread-safe variation of e_source_mail_submission_get_sent_folder().
252  * Use this function when accessing @extension from multiple threads.
253  *
254  * The returned string should be freed with g_free() when no longer needed.
255  *
256  * Returns: (nullable): a newly-allocated copy of #ESourceMailSubmission:sent-folder
257  *
258  * Since: 3.6
259  **/
260 gchar *
e_source_mail_submission_dup_sent_folder(ESourceMailSubmission * extension)261 e_source_mail_submission_dup_sent_folder (ESourceMailSubmission *extension)
262 {
263 	const gchar *protected;
264 	gchar *duplicate;
265 
266 	g_return_val_if_fail (E_IS_SOURCE_MAIL_SUBMISSION (extension), NULL);
267 
268 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
269 
270 	protected = e_source_mail_submission_get_sent_folder (extension);
271 	duplicate = g_strdup (protected);
272 
273 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
274 
275 	return duplicate;
276 }
277 
278 /**
279  * e_source_mail_submission_set_sent_folder:
280  * @extension: an #ESourceMailSubmission
281  * @sent_folder: (nullable): an identifier for the preferred sent folder,
282  *               or %NULL
283  *
284  * Sets the preferred folder for sent messages by an identifier string.
285  * The format of the identifier string is defined by the client application.
286  *
287  * The internal copy of @sent_folder is automatically stripped of leading
288  * and trailing whitespace.  If the resulting string is empty, %NULL is set
289  * instead.
290  *
291  * Since: 3.6
292  **/
293 void
e_source_mail_submission_set_sent_folder(ESourceMailSubmission * extension,const gchar * sent_folder)294 e_source_mail_submission_set_sent_folder (ESourceMailSubmission *extension,
295                                           const gchar *sent_folder)
296 {
297 	g_return_if_fail (E_IS_SOURCE_MAIL_SUBMISSION (extension));
298 
299 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
300 
301 	if (e_util_strcmp0 (extension->priv->sent_folder, sent_folder) == 0) {
302 		e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
303 		return;
304 	}
305 
306 	g_free (extension->priv->sent_folder);
307 	extension->priv->sent_folder = e_util_strdup_strip (sent_folder);
308 
309 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
310 
311 	g_object_notify (G_OBJECT (extension), "sent-folder");
312 }
313 
314 /**
315  * e_source_mail_submission_get_use_sent_folder:
316  * @extension: an #ESourceMailSubmission
317  *
318  * Returns: whether save messages to the sent folder at all
319  *
320  * Since: 3.26
321  **/
322 gboolean
e_source_mail_submission_get_use_sent_folder(ESourceMailSubmission * extension)323 e_source_mail_submission_get_use_sent_folder (ESourceMailSubmission *extension)
324 {
325 	g_return_val_if_fail (E_IS_SOURCE_MAIL_SUBMISSION (extension), FALSE);
326 
327 	return extension->priv->use_sent_folder;
328 }
329 
330 /**
331  * e_source_mail_submission_set_use_sent_folder:
332  * @extension: an #ESourceMailSubmission
333  * @use_sent_folder: the value to set
334  *
335  * Sets whether save messages to the sent folder at all.
336  *
337  * Since: 3.26
338  **/
339 void
e_source_mail_submission_set_use_sent_folder(ESourceMailSubmission * extension,gboolean use_sent_folder)340 e_source_mail_submission_set_use_sent_folder (ESourceMailSubmission *extension,
341 					      gboolean use_sent_folder)
342 {
343 	g_return_if_fail (E_IS_SOURCE_MAIL_SUBMISSION (extension));
344 
345 	if ((extension->priv->use_sent_folder ? 1 : 0) == (use_sent_folder ? 1 : 0))
346 		return;
347 
348 	extension->priv->use_sent_folder = use_sent_folder;
349 
350 	g_object_notify (G_OBJECT (extension), "use-sent-folder");
351 }
352 
353 /**
354  * e_source_mail_submission_get_transport_uid:
355  * @extension: an #ESourceMailSubmission
356  *
357  * Returns the #ESource:uid of the #ESource that describes the mail
358  * transport to be used for outgoing messages.
359  *
360  * Returns: (nullable): the mail transport #ESource:uid
361  *
362  * Since: 3.6
363  **/
364 const gchar *
e_source_mail_submission_get_transport_uid(ESourceMailSubmission * extension)365 e_source_mail_submission_get_transport_uid (ESourceMailSubmission *extension)
366 {
367 	g_return_val_if_fail (E_IS_SOURCE_MAIL_SUBMISSION (extension), NULL);
368 
369 	return extension->priv->transport_uid;
370 }
371 
372 /**
373  * e_source_mail_submission_dup_transport_uid:
374  * @extension: an #ESourceMailSubmission
375  *
376  * Thread-safe variation of e_source_mail_submission_get_transport_uid().
377  * Use this function when accessing @extension from multiple threads.
378  *
379  * The returned string should be freed with g_free() when no longer needed.
380  *
381  * Returns: (nullable): a newly-allocated copy of #ESourceMailSubmission:transport-uid
382  *
383  * Since: 3.6
384  **/
385 gchar *
e_source_mail_submission_dup_transport_uid(ESourceMailSubmission * extension)386 e_source_mail_submission_dup_transport_uid (ESourceMailSubmission *extension)
387 {
388 	const gchar *protected;
389 	gchar *duplicate;
390 
391 	g_return_val_if_fail (E_IS_SOURCE_MAIL_SUBMISSION (extension), NULL);
392 
393 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
394 
395 	protected = e_source_mail_submission_get_transport_uid (extension);
396 	duplicate = g_strdup (protected);
397 
398 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
399 
400 	return duplicate;
401 }
402 
403 /**
404  * e_source_mail_submission_set_transport_uid:
405  * @extension: an #ESourceMailSubmission
406  * @transport_uid: (nullable): the mail transport #ESource:uid, or %NULL
407  *
408  * Sets the #ESource:uid of the #ESource that describes the mail
409  * transport to be used for outgoing messages.
410  *
411  * Since: 3.6
412  **/
413 void
e_source_mail_submission_set_transport_uid(ESourceMailSubmission * extension,const gchar * transport_uid)414 e_source_mail_submission_set_transport_uid (ESourceMailSubmission *extension,
415                                             const gchar *transport_uid)
416 {
417 	g_return_if_fail (E_IS_SOURCE_MAIL_SUBMISSION (extension));
418 
419 	e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
420 
421 	if (g_strcmp0 (extension->priv->transport_uid, transport_uid) == 0) {
422 		e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
423 		return;
424 	}
425 
426 	g_free (extension->priv->transport_uid);
427 	extension->priv->transport_uid = g_strdup (transport_uid);
428 
429 	e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
430 
431 	g_object_notify (G_OBJECT (extension), "transport-uid");
432 }
433 
434 /**
435  * e_source_mail_submission_get_replies_to_origin_folder:
436  * @extension: an #ESourceMailSubmission
437  *
438  * Returns whether save replies in the folder of the message
439  * being replied to, instead of the Sent folder.
440  *
441  * Returns: whether save replies in the folder of the message being replied to
442  *
443  * Since: 3.8
444  **/
445 gboolean
e_source_mail_submission_get_replies_to_origin_folder(ESourceMailSubmission * extension)446 e_source_mail_submission_get_replies_to_origin_folder (ESourceMailSubmission *extension)
447 {
448 	g_return_val_if_fail (E_IS_SOURCE_MAIL_SUBMISSION (extension), FALSE);
449 
450 	return extension->priv->replies_to_origin_folder;
451 }
452 
453 /**
454  * e_source_mail_submission_set_replies_to_origin_folder:
455  * @extension: an #ESourceMailSubmission
456  * @replies_to_origin_folder: new value
457  *
458  * Sets whether save replies in the folder of the message
459  * being replied to, instead of the Sent folder.
460  *
461  * Since: 3.8
462  **/
463 void
e_source_mail_submission_set_replies_to_origin_folder(ESourceMailSubmission * extension,gboolean replies_to_origin_folder)464 e_source_mail_submission_set_replies_to_origin_folder (ESourceMailSubmission *extension,
465                                                        gboolean replies_to_origin_folder)
466 {
467 	g_return_if_fail (E_IS_SOURCE_MAIL_SUBMISSION (extension));
468 
469 	if (extension->priv->replies_to_origin_folder == replies_to_origin_folder)
470 		return;
471 
472 	extension->priv->replies_to_origin_folder = replies_to_origin_folder;
473 
474 	g_object_notify (G_OBJECT (extension), "replies-to-origin-folder");
475 }
476