1 /*
2 * e-source-autoconfig.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-autoconfig
20 * @include: libedataserver/libedataserver.h
21 * @short_description: #ESource extension for autoconfig settings
22 *
23 * The #ESourceAutoconfig extension keeps a mapping between user-specific
24 * sources and system-wide ones.
25 *
26 * Access the extension as follows:
27 *
28 * |[
29 * #include <libedataserver/libedataserver.h>
30 *
31 * ESourceAutoconfig *extension;
32 *
33 * extension = e_source_get_extension (source, E_SOURCE_EXTENSION_AUTOCONFIG);
34 * ]|
35 **/
36
37 #include "e-source-autoconfig.h"
38
39 struct _ESourceAutoconfigPrivate {
40 gchar *revision;
41 };
42
43 enum {
44 PROP_0,
45 PROP_REVISION
46 };
47
G_DEFINE_TYPE_WITH_PRIVATE(ESourceAutoconfig,e_source_autoconfig,E_TYPE_SOURCE_EXTENSION)48 G_DEFINE_TYPE_WITH_PRIVATE (
49 ESourceAutoconfig,
50 e_source_autoconfig,
51 E_TYPE_SOURCE_EXTENSION)
52
53 static void
54 source_autoconfig_get_property (GObject *object,
55 guint property_id,
56 GValue *value,
57 GParamSpec *pspec)
58 {
59 switch (property_id) {
60 case PROP_REVISION:
61 g_value_take_string (
62 value,
63 e_source_autoconfig_dup_revision (
64 E_SOURCE_AUTOCONFIG (object)));
65 return;
66 }
67
68 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
69 }
70
71 static void
source_autoconfig_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)72 source_autoconfig_set_property (GObject *object,
73 guint property_id,
74 const GValue *value,
75 GParamSpec *pspec)
76 {
77 switch (property_id) {
78 case PROP_REVISION:
79 e_source_autoconfig_set_revision (
80 E_SOURCE_AUTOCONFIG (object),
81 g_value_get_string (value));
82 return;
83 }
84
85 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
86 }
87
88 static void
source_autoconfig_finalize(GObject * object)89 source_autoconfig_finalize (GObject *object)
90 {
91 ESourceAutoconfigPrivate *priv;
92
93 priv = E_SOURCE_AUTOCONFIG (object)->priv;
94
95 g_free (priv->revision);
96
97 /* Chain up to parent's finalize() method. */
98 G_OBJECT_CLASS (e_source_autoconfig_parent_class)->finalize (object);
99 }
100
101 static void
e_source_autoconfig_class_init(ESourceAutoconfigClass * class)102 e_source_autoconfig_class_init (ESourceAutoconfigClass *class)
103 {
104 GObjectClass *object_class;
105 ESourceExtensionClass *extension_class;
106
107 object_class = G_OBJECT_CLASS (class);
108 object_class->set_property = source_autoconfig_set_property;
109 object_class->get_property = source_autoconfig_get_property;
110 object_class->finalize = source_autoconfig_finalize;
111
112 extension_class = E_SOURCE_EXTENSION_CLASS (class);
113 extension_class->name = E_SOURCE_EXTENSION_AUTOCONFIG;
114
115 g_object_class_install_property (
116 object_class,
117 PROP_REVISION,
118 g_param_spec_string (
119 "revision",
120 "Revision",
121 "Identifier to map a particular version of a system-wide source to a user-specific source",
122 "",
123 G_PARAM_READWRITE |
124 G_PARAM_CONSTRUCT |
125 G_PARAM_EXPLICIT_NOTIFY |
126 G_PARAM_STATIC_STRINGS |
127 E_SOURCE_PARAM_SETTING));
128 }
129
130 static void
e_source_autoconfig_init(ESourceAutoconfig * extension)131 e_source_autoconfig_init (ESourceAutoconfig *extension)
132 {
133 extension->priv = e_source_autoconfig_get_instance_private (extension);
134 }
135
136 /**
137 * e_source_autoconfig_get_revision:
138 * @extension: an #ESourceAutoconfig
139 *
140 * Returns the revision of a data source. This maps a particular version of a
141 * system-wide source to a user-specific source.
142 *
143 * If doesn't match, the system-wide source will be copied to the user-specific
144 * evolution config directory, preserving the already present fields that are
145 * not defined by the system-wide source.
146 *
147 * If it matches, no copying is done.
148 *
149 * Returns: revision of the data source
150 *
151 * Since: 3.24
152 **/
153 const gchar *
e_source_autoconfig_get_revision(ESourceAutoconfig * extension)154 e_source_autoconfig_get_revision (ESourceAutoconfig *extension)
155 {
156 g_return_val_if_fail (E_IS_SOURCE_AUTOCONFIG (extension), NULL);
157
158 return extension->priv->revision;
159 }
160
161 /**
162 * e_source_autoconfig_dup_revision:
163 * @extension: an #ESourceAutoconfig
164 *
165 * Thread-safe variation of e_source_autoconfig_get_revision().
166 * Use this function when accessing @extension from multiple threads.
167 *
168 * The returned string should be freed with g_free() when no longer needed.
169 *
170 * Returns: (transfer full): a newly-allocated copy of #ESourceAutoconfig:revision
171 *
172 * Since: 3.24
173 **/
174 gchar *
e_source_autoconfig_dup_revision(ESourceAutoconfig * extension)175 e_source_autoconfig_dup_revision (ESourceAutoconfig *extension)
176 {
177 const gchar *protected;
178 gchar *duplicate;
179
180 g_return_val_if_fail (E_IS_SOURCE_AUTOCONFIG (extension), NULL);
181
182 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
183
184 protected = e_source_autoconfig_get_revision (extension);
185 duplicate = g_strdup (protected);
186
187 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
188
189 return duplicate;
190 }
191
192 /**
193 * e_source_autoconfig_set_revision:
194 * @extension: an #ESourceAutoconfig
195 * @revision: a revision
196 *
197 * Sets the revision used to map a particular version of a system-wide source
198 * to a user-specific source.
199 *
200 * If doesn't match, the system-wide source will be copied to the user-specific
201 * evolution config directory, preserving the already present fields that are
202 * not defined by the system-wide source.
203 *
204 * If it matches, no copying is done.
205 *
206 * The internal copy of @revision is automatically stripped of leading and
207 * trailing whitespace.
208 *
209 * Since: 3.24
210 **/
211 void
e_source_autoconfig_set_revision(ESourceAutoconfig * extension,const gchar * revision)212 e_source_autoconfig_set_revision (ESourceAutoconfig *extension,
213 const gchar *revision)
214 {
215 g_return_if_fail (E_IS_SOURCE_AUTOCONFIG (extension));
216
217 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
218
219 if (e_util_strcmp0 (extension->priv->revision, revision) == 0) {
220 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
221 return;
222 }
223
224 g_free (extension->priv->revision);
225 extension->priv->revision = e_util_strdup_strip (revision);
226
227 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
228
229 g_object_notify (G_OBJECT (extension), "revision");
230 }
231