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 }