evolution-3.6.4/widgets/misc/e-cal-source-config.c

No issues found

  1 /*
  2  * e-cal-source-config.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 #include "e-cal-source-config.h"
 20 
 21 #include <config.h>
 22 #include <glib/gi18n-lib.h>
 23 
 24 #include <e-util/e-util.h>
 25 
 26 #define E_CAL_SOURCE_CONFIG_GET_PRIVATE(obj) \
 27 	(G_TYPE_INSTANCE_GET_PRIVATE \
 28 	((obj), E_TYPE_CAL_SOURCE_CONFIG, ECalSourceConfigPrivate))
 29 
 30 struct _ECalSourceConfigPrivate {
 31 	ECalClientSourceType source_type;
 32 	GtkWidget *color_button;
 33 	GtkWidget *default_button;
 34 };
 35 
 36 enum {
 37 	PROP_0,
 38 	PROP_SOURCE_TYPE
 39 };
 40 
 41 G_DEFINE_TYPE (
 42 	ECalSourceConfig,
 43 	e_cal_source_config,
 44 	E_TYPE_SOURCE_CONFIG)
 45 
 46 static ESource *
 47 cal_source_config_ref_default (ESourceConfig *config)
 48 {
 49 	ECalSourceConfigPrivate *priv;
 50 	ESourceRegistry *registry;
 51 
 52 	priv = E_CAL_SOURCE_CONFIG_GET_PRIVATE (config);
 53 	registry = e_source_config_get_registry (config);
 54 
 55 	if (priv->source_type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS)
 56 		return e_source_registry_ref_default_calendar (registry);
 57 	else if (priv->source_type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS)
 58 		return e_source_registry_ref_default_memo_list (registry);
 59 	else if (priv->source_type == E_CAL_CLIENT_SOURCE_TYPE_TASKS)
 60 		return e_source_registry_ref_default_task_list (registry);
 61 
 62 	g_return_val_if_reached (NULL);
 63 }
 64 
 65 static void
 66 cal_source_config_set_default (ESourceConfig *config,
 67                                ESource *source)
 68 {
 69 	ECalSourceConfigPrivate *priv;
 70 	ESourceRegistry *registry;
 71 
 72 	priv = E_CAL_SOURCE_CONFIG_GET_PRIVATE (config);
 73 	registry = e_source_config_get_registry (config);
 74 
 75 	if (priv->source_type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS)
 76 		e_source_registry_set_default_calendar (registry, source);
 77 	else if (priv->source_type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS)
 78 		e_source_registry_set_default_memo_list (registry, source);
 79 	else if (priv->source_type == E_CAL_CLIENT_SOURCE_TYPE_TASKS)
 80 		e_source_registry_set_default_task_list (registry, source);
 81 }
 82 
 83 static void
 84 cal_source_config_set_source_type (ECalSourceConfig *config,
 85                                    ECalClientSourceType source_type)
 86 {
 87 	config->priv->source_type = source_type;
 88 }
 89 
 90 static void
 91 cal_source_config_set_property (GObject *object,
 92                                 guint property_id,
 93                                 const GValue *value,
 94                                 GParamSpec *pspec)
 95 {
 96 	switch (property_id) {
 97 		case PROP_SOURCE_TYPE:
 98 			cal_source_config_set_source_type (
 99 				E_CAL_SOURCE_CONFIG (object),
100 				g_value_get_enum (value));
101 			return;
102 	}
103 
104 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
105 }
106 
107 static void
108 cal_source_config_get_property (GObject *object,
109                                 guint property_id,
110                                 GValue *value,
111                                 GParamSpec *pspec)
112 {
113 	switch (property_id) {
114 		case PROP_SOURCE_TYPE:
115 			g_value_set_enum (
116 				value,
117 				e_cal_source_config_get_source_type (
118 				E_CAL_SOURCE_CONFIG (object)));
119 			return;
120 	}
121 
122 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
123 }
124 
125 static void
126 cal_source_config_dispose (GObject *object)
127 {
128 	ECalSourceConfigPrivate *priv;
129 
130 	priv = E_CAL_SOURCE_CONFIG_GET_PRIVATE (object);
131 
132 	if (priv->color_button != NULL) {
133 		g_object_unref (priv->color_button);
134 		priv->color_button = NULL;
135 	}
136 
137 	if (priv->default_button != NULL) {
138 		g_object_unref (priv->default_button);
139 		priv->default_button = NULL;
140 	}
141 
142 	/* Chain up to parent's dispose() method. */
143 	G_OBJECT_CLASS (e_cal_source_config_parent_class)->dispose (object);
144 }
145 
146 static void
147 cal_source_config_constructed (GObject *object)
148 {
149 	ECalSourceConfigPrivate *priv;
150 	ESource *default_source;
151 	ESource *original_source;
152 	ESourceConfig *config;
153 	GObjectClass *class;
154 	GtkWidget *widget;
155 	const gchar *label;
156 
157 	/* Chain up to parent's constructed() method. */
158 	class = G_OBJECT_CLASS (e_cal_source_config_parent_class);
159 	class->constructed (object);
160 
161 	config = E_SOURCE_CONFIG (object);
162 	priv = E_CAL_SOURCE_CONFIG_GET_PRIVATE (object);
163 
164 	widget = gtk_color_button_new ();
165 	priv->color_button = g_object_ref_sink (widget);
166 	gtk_widget_show (widget);
167 
168 	switch (priv->source_type) {
169 		case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
170 			label = _("Mark as default calendar");
171 			break;
172 		case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
173 			label = _("Mark as default task list");
174 			break;
175 		case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
176 			label = _("Mark as default memo list");
177 			break;
178 		default:
179 			/* No need to translate this string. */
180 			label = "Invalid ECalSourceType value";
181 			g_warn_if_reached ();
182 	}
183 
184 	widget = gtk_check_button_new_with_label (label);
185 	priv->default_button = g_object_ref_sink (widget);
186 	gtk_widget_show (widget);
187 
188 	default_source = cal_source_config_ref_default (config);
189 	original_source = e_source_config_get_original_source (config);
190 
191 	if (original_source != NULL) {
192 		gboolean active;
193 
194 		active = e_source_equal (original_source, default_source);
195 		g_object_set (priv->default_button, "active", active, NULL);
196 	}
197 
198 	g_object_unref (default_source);
199 
200 	e_source_config_insert_widget (
201 		config, NULL, _("Color:"), priv->color_button);
202 
203 	e_source_config_insert_widget (
204 		config, NULL, NULL, priv->default_button);
205 }
206 
207 static const gchar *
208 cal_source_config_get_backend_extension_name (ESourceConfig *config)
209 {
210 	ECalSourceConfig *cal_config;
211 	const gchar *extension_name;
212 
213 	cal_config = E_CAL_SOURCE_CONFIG (config);
214 
215 	switch (e_cal_source_config_get_source_type (cal_config)) {
216 		case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
217 			extension_name = E_SOURCE_EXTENSION_CALENDAR;
218 			break;
219 		case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
220 			extension_name = E_SOURCE_EXTENSION_TASK_LIST;
221 			break;
222 		case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
223 			extension_name = E_SOURCE_EXTENSION_MEMO_LIST;
224 			break;
225 		default:
226 			g_return_val_if_reached (NULL);
227 	}
228 
229 	return extension_name;
230 }
231 
232 static GList *
233 cal_source_config_list_eligible_collections (ESourceConfig *config)
234 {
235 	GQueue trash = G_QUEUE_INIT;
236 	GList *list, *link;
237 
238 	/* Chain up to parent's list_eligible_collections() method. */
239 	list = E_SOURCE_CONFIG_CLASS (e_cal_source_config_parent_class)->
240 		list_eligible_collections (config);
241 
242 	for (link = list; link != NULL; link = g_list_next (link)) {
243 		ESource *source = E_SOURCE (link->data);
244 		ESourceCollection *extension;
245 		const gchar *extension_name;
246 
247 		extension_name = E_SOURCE_EXTENSION_COLLECTION;
248 		extension = e_source_get_extension (source, extension_name);
249 
250 		if (!e_source_collection_get_calendar_enabled (extension))
251 			g_queue_push_tail (&trash, link);
252 	}
253 
254 	/* Remove ineligible collections from the list. */
255 	while ((link = g_queue_pop_head (&trash)) != NULL) {
256 		g_object_unref (link->data);
257 		list = g_list_delete_link (list, link);
258 	}
259 
260 	return list;
261 }
262 
263 static void
264 cal_source_config_init_candidate (ESourceConfig *config,
265                                   ESource *scratch_source)
266 {
267 	ECalSourceConfigPrivate *priv;
268 	ESourceConfigClass *class;
269 	ESourceExtension *extension;
270 	const gchar *extension_name;
271 
272 	/* Chain up to parent's init_candidate() method. */
273 	class = E_SOURCE_CONFIG_CLASS (e_cal_source_config_parent_class);
274 	class->init_candidate (config, scratch_source);
275 
276 	priv = E_CAL_SOURCE_CONFIG_GET_PRIVATE (config);
277 
278 	extension_name = e_source_config_get_backend_extension_name (config);
279 	extension = e_source_get_extension (scratch_source, extension_name);
280 
281 	g_object_bind_property_full (
282 		extension, "color",
283 		priv->color_button, "color",
284 		G_BINDING_BIDIRECTIONAL |
285 		G_BINDING_SYNC_CREATE,
286 		e_binding_transform_string_to_color,
287 		e_binding_transform_color_to_string,
288 		NULL, (GDestroyNotify) NULL);
289 }
290 
291 static void
292 cal_source_config_commit_changes (ESourceConfig *config,
293                                   ESource *scratch_source)
294 {
295 	ECalSourceConfigPrivate *priv;
296 	GtkToggleButton *toggle_button;
297 	ESourceConfigClass *class;
298 	ESource *default_source;
299 
300 	priv = E_CAL_SOURCE_CONFIG_GET_PRIVATE (config);
301 	toggle_button = GTK_TOGGLE_BUTTON (priv->default_button);
302 
303 	/* Chain up to parent's commit_changes() method. */
304 	class = E_SOURCE_CONFIG_CLASS (e_cal_source_config_parent_class);
305 	class->commit_changes (config, scratch_source);
306 
307 	default_source = cal_source_config_ref_default (config);
308 
309 	/* The default setting is a little tricky to get right.  If
310 	 * the toggle button is active, this ESource is now the default.
311 	 * That much is simple.  But if the toggle button is NOT active,
312 	 * then we have to inspect the old default.  If this ESource WAS
313 	 * the default, reset the default to 'system'.  If this ESource
314 	 * WAS NOT the old default, leave it alone. */
315 	if (gtk_toggle_button_get_active (toggle_button))
316 		cal_source_config_set_default (config, scratch_source);
317 	else if (e_source_equal (scratch_source, default_source))
318 		cal_source_config_set_default (config, NULL);
319 
320 	g_object_unref (default_source);
321 }
322 
323 static void
324 e_cal_source_config_class_init (ECalSourceConfigClass *class)
325 {
326 	GObjectClass *object_class;
327 	ESourceConfigClass *source_config_class;
328 
329 	g_type_class_add_private (class, sizeof (ECalSourceConfigPrivate));
330 
331 	object_class = G_OBJECT_CLASS (class);
332 	object_class->set_property = cal_source_config_set_property;
333 	object_class->get_property = cal_source_config_get_property;
334 	object_class->dispose = cal_source_config_dispose;
335 	object_class->constructed = cal_source_config_constructed;
336 
337 	source_config_class = E_SOURCE_CONFIG_CLASS (class);
338 	source_config_class->get_backend_extension_name =
339 		cal_source_config_get_backend_extension_name;
340 	source_config_class->list_eligible_collections =
341 		cal_source_config_list_eligible_collections;
342 	source_config_class->init_candidate = cal_source_config_init_candidate;
343 	source_config_class->commit_changes = cal_source_config_commit_changes;
344 
345 	g_object_class_install_property (
346 		object_class,
347 		PROP_SOURCE_TYPE,
348 		g_param_spec_enum (
349 			"source-type",
350 			"Source Type",
351 			"The iCalendar object type",
352 			E_TYPE_CAL_CLIENT_SOURCE_TYPE,
353 			E_CAL_CLIENT_SOURCE_TYPE_EVENTS,
354 			G_PARAM_READWRITE |
355 			G_PARAM_CONSTRUCT_ONLY |
356 			G_PARAM_STATIC_STRINGS));
357 }
358 
359 static void
360 e_cal_source_config_init (ECalSourceConfig *config)
361 {
362 	config->priv = E_CAL_SOURCE_CONFIG_GET_PRIVATE (config);
363 }
364 
365 GtkWidget *
366 e_cal_source_config_new (ESourceRegistry *registry,
367                          ESource *original_source,
368                          ECalClientSourceType source_type)
369 {
370 	g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
371 
372 	if (original_source != NULL)
373 		g_return_val_if_fail (E_IS_SOURCE (original_source), NULL);
374 
375 	return g_object_new (
376 		E_TYPE_CAL_SOURCE_CONFIG, "registry", registry,
377 		"original-source", original_source, "source-type",
378 		source_type, NULL);
379 }
380 
381 ECalClientSourceType
382 e_cal_source_config_get_source_type (ECalSourceConfig *config)
383 {
384 	g_return_val_if_fail (E_IS_CAL_SOURCE_CONFIG (config), 0);
385 
386 	return config->priv->source_type;
387 }
388 
389 void
390 e_cal_source_config_add_offline_toggle (ECalSourceConfig *config,
391                                         ESource *scratch_source)
392 {
393 	GtkWidget *widget;
394 	ESourceExtension *extension;
395 	const gchar *extension_name;
396 	const gchar *label;
397 
398 	g_return_if_fail (E_IS_CAL_SOURCE_CONFIG (config));
399 	g_return_if_fail (E_IS_SOURCE (scratch_source));
400 
401 	extension_name = E_SOURCE_EXTENSION_OFFLINE;
402 	extension = e_source_get_extension (scratch_source, extension_name);
403 
404 	switch (e_cal_source_config_get_source_type (config)) {
405 		case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
406 			label = _("Copy calendar contents locally "
407 				  "for offline operation");
408 			break;
409 		case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
410 			label = _("Copy task list contents locally "
411 				  "for offline operation");
412 			break;
413 		case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
414 			label = _("Copy memo list contents locally "
415 				  "for offline operation");
416 			break;
417 		default:
418 			g_return_if_reached ();
419 	}
420 
421 	widget = gtk_check_button_new_with_label (label);
422 	e_source_config_insert_widget (
423 		E_SOURCE_CONFIG (config), scratch_source, NULL, widget);
424 	gtk_widget_show (widget);
425 
426 	g_object_bind_property (
427 		extension, "stay-synchronized",
428 		widget, "active",
429 		G_BINDING_BIDIRECTIONAL |
430 		G_BINDING_SYNC_CREATE);
431 }