Add new ESource classes.
[platform/upstream/evolution-data-server.git] / libedataserver / e-source-alarms.c
1 /*
2  * e-source-alarms.c
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) version 3.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with the program; if not, see <http://www.gnu.org/licenses/>
16  *
17  */
18
19 /**
20  * SECTION: e-source-alarms
21  * @include: libedataserver/e-source-alarms.h
22  * @short_description: #ESource extension for alarm state
23  *
24  * The #ESourceAlarms extension tracks alarm state for a calendar.
25  *
26  * Access the extension as follows:
27  *
28  * |[
29  *   #include <libedataserver/e-source-alarms.h>
30  *
31  *   ESourceAlarms *extension;
32  *
33  *   extension = e_source_get_extension (source, E_SOURCE_EXTENSION_ALARMS);
34  * ]|
35  **/
36
37 #include "e-source-alarms.h"
38
39 #define E_SOURCE_ALARMS_GET_PRIVATE(obj) \
40         (G_TYPE_INSTANCE_GET_PRIVATE \
41         ((obj), E_TYPE_SOURCE_ALARMS, ESourceAlarmsPrivate))
42
43 struct _ESourceAlarmsPrivate {
44         GMutex *property_lock;
45         gboolean include_me;
46         gchar *last_notified;
47 };
48
49 enum {
50         PROP_0,
51         PROP_INCLUDE_ME,
52         PROP_LAST_NOTIFIED
53 };
54
55 G_DEFINE_TYPE (
56         ESourceAlarms,
57         e_source_alarms,
58         E_TYPE_SOURCE_EXTENSION)
59
60 static void
61 source_alarms_set_property (GObject *object,
62                             guint property_id,
63                             const GValue *value,
64                             GParamSpec *pspec)
65 {
66         switch (property_id) {
67                 case PROP_INCLUDE_ME:
68                         e_source_alarms_set_include_me (
69                                 E_SOURCE_ALARMS (object),
70                                 g_value_get_boolean (value));
71                         return;
72
73                 case PROP_LAST_NOTIFIED:
74                         e_source_alarms_set_last_notified (
75                                 E_SOURCE_ALARMS (object),
76                                 g_value_get_string (value));
77                         return;
78         }
79
80         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
81 }
82
83 static void
84 source_alarms_get_property (GObject *object,
85                             guint property_id,
86                             GValue *value,
87                             GParamSpec *pspec)
88 {
89         switch (property_id) {
90                 case PROP_INCLUDE_ME:
91                         g_value_set_boolean (
92                                 value,
93                                 e_source_alarms_get_include_me (
94                                 E_SOURCE_ALARMS (object)));
95                         return;
96
97                 case PROP_LAST_NOTIFIED:
98                         g_value_take_string (
99                                 value,
100                                 e_source_alarms_dup_last_notified (
101                                 E_SOURCE_ALARMS (object)));
102                         return;
103         }
104
105         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
106 }
107
108 static void
109 source_alarms_finalize (GObject *object)
110 {
111         ESourceAlarmsPrivate *priv;
112
113         priv = E_SOURCE_ALARMS_GET_PRIVATE (object);
114
115         g_mutex_free (priv->property_lock);
116
117         g_free (priv->last_notified);
118
119         /* Chain up to parent's finalize() method. */
120         G_OBJECT_CLASS (e_source_alarms_parent_class)->finalize (object);
121 }
122
123 static void
124 e_source_alarms_class_init (ESourceAlarmsClass *class)
125 {
126         GObjectClass *object_class;
127         ESourceExtensionClass *extension_class;
128
129         g_type_class_add_private (class, sizeof (ESourceAlarmsPrivate));
130
131         object_class = G_OBJECT_CLASS (class);
132         object_class->set_property = source_alarms_set_property;
133         object_class->get_property = source_alarms_get_property;
134         object_class->finalize = source_alarms_finalize;
135
136         extension_class = E_SOURCE_EXTENSION_CLASS (class);
137         extension_class->name = E_SOURCE_EXTENSION_ALARMS;
138
139         g_object_class_install_property (
140                 object_class,
141                 PROP_INCLUDE_ME,
142                 g_param_spec_boolean (
143                         "include-me",
144                         "IncludeMe",
145                         "Include this source in alarm notifications",
146                         TRUE,
147                         G_PARAM_READWRITE |
148                         G_PARAM_CONSTRUCT |
149                         G_PARAM_STATIC_STRINGS |
150                         E_SOURCE_PARAM_SETTING));
151
152         g_object_class_install_property (
153                 object_class,
154                 PROP_LAST_NOTIFIED,
155                 g_param_spec_string (
156                         "last-notified",
157                         "LastNotified",
158                         "Last alarm notification (in ISO 8601 format)",
159                         NULL,
160                         G_PARAM_READWRITE |
161                         G_PARAM_CONSTRUCT |
162                         G_PARAM_STATIC_STRINGS |
163                         E_SOURCE_PARAM_SETTING));
164 }
165
166 static void
167 e_source_alarms_init (ESourceAlarms *extension)
168 {
169         extension->priv = E_SOURCE_ALARMS_GET_PRIVATE (extension);
170         extension->priv->property_lock = g_mutex_new ();
171 }
172
173 /**
174  * e_source_alarms_get_include_me:
175  * @extension: an #ESourceAlarms
176  *
177  * Returns whether the user should be alerted about upcoming appointments
178  * in the calendar described by the #ESource to which @extension belongs.
179  *
180  * Alarm daemons such as evolution-alarm-notify can use this property to
181  * decide which calendars to query for upcoming appointments.
182  *
183  * Returns: whether to show alarms for upcoming appointments
184  *
185  * Since: 3.6
186  **/
187 gboolean
188 e_source_alarms_get_include_me (ESourceAlarms *extension)
189 {
190         g_return_val_if_fail (E_IS_SOURCE_ALARMS (extension), FALSE);
191
192         return extension->priv->include_me;
193 }
194
195 /**
196  * e_source_alarms_set_include_me:
197  * @extension: an #ESourceAlarms
198  * @include_me: whether to show alarms for upcoming appointments
199  *
200  * Sets whether the user should be alerted about upcoming appointments in
201  * the calendar described by the #ESource to which @extension belongs.
202  *
203  * Alarm daemons such as evolution-alarm-notify can use this property to
204  * decide which calendars to query for upcoming appointments.
205  *
206  * Since: 3.6
207  **/
208 void
209 e_source_alarms_set_include_me (ESourceAlarms *extension,
210                                 gboolean include_me)
211 {
212         g_return_if_fail (E_IS_SOURCE_ALARMS (extension));
213
214         extension->priv->include_me = include_me;
215
216         g_object_notify (G_OBJECT (extension), "include-me");
217 }
218
219 /**
220  * e_source_alarms_get_last_notified:
221  * @extension: an #ESourceAlarms
222  *
223  * Returns an ISO 8601 formatted timestamp of when the user was last
224  * alerted about an upcoming appointment in the calendar described by
225  * the #ESource to which @extension belongs.  If no valid timestamp
226  * has been set, the function will return %NULL.
227  *
228  * Returns: an ISO 8601 timestamp, or %NULL
229  *
230  * Since: 3.6
231  **/
232 const gchar *
233 e_source_alarms_get_last_notified (ESourceAlarms *extension)
234 {
235         g_return_val_if_fail (E_IS_SOURCE_ALARMS (extension), NULL);
236
237         return extension->priv->last_notified;
238 }
239
240 /**
241  * e_source_alarms_dup_last_notified:
242  * @extension: an #ESourceAlarms
243  *
244  * Thread-safe variation of e_source_alarms_get_last_notified().
245  * Use this function when accessing @extension from multiple threads.
246  *
247  * The returned string should be freed with g_free() when no longer needed.
248  *
249  * Returns: a newly-allocated copy of #ESourceAlarms:last-notified
250  *
251  * Since: 3.6
252  **/
253 gchar *
254 e_source_alarms_dup_last_notified (ESourceAlarms *extension)
255 {
256         const gchar *protected;
257         gchar *duplicate;
258
259         g_return_val_if_fail (E_IS_SOURCE_ALARMS (extension), NULL);
260
261         g_mutex_lock (extension->priv->property_lock);
262
263         protected = e_source_alarms_get_last_notified (extension);
264         duplicate = g_strdup (protected);
265
266         g_mutex_unlock (extension->priv->property_lock);
267
268         return duplicate;
269 }
270
271 /**
272  * e_source_alarms_set_last_notified:
273  * @extension: an #ESourceAlarms
274  * @last_notified: (allow-none): an ISO 8601 timestamp, or %NULL
275  *
276  * Sets an ISO 8601 formatted timestamp of when the user was last
277  * alerted about an upcoming appointment in the calendar described
278  * by the #ESource to which @extension belongs.
279  *
280  * If @last_notified is non-%NULL, the function will validate the
281  * timestamp before setting the #ESourceAlarms:last-notified property.
282  * Invalid timestamps are discarded with a runtime warning.
283  *
284  * Generally, this function should only be called by an alarm daemon
285  * such as evolution-alarm-notify.
286  *
287  * Since: 3.6
288  **/
289 void
290 e_source_alarms_set_last_notified (ESourceAlarms *extension,
291                                    const gchar *last_notified)
292 {
293         g_return_if_fail (E_IS_SOURCE_ALARMS (extension));
294
295         if (last_notified != NULL) {
296                 GTimeVal time_val;
297
298                 if (!g_time_val_from_iso8601 (last_notified, &time_val)) {
299                         g_warning ("Invalid timestamp: %s", last_notified);
300                         return;
301                 }
302         }
303
304         g_mutex_lock (extension->priv->property_lock);
305
306         g_free (extension->priv->last_notified);
307         extension->priv->last_notified = g_strdup (last_notified);
308
309         g_mutex_unlock (extension->priv->property_lock);
310
311         g_object_notify (G_OBJECT (extension), "last-notified");
312 }