Add new ESource classes.
[platform/upstream/evolution-data-server.git] / libedataserver / e-source-selectable.c
1 /*
2  * e-source-selectable.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-selectable
21  * @include: libedataserver/e-source-selectable.h
22  * @short_description: Base class for selectable data sources
23  * @see_also: #ESourceAddressBook, #ESourceCalendar, #ESourceMemoList,
24  *            #ESourceTaskList
25  *
26  * #ESourceSelectable is an abstract base class for data sources
27  * that can be selected in an #ESourceSelector or similar widget.
28  **/
29
30 #include "e-source-selectable.h"
31
32 #include <libedataserver/e-data-server-util.h>
33
34 #define E_SOURCE_SELECTABLE_GET_PRIVATE(obj) \
35         (G_TYPE_INSTANCE_GET_PRIVATE \
36         ((obj), E_TYPE_SOURCE_SELECTABLE, ESourceSelectablePrivate))
37
38 struct _ESourceSelectablePrivate {
39         GMutex *property_lock;
40         gchar *color;
41         gboolean selected;
42 };
43
44 enum {
45         PROP_0,
46         PROP_COLOR,
47         PROP_SELECTED
48 };
49
50 G_DEFINE_ABSTRACT_TYPE (
51         ESourceSelectable,
52         e_source_selectable,
53         E_TYPE_SOURCE_BACKEND)
54
55 static void
56 source_selectable_set_property (GObject *object,
57                                 guint property_id,
58                                 const GValue *value,
59                                 GParamSpec *pspec)
60 {
61         switch (property_id) {
62                 case PROP_COLOR:
63                         e_source_selectable_set_color (
64                                 E_SOURCE_SELECTABLE (object),
65                                 g_value_get_string (value));
66                         return;
67
68                 case PROP_SELECTED:
69                         e_source_selectable_set_selected (
70                                 E_SOURCE_SELECTABLE (object),
71                                 g_value_get_boolean (value));
72                         return;
73         }
74
75         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
76 }
77
78 static void
79 source_selectable_get_property (GObject *object,
80                                 guint property_id,
81                                 GValue *value,
82                                 GParamSpec *pspec)
83 {
84         switch (property_id) {
85                 case PROP_COLOR:
86                         g_value_take_string (
87                                 value,
88                                 e_source_selectable_dup_color (
89                                 E_SOURCE_SELECTABLE (object)));
90                         return;
91
92                 case PROP_SELECTED:
93                         g_value_set_boolean (
94                                 value,
95                                 e_source_selectable_get_selected (
96                                 E_SOURCE_SELECTABLE (object)));
97                         return;
98         }
99
100         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
101 }
102
103 static void
104 source_selectable_finalize (GObject *object)
105 {
106         ESourceSelectablePrivate *priv;
107
108         priv = E_SOURCE_SELECTABLE_GET_PRIVATE (object);
109
110         g_mutex_free (priv->property_lock);
111
112         g_free (priv->color);
113
114         /* Chain up to parent's finalize() method. */
115         G_OBJECT_CLASS (e_source_selectable_parent_class)->finalize (object);
116 }
117
118 static void
119 e_source_selectable_class_init (ESourceSelectableClass *class)
120 {
121         GObjectClass *object_class;
122
123         g_type_class_add_private (class, sizeof (ESourceSelectablePrivate));
124
125         object_class = G_OBJECT_CLASS (class);
126         object_class->set_property = source_selectable_set_property;
127         object_class->get_property = source_selectable_get_property;
128         object_class->finalize = source_selectable_finalize;
129
130         /* We do not provide an extension name,
131          * which is why the class is abstract. */
132
133         g_object_class_install_property (
134                 object_class,
135                 PROP_COLOR,
136                 g_param_spec_string (
137                         "color",
138                         "Color",
139                         "Textual specification of a color",
140                         "#becedd",
141                         G_PARAM_READWRITE |
142                         G_PARAM_CONSTRUCT |
143                         G_PARAM_STATIC_STRINGS |
144                         E_SOURCE_PARAM_SETTING));
145
146         g_object_class_install_property (
147                 object_class,
148                 PROP_SELECTED,
149                 g_param_spec_boolean (
150                         "selected",
151                         "Selected",
152                         "Whether the data source is selected",
153                         TRUE,
154                         G_PARAM_READWRITE |
155                         G_PARAM_CONSTRUCT |
156                         G_PARAM_STATIC_STRINGS |
157                         E_SOURCE_PARAM_SETTING));
158 }
159
160 static void
161 e_source_selectable_init (ESourceSelectable *extension)
162 {
163         extension->priv = E_SOURCE_SELECTABLE_GET_PRIVATE (extension);
164         extension->priv->property_lock = g_mutex_new ();
165 }
166
167 /**
168  * e_source_selectable_get_color:
169  * @extension: an #ESourceSelectable
170  *
171  * Returns the color specification for the #ESource to which @extension
172  * belongs.  A colored block is often displayed next to the data source's
173  * display name in user interfaces.
174  *
175  * Returns: the color specification for the #ESource
176  *
177  * Since: 3.6
178  **/
179 const gchar *
180 e_source_selectable_get_color (ESourceSelectable *extension)
181 {
182         g_return_val_if_fail (E_IS_SOURCE_SELECTABLE (extension), NULL);
183
184         return extension->priv->color;
185 }
186
187 /**
188  * e_source_selectable_dup_color:
189  * @extension: an #ESourceSelectable
190  *
191  * Thread-safe variation of e_source_selectable_get_color().
192  * Use this function when accessing @extension from multiple threads.
193  *
194  * The returned string should be freed with g_free() when no longer needed.
195  *
196  * Returns: a newly-allocated copy of #ESourceSelectable:color
197  *
198  * Since: 3.6
199  **/
200 gchar *
201 e_source_selectable_dup_color (ESourceSelectable *extension)
202 {
203         const gchar *protected;
204         gchar *duplicate;
205
206         g_return_val_if_fail (E_IS_SOURCE_SELECTABLE (extension), NULL);
207
208         g_mutex_lock (extension->priv->property_lock);
209
210         protected = e_source_selectable_get_color (extension);
211         duplicate = g_strdup (protected);
212
213         g_mutex_unlock (extension->priv->property_lock);
214
215         return duplicate;
216 }
217
218 /**
219  * e_source_selectable_set_color:
220  * @extension: an #ESourceSelectable
221  * @color: (allow-none): a color specification, or %NULL
222  *
223  * Sets the color specification for the #ESource to which @extension
224  * belongs.  A colored block is often displayed next to the data source's
225  * display name in user interfaces.
226  *
227  * The internal copy of @color is automatically stripped of leading and
228  * trailing whitespace.  If the resulting string is empty, %NULL is set
229  * instead.
230  *
231  * Since: 3.6
232  **/
233 void
234 e_source_selectable_set_color (ESourceSelectable *extension,
235                                const gchar *color)
236 {
237         g_return_if_fail (E_IS_SOURCE_SELECTABLE (extension));
238
239         g_mutex_lock (extension->priv->property_lock);
240
241         g_free (extension->priv->color);
242         extension->priv->color = e_util_strdup_strip (color);
243
244         g_mutex_unlock (extension->priv->property_lock);
245
246         g_object_notify (G_OBJECT (extension), "color");
247 }
248
249 /**
250  * e_source_selectable_get_selected:
251  * @extension: an #ESourceSelectable
252  *
253  * Returns the selected state of the #ESource to which @extension belongs.
254  * The selected state is often represented as a checkbox next to the data
255  * source's display name in user interfaces.
256  *
257  * Returns: the selected state for the #ESource
258  *
259  * Since: 3.6
260  **/
261 gboolean
262 e_source_selectable_get_selected (ESourceSelectable *extension)
263 {
264         g_return_val_if_fail (E_IS_SOURCE_SELECTABLE (extension), FALSE);
265
266         return extension->priv->selected;
267 }
268
269 /**
270  * e_source_selectable_set_selected:
271  * @extension: an #ESourceSelectable
272  * @selected: selected state
273  *
274  * Sets the selected state for the #ESource to which @extension belongs.
275  * The selected state is often represented as a checkbox next to the data
276  * source's display name in user interfaces.
277  *
278  * Since: 3.6
279  **/
280 void
281 e_source_selectable_set_selected (ESourceSelectable *extension,
282                                   gboolean selected)
283 {
284         g_return_if_fail (E_IS_SOURCE_SELECTABLE (extension));
285
286         extension->priv->selected = selected;
287
288         g_object_notify (G_OBJECT (extension), "selected");
289 }
290