evolution-3.6.4/modules/cal-config-local/evolution-cal-config-local.c

No issues found

  1 /*
  2  * evolution-cal-config-local.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 <config.h>
 20 #include <glib/gi18n-lib.h>
 21 
 22 #include <libebackend/libebackend.h>
 23 
 24 #include <misc/e-cal-source-config.h>
 25 #include <misc/e-source-config-backend.h>
 26 
 27 #include "e-source-local.h"
 28 
 29 typedef ESourceConfigBackend ECalConfigLocal;
 30 typedef ESourceConfigBackendClass ECalConfigLocalClass;
 31 
 32 typedef struct _Context Context;
 33 
 34 struct _Context {
 35 	GtkWidget *custom_file_checkbox;
 36 	GtkWidget *custom_file_chooser;
 37 	GtkWidget *writable_checkbox;
 38 };
 39 
 40 /* Module Entry Points */
 41 void e_module_load (GTypeModule *type_module);
 42 void e_module_unload (GTypeModule *type_module);
 43 
 44 /* Forward Declarations */
 45 GType e_cal_config_local_get_type (void);
 46 
 47 G_DEFINE_DYNAMIC_TYPE (
 48 	ECalConfigLocal,
 49 	e_cal_config_local,
 50 	E_TYPE_SOURCE_CONFIG_BACKEND)
 51 
 52 static void
 53 cal_config_local_context_free (Context *context)
 54 {
 55 	g_object_unref (context->custom_file_checkbox);
 56 	g_object_unref (context->custom_file_chooser);
 57 	g_object_unref (context->writable_checkbox);
 58 
 59 	g_slice_free (Context, context);
 60 }
 61 
 62 static gboolean
 63 cal_config_local_active_to_custom_file (GBinding *binding,
 64                                         const GValue *source_value,
 65                                         GValue *target_value,
 66                                         gpointer user_data)
 67 {
 68 	Context *context = user_data;
 69 	GtkFileChooser *file_chooser;
 70 	GFile *file = NULL;
 71 
 72 	file_chooser = GTK_FILE_CHOOSER (context->custom_file_chooser);
 73 
 74 	if (g_value_get_boolean (source_value))
 75 		file = gtk_file_chooser_get_file (file_chooser);
 76 
 77 	g_value_take_object (target_value, file);
 78 
 79 	return TRUE;
 80 }
 81 
 82 static gboolean
 83 cal_config_local_custom_file_to_active (GBinding *binding,
 84                                         const GValue *source_value,
 85                                         GValue *target_value,
 86                                         gpointer user_data)
 87 {
 88 	Context *context = user_data;
 89 	GtkFileChooser *file_chooser;
 90 	GFile *file;
 91 	gboolean success;
 92 
 93 	file_chooser = GTK_FILE_CHOOSER (context->custom_file_chooser);
 94 
 95 	file = g_value_get_object (source_value);
 96 
 97 	if (file == NULL) {
 98 		g_value_set_boolean (target_value, FALSE);
 99 		return TRUE;
100 	}
101 
102 	success = gtk_file_chooser_set_file (file_chooser, file, NULL);
103 	g_value_set_boolean (target_value, success);
104 
105 	return success;
106 }
107 
108 static void
109 cal_config_local_file_set_cb (GtkFileChooserButton *button,
110                               GtkWidget *custom_file_checkbox)
111 {
112 	/* This will update ESourceLocal:custom-file. */
113 	g_object_notify (G_OBJECT (custom_file_checkbox), "active");
114 }
115 
116 static void
117 cal_config_local_insert_widgets (ESourceConfigBackend *backend,
118                                  ESource *scratch_source)
119 {
120 	ESourceConfig *config;
121 	ESource *builtin_source;
122 	ESourceRegistry *registry;
123 	ESourceExtension *extension;
124 	GtkFileFilter *filter;
125 	GtkWidget *container;
126 	GtkWidget *widget;
127 	Context *context;
128 	gboolean source_is_builtin = FALSE;
129 	const gchar *extension_name;
130 	const gchar *uid;
131 	gchar *markup;
132 
133 	uid = e_source_get_uid (scratch_source);
134 	config = e_source_config_backend_get_config (backend);
135 	registry = e_source_config_get_registry (config);
136 
137 	/* The built-in sources can't use a custom file. */
138 
139 	builtin_source = e_source_registry_ref_builtin_calendar (registry);
140 	source_is_builtin |= e_source_equal (scratch_source, builtin_source);
141 	g_object_unref (builtin_source);
142 
143 	builtin_source = e_source_registry_ref_builtin_memo_list (registry);
144 	source_is_builtin |= e_source_equal (scratch_source, builtin_source);
145 	g_object_unref (builtin_source);
146 
147 	builtin_source = e_source_registry_ref_builtin_task_list (registry);
148 	source_is_builtin |= e_source_equal (scratch_source, builtin_source);
149 	g_object_unref (builtin_source);
150 
151 	if (source_is_builtin)
152 		return;
153 
154 	context = g_slice_new (Context);
155 
156 	g_object_set_data_full (
157 		G_OBJECT (backend), uid, context,
158 		(GDestroyNotify) cal_config_local_context_free);
159 
160 	widget = gtk_check_button_new_with_label (
161 		_("Use an existing iCalendar (ics) file"));
162 	e_source_config_insert_widget (
163 		config, scratch_source, NULL, widget);
164 	context->custom_file_checkbox = g_object_ref (widget);
165 	gtk_widget_show (widget);
166 
167 	g_signal_connect_swapped (
168 		widget, "toggled",
169 		G_CALLBACK (e_source_config_resize_window), config);
170 
171 	container = e_source_config_get_page (config, scratch_source);
172 
173 	/* Put some extra padding above and below the header. */
174 	widget = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
175 	gtk_alignment_set_padding (GTK_ALIGNMENT (widget), 12, 6, 0, 0);
176 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
177 	gtk_widget_show (widget);
178 
179 	g_object_bind_property (
180 		context->custom_file_checkbox, "active",
181 		widget, "visible",
182 		G_BINDING_SYNC_CREATE);
183 
184 	container = widget;
185 
186 	markup = g_markup_printf_escaped ("<b>%s</b>", _("iCalendar File"));
187 	widget = gtk_label_new (markup);
188 	gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
189 	gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
190 	gtk_container_add (GTK_CONTAINER (container), widget);
191 	gtk_widget_show (widget);
192 	g_free (markup);
193 
194 	filter = gtk_file_filter_new ();
195 	gtk_file_filter_add_mime_type (filter, "text/calendar");
196 
197 	widget = gtk_file_chooser_button_new (
198 		_("Choose an iCalendar file"), GTK_FILE_CHOOSER_ACTION_OPEN);
199 	gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (widget), filter);
200 	e_source_config_insert_widget (
201 		config, scratch_source, _("File:"), widget);
202 	context->custom_file_chooser = g_object_ref (widget);
203 	gtk_widget_show (widget);
204 
205 	g_signal_connect (
206 		widget, "file-set",
207 		G_CALLBACK (cal_config_local_file_set_cb),
208 		context->custom_file_checkbox);
209 
210 	g_object_bind_property (
211 		context->custom_file_checkbox, "active",
212 		widget, "visible",
213 		G_BINDING_SYNC_CREATE);
214 
215 	widget = gtk_check_button_new_with_label (
216 		_("Allow Evolution to update the file"));
217 	e_source_config_insert_widget (
218 		config, scratch_source, NULL, widget);
219 	context->writable_checkbox = g_object_ref (widget);
220 	gtk_widget_show (widget);
221 
222 	g_object_bind_property (
223 		context->custom_file_checkbox, "active",
224 		widget, "visible",
225 		G_BINDING_SYNC_CREATE);
226 
227 	extension_name = E_SOURCE_EXTENSION_LOCAL_BACKEND;
228 	extension = e_source_get_extension (scratch_source, extension_name);
229 
230 	g_object_bind_property_full (
231 		extension, "custom-file",
232 		context->custom_file_checkbox, "active",
233 		G_BINDING_BIDIRECTIONAL |
234 		G_BINDING_SYNC_CREATE,
235 		cal_config_local_custom_file_to_active,
236 		cal_config_local_active_to_custom_file,
237 		context, (GDestroyNotify) NULL);
238 }
239 
240 static gboolean
241 cal_config_local_check_complete (ESourceConfigBackend *backend,
242                                  ESource *scratch_source)
243 {
244 	ESourceLocal *extension;
245 	GtkToggleButton *toggle_button;
246 	Context *context;
247 	GFile *file;
248 	const gchar *extension_name;
249 	const gchar *uid;
250 	gboolean active;
251 
252 	uid = e_source_get_uid (scratch_source);
253 	context = g_object_get_data (G_OBJECT (backend), uid);
254 
255 	/* This function might get called before we install a
256 	 * context for this ESource, in which case just return. */
257 	if (context == NULL)
258 		return FALSE;
259 
260 	extension_name = E_SOURCE_EXTENSION_LOCAL_BACKEND;
261 	extension = e_source_get_extension (scratch_source, extension_name);
262 
263 	file = e_source_local_get_custom_file (extension);
264 
265 	toggle_button = GTK_TOGGLE_BUTTON (context->custom_file_checkbox);
266 	active = gtk_toggle_button_get_active (toggle_button);
267 
268 	/* If toggle button is active we need a valid file. */
269 	return !active || (file != NULL);
270 }
271 
272 static void
273 e_cal_config_local_class_init (ESourceConfigBackendClass *class)
274 {
275 	EExtensionClass *extension_class;
276 
277 	extension_class = E_EXTENSION_CLASS (class);
278 	extension_class->extensible_type = E_TYPE_CAL_SOURCE_CONFIG;
279 
280 	class->parent_uid = "local-stub";
281 	class->backend_name = "local";
282 	class->insert_widgets = cal_config_local_insert_widgets;
283 	class->check_complete = cal_config_local_check_complete;
284 }
285 
286 static void
287 e_cal_config_local_class_finalize (ESourceConfigBackendClass *class)
288 {
289 }
290 
291 static void
292 e_cal_config_local_init (ESourceConfigBackend *backend)
293 {
294 }
295 
296 G_MODULE_EXPORT void
297 e_module_load (GTypeModule *type_module)
298 {
299 	e_source_local_type_register (type_module);
300 	e_cal_config_local_register_type (type_module);
301 }
302 
303 G_MODULE_EXPORT void
304 e_module_unload (GTypeModule *type_module)
305 {
306 }